diff --git a/apps/shelter/src/pages/settings/account/index.tsx b/apps/shelter/src/pages/settings/account/index.tsx index 0c8e621f..0962e811 100644 --- a/apps/shelter/src/pages/settings/account/index.tsx +++ b/apps/shelter/src/pages/settings/account/index.tsx @@ -29,7 +29,7 @@ const phoneRegx2 = /^(0(2|3[1-3]|4[1-4]|5[1-5]|6[1-4]))-(\d{3,4})-(\d{4})$/; const accountSchema = z.object({ name: z.string().trim().min(2, { message: '이름은 2글자 이상입니다' }), - address: z.string().min(3, { message: '보호소 주소 정보는 필수입니다' }), + address: z.string().min(1, { message: '보호소 주소 정보는 필수입니다' }), addressDetail: z .string() .trim() diff --git a/apps/shelter/src/pages/volunteers/detail/index.tsx b/apps/shelter/src/pages/volunteers/detail/index.tsx index 753e4668..bb72913d 100644 --- a/apps/shelter/src/pages/volunteers/detail/index.tsx +++ b/apps/shelter/src/pages/volunteers/detail/index.tsx @@ -5,14 +5,16 @@ import { HStack, Text, useDisclosure, + useToast, VStack, } from '@chakra-ui/react'; +import { useMutation } from '@tanstack/react-query'; import { Suspense, useEffect, useState } from 'react'; import { useNavigate, useParams } from 'react-router-dom'; import AlertModal from 'shared/components/AlertModal'; import ImageCarousel from 'shared/components/ImageCarousel'; import InfoTextList from 'shared/components/InfoTextList'; -import { LabelProps } from 'shared/components/Label'; +import Label from 'shared/components/Label'; import LabelText from 'shared/components/LabelText'; import useDetailHeaderStore from 'shared/store/detailHeaderStore'; import { @@ -21,16 +23,21 @@ import { getDDay, } from 'shared/utils/date'; +import { + closeShelterRecruitment, + deleteShelterRecruitment, +} from '@/apis/recruitment'; + import useGetVolunteerDetail from './_hooks/useGetVolunteerDetail'; const handleDeletePost = (postId: number) => { - // TODO: VolunteerPost delete API 호출 - console.log('[Delete Volunteer] postId:', postId); + deleteShelterRecruitment(postId); }; function VolunteersDetail() { const setOnDelete = useDetailHeaderStore((state) => state.setOnDelete); + const toast = useToast(); useEffect(() => { setOnDelete(handleDeletePost); @@ -40,15 +47,34 @@ function VolunteersDetail() { }, [setOnDelete]); const navigate = useNavigate(); - const { id: recruitmentId } = useParams(); + const { id } = useParams(); + const recruitmentId = Number(id); const { isOpen, onOpen, onClose } = useDisclosure(); - const { data: recruitment } = useGetVolunteerDetail(Number(recruitmentId)); + const { data: recruitment } = useGetVolunteerDetail(recruitmentId); + + const { mutate: closedRecruitment } = useMutation({ + mutationFn: async (recruitmentId: number) => + closeShelterRecruitment(recruitmentId), + onSuccess: () => { + toast({ + position: 'top', + description: '모집마감되었습니다.', + status: 'success', + duration: 1500, + }); + setIsClosed(true); + }, + onError: (error) => { + console.error(error); + }, + }); const startDate = new Date(recruitment.startTime); const deadline = new Date(recruitment.deadline); const createdAt = new Date(recruitment.createdAt); + const volunteerDateDay = getDDay(recruitment.deadline); const volunteerDate = createFormattedTime(startDate); const volunteerDay = createWeekDayLocalString(startDate); @@ -56,26 +82,16 @@ function VolunteersDetail() { const deadlineDate = createFormattedTime(deadline); const deadlineDay = createWeekDayLocalString(deadline); - const [label, setLabel] = useState({ - labelTitle: '모집중', - type: 'GREEN', - }); - const [isClosed, setIsClosed] = useState(false); - - useEffect(() => { - if (recruitment.isClosed) { - setIsClosed(true); - setLabel({ labelTitle: '마감완료', type: 'GRAY' }); - } - }, [recruitment.isClosed]); + const [isClosed, setIsClosed] = useState( + recruitment.isClosed || volunteerDateDay < 0, + ); const goManageApply = () => navigate(`/manage/apply/${recruitmentId}`); const goManageAttendance = () => navigate(`/manage/attendance/${recruitmentId}`); - const onCloseRecruitment = () => { + const onCloseRecruitment = (recruitmentId: number) => { + closedRecruitment(recruitmentId); onClose(); - setIsClosed(true); - setLabel({ labelTitle: '마감완료', type: 'GRAY' }); }; return ( @@ -84,16 +100,20 @@ function VolunteersDetail() { )} - + {isClosed ? ( + @@ -168,7 +188,7 @@ function VolunteersDetail() { btnTitle="마감하기" isOpen={isOpen} onClose={onClose} - onClick={onCloseRecruitment} + onClick={() => onCloseRecruitment(recruitmentId)} /> );