Skip to content

Commit

Permalink
Merge pull request #310 from Anifriends/develop
Browse files Browse the repository at this point in the history
release: v0.1.8
  • Loading branch information
sukvvon authored Dec 2, 2023
2 parents 62be627 + ba54e90 commit ee11d32
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 49 deletions.
3 changes: 1 addition & 2 deletions apps/shelter/src/pages/my/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ function ShelterMy() {
};

return (
<Box>
<Box pb="50px">
<ProfileInfo
infoImage={imageUrl}
infoTitle={name}
Expand Down Expand Up @@ -99,7 +99,6 @@ function ShelterMy() {
settingItems={[
{ itemTitle: '계정 정보 수정하기', onClick: goSettingsAccount },
{ itemTitle: '비밀번호 변경하기', onClick: goSettingsPassword },
{ itemTitle: '로그아웃하기', onClick: goSettingsPassword },
]}
/>
<SettingGroup
Expand Down
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
49 changes: 30 additions & 19 deletions apps/shelter/src/pages/volunteers/update/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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'],
Expand All @@ -56,14 +62,11 @@ type RecruitmentSchema = z.infer<typeof recruitmentSchema>;

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));

Expand Down Expand Up @@ -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),
Expand All @@ -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);
Expand Down Expand Up @@ -233,4 +236,12 @@ export default function VolunteersUpdatePage() {
</form>
</Box>
);
};

export default function VolunteersUpdatePage() {
return (
<Suspense fallback={<Loader />}>
<UpdateForm />
</Suspense>
);
}

1 comment on commit ee11d32

@vercel
Copy link

@vercel vercel bot commented on ee11d32 Dec 2, 2023

Choose a reason for hiding this comment

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

Successfully deployed to the following URLs:

anifriends-frontend-volunteer – ./apps/volunteer

anifriends-frontend-volunteer-dongja.vercel.app
anifriends-frontend-volunteer-git-main-dongja.vercel.app
anifriends-frontend-volunteer.vercel.app

Please sign in to comment.