- 커피챗 진행 방식 - ( - - option.value === field.value)} - onChange={(value) => field.onChange(value)} - > - - - - - {MEETING_TYPE_OPTIONS.map((option) => ( - - ))} - - - - )} - /> -
유의사항 @@ -49,7 +49,7 @@ export default function MyInfoForm() { fixedHeight={126} lineBreakPlaceholder={['• 직무 경험이나 관심 분야를 적어주면 더 좋아요!']} isError={!!errors.memberInfo?.introduction} - errorMessage='자기소개를 입력해주세요' + errorMessage={errors.memberInfo?.introduction?.message} onChange={(e) => field.onChange(e.target.value)} /> @@ -61,7 +61,7 @@ export default function MyInfoForm() { fixedHeight={150} lineBreakPlaceholder={['• 직무 경험이나 관심 분야를 적어주면 더 좋아요!']} isError={!!errors.memberInfo?.introduction} - errorMessage='자기소개를 입력해주세요' + errorMessage={errors.memberInfo?.introduction?.message} onChange={(e) => field.onChange(e.target.value)} /> diff --git a/src/components/coffeechat/upload/CoffeechatForm/schema.ts b/src/components/coffeechat/upload/CoffeechatForm/schema.ts index 72770ed12..2740b06e1 100644 --- a/src/components/coffeechat/upload/CoffeechatForm/schema.ts +++ b/src/components/coffeechat/upload/CoffeechatForm/schema.ts @@ -21,7 +21,7 @@ const coffeeChatInfoSchema = yup.object().shape({ .min(1, '커피챗 주제 키워드를 선택해주세요') .required('커피챗 주제 키워드를 선택해주세요'), topic: yup.string().required('커피챗 주제 소개를 입력해주세요'), - meetingType: yup.string().nullable(), + meetingType: yup.string().nullable().required('커피챗 진행 방식을 선택해주세요'), guideline: yup.string().nullable(), }); diff --git a/src/components/coffeechat/upload/CoffeechatForm/types.ts b/src/components/coffeechat/upload/CoffeechatForm/types.ts index ec70fbd26..a2f76ac5e 100644 --- a/src/components/coffeechat/upload/CoffeechatForm/types.ts +++ b/src/components/coffeechat/upload/CoffeechatForm/types.ts @@ -1,15 +1,15 @@ export interface CoffeechatFormContent { memberInfo: { - career: string[] | string | null; - introduction: string | null; + career: string[] | string | null | undefined; + introduction: string | null | undefined; }; coffeeChatInfo: { - sections: string[]; - bio: string | null; - topicTypes: string[]; - topic: string | null; - meetingType: string | null; - guideline: string | null; + sections: string[] | undefined; + bio: string | null | undefined; + topicTypes: string[] | undefined; + topic: string | null | undefined; + meetingType: string | null | undefined; + guideline: string | null | undefined; }; } diff --git a/src/components/common/form/TextFieldLineBreak/index.tsx b/src/components/common/form/TextFieldLineBreak/index.tsx index 720d64d31..7a762392f 100644 --- a/src/components/common/form/TextFieldLineBreak/index.tsx +++ b/src/components/common/form/TextFieldLineBreak/index.tsx @@ -38,6 +38,7 @@ export default function TextFieldLineBreak({ errorMessage={errorMessage} onChange={onChange} autoFocus={isError} + disableEnterSubmit /> {!value && ( diff --git a/src/pages/coffeechat/edit/[id].tsx b/src/pages/coffeechat/edit/[id].tsx index 807f907ec..46152d49b 100644 --- a/src/pages/coffeechat/edit/[id].tsx +++ b/src/pages/coffeechat/edit/[id].tsx @@ -1,17 +1,30 @@ +import { DialogOptionType, useDialog, useToast } from '@sopt-makers/ui'; +import { useMutation, useQueryClient } from '@tanstack/react-query'; +import { useRouter } from 'next/router'; +import { playgroundLink } from 'playground-common/export'; +import { FieldValues } from 'react-hook-form'; + import { editCoffeechat } from '@/api/endpoint/coffeechat/editCoffeechat'; +import { useGetCoffeechatDetail } from '@/api/endpoint/coffeechat/getCoffeechatDetail'; +import { useGetMemberOfMe } from '@/api/endpoint/members/getMemberOfMe'; import AuthRequired from '@/components/auth/AuthRequired'; +import CoffeechatLoading from '@/components/coffeechat/Loading'; import CoffeechatUploadPage from '@/components/coffeechat/page/CoffeechatUploadPage'; import { CoffeechatFormContent } from '@/components/coffeechat/upload/CoffeechatForm/types'; -import Loading from '@/components/common/Loading'; +import useStringRouterQuery from '@/hooks/useStringRouterQuery'; import { setLayout } from '@/utils/layout'; -import { useMutation } from '@tanstack/react-query'; -import { FieldValues } from 'react-hook-form'; const CoffeechatEdit = () => { - // const router = useRouter(); - // const queryClient = useQueryClient(); + const { query, status } = useStringRouterQuery(['id'] as const); + const memberId = status === 'success' ? query.id : ''; + const router = useRouter(); + const queryClient = useQueryClient(); + const { data: me } = useGetMemberOfMe(); + const { data: openerProfile, isError, error, isPending: isDetailPending } = useGetCoffeechatDetail(memberId); + const { open } = useDialog(); + const { open: toastOpen } = useToast(); - const { mutate, isPending } = useMutation({ + const { mutate, isPending: isEditPending } = useMutation({ mutationFn: (reqeustBody: CoffeechatFormContent) => editCoffeechat.request({ ...reqeustBody }), }); @@ -21,46 +34,98 @@ const CoffeechatEdit = () => { mutate( { - memberInfo: { ...memberInfo, career: memberInfo.career ? memberInfo.career[0] : null }, - coffeeChatInfo: { ...coffeeChatInfo }, + memberInfo: { + ...memberInfo, + career: memberInfo.career + ? Array.isArray(memberInfo.career) + ? memberInfo.career[0] + : memberInfo.career + : null, + }, + coffeeChatInfo: { ...coffeeChatInfo, meetingType: coffeeChatInfo.meetingType ?? '온/오프라인' }, }, { onSuccess: async () => { - // TODO: 쿼리 무효화 및 페이지 이동 처리 - // queryClient.invalidateQueries({ queryKey: 'coffeechat' }); - // await router.push(playgroundLink.coffeechatdetail()); + queryClient.invalidateQueries({ + predicate: (query) => ['getRecentCoffeeChat', 'getMembersCoffeeChat'].includes(query.queryKey[0] as string), + }); + toastOpen({ icon: 'success', content: '커피챗이 오픈됐어요! 경험을 나눠주셔서 감사해요.' }); + + await router.push(playgroundLink.coffeechatDetail(me?.id ?? '')); }, onError: (error) => { - console.error('업로드 실패:', error); + const option: DialogOptionType = { + title: `${error.message}`, + description: ``, + type: 'single', + typeOptions: { + approveButtonText: '확인', + buttonFunction: async () => await router.push(playgroundLink.coffeechat()), + }, + }; + open(option); }, }, ); }; - // TODO: 데이터 get api 패칭 필요 + // FIXME: url에서 직접 id 변경하여 접속하는 경우, 다른 사람의 커피챗 수정 불가능하도록 막기 + // useEffect(() => { + // if (memberId !== String(me?.id)) { + // open({ + // title: '다른 사람의 커피챗은 수정할 수 없어요', + // description: ``, + // type: 'single', + // typeOptions: { + // approveButtonText: '확인', + // buttonFunction: async () => await router.push(playgroundLink.coffeechat()), + // }, + // }); + // } + // }, [me?.id, memberId, open, router]); + + // FIXME: 존재하지 않는 커피챗 id 접속 + // useEffect(() => { + // if (isError) { + // const axiosError = error as AxiosError; + + // open({ + // title: `${axiosError?.response?.data}`, + // description: ``, + // type: 'single', + // typeOptions: { + // approveButtonText: '확인', + // buttonFunction: async () => await router.push(playgroundLink.coffeechat()), + // }, + // }); + // } + // }, [error, isError, open, router]); + const defaultForm = { memberInfo: { - career: '주니어 (0-3년)', //TODO: 데이터 가져와서 배열에 담기 - introduction: '안녕하세요! 저는 프론트엔드 개발자로 다양한 프로젝트 경험을 쌓고 있습니다.', + career: openerProfile?.career, + introduction: openerProfile?.introduction, }, coffeeChatInfo: { - sections: ['프론트', '디자인'], - bio: '프론트엔드 커리어 상담', - topicTypes: ['포트폴리오', '이력서/자소서'], - topic: '프론트엔드 개발자로서의 커리어에 대해 상담하고 싶습니다.\n포트폴리오 제작과 인터뷰 팁도 나누고자 합니다.', - meetingType: '온라인', - guideline: '시간 약속을 꼭 지켜주세요.\n질문은 미리 준비해 오시면 더욱 좋습니다.', + sections: openerProfile?.sections, + bio: openerProfile?.bio, + topicTypes: openerProfile?.topicTypeList, + topic: openerProfile?.topic, + meetingType: openerProfile?.meetingType, + guideline: openerProfile?.guideline, }, }; - if (isPending) { - // TODO: 데이터 get 해올 때의 isPending도 추가 - return ; + if (isDetailPending || isEditPending) { + return ; } return ( - + {(status === 'loading' || status === 'error') && null} + {status === 'success' && openerProfile && memberId === String(me?.id) && !isError ? ( + + ) : null} ); }; diff --git a/src/pages/coffeechat/index.tsx b/src/pages/coffeechat/index.tsx index 8b958ade6..49e0b6b59 100644 --- a/src/pages/coffeechat/index.tsx +++ b/src/pages/coffeechat/index.tsx @@ -1,17 +1,17 @@ -import AuthRequired from "@/components/auth/AuthRequired"; -import CoffeeChatCategory from "@/components/coffeechat/CoffeeChatCategory"; -import CoffeeChatRecentList from "@/components/coffeechat/CoffeeRecentChatList"; -import Header from "@/components/common/Header"; -import { setLayout } from "@/utils/layout"; +import AuthRequired from '@/components/auth/AuthRequired'; +import CoffeeChatCategory from '@/components/coffeechat/CoffeeChatCategory'; +import CoffeeChatRecentList from '@/components/coffeechat/CoffeeRecentChatList'; +import { setLayout } from '@/utils/layout'; -const CoffeeChatMainPage=()=>{ - return ( +const CoffeeChatMainPage = () => { + return ( - - - ) -} + + + + ); +}; setLayout(CoffeeChatMainPage, 'headerFooter'); setLayout(CoffeeChatMainPage, 'header'); setLayout(CoffeeChatMainPage, 'headerOnlyDesktop'); -export default CoffeeChatMainPage; \ No newline at end of file +export default CoffeeChatMainPage; diff --git a/src/pages/coffeechat/upload.tsx b/src/pages/coffeechat/upload.tsx index 662ded0bd..e5672153d 100644 --- a/src/pages/coffeechat/upload.tsx +++ b/src/pages/coffeechat/upload.tsx @@ -1,16 +1,21 @@ -import { useMutation } from '@tanstack/react-query'; +import { DialogOptionType, useDialog, useToast } from '@sopt-makers/ui'; +import { useMutation, useQueryClient } from '@tanstack/react-query'; +import { useRouter } from 'next/router'; +import { playgroundLink } from 'playground-common/export'; +import { FieldValues } from 'react-hook-form'; import { uploadCoffeechat } from '@/api/endpoint/coffeechat/uploadCoffeechat'; import AuthRequired from '@/components/auth/AuthRequired'; +import CoffeechatLoading from '@/components/coffeechat/Loading'; import CoffeechatUploadPage from '@/components/coffeechat/page/CoffeechatUploadPage'; import { CoffeechatFormContent } from '@/components/coffeechat/upload/CoffeechatForm/types'; -import Loading from '@/components/common/Loading'; import { setLayout } from '@/utils/layout'; -import { FieldValues } from 'react-hook-form'; const CoffeechatUpload = () => { - // const router = useRouter(); - // const queryClient = useQueryClient(); + const router = useRouter(); + const queryClient = useQueryClient(); + const { open: toastOpen } = useToast(); + const { open } = useDialog(); const { mutate, isPending } = useMutation({ mutationFn: (reqeustBody: CoffeechatFormContent) => uploadCoffeechat.request({ ...reqeustBody }), @@ -22,42 +27,40 @@ const CoffeechatUpload = () => { mutate( { - memberInfo: { ...memberInfo, career: memberInfo.career ? memberInfo.career[0] : null }, - coffeeChatInfo: { ...coffeeChatInfo }, + memberInfo: { + ...memberInfo, + career: memberInfo.career + ? Array.isArray(memberInfo.career) + ? memberInfo.career[0] + : memberInfo.career + : null, + }, + coffeeChatInfo: { ...coffeeChatInfo, meetingType: coffeeChatInfo.meetingType ?? '온/오프라인' }, }, { onSuccess: async () => { - // TODO: 쿼리 무효화 및 페이지 이동 처리 - // queryClient.invalidateQueries({ queryKey: 'coffeechat' }); - // await router.push(playgroundLink.coffeechat()); + queryClient.invalidateQueries({ + predicate: (query) => ['getRecentCoffeeChat', 'getMembersCoffeeChat'].includes(query.queryKey[0] as string), + }); + toastOpen({ icon: 'success', content: '커피챗이 오픈됐어요! 경험을 나눠주셔서 감사해요.' }); + await router.push(playgroundLink.coffeechat()); }, onError: (error) => { - console.error('업로드 실패:', error); + const option: DialogOptionType = { + title: `${error.message}`, + description: ``, + type: 'single', + typeOptions: { + approveButtonText: '확인', + buttonFunction: async () => await router.push(playgroundLink.coffeechat()), + }, + }; + open(option); }, }, ); }; - // const onSubmit = (data: CoffeechatFormContent) => { - // const { memberInfo, coffeeChatInfo } = data; - // mutate( - // { - // memberInfo: { ...memberInfo, career: memberInfo.career ? memberInfo.career[0] : null }, - // coffeeChatInfo: { ...coffeeChatInfo }, - // }, - // { - // onSuccess: async () => { - // // TODO: 쿼리 무효화 및 페이지 이동 처리 - // // queryClient.invalidateQueries({ queryKey: 'coffeechat' }); - // // await router.push(playgroundLink.coffeechat()); - // }, - // onError: (error) => { - // console.error('업로드 실패:', error); - // }, - // }, - // ); - // }; - const defaultForm = { memberInfo: { career: null, @@ -74,7 +77,7 @@ const CoffeechatUpload = () => { }; if (isPending) { - return ; + return ; } return (