Skip to content

Commit 930f753

Browse files
authored
Merge pull request #505 from meowzip/reese
feat: Enhance diary modal UX with loading states and form validation
2 parents 3afbc8e + 5535f1b commit 930f753

File tree

14 files changed

+71
-60
lines changed

14 files changed

+71
-60
lines changed

src/app/@modal/(...)diary/[id]/edit/page.tsx

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@ import { getDiaryDetail } from '@/services/diary';
99
const DiaryEditModalPage = ({ params: { id } }: { params: { id: number } }) => {
1010
const router = useRouter();
1111

12-
const { data: diaryDetail } = useQuery({
12+
const {
13+
data: diaryDetail,
14+
isLoading,
15+
isError
16+
} = useQuery({
1317
queryKey: ['diaryDetail', id],
1418
queryFn: () => getDiaryDetail(id),
1519
staleTime: 0
@@ -19,10 +23,20 @@ const DiaryEditModalPage = ({ params: { id } }: { params: { id: number } }) => {
1923
router.back();
2024
};
2125

22-
if (!diaryDetail) {
26+
if (isLoading) {
27+
return (
28+
<div className="fixed inset-0 z-[200] flex items-center justify-center bg-black bg-opacity-50">
29+
<div className="rounded-lg bg-white p-4 shadow-xl">
30+
<p>일지 정보를 불러오는 중...</p>
31+
</div>
32+
</div>
33+
);
34+
}
35+
36+
if (isError || !diaryDetail) {
2337
console.error('일지 상세 정보를 불러오는데 실패했거나 데이터가 없습니다.');
2438
return (
25-
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50">
39+
<div className="fixed inset-0 z-[200] flex items-center justify-center bg-black bg-opacity-50">
2640
<div className="rounded-lg bg-white p-4 shadow-xl">
2741
<p>일지 정보를 불러오는 데 실패했습니다.</p>
2842
<button
@@ -37,11 +51,15 @@ const DiaryEditModalPage = ({ params: { id } }: { params: { id: number } }) => {
3751
}
3852

3953
return (
40-
<DiaryWriteModal
41-
onClose={handleClose}
42-
id={diaryDetail.id}
43-
diaryDetail={diaryDetail}
44-
/>
54+
<div className="fixed inset-0 z-[200] flex items-center justify-center bg-black bg-opacity-50">
55+
<div className="h-screen w-full max-w-[640px] overflow-hidden bg-white">
56+
<DiaryWriteModal
57+
onClose={handleClose}
58+
id={diaryDetail.id}
59+
diaryDetail={diaryDetail}
60+
/>
61+
</div>
62+
</div>
4563
);
4664
};
4765

src/app/community/[slug]/page.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,6 @@ const DetailPage = ({ params: { slug } }: { params: { slug: number } }) => {
5454

5555
const comments = commentsData?.items || [];
5656

57-
useEffect(() => {
58-
if (!feedDetail) return;
59-
}, [slug, feedDetail]);
60-
6157
useEffect(() => {
6258
if (bottomSheetRef.current) {
6359
const height = bottomSheetRef.current.scrollHeight;
@@ -151,9 +147,13 @@ const DetailPage = ({ params: { slug } }: { params: { slug: number } }) => {
151147
setEditBottomSheet(!editBottomSheet);
152148
}}
153149
heightPercent={['50%', '60%']}
154-
name={feedDetail?.memberNickname}
150+
name={
151+
selectedComment
152+
? selectedComment?.memberNickname
153+
: feedDetail?.writerNickname
154+
}
155155
memberId={
156-
selectedComment ? selectedComment?.memberId : feedDetail?.memberId
156+
selectedComment ? selectedComment?.memberId : feedDetail?.writerId
157157
}
158158
onDelete={() => {
159159
selectedComment

src/app/diary/diaryType.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export interface DiaryRegisterReqObj {
1818
images: string[];
1919
caredDate: string;
2020
caredTime: string;
21-
taggedCats?: number[];
21+
catIds: number[];
2222
}
2323

2424
export interface TaggedCat {

src/app/profile/alarm/page.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,7 @@ const AlarmPage = () => {
113113
const readAllNotification = useMutation({
114114
mutationFn: () => readAllNotificationOnServer(),
115115
onSuccess: (data: any) => {
116-
if (data.status !== 'OK') {
117-
console.log('error');
118-
} else {
116+
if (data.status === 'OK') {
119117
setHasNewNotification(false);
120118
refetchNotifications();
121119
refetchCoParentNotifications();

src/components/community/FeedWriteModal.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ const FeedWriteModal = ({ onClose, feedDetail }: FeedWriteModalProps) => {
130130
predicate: query => query.queryKey[0] === 'feeds'
131131
});
132132
onClose();
133-
router.push('/community');
133+
router.replace('/community');
134134
} else {
135135
console.error('게시글 등록 중 오류:', response.message);
136136
}

src/components/diary/DiaryWriteModal.tsx

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ type DiaryRegisterReqWithCats = Omit<DiaryRegisterReqObj, 'taggedCats'> & {
4747

4848
interface DiaryWriteModalProps {
4949
onClose: () => void;
50-
id: number;
50+
id?: number;
5151
diaryDetail?: DiaryRegisterReqWithCats;
5252
}
5353

@@ -97,7 +97,8 @@ const DiaryWriteModal = ({
9797
setValue,
9898
formState: { errors, isSubmitting },
9999
handleSubmit,
100-
reset
100+
reset,
101+
trigger
101102
} = form;
102103

103104
const watchedData = watch();
@@ -177,21 +178,29 @@ const DiaryWriteModal = ({
177178

178179
const formattedDate = formatDateToISO(data.caredDate);
179180

181+
const catIds = data.taggedCats.map(cat => Number(cat.id));
182+
180183
return {
181184
isGivenWater: data.isGivenWater,
182185
isFeed: data.isFeed,
183186
content: data.content,
184187
caredDate: formattedDate,
185188
caredTime: displayTime(),
186-
taggedCats: data.taggedCats.map(cat => Number(cat.id)),
189+
catIds: catIds,
187190
images: processedImages
188191
};
189192
};
190193

191194
const onSubmit = (data: DiaryFormData) => {
192195
if (isSubmitting) return;
193196

194-
// 내용이 없을 때 알림
197+
if (!data.taggedCats || data.taggedCats.length === 0) {
198+
toast({
199+
description: '고양이를 선택해주세요'
200+
});
201+
return;
202+
}
203+
195204
if (!data.content.trim()) {
196205
toast({
197206
description: '간단한 돌봄 기록이라도 남겨보세요!'
@@ -215,9 +224,7 @@ const DiaryWriteModal = ({
215224
const onError = (errors: any) => {
216225
if (errors.taggedCats) {
217226
toast({
218-
title: '고양이 선택 필요',
219-
description:
220-
errors.taggedCats.message || '고양이를 최소 1마리 이상 선택해주세요.'
227+
description: '고양이를 선택해주세요'
221228
});
222229
} else if (errors.images) {
223230
toast({
@@ -255,6 +262,9 @@ const DiaryWriteModal = ({
255262
editDiaryOnServer(reqObj),
256263
onSuccess: () => {
257264
queryClient.invalidateQueries({ queryKey: ['diaryDetail'] });
265+
toast({
266+
description: '일지가 성공적으로 수정되었습니다.'
267+
});
258268
onClose();
259269
},
260270
onError: error => {
@@ -295,14 +305,23 @@ const DiaryWriteModal = ({
295305
}
296306
};
297307

298-
const handleAddCats = (
308+
const handleAddCats = async (
299309
cats: CatType[] | ((prev: CatType[]) => CatType[])
300310
) => {
311+
let newCats: CatType[];
312+
301313
if (typeof cats === 'function') {
302-
setValue('taggedCats', cats(taggedCats));
314+
newCats = cats(taggedCats);
303315
} else {
304-
setValue('taggedCats', cats);
316+
newCats = cats;
305317
}
318+
319+
setValue('taggedCats', newCats, {
320+
shouldValidate: true,
321+
shouldDirty: true
322+
});
323+
324+
await trigger('taggedCats');
306325
};
307326

308327
const chipObjList = [
@@ -312,7 +331,7 @@ const DiaryWriteModal = ({
312331

313332
return (
314333
<>
315-
<div className="h-screen w-full max-w-[640px] overflow-y-auto">
334+
<div className="h-full w-full overflow-y-auto">
316335
<Topbar type="three">
317336
<Topbar.Back onClick={onClose} />
318337
<Topbar.Title title="일지쓰기" />

src/components/ui/Chip.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,14 @@ interface ChipProps {
1313
const Chip = ({ propObj, icon, onClick }: ChipProps) => {
1414
return (
1515
<button
16+
type="button"
1617
id={propObj.key}
17-
className={`px-[14px] py-[5px] border-12 rounded-[20px] text-btn-2 ${
18+
className={`rounded-[20px] border-12 px-[14px] py-[5px] text-btn-2 ${
1819
icon && 'flex items-center gap-1'
1920
} ${
2021
propObj.checked
21-
? 'text-pr-500 bg-gr-white border-pr-500'
22-
: 'text-gr-500 bg-gr-50 border-gr-50'
22+
? 'border-pr-500 bg-gr-white text-pr-500'
23+
: 'border-gr-50 bg-gr-50 text-gr-500'
2324
}`}
2425
onClick={onClick}
2526
>
@@ -29,7 +30,7 @@ const Chip = ({ propObj, icon, onClick }: ChipProps) => {
2930
alt="icon"
3031
width={20}
3132
height={20}
32-
className="w-5 h-5"
33+
className="h-5 w-5"
3334
/>
3435
)}
3536
<p>{propObj.content}</p>

src/components/ui/Input.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ const Input = forwardRef<HTMLInputElement, InputProps>(
3737
iconEnd,
3838
onClear,
3939
disabled,
40-
// validator,
4140
error,
4241
helperText,
4342
loading,

src/components/ui/Toast.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const ToastViewport = React.forwardRef<
1414
<ToastPrimitives.Viewport
1515
ref={ref}
1616
className={cn(
17-
'fixed left-1/2 top-1/2 z-[100] flex max-h-screen -translate-x-1/2 -translate-y-1/2 flex-col-reverse p-4 sm:bottom-0 sm:right-0 sm:top-auto sm:flex-col md:max-w-[280px]',
17+
'fixed left-1/2 top-1/2 z-[300] flex max-h-screen -translate-x-1/2 -translate-y-1/2 flex-col-reverse p-4 sm:bottom-0 sm:right-0 sm:top-auto sm:flex-col md:max-w-[280px]',
1818
className
1919
)}
2020
{...props}

src/components/zip/CatInfo.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,6 @@ export default function CatInfo({
199199
updatedCatData.croppedImage = null;
200200
}
201201

202-
console.log('최종 제출 데이터:', updatedCatData);
203202
mutation.mutate(updatedCatData);
204203
} catch (error) {
205204
console.error('Error:', error);

0 commit comments

Comments
 (0)