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

feat: 봉사모집마감 추가 #309

Merged
merged 3 commits into from
Dec 2, 2023
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 apps/shelter/src/pages/settings/account/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
74 changes: 47 additions & 27 deletions apps/shelter/src/pages/volunteers/detail/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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);

Expand All @@ -40,42 +47,51 @@ 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);

const deadlineDate = createFormattedTime(deadline);
const deadlineDay = createWeekDayLocalString(deadline);

const [label, setLabel] = useState<LabelProps>({
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 (
Expand All @@ -84,16 +100,20 @@ function VolunteersDetail() {
<ImageCarousel imageUrls={recruitment.imageUrls} />
)}
<VStack spacing="5px" align="flex-start" p={4}>
<LabelText
labelTitle={label.labelTitle}
type={label.type}
content={`D-${getDDay(recruitment.deadline)}`}
/>
{isClosed ? (
<Label labelTitle="마감완료" type="GRAY" />
) : (
<LabelText
labelTitle="모집중"
content={`D-${volunteerDateDay === 0 ? 'Day' : volunteerDateDay}`}
/>
)}
<Text fontSize="xl" fontWeight="semibold">
{recruitment.title}
</Text>
<Text fontSize="sm" fontWeight="normal" color="gray.500">
작성일 | {createFormattedTime(createdAt)}(수정됨)
작성일 | {createFormattedTime(createdAt)}
{recruitment.createdAt && ' (수정됨)'}
</Text>
</VStack>
<Divider />
Expand Down Expand Up @@ -168,7 +188,7 @@ function VolunteersDetail() {
btnTitle="마감하기"
isOpen={isOpen}
onClose={onClose}
onClick={onCloseRecruitment}
onClick={() => onCloseRecruitment(recruitmentId)}
/>
</Box>
);
Expand Down