Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion src/app/login/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export default function Login() {
return (
<div className="flex min-h-screen flex-col items-center justify-center">
<LoginForm />
{/* <DummyUser /> */}
<DummyUser />
</div>
);
}
14 changes: 14 additions & 0 deletions src/app/meeting/[category]/(modal)/[id]/[status]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
'use client';

import { redirect } from 'next/navigation';

export default function NeedLoginModal({
params,
}: {
params: { category: string; id: string; status: string };
}) {
const category = params.category;
const meetingId = Number(params.id);

redirect(`/meeting/${category}/${meetingId}`);
}
29 changes: 29 additions & 0 deletions src/app/meeting/[category]/@modal/[id]/(.)APPROVED/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
'use client';

import ModalRegisterComplete from '@/app/meeting/_features/modal-content/ModalRegisterComplete';
import ModalPortal from '@/components/ui/modal/ModalPortal';
import { useRouter } from 'next/navigation';

export default function UserListModal({
params,
}: {
params: { category: string; id: number };
}) {
const router = useRouter();
const category = params.category;
const meetingId = Number(params.id);

return (
<ModalPortal
isOpen={true}
onClose={() =>
router.push(`/meeting/${category}/${meetingId}`, { scroll: false })
}
confirmText="내 모임 보러가기"
cancelText="확인"
modalClassName="w-96"
>
<ModalRegisterComplete />
</ModalPortal>
);
}
40 changes: 40 additions & 0 deletions src/app/meeting/[category]/@modal/[id]/(.)CANCEL/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
'use client';

import ModalCancel from '@/app/meeting/_features/modal-content/ModalCancel';
import ModalPortal from '@/components/ui/modal/ModalPortal';
import { useMeetingQuitMutation } from '@/hooks/mutations/useMeetingMutation';
import { useRouter } from 'next/navigation';

export default function UserListModal({
params,
}: {
params: { category: string; id: number };
}) {
const router = useRouter();
const category = params.category;
const meetingId = Number(params.id);

const { mutate: cancelMutate } = useMeetingQuitMutation({
meetingId: meetingId,
});

const handleConfirm = () => {
cancelMutate();
router.back();
};

return (
<ModalPortal
isOpen={true}
onClose={() =>
router.push(`/meeting/${category}/${meetingId}`, { scroll: false })
}
onConfirm={handleConfirm}
confirmText="신청 취소"
cancelText="돌아가기"
modalClassName="w-96"
>
<ModalCancel />
</ModalPortal>
);
}
30 changes: 30 additions & 0 deletions src/app/meeting/[category]/@modal/[id]/(.)PENDING/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
'use client';

import ModalRegisterWait from '@/app/meeting/_features/modal-content/ModalRegisterWait';
import ModalPortal from '@/components/ui/modal/ModalPortal';
import { useRouter } from 'next/navigation';

export default function UserListModal({
params,
}: {
params: { category: string; id: number };
}) {
const router = useRouter();
const category = params.category;
const meetingId = Number(params.id);

return (
<ModalPortal
isOpen={true}
onClose={() =>
router.push(`/meeting/${category}/${meetingId}`, { scroll: false })
}
onConfirm={() => router.push('/my-meeting/my?type=joined')}
confirmText="내 모임 보러가기"
cancelText="확인"
modalClassName="w-96"
>
<ModalRegisterWait />
</ModalPortal>
);
}
55 changes: 55 additions & 0 deletions src/app/meeting/[category]/@modal/[id]/(.)intro-input/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
'use client';

import ModalRegisterInput from '@/app/meeting/_features/modal-content/ModalRegisterInput';
import ModalPortal from '@/components/ui/modal/ModalPortal';
import { useMeetingMutation } from '@/hooks/mutations/useMeetingMutation';
import { translateCategoryNameToEng } from '@/util/searchFilter';
import { useRouter } from 'next/navigation';
import { useState } from 'react';

export default function UserListModal({
params,
}: {
params: { category: string; id: number };
}) {
const router = useRouter();
const [value, setValue] = useState('');

const meetingId = Number(params.id);
const category = params.category;

const { mutate } = useMeetingMutation({
onSuccessCallback: (status: string) =>
router.push(
`/meeting/${translateCategoryNameToEng(category)}/${meetingId}/${status}`,
{ scroll: false },
),
onErrorCallback: () =>
router.push(
`/meeting/${translateCategoryNameToEng(category)}/${meetingId}`,
{ scroll: false },
),
meetingId: meetingId,
});

const handleConfirm = () => {
mutate({ message: value });
setValue('');
router.push(
`/meeting/${translateCategoryNameToEng(category)}/${meetingId}/intro-input`,
{ scroll: false },
);
};

return (
<ModalPortal
isOpen={true}
onConfirm={handleConfirm}
confirmText="보내기"
cancelText="취소"
modalClassName="w-[520px] py-[12px]"
>
<ModalRegisterInput value={value} setValue={setValue} />
</ModalPortal>
);
}
22 changes: 22 additions & 0 deletions src/app/meeting/[category]/@modal/[id]/(.)need-login/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
'use client';

import ModalPortal from '@/components/ui/modal/ModalPortal';
import { useRouter } from 'next/navigation';

export default function UserListModal() {
const router = useRouter();

return (
<ModalPortal
isOpen={true}
onConfirm={() => router.push('/login')}
confirmText="로그인"
cancelText="취소"
modalClassName="w-96"
>
<div className="text-cg8 typo-head3 flex w-full justify-center">
<p className="text-white">로그인이 필요한 서비스입니다.</p>
</div>
</ModalPortal>
);
}
42 changes: 42 additions & 0 deletions src/app/meeting/[category]/@modal/[id]/(.)register/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
'use client';

import ModalBeforeLogin from '@/app/meeting/_features/modal-content/ModalBeforeLogin';
import ModalPortal from '@/components/ui/modal/ModalPortal';
import { meetingKeys } from '@/hooks/queries/useMeetingQueries';
import { translateCategoryNameToEng } from '@/util/searchFilter';
import { useQueryClient } from '@tanstack/react-query';
import { useRouter } from 'next/navigation';
import { MeetingDetail } from 'service/api/meeting';

export default function UserListModal({
params,
}: {
params: { category: string; id: number };
}) {
const router = useRouter();
const meetingId = Number(params.id);
const queryClient = useQueryClient();

const meeting = queryClient.getQueryData<MeetingDetail>(
meetingKeys.detailInfo(meetingId),
);

if (!meeting) return null;

return (
<ModalPortal
isOpen={true}
onConfirm={() =>
router.push(
`/meeting/${translateCategoryNameToEng(meeting.categoryTitle)}/${meeting.meetingId}/intro-input`,
{ scroll: false },
)
}
confirmText="신청"
cancelText="취소"
modalClassName="w-96"
>
<ModalBeforeLogin meeting={meeting!} />
</ModalPortal>
);
}
3 changes: 3 additions & 0 deletions src/app/meeting/[category]/@modal/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function DefaultModal() {
return null; // 기본적으로 모달 없음
}
54 changes: 28 additions & 26 deletions src/app/meeting/_features/CardRightSection.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,31 @@
'use client';

import { Button } from '@/components/ui/Button';
import Modal from '@/components/ui/modal/Modal';
import useCard from '@/hooks/useCard';
import { getAccessToken } from '@/lib/serverActions';
import { getDDay } from '@/util/date';
import { translateCategoryNameToEng } from '@/util/searchFilter';
import { useRouter } from 'next/navigation';
import { MeetingDetail } from 'service/api/meeting';

const CardRightSection = ({ meeting }: { meeting: MeetingDetail }) => {
const {
handleModalOpen,
isModalOpen,
setIsModalOpen,
handleModalConfirm,
modalValue,
renderModalContent,
} = useCard(meeting);
const router = useRouter();

const handleRegister = async () => {
const token = await getAccessToken();

// 로그인 전인지 확인
if (!token) {
router.push(
`/meeting/${translateCategoryNameToEng(meeting.categoryTitle)}/${meeting.meetingId}/need-login`,
{ scroll: false },
);
} else {
router.push(
`/meeting/${translateCategoryNameToEng(meeting.categoryTitle)}/${meeting.meetingId}/register`,
{ scroll: false },
);
}
};

return (
<div className="flex w-full flex-col justify-end gap-[24px] py-[16px] md:p-[16px] lg:h-[208px] lg:w-[318px]">
Expand All @@ -33,33 +44,24 @@ const CardRightSection = ({ meeting }: { meeting: MeetingDetail }) => {
인원이 꽉찼어요
</Button>
) : (
<Button
className="w-full"
onClick={() => handleModalOpen('registerCheck')}
>
<Button className="w-full" onClick={handleRegister}>
신청하기
</Button>
)
) : (
<Button
className="w-full"
variant={'outline'}
onClick={() => handleModalOpen('cancel')}
onClick={() =>
router.push(
`/meeting/${translateCategoryNameToEng(meeting.categoryTitle)}/${meeting.meetingId}/CANCEL`,
{ scroll: false },
)
}
>
신청 취소하기
</Button>
)}

<Modal
isOpen={isModalOpen}
onClose={() => setIsModalOpen(false)}
onConfirm={handleModalConfirm}
confirmText={modalValue.confirmText}
cancelText={modalValue.cancelText}
modalClassName={`w-96 ${modalValue.modalClassName}`}
>
{renderModalContent()}
</Modal>
</div>
);
};
Expand Down
13 changes: 7 additions & 6 deletions src/app/meeting/_features/modal-content/ModalRegisterInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,21 @@
import { Dispatch, SetStateAction } from 'react';

const ModalRegisterInput = ({
ment,
setMent,
value,
setValue,
}: {
ment: string;
setMent: Dispatch<SetStateAction<string>>;
value: string;
setValue: Dispatch<SetStateAction<string>>;
Copy link
Contributor

Choose a reason for hiding this comment

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

setState 함수를 직접적으로 props로 전달하는 것은 자식 컴포넌트에 부모 컴포넌트 데이터 변경 주도권을 넘겨주는것과 같아서 좋지 않다고 알고 있습니당! 콜백 함수로 감싸서 전달하는 방식이 더 좋을 것 같아요
해당 내용과 관련된 블로그 링크 첨부할테니 참고하시면 좋을 것 같습니다!

https://velog.io/@thisishwarang/React-setState-%EC%9E%90%EC%B2%B4%EB%A5%BC-props%EB%A1%9C-%EC%A0%84%EB%8B%AC%ED%95%98%EC%A7%80-%EB%A7%90%EC%95%84%EC%95%BC-%ED%95%98%EB%8A%94-%EC%9D%B4%EC%9C%A0

}) => {
return (
<div className="flex flex-col items-center justify-center gap-[24px]">
<h3 className="typo-head3 text-Cgray800">
마이 페이지에 등록된 정보가 주최자에게 전달됩니다!
</h3>
<textarea
value={ment}
onChange={(e) => setMent(e.target.value)}
value={value}
onChange={(e) => setValue(e.target.value)}
onClick={(e) => e.stopPropagation()}
className="typo-button1 h-[120px] w-full resize-none rounded-[12px] bg-Cgray200 px-[16px] py-[14px] text-Cgray500 placeholder:text-Cgray400"
placeholder="인삿말을 남겨주세요!"
/>
Expand Down
9 changes: 3 additions & 6 deletions src/hooks/mutations/useMeetingMutation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,18 @@ const useMeetingMutation = ({
onErrorCallback,
meetingId,
}: {
onSuccessCallback: (state: string) => Promise<void>;
onSuccessCallback: (status: string) => void;
onErrorCallback: () => void;
meetingId: number;
}) => {
const queryClient = useQueryClient();
const { showToast } = useToast();

return useMutation({
mutationFn: ({ message }: { message: string }) =>
postMeetingRegister({ meetingId, message }),
onSuccess: async (res) => {
if (res.status === 'APPROVED') {
onSuccessCallback('registerComplete');
} else if (res.status === 'PENDING') {
onSuccessCallback('registerWait');
}
onSuccessCallback(res.status);
queryClient.invalidateQueries({
queryKey: meetingKeys.detailInfo(meetingId),
});
Expand Down
Loading
Loading