diff --git a/apps/shelter/src/pages/my/index.tsx b/apps/shelter/src/pages/my/index.tsx
index 32a1ca1b..b6198145 100644
--- a/apps/shelter/src/pages/my/index.tsx
+++ b/apps/shelter/src/pages/my/index.tsx
@@ -67,7 +67,7 @@ function ShelterMy() {
};
return (
-
+
{
- // 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 ? (
+
+ ) : (
+
+ )}
{recruitment.title}
- 작성일 | {createFormattedTime(createdAt)}(수정됨)
+ 작성일 | {createFormattedTime(createdAt)}
+ {recruitment.createdAt && ' (수정됨)'}
@@ -168,7 +188,7 @@ function VolunteersDetail() {
btnTitle="마감하기"
isOpen={isOpen}
onClose={onClose}
- onClick={onCloseRecruitment}
+ onClick={() => onCloseRecruitment(recruitmentId)}
/>
);
diff --git a/apps/shelter/src/pages/volunteers/update/index.tsx b/apps/shelter/src/pages/volunteers/update/index.tsx
index 41802e6e..51e88a35 100644
--- a/apps/shelter/src/pages/volunteers/update/index.tsx
+++ b/apps/shelter/src/pages/volunteers/update/index.tsx
@@ -13,10 +13,11 @@ import {
} from '@chakra-ui/react';
import { zodResolver } from '@hookform/resolvers/zod';
import { useMutation, useQueryClient } from '@tanstack/react-query';
-import { useCallback, useEffect } from 'react';
+import { Suspense, useCallback, useEffect } from 'react';
import { SubmitHandler, useForm } from 'react-hook-form';
import { useNavigate, useParams } from 'react-router-dom';
import EditPhotoList from 'shared/components/EditPhotoList';
+import Loader from 'shared/components/Loader';
import { usePhotosUpload } from 'shared/hooks/usePhotosUpload';
import { getKoreanTime } from 'shared/utils/date';
import * as z from 'zod';
@@ -31,21 +32,26 @@ import useGetVolunteerDetail, {
const recruitmentSchema = z
.object({
title: z.string().min(1, '제목은 필수로 입력해주세요'),
- startTime: z.coerce.date(),
- endTime: z.coerce.date(),
- deadline: z.coerce.date(),
+ startTime: z.string(),
+ endTime: z.string(),
+ deadline: z.string(),
capacity: z.coerce.number(),
content: z
.string()
.optional()
.refine((val) => val?.length && val.length < 500, '에러입니다'),
})
- .refine(({ startTime, endTime }) => startTime.getTime() < endTime.getTime(), {
- message: '봉사 시작 일시 이후로 입력해주세요 ',
- path: ['endTime'],
- })
.refine(
- ({ startTime, deadline }) => deadline.getTime() <= startTime.getTime(),
+ ({ startTime, endTime }) =>
+ new Date(startTime).getTime() < new Date(endTime).getTime(),
+ {
+ message: '봉사 시작 일시 이후로 입력해주세요 ',
+ path: ['endTime'],
+ },
+ )
+ .refine(
+ ({ startTime, deadline }) =>
+ new Date(deadline).getTime() <= new Date(startTime).getTime(),
{
message: '봉사 시작 일시 전으로 입력해주세요',
path: ['deadLine'],
@@ -56,14 +62,11 @@ type RecruitmentSchema = z.infer;
const UPLOAD_LIMIT = 5;
-export default function VolunteersUpdatePage() {
+const UpdateForm = () => {
const { id: recruitmentId } = useParams<{ id: string }>() as { id: string };
const navigate = useNavigate();
const queryClient = useQueryClient();
- // TODO 이 훅에서 startDate, endDate와 같은 날짜데이터를 가공하기 때문에
- // 다른 훅을 만들어서 사용해야 할 것 같습니다.
- // 혹은 훅 내의 select 옵션을 수정해야 할 것 같습니다.
const { data: recruitment, isPending: isRecruitFetchLoading } =
useGetVolunteerDetail(Number(recruitmentId));
@@ -111,9 +114,9 @@ export default function VolunteersUpdatePage() {
recruitmentId: Number(recruitmentId),
request: {
...data,
- startTime: getKoreanTime(startTime).toISOString(),
- endTime: getKoreanTime(endTime).toISOString(),
- deadline: getKoreanTime(deadline).toISOString(),
+ startTime: getKoreanTime(new Date(startTime)).toISOString(),
+ endTime: getKoreanTime(new Date(endTime)).toISOString(),
+ deadline: getKoreanTime(new Date(deadline)).toISOString(),
imageUrls: photos
.filter(({ url }) => url !== 'upload-failed')
.map(({ url }) => url),
@@ -124,9 +127,9 @@ export default function VolunteersUpdatePage() {
const setVolunteersRecruitmentFormvalues = useCallback(
(recruitment: RecruitmentDetail) => {
setValue('title', recruitment.title);
- setValue('startTime', new Date(recruitment.startTime));
- setValue('endTime', new Date(recruitment.endTime));
- setValue('deadline', new Date(recruitment.deadline));
+ setValue('startTime', recruitment.startTime.slice(0, -3));
+ setValue('endTime', recruitment.endTime.slice(0, -3));
+ setValue('deadline', recruitment.deadline.slice(0, -3));
setValue('capacity', recruitment.capacity);
setValue('content', recruitment?.content ?? '');
setImageUrls(recruitment.imageUrls);
@@ -233,4 +236,12 @@ export default function VolunteersUpdatePage() {
);
+};
+
+export default function VolunteersUpdatePage() {
+ return (
+ }>
+
+
+ );
}