Skip to content

Commit

Permalink
[#127] feat: 성장기록 수정 구현 완료
Browse files Browse the repository at this point in the history
  • Loading branch information
mun-jihye committed Jun 19, 2024
1 parent 454439c commit d8c283a
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 43 deletions.
8 changes: 4 additions & 4 deletions api/growth/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { Growth } from '@/types/growth';
import { axiosInstance } from '..';
import { AddGrowthData, GrowthDetails } from '@/types/growth/details';
import { GrowthDetails, GrowthDetailsData } from '@/types/growth/details';
import { GrowthSearchData } from '@/types/growth/search';

export default class GrowthAPI {
constructor() {}

async createGrowth(formData: AddGrowthData) {
async createGrowth(formData: GrowthDetailsData) {
return await axiosInstance.post('/growth', formData);
}

Expand All @@ -26,8 +26,8 @@ export default class GrowthAPI {
).data;
}

async modifyGrowth(growthId: number) {
return await axiosInstance.put(`/growth/${growthId}`);
async modifyGrowth(growthId: number, data: GrowthDetailsData) {
return await axiosInstance.put(`/growth/${growthId}`, data);
}

async deleteGrowth(growthId: number) {
Expand Down
4 changes: 2 additions & 2 deletions components/calendar-monthly/pet-radio.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import Image from 'next/image';
import styles from './pet-radio.module.scss';
import { FieldValues, UseFormRegister } from 'react-hook-form';
import { IFormInput } from '@/types/calendar';
import { AddGrowthData } from '@/types/growth/details';
import { GrowthDetailsData } from '@/types/growth/details';

interface PetRadio {
register: UseFormRegister<IFormInput & FieldValues> | UseFormRegister<AddGrowthData & FieldValues>;
register: UseFormRegister<IFormInput & FieldValues> | UseFormRegister<GrowthDetailsData & FieldValues>;
petName: string;
petImage: string;
defaultPet?: string;
Expand Down
8 changes: 3 additions & 5 deletions hooks/queries/growth/use-post-growth-query.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
import GrowthAPI from '@/api/growth';
import { AddGrowthData } from '@/types/growth/details';
import { GrowthDetailsData } from '@/types/growth/details';
import { useMutation, useQueryClient } from '@tanstack/react-query';

const growthAPI = new GrowthAPI();

export const useCreateGrotwthMutation = () => {
return useMutation({
mutationFn: async (data: AddGrowthData) => await growthAPI.createGrowth(data),
mutationFn: async (data: GrowthDetailsData) => await growthAPI.createGrowth(data),
});
};

export const useModifyGrowthMutation = (growthId: number) => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async () => await growthAPI.modifyGrowth(growthId),
onSuccess: () => queryClient.invalidateQueries({ queryKey: ['growth', growthId], refetchType: 'active' }),
mutationFn: (data: GrowthDetailsData) => growthAPI.modifyGrowth(growthId, data),
});
};

Expand Down
54 changes: 39 additions & 15 deletions pages/growth/[growthId]/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import usePetsQuery from '@/hooks/queries/calendar/use-pets-query';
import { useGetGrowthDetailQuery } from '@/hooks/queries/growth/use-get-growth-queries';
import { useModifyGrowthMutation } from '@/hooks/queries/growth/use-post-growth-query';
import useModal from '@/hooks/use-modal';
import { AddGrowthData } from '@/types/growth/details';
import { GrowthDetailsContent, GrowthDetailsData } from '@/types/growth/details';
import { GROWTH_CATEGORY } from '@/utils/constants/growth';
import { GetServerSidePropsContext, InferGetServerSidePropsType } from 'next';
import { Params } from 'next/dist/shared/lib/router/utils/route-matcher';
Expand All @@ -14,6 +14,8 @@ import CategoryInputs from '../create/category-inputs';
import classNames from 'classnames';
import CompleteModal from '../create/complete-modal';
import PetRadio from '@/components/calendar-monthly/pet-radio';
import useCalenderDateStore from '@/store/calendar.store';
import { convertToLocalDate } from '@/utils/convert-local-date';

export async function getServerSideProps(context: GetServerSidePropsContext) {
const {
Expand All @@ -31,22 +33,31 @@ export default function GrowthModify({ growthId }: InferGetServerSidePropsType<t
const modifyMutation = useModifyGrowthMutation(growthId);

const [selectedCategory, setSelectedCategory] = useState<string>('');
const [memo, setMemo] = useState<string>('');
const [content, setContent] = useState({});
const [initPetName, setInitPetName] = useState('');
const year = useCalenderDateStore.use.year().toString();
const month = (useCalenderDateStore.use.month() + 1).toString();
const date = useCalenderDateStore.use.date().toString();
const localDate = convertToLocalDate({ year, month, day: date });

useEffect(() => {
if (growthList?.data?.category) {
setSelectedCategory(growthList?.data.category);
if (growthList?.data) {
setMemo(growthList.data.content.memo);
setSelectedCategory(growthList.data.category);
setContent(growthList.data.content);
setInitPetName(growthList.data.petName);
}
}, [growthList]);

console.log(initPetName);
const {
register,
handleSubmit,
formState: { errors, isValid },
} = useForm<AddGrowthData>({
} = useForm<GrowthDetailsData>({
mode: 'onBlur',
defaultValues: {
date: growthList?.data.dateTime,
category: growthList?.data.category,
content: growthList?.data.content,
dateTime: localDate,
},
});
const openModal = () => {
Expand All @@ -60,18 +71,17 @@ export default function GrowthModify({ growthId }: InferGetServerSidePropsType<t
setSelectedCategory(event.target.value);
};

const onSubmit: SubmitHandler<AddGrowthData> = (data) => {
const onSubmit: SubmitHandler<GrowthDetailsData> = (data) => {
console.log(data);
modifyMutation.mutate(data, {
onSuccess: (response) => {
console.log('Success:', response);
onSuccess: () => {
openModal();
},
onError: (error) => {
console.error('Error:', error);
},
});
};
console.log(growthList?.data);
return (
<>
<div className={styles.wrapper}>
Expand All @@ -80,18 +90,26 @@ export default function GrowthModify({ growthId }: InferGetServerSidePropsType<t
반려동물 선택
<div className={styles.petLabelContainer}>
{!!pets.length &&
initPetName !== '' &&
pets.map((pet, i) => (
<PetRadio key={i} register={register} petName={pet.name} petImage={pet.imageUrl} />
<PetRadio
key={i}
defaultPet={initPetName}
register={register}
petName={pet.name}
petImage={pet.imageUrl}
/>
))}
</div>
{errors.petName && <p className={styles.error}>{errors.petName.message}</p>}
</div>
<div className={styles.division}></div>
<textarea
{...register('content.memo', { required: '*내용을 입력해주세요.' })}
{...register('content.memo')}
className={styles.memo}
id="content.memo"
placeholder={`메모\n어떤 일정인지 자세하게 기록하실 수 있어요!`}
defaultValue={memo}
/>
{errors.content?.memo && <p className={styles.error}>{errors.content.memo.message}</p>}

Expand All @@ -106,14 +124,20 @@ export default function GrowthModify({ growthId }: InferGetServerSidePropsType<t
type="radio"
checked={selectedCategory === category}
onChange={handleCategoryChange}
defaultValue={category}
/>
<div className={styles.categoryIcon}></div>
<p className={styles.categoryName}>{category}</p>
</label>
))}
</div>
</div>
<CategoryInputs errors={errors} selectedCategory={selectedCategory} register={register} />
<CategoryInputs
defaultValue={content as GrowthDetailsContent}
errors={errors}
selectedCategory={selectedCategory}
register={register}
/>
<button
className={classNames(styles.submit, {
[styles.disabled]: !isValid,
Expand Down
24 changes: 19 additions & 5 deletions pages/growth/create/category-inputs/index.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import { AddGrowthData } from '@/types/growth/details';
import { GrowthDetailsData, GrowthDetailsContent } from '@/types/growth/details';
import { FieldErrors, UseFormRegister } from 'react-hook-form';
import styles from './category-inputs.module.scss';

interface CategoryInputsProps {
selectedCategory: string;
register: UseFormRegister<AddGrowthData>;
errors: FieldErrors<AddGrowthData>;
register: UseFormRegister<GrowthDetailsData>;
errors: FieldErrors<GrowthDetailsData>;
defaultValue: GrowthDetailsContent;
}

export default function CategoryInputs({ errors, selectedCategory, register }: CategoryInputsProps) {
export default function CategoryInputs({ defaultValue, errors, selectedCategory, register }: CategoryInputsProps) {
const { food, snack, abnormalSymptom, hospitalName, symptom, diagnosis, medicationMethod, price } = defaultValue;
const formatInputValue = (value: string): string => {
return value.replace(/[^0-9]/g, '');
};
Expand All @@ -31,6 +33,7 @@ export default function CategoryInputs({ errors, selectedCategory, register }: C
{...register('content.snack', { required: '*내용을 입력해주세요.' })}
placeholder="간식의 이름을 입력해주세요"
className={styles.input}
defaultValue={snack}
/>
{errors.content?.snack && <p className={styles.error}>{errors.content.snack.message}</p>}
</div>
Expand All @@ -43,6 +46,7 @@ export default function CategoryInputs({ errors, selectedCategory, register }: C
{...register('content.abnormalSymptom', { required: '*내용을 입력해주세요.' })}
placeholder="이상 증상을 입력해주세요"
className={styles.input}
defaultValue={abnormalSymptom}
/>
{errors.content?.abnormalSymptom && <p className={styles.error}>{errors.content.abnormalSymptom.message}</p>}
</div>
Expand All @@ -56,6 +60,7 @@ export default function CategoryInputs({ errors, selectedCategory, register }: C
{...register('content.hospitalName')}
placeholder="병원의 이름을 입력해주세요"
className={styles.input}
defaultValue={hospitalName}
/>
</div>
<div className={styles.inputGroup}>
Expand All @@ -64,19 +69,26 @@ export default function CategoryInputs({ errors, selectedCategory, register }: C
{...register('content.symptom', { required: '*내용을 입력해주세요.' })}
placeholder="증상을 입력해주세요"
className={styles.input}
defaultValue={symptom}
/>
{errors.content?.symptom && <p className={styles.error}>{errors.content.symptom.message}</p>}
</div>
<div className={styles.inputGroup}>
<label className={styles.label}>진료 내용</label>
<input {...register('content.diagnosis')} placeholder="진료 내용을 입력해주세요" className={styles.input} />
<input
{...register('content.diagnosis')}
placeholder="진료 내용을 입력해주세요"
className={styles.input}
defaultValue={diagnosis}
/>
</div>
<div className={styles.inputGroup}>
<label className={styles.label}>복용 방법</label>
<input
{...register('content.medicationMethod')}
placeholder="복용 방법을 입력해주세요"
className={styles.input}
defaultValue={medicationMethod}
/>
</div>
<div className={styles.inputGroup}>
Expand All @@ -86,6 +98,7 @@ export default function CategoryInputs({ errors, selectedCategory, register }: C
placeholder="1,000 ₩"
className={styles.input}
onInput={handlePriceInput}
defaultValue={price}
/>
</div>
</div>
Expand All @@ -98,6 +111,7 @@ export default function CategoryInputs({ errors, selectedCategory, register }: C
{...register('content.food', { required: '*내용을 입력해주세요.' })}
placeholder="사료의 이름을 입력해주세요"
className={styles.input}
defaultValue={food}
/>
{errors.content?.food && <p className={styles.error}>{errors.content.food.message}</p>}
</div>
Expand Down
28 changes: 22 additions & 6 deletions pages/growth/create/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { SubmitHandler, useForm } from 'react-hook-form';
import styles from './create.module.scss';
import PetRadio from '@/components/calendar-monthly/pet-radio';
import { GROWTH_CATEGORY } from '@/utils/constants/growth';
import { AddGrowthData } from '@/types/growth/details';
import { GrowthDetailsData, GrowthDetailsContent } from '@/types/growth/details';
import classNames from 'classnames';
import CategoryInputs from './category-inputs';
import usePetsQuery from '@/hooks/queries/calendar/use-pets-query';
Expand All @@ -24,17 +24,28 @@ export default function CreateGrowth() {
const month = (useCalenderDateStore.use.month() + 1).toString();
const date = useCalenderDateStore.use.date().toString();
const localDate = convertToLocalDate({ year, month, day: date });
const content: GrowthDetailsContent = {
food: '',
snack: '',
abnormalSymptom: '',
hospitalName: '',
symptom: '',
diagnosis: '',
medicationMethod: '',
price: 0,
memo: '',
};

const [selectedCategory, setSelectedCategory] = useState(GROWTH_CATEGORY[0]);

const {
register,
handleSubmit,
formState: { errors, isValid },
} = useForm<AddGrowthData>({
} = useForm<GrowthDetailsData>({
mode: 'onBlur',
defaultValues: {
date: localDate,
dateTime: localDate,
category: GROWTH_CATEGORY[0],
},
});
Expand All @@ -49,7 +60,7 @@ export default function CreateGrowth() {
setSelectedCategory(event.target.value);
};

const onSubmit: SubmitHandler<AddGrowthData> = (data) => {
const onSubmit: SubmitHandler<GrowthDetailsData> = (data) => {
createGrowthMutation.mutate(data, {
onSuccess: (response) => {
console.log('Success:', response);
Expand All @@ -76,7 +87,7 @@ export default function CreateGrowth() {
</div>
<div className={styles.division}></div>
<textarea
{...register('content.memo', { required: '*내용을 입력해주세요.' })}
{...register('content.memo')}
className={styles.memo}
id="content.memo"
placeholder={`메모\n어떤 일정인지 자세하게 기록하실 수 있어요!`}
Expand All @@ -101,7 +112,12 @@ export default function CreateGrowth() {
))}
</div>
</div>
<CategoryInputs errors={errors} selectedCategory={selectedCategory} register={register} />
<CategoryInputs
defaultValue={content}
errors={errors}
selectedCategory={selectedCategory}
register={register}
/>
<button
className={classNames(styles.submit, {
[styles.disabled]: !isValid,
Expand Down
13 changes: 7 additions & 6 deletions types/growth/details.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ export interface GrowthDetails {
data: GrowthDetailsData;
}

export interface AddGrowthData {
date: string;
petName: string;
category: string;
content: GrowthDetailsContent;
}
// export interface AddGrowthData {
// date: string;
// petName: string;
// category: string;
// content: GrowthDetailsContent;
// }

export interface GrowthDetailsData {
id: number;
Expand All @@ -18,6 +18,7 @@ export interface GrowthDetailsData {
dateTime: string;
nickname: string;
isMine: boolean;
petName: string;
}

export interface GrowthDetailsContent {
Expand Down

0 comments on commit d8c283a

Please sign in to comment.