Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FE] 생성한 행사 모아보기 페이지 #856

Merged
merged 7 commits into from
Dec 18, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion client/src/apis/request/event.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Event, EventCreationData, EventId, EventName, User} from 'types/serviceType';
import {CreatedEvents, Event, EventCreationData, EventId, EventName, User} from 'types/serviceType';
import {WithErrorHandlingStrategy} from '@errors/RequestGetError';

import {ADMIN_API_PREFIX, USER_API_PREFIX} from '@apis/endpointPrefix';
Expand Down Expand Up @@ -53,3 +53,9 @@ export const requestPatchUser = async (args: RequestPatchUser) => {
},
});
};

export const requestGetCreatedEvents = async () => {
return await requestGet<CreatedEvents>({
endpoint: `${USER_API_PREFIX}/mine`,
});
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import {css} from '@emotion/react';

import {WithTheme} from '@components/Design/type/withTheme';

export const inProgressCheckStyle = ({inProgress, theme}: WithTheme<{inProgress: boolean}>) =>
css({
display: 'flex',
alignItems: 'center',
gap: '0.125rem',
border: `1px solid ${inProgress ? theme.colors.primary : theme.colors.gray}`,
borderRadius: '0.5rem',
padding: '0.25rem 0.375rem',
height: '1.25rem',

'.in-progress-check-text': {
color: inProgress ? theme.colors.primary : theme.colors.gray,
paddingTop: '0.0625rem',
},
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/** @jsxImportSource @emotion/react */
import {useNavigate} from 'react-router-dom';

import Text from '@HDcomponents/Text/Text';

import {useTheme} from '@components/Design';

import Flex from '../Flex/Flex';
import Input from '../Input/Input';

import {CreatedEventItemProps, CreatedEventListProps} from './CreatedEvent.type';
import {inProgressCheckStyle} from './CreatedEvent.style';

function InProgressCheck({inProgress}: {inProgress: boolean}) {
const {theme} = useTheme();

return (
<div css={inProgressCheckStyle({theme, inProgress})}>
<Text size="tiny" className="in-progress-check-text">
{inProgress ? '진행' : '완료'}
</Text>
</div>
);
}

function CreatedEventItem({createdEvent}: CreatedEventItemProps) {
const navigate = useNavigate();
const onClick = () => {
navigate(`/event/${createdEvent.eventId}/admin`);
};

return (
<Flex
justifyContent="spaceBetween"
alignItems="center"
height="2.5rem"
padding="0.5rem 1rem"
paddingInline="0.5rem"
>
<Flex gap="0.5rem" alignItems="center" onClick={onClick}>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

확실히 그래요.. 이런 스타일을 복사 붙여 넣기 하면서 유지 보수가 어려워진다는 점 공감합니다.
이런 자주 사용하는 레이아웃을 따로 정의해서 가져온다면 개선할 수 있지 않을까 생각합니다.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

추가로 여기 Flex 컴포넌트의 onClick 궁금한 점이 있습니다.
onClick의 범위가 아래 사진 영역만큼인가요?

이미지 설명

아니면 가로 전체인가요?

이미지 설명

토다리는 어떤 경우가 사용자에게 더 편한 경험을 줄 것이라고 생각하는지 궁금합니다!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오호 아래 영역이 더 나을 것이라고 판단되네요.
위에 onClick을 넣도록 변경하겠습니다~

95b2fae

<InProgressCheck inProgress={createdEvent.isFinished} />
<Text size="bodyBold" color="onTertiary">
{createdEvent.eventName}
</Text>
</Flex>
</Flex>
);
}

function CreatedEventList({createdEvents, eventName, onSearch, placeholder}: CreatedEventListProps) {
return (
<Flex
flexDirection="column"
width="100%"
backgroundColor="white"
padding="0.5rem 1rem"
paddingInline="0.5rem"
gap="0.5rem"
height="100%"
cssProp={{borderRadius: '1rem'}}
>
<Input inputType="search" value={eventName} onChange={onSearch} placeholder={placeholder} />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

원하는 행사 서칭까지 가능하도록 해주시다니~ 👍

{createdEvents.length !== 0 &&
createdEvents.map(createdEvent => <CreatedEventItem key={createdEvent.eventId} createdEvent={createdEvent} />)}
</Flex>
);
}

export default CreatedEventList;
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import {CreatedEvent} from './../../../../types/serviceType';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

types/serviceType로 import 할 수 없었나요?.?


export interface CreatedEventItemProps {
createdEvent: CreatedEvent;
}

export interface CreatedEventListProps {
eventName: string;
onSearch: ({target}: React.ChangeEvent<HTMLInputElement>) => void;
placeholder: string;
createdEvents: CreatedEvent[];
}
1 change: 1 addition & 0 deletions client/src/constants/queryKeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const QUERY_KEYS = {
images: 'images',
kakaoClientId: 'kakao-client-id',
kakaoLogin: 'kakao-login',
createdEvents: 'createdEvents',
};

export default QUERY_KEYS;
1 change: 1 addition & 0 deletions client/src/constants/routerUrls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export const ROUTER_URLS = {
event: EVENT,
login: '/login',
myPage: '/mypage',
createdEvents: '/mypage/events',
guestEventLogin: `${EVENT_WITH_EVENT_ID}/admin/guest/login`,
memberEventLogin: `${EVENT_WITH_EVENT_ID}/admin/member/login`,
kakaoLoginRedirectUri: process.env.KAKAO_REDIRECT_URI,
Expand Down
2 changes: 1 addition & 1 deletion client/src/hooks/queries/bill/useRequestGetBillDetails.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const useRequestGetBillDetails = ({billId, ...props}: WithErrorHandlingStrategy<
const eventId = getEventIdByUrl();

const {data, ...rest} = useQuery({
queryKey: [QUERY_KEYS.billDetails, billId],
queryKey: [QUERY_KEYS.billDetails, billId, eventId],
queryFn: () => requestGetBillDetails({eventId, billId, ...props}),
});

Expand Down
23 changes: 23 additions & 0 deletions client/src/hooks/queries/event/useRequestGetCreatedEvents.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import {useQuery} from '@tanstack/react-query';

import {requestGetCreatedEvents} from '@apis/request/event';

import QUERY_KEYS from '@constants/queryKeys';

const useRequestGetCreatedEvents = () => {
const {data, ...rest} = useQuery({
queryKey: [QUERY_KEYS.createdEvents],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

유저 로그아웃이 없으니깐 토다리가 작성해준 대로 이 부분은 queryKey 배열의 두 번째 인자 신경 쓰지 않아도 될 것 같아요!

queryFn: () => requestGetCreatedEvents(),
select: data => ({
...data,
events: data.events.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

select 좋은 것 같아요! 이 시간 비교는 밀리초 단위로 비교되는 건가요?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아뇨 10^-6 까지 비교합니다 ㅋㅋ

}),
});

return {
events: data?.events,
...rest,
};
};

export default useRequestGetCreatedEvents;
2 changes: 1 addition & 1 deletion client/src/hooks/queries/event/useRequestGetEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const useRequestGetEvent = ({...props}: WithErrorHandlingStrategy | null = {}) =
const eventId = getEventIdByUrl();

const {data, ...rest} = useSuspenseQuery({
queryKey: [QUERY_KEYS.event],
queryKey: [QUERY_KEYS.event, eventId],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

원래는 이벤트 생성을 했을 때 removeQueries를 사용해서 캐시를 전부 날려주었기 때문에 문제가 없었는데, 이제는 생성 외에 다른 이벤트 접근이 가능해서 일어난 문제였네요.. 이것 외에 또 다른 부작용은 없었나요?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

우선 손수 테스트 한 케이스에선 별도로 없었습니다~!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오호 좋아요~

queryFn: () => requestGetEvent({eventId, ...props}),
});

Expand Down
2 changes: 1 addition & 1 deletion client/src/hooks/queries/member/useRequestGetAllMembers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const useRequestGetAllMembers = ({...props}: WithErrorHandlingStrategy | null =
const eventId = getEventIdByUrl();

const {data, ...rest} = useQuery({
queryKey: [QUERY_KEYS.allMembers],
queryKey: [QUERY_KEYS.allMembers, eventId],
queryFn: () => requestGetAllMembers({eventId, ...props}),
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const useRequestGetCurrentMembers = ({...props}: WithErrorHandlingStrategy | nul
const eventId = getEventIdByUrl();

const {data, ...rest} = useQuery({
queryKey: [QUERY_KEYS.currentMembers],
queryKey: [QUERY_KEYS.currentMembers, eventId],
queryFn: () => requestGetCurrentMembers({eventId, ...props}),
});

Expand Down
2 changes: 1 addition & 1 deletion client/src/hooks/queries/report/useRequestGetReports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const useRequestGetReports = ({...props}: WithErrorHandlingStrategy | null = {})
const eventId = getEventIdByUrl();

const {data, ...rest} = useQuery({
queryKey: [QUERY_KEYS.reports],
queryKey: [QUERY_KEYS.reports, eventId],
queryFn: () => requestGetReports({eventId, ...props}),
});

Expand Down
2 changes: 1 addition & 1 deletion client/src/hooks/queries/step/useRequestGetSteps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const useRequestGetSteps = ({...props}: WithErrorHandlingStrategy | null = {}) =
const eventId = getEventIdByUrl();

const queryResult = useQuery({
queryKey: [QUERY_KEYS.steps],
queryKey: [QUERY_KEYS.steps, eventId],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오우.. 다른 부분도 꼼꼼히 체크해서 eventId 넣어주셨군요! 쵝오

queryFn: () => requestGetSteps({eventId, ...props}),
});

Expand Down
55 changes: 55 additions & 0 deletions client/src/pages/CreatedEventsPage/CreatedEventsPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import {css} from '@emotion/react';
import {useEffect, useState} from 'react';

import CreatedEventList from '@components/Design/components/CreatedEvent/CreatedEvent';
import useRequestGetCreatedEvents from '@hooks/queries/event/useRequestGetCreatedEvents';

import {MainLayout, Top, TopNav} from '@components/Design';

export default function CreatedEventsPage() {
const [eventName, setEventName] = useState('');
const {events} = useRequestGetCreatedEvents();
const [matchedEvents, setMatchedEvents] = useState(events);

useEffect(() => {
setMatchedEvents(events?.filter(event => event.eventName.includes(eventName)));
}, [eventName, events]);

const onSearch = (e: React.ChangeEvent<HTMLInputElement>) => {
setEventName(e.target.value);
};

return (
<MainLayout backgroundColor="white">
<TopNav>
<TopNav.Item displayName="뒤로가기" noEmphasis routePath="-1" />
</TopNav>
<div
css={css`
display: flex;
flex-direction: column;
gap: 1rem;
padding: 1rem;
`}
>
<Top>
<Top.Line text="지금까지 주최했던 행사를" emphasize={['주최했던 행사']} />
<Top.Line text="확인해 보세요" />
</Top>
</div>
<div
css={css`
display: flex;
padding-inline: 0.5rem;
`}
>
<CreatedEventList
createdEvents={matchedEvents ?? []}
eventName={eventName}
onSearch={onSearch}
placeholder="행사 이름 검색"
/>
</div>
</MainLayout>
);
}
7 changes: 6 additions & 1 deletion client/src/pages/MyPage/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import {useNavigate} from 'react-router-dom';

import {Button, Flex, FunnelLayout, MainLayout, Text, TextButton, TopNav, useTheme} from '@components/Design';

import {ROUTER_URLS} from '@constants/routerUrls';

import {mockImageStyle} from './MyPage.style';
import Container from './Container';

const MyPage = () => {
const {theme} = useTheme();
const navigate = useNavigate();

return (
<MainLayout backgroundColor="gray">
Expand Down Expand Up @@ -33,7 +38,7 @@ const MyPage = () => {
<TextButton textColor="onTertiary" textSize="body">
기본 계좌 번호 설정하기
</TextButton>
<TextButton textColor="onTertiary" textSize="body">
<TextButton textColor="onTertiary" textSize="body" onClick={() => navigate(ROUTER_URLS.createdEvents)}>
내가 만든 행사 목록 보기
</TextButton>
<TextButton textColor="onTertiary" textSize="body">
Expand Down
5 changes: 5 additions & 0 deletions client/src/router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const LoginPage = lazy(() => import('@pages/LoginPage'));
const MyPage = lazy(() => import('@pages/MyPage'));
const LoginRedirectPage = lazy(() => import('@pages/LoginPage/LoginRedirectPage'));
const LoginFailFallback = lazy(() => import('@pages/LoginPage/LoginFailFallback'));
const CreatedEventsPage = lazy(() => import('@pages/CreatedEventsPage/CreatedEventsPage'));

const router = createBrowserRouter([
{
Expand Down Expand Up @@ -135,6 +136,10 @@ const router = createBrowserRouter([
path: ROUTER_URLS.qrCode,
element: <QRCodePage />,
},
{
path: ROUTER_URLS.createdEvents,
element: <CreatedEventsPage />,
},
],
},
{
Expand Down
11 changes: 11 additions & 0 deletions client/src/types/serviceType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,14 @@ export interface ImageFile {
id: number;
url: string;
}

export interface CreatedEvent {
eventId: string;
eventName: string;
isFinished: boolean;
createdAt: string;
}

export interface CreatedEvents {
events: CreatedEvent[];
}
Loading