Skip to content

Commit

Permalink
Merge pull request #74 from jakkemomo/general_fixes
Browse files Browse the repository at this point in the history
General fixes
  • Loading branch information
algoritmi4 authored Aug 25, 2024
2 parents 1d08660 + 96b72dc commit 0f4b93b
Show file tree
Hide file tree
Showing 76 changed files with 670 additions and 744 deletions.
3 changes: 3 additions & 0 deletions public/images/svg.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 6 additions & 6 deletions src/app/appRouter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,12 @@ const appRouter = createBrowserRouter([
<RemoteProfileView/>
)
},
{
{
path: '/subscription',
element: (
<SubscriptionPage/>
),
},
},
{
path: '/profile/edit',
element: (
Expand Down Expand Up @@ -95,21 +95,21 @@ const appRouter = createBrowserRouter([
{
path: '/',
element: (
<HomePage/>
<HomePage />
),
},
{
path: '/events/:eventId',
element: (
<EventPage/>
<EventPage />
)
},
{
path: '*',
element: (
<NonFound/>
<NonFound />
),
}
},
]
},
{
Expand Down
16 changes: 14 additions & 2 deletions src/app/guards/RouteGuard.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useMyDetailsQuery } from "@/entities/profile/api/profileApi";
import { ReactElement } from "react";
import { ReactElement, useEffect, useState } from "react";
import { Navigate } from "react-router-dom";

interface GuestGuardProps {
Expand All @@ -8,11 +8,23 @@ interface GuestGuardProps {
}

function RouteGuard({ children, type }: GuestGuardProps) {
const [isError, setIsError] = useState(false);

const {
isError,
isError: isProfileError,
isSuccess
} = useMyDetailsQuery();

useEffect(() => {
if (isProfileError) {
setIsError(true);
}

if (isSuccess) {
setIsError(false);
}
}, [isSuccess, isProfileError]);

if (isError && type === 'guest') {
return <Navigate to="/" replace />
}
Expand Down
92 changes: 50 additions & 42 deletions src/entities/event/ui/EventCard.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {ReactElement, useEffect, useState} from "react";
import {MouseEvent, ReactElement, useEffect, useState} from "react";
import {IEvent} from "../model/types";
import { Link } from "react-router-dom";
import { useNavigate } from "react-router-dom";
import Svg from "@/shared/ui/Svg";
import { useLikeEventMutation, useUnlikeEventMutation } from "../api/eventApi";
import cx from 'classnames';
Expand All @@ -18,10 +18,14 @@ export function EventCard({
}: IEventCard): ReactElement {
const [isFavorite, setIsFavorite] = useState(event.is_favorite);

const navigate = useNavigate();

const [likeEvent] = useLikeEventMutation();
const [unlikeEvent] = useUnlikeEventMutation();

const onLike = () => {
const onLike = (e: MouseEvent<SVGSVGElement>) => {
e.stopPropagation();

setIsFavorite(true);

likeEvent(event.id)
Expand All @@ -30,7 +34,9 @@ export function EventCard({
.catch(() => setIsFavorite(false));
}

const onUnlike = () => {
const onUnlike = (e: MouseEvent<SVGSVGElement>) => {
e.stopPropagation();

setIsFavorite(false);

unlikeEvent(event.id)
Expand All @@ -46,12 +52,16 @@ export function EventCard({
return (
<div className={
cx(
"w-full flex flex-col", {
"relative w-full flex flex-col my-3 ml-2.5", {
'max-w-[225px] mr-[40px]': size === 'sm',
'max-w-[270px] mr-[45px]': size === 'lg'
},
extraCardClass
)}>
<div
onClick={() => navigate(`/events/${event.id}`)}
className="absolute inset-[-10px] hoverscreen:hover:border-1 border-solid border-main-violet-600 hoverscreen:hover:rounded-def cursor-pointer z-10"
/>
<div className="flex justify-between">
<p className={
cx(
Expand All @@ -64,50 +74,48 @@ export function EventCard({
id="heart-icon"
className={
cx(
"cursor-pointer", {
"cursor-pointer z-20 duration-150 hoverscreen:hover:opacity-70", {
'w-5 h-5': size === 'sm',
'w-6 h-6': size === 'lg'
}
)}
viewBox="0 0 24 24"
onClick={isFavorite ? onUnlike : onLike}
extraUseClass={isFavorite ? "!fill-but-primary stroke-but-primary" : "stroke-text-black"}
onClick={isFavorite ? (e) => onUnlike(e) : (e) => onLike(e)}
extraUseClass={isFavorite ? "!fill-main-violet-600 stroke-main-violet-600" : "stroke-text-black"}
/>
</div>
<Link to={`/events/${event.id}`}>
<figure className={
cx(
"group flex flex-col cursor-pointer rounded-12 max-h-[188px] mt-[7px] overflow-hidden", {
'max-h-[157px]': size === 'sm',
'max-h-[188px]': size === 'lg'
}
)}>
<img className={
cx(
"group-hover:scale-105 duration-300 ease-in-out rounded-t-def object-cover", {
'h-[120px]': size === 'sm',
'h-[143px]': size === 'lg'
}
)
} src={`https://storage.googleapis.com/meetups-dev/media/${event.image_url}`} alt={`Изображение ивента ${event.name}`} />
<div className={
cx(
`h-[45px] bg-gray rounded-b-def flex items-center justify-center pl-[16px] pr-[7px] relative ${event.name.length > 21 && "before:w-[60px] before:rounded-b-[12px] before:absolute before:right-0 before:h-full before:bg-text-fade-out"}`, {
'h-[37px]': size === 'sm',
'h-[45px]': size === 'lg'
}
)}>
<figcaption className={
cx(
"group-hover:font-bold capitalize font-semibold text-text-black overflow-hidden whitespace-nowrap text-clip", {
'text-[16px]': size === 'sm',
'text-[20px]': size === 'lg'
}
)
}>{event.name}</figcaption>
</div>
</figure>
</Link>
<figure className={
cx(
"flex flex-col cursor-pointer rounded-12 max-h-[188px] mt-[7px] overflow-hidden", {
'max-h-[157px]': size === 'sm',
'max-h-[188px]': size === 'lg'
}
)}>
<img className={
cx(
"duration-300 ease-in-out rounded-t-def object-cover", {
'h-[120px]': size === 'sm',
'h-[143px]': size === 'lg'
}
)
} src={`https://storage.googleapis.com/meetups-dev/media/${event.image_url}`} alt={`Изображение ивента ${event.name}`} />
<div className={
cx(
`h-[45px] bg-secondary-100 rounded-b-def flex items-center justify-center relative ${event.name.length > 21 && "before:w-[60px] before:rounded-b-[12px] before:absolute before:right-0 before:h-full before:bg-text-fade-out pl-4"}`, {
'h-[37px]': size === 'sm',
'h-[45px]': size === 'lg'
}
)}>
<figcaption className={
cx(
"capitalize font-semibold text-text-black overflow-hidden whitespace-nowrap text-clip", {
'text-[16px]': size === 'sm',
'text-[20px]': size === 'lg'
}
)
}>{event.name}</figcaption>
</div>
</figure>
<div className={
cx(
"flex justify-between", {
Expand Down
2 changes: 1 addition & 1 deletion src/entities/eventParticipants/ui/ParticipantCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ function ParticipantCard({
onClick={isOwnerView ? () => onKick(participant.id) : undefined}
iconId={isOwnerView ? "delete-person-icon" : "add-person-icon"}
size="lg"
importance={isOwnerView ? "primary-opposite" : "primary"}
importance={isOwnerView ? "tetriary" : "primary"}
extraClass="ml-auto"
disabled={isButtonDisabled}
/>
Expand Down
2 changes: 1 addition & 1 deletion src/entities/eventParticipants/ui/ParticipantsPopup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ function ParticipantsPopup({ eventId, owner, isOpen, handleClose }: IParticipant
next={() => setOffset((state) => state + 10)}
loader={<p>Loading...</p>}
height={372}
className="pr-[22px] rounded-l-[20px] [&::-webkit-scrollbar]:w-1 [&::-webkit-scrollbar-track]:bg-[#F3F3F5] [&::-webkit-scrollbar-track]:rounded-[10px] [&::-webkit-scrollbar-thumb]:bg-text-light-gray [&::-webkit-scrollbar-thumb]:rounded-[10px]"
className="pr-[22px] rounded-l-[20px] [&::-webkit-scrollbar]:w-1 [&::-webkit-scrollbar-track]:bg-[#F3F3F5] [&::-webkit-scrollbar-track]:rounded-[10px] [&::-webkit-scrollbar-thumb]:bg-secondary-600 [&::-webkit-scrollbar-thumb]:rounded-[10px]"
>
{
collectPartiсipants().participants.map((el) => (
Expand Down
13 changes: 9 additions & 4 deletions src/entities/profile/api/profileApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {baseApi} from '@/shared/api'
import {ProfileDetails, ProfileId, ProfileFollowing, IFollowResponse, ProfileDetailsDto, IFollowRequest, IGetFollowStatusRequest} from "@/entities/profile/model/types";
import {mapProfileDetails} from "@/entities/profile/lib/mapProfileDetails";
import { EditProfileValidationSchema } from '@/features/editProfile/model/editProfileFormSchema';
import { CITIES_TAG, PROFILE_TAG, SESSION_TAG } from '@/shared/api/tags';
import { CITIES_TAG, FOLLOW_STATUS_TAG, FOLLOWERS_TAG, FOLLOWINGS_TAG, PROFILE_TAG, SESSION_TAG } from '@/shared/api/tags';

export const profileApi = baseApi.injectEndpoints({
endpoints: (build) => ({
Expand All @@ -27,29 +27,34 @@ export const profileApi = baseApi.injectEndpoints({
url: `/users/${userId}/following/`,
params: { username },
}),
providesTags: [FOLLOWINGS_TAG]
}),
getFollowStatus: build.query<ProfileFollowing, IGetFollowStatusRequest>({
query: ({ user_id, followed_user_id }) => ({
url: `/users/${followed_user_id}/follow/${user_id}/status/`,
method: 'GET'
})
}),
providesTags: [FOLLOW_STATUS_TAG]
}),
getFollowers: build.query<ProfileFollowing[], ProfileId>({
query: ({userId}) => ({
url: `/users/${userId}/followers/`,
}),
providesTags: [FOLLOWERS_TAG]
}),
follow: build.mutation<IFollowResponse, ProfileId>({
query: ({userId}) => ({
url: `/users/${userId}/follow/`,
method: 'POST',
})
}),
invalidatesTags: [FOLLOWINGS_TAG, FOLLOWERS_TAG, FOLLOW_STATUS_TAG]
}),
unFollow: build.mutation<void, ProfileId>({
query: ({userId}) => ({
url: `/users/${userId}/unfollow/`,
method: 'DELETE',
})
}),
invalidatesTags: [FOLLOWINGS_TAG, FOLLOWERS_TAG, FOLLOW_STATUS_TAG]
}),
editProfile: build.mutation<EditProfileValidationSchema, ProfileId>({
query: ({userId, ...patch}) => ({
Expand Down
11 changes: 8 additions & 3 deletions src/entities/profile/model/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,21 +47,26 @@ export interface ProfileDetailsDto extends ProfileDto {
city: ICity
}

export type IFollowStatus = 'ACCEPTED' | 'PENDING' | 'DECLINED' | 'NOT_FOLLOWED' | undefined;
export enum FollowStatusEnum {
ACCEPTED = 'ACCEPTED',
PENDING = 'PENDING',
DECLINED = 'DECLINED',
NOT_FOLLOWED = 'NOT_FOLLOWED'
}

export interface ProfileFollowing {
user: number;
follower: number;
username: string;
status: IFollowStatus;
status: FollowStatusEnum;
image_url: string
}

export interface IFollowResponse {
user: number;
follower: number;
username: string;
status: IFollowStatus;
status: FollowStatusEnum;
image_url: string
}

Expand Down
12 changes: 7 additions & 5 deletions src/entities/review/ui/ReviewCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ export interface IReviewCard {
export function ReviewCard({ review }: IReviewCard): ReactElement {
const [isOpen, setIsOpen] = useState(false);

const { ref, isOverflowY } = useOverflowY();
const { ref, isOverflowY } = useOverflowY({
deps: [review.review]
});

const renderStars = (rating: number) => {
const starsArr = [];
Expand Down Expand Up @@ -40,21 +42,21 @@ export function ReviewCard({ review }: IReviewCard): ReactElement {
return (
<div className="flex flex-col bg-white w-[375px] min-h-[255px]">
<div className="flex">
<div className="flex flex-col rounded-t-[14px] w-full bg-custom-gray px-6 pt-[19px]">
<div className="flex flex-col rounded-t-[14px] w-full bg-secondary-100 px-6 pt-[19px]">
<h3 className="text-[18px] leading-[23px] font-semibold text-text-black">{review.created_by.username}</h3>
<div className="flex mt-[5px]">
{renderStars(review.rating)}
</div>
</div>
<div className="bg-custom-gray shrink-0">
<div className="bg-secondary-100 shrink-0">
<div className="flex justify-end w-[70px] h-full ml-auto bg-white rounded-es-[25px]">
<img src={`${config.BASE_IMAGE_URL}${review.created_by.image_url}`} alt={`Аватар пользователя ${review.created_by.username}`} className="profile-pic h-[60px] w-[60px] rounded-full"/>
</div>
</div>
</div>
<div className="flex flex-col grow bg-custom-gray rounded-r-[14px] rounded-es-[14px] px-6 py-[18px]">
<div className="flex flex-col grow bg-secondary-100 rounded-r-[14px] rounded-es-[14px] px-6 py-[18px]">
<div ref={ref} className={`relative overflow-y-hidden ${isOpen ? "" : "max-h-[115px]"}`}>
<p className={`text-lg whitespace-pre-wrap break-words font-light text-neutral-600 after:absolute after:w-[137px] after:h-[18px] after:bottom-0 after:right-0 after:bg-review-text-fade-out after:block"}`}>{review.review}</p>
<p className={`text-lg whitespace-pre-wrap break-words font-light text-neutral-600 ${isOpen ? "" : "after:absolute after:w-[137px] after:h-[18px] after:bottom-0 after:right-0 after:bg-review-text-fade-out after:block"}`}>{review.review}</p>
</div>
<div className={`flex items-center justify-between ${isOpen ? "mt-[17px]" : "mt-auto"}`}>
<p className="text-[14px] leading-[18px] text-[#737373]">{new Date(review.created_at).toLocaleDateString()}</p>
Expand Down
Loading

0 comments on commit 0f4b93b

Please sign in to comment.