Skip to content

Commit f530566

Browse files
authored
Merge pull request #87 from six-goguma/Fix/issue-#81
issue#81 게시글 작성, 수정 페이지 오류 해결
2 parents 212482b + 6fd8e0e commit f530566

File tree

8 files changed

+53
-59
lines changed

8 files changed

+53
-59
lines changed

src/pages/post-edit/apis/post-edit.api.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ export const updatePost = async (
1919
return response.data;
2020
};
2121

22-
export const updatePostTags = async (postId: number, tagId: number[]) => {
22+
export const updatePostTags = async (postId: number, tagIds: number[]) => {
2323
const response = await fetchInstance.put(`${POSTS_PATH}/${postId}/tags`, {
24-
body: JSON.stringify({ tagId }),
24+
body: JSON.stringify({ tagIds }),
2525
});
2626

2727
return response.data;

src/pages/post-edit/ui/PostEditPage.tsx

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,28 @@
11
import { useEffect, useState } from 'react';
22
import { FieldErrors, useForm } from 'react-hook-form';
3-
import { useParams } from 'react-router-dom';
3+
import { useNavigate, useParams } from 'react-router-dom';
44

55
import { Box, useDisclosure, VStack } from '@chakra-ui/react';
66

77
import { getPostDetail, getPostTags } from '@pages/post-detail/apis';
88

99
import { PostTitle, PostTag, PostContent, PostButtons, Form } from '@shared/components';
10+
import { RouterPath } from '@shared/constants';
1011
import { useCustomToast } from '@shared/hooks';
1112
import { PostFormData } from '@shared/types';
1213

1314
import { PostModal } from '@widgets/modals';
14-
import { LoadingView } from '@widgets/view';
1515

1616
import { updatePost, updatePostTags } from '../apis';
17+
import { SkeletonPostEditPage } from './SkeletonPostEditPage';
1718
import { useQuery } from '@tanstack/react-query';
1819

1920
export const PostEditPage = () => {
2021
const { isOpen, onOpen, onClose } = useDisclosure();
2122
const { postId } = useParams<{ postId: string }>();
2223
const customToast = useCustomToast();
2324
const [hasErrorToastShown, setHasErrorToastShown] = useState(false);
25+
const navigate = useNavigate();
2426

2527
const {
2628
data: postDetail,
@@ -80,28 +82,21 @@ export const PostEditPage = () => {
8082
const onUpdatePostButton = async (modalData: { thumbnail: string; summary: string }) => {
8183
try {
8284
const data = form.getValues();
83-
console.log('게시글 데이터 제출:', data);
84-
85-
const updatedPost = await updatePost(Number(postId), {
85+
await updatePost(Number(postId), {
8686
title: data.title,
8787
contents: data.content,
8888
thumbnail: modalData.thumbnail,
8989
summary: modalData.summary,
9090
});
91-
92-
console.log('게시글 수정 성공:', updatedPost);
93-
9491
if (data.tag !== null && data.tag !== undefined) {
9592
await updatePostTags(Number(postId), data.tag);
9693
}
97-
9894
customToast({
9995
toastStatus: 'success',
10096
toastTitle: '게시글 수정 완료',
10197
toastDescription: '게시글이 성공적으로 수정되었습니다!',
10298
});
103-
104-
onClose();
99+
navigate(RouterPath.MAIN);
105100
} catch (error) {
106101
console.error('게시글 수정 실패:', error);
107102
customToast({
@@ -134,7 +129,7 @@ export const PostEditPage = () => {
134129
}
135130
};
136131

137-
if (isPostLoading || isTagsLoading) return <LoadingView />;
132+
if (isPostLoading || isTagsLoading) return <SkeletonPostEditPage />;
138133
if (!postDetail || !postTag) return <Box>데이터를 불러올 수 없습니다.</Box>;
139134

140135
return (
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { VStack, Skeleton, SkeletonText, Box } from '@chakra-ui/react';
2+
3+
export const SkeletonPostEditPage = () => {
4+
return (
5+
<VStack w='full' py='20px' px='30px' gap='4' align='start' bg='white'>
6+
<Skeleton height='40px' width='80%' borderRadius='5px' mt={10} />
7+
<Skeleton height='40px' width='40%' borderRadius='5px' />
8+
<Box w='full'>
9+
<SkeletonText noOfLines={50} spacing='4' skeletonHeight='16px' />
10+
</Box>
11+
<Skeleton height='50px' width='120px' borderRadius='5px' />
12+
</VStack>
13+
);
14+
};

src/pages/post-write/apis/post-write.api.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ export const createPost = async (postData: {
2424
return response.data;
2525
};
2626

27-
export const savePostTags = async (postId: number, tagId: number[] | null) => {
27+
export const savePostTags = async (postId: number, tagIds: number[] | null) => {
2828
const response = await fetchInstance.post(`${POSTS_PATH}/${postId}/tags`, {
29-
body: JSON.stringify({ tagId }),
29+
body: JSON.stringify({ tagIds }),
3030
headers: {
3131
'Content-Type': 'application/json',
3232
},

src/pages/post-write/ui/PostWritePage.tsx

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import { useForm, FieldErrors } from 'react-hook-form';
2+
import { useNavigate } from 'react-router-dom';
23

34
import { useDisclosure, VStack } from '@chakra-ui/react';
45

56
import { Form, PostTitle, PostTag, PostContent, PostButtons } from '@shared/components';
7+
import { RouterPath } from '@shared/constants';
68
import { useCustomToast } from '@shared/hooks';
79
import { PostFormData } from '@shared/types';
810

@@ -20,7 +22,7 @@ export const PostWritePage = () => {
2022
summary: '',
2123
},
2224
});
23-
25+
const navigate = useNavigate();
2426
const customToast = useCustomToast();
2527
const { isOpen, onOpen, onClose } = useDisclosure();
2628

@@ -31,29 +33,21 @@ export const PostWritePage = () => {
3133
const onCreatePostButton = async (modalData: { thumbnail: string; summary: string }) => {
3234
try {
3335
const data = methods.getValues();
34-
console.log('게시글 데이터 제출:', data);
35-
3636
const createdPost = await createPost({
3737
title: data.title,
3838
contents: data.content,
3939
thumbnail: modalData.thumbnail,
4040
summary: modalData.summary,
4141
});
42-
43-
console.log('게시글 생성 성공:', createdPost);
44-
4542
if (createdPost?.id) {
4643
await savePostTags(createdPost.id, data.tag);
47-
console.log('태그 저장 성공');
4844
}
49-
5045
customToast({
5146
toastStatus: 'success',
5247
toastTitle: '게시글 출간 완료',
5348
toastDescription: '게시글이 성공적으로 출간되었습니다!',
5449
});
55-
56-
onClose();
50+
navigate(RouterPath.MAIN);
5751
} catch (error) {
5852
console.error('게시글 출간 실패:', error);
5953
customToast({

src/shared/components/post-form/post-content/ui/PostContent.tsx

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -22,25 +22,6 @@ export const PostContent = ({ contents }: PostContentFieldEditorProps) => {
2222
const { control } = useFormContext();
2323
const isMobile = useBreakpointValue({ base: true, md: false });
2424

25-
function generateStorageId(): string {
26-
const lettersAndNumbers: string =
27-
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
28-
29-
let result: string = '';
30-
31-
for (let i = 0; i < 10; i++) {
32-
result += lettersAndNumbers.charAt(Math.floor(Math.random() * lettersAndNumbers.length));
33-
}
34-
35-
return result
36-
.split('')
37-
.sort(() => Math.random() - 0.5)
38-
.join('');
39-
}
40-
41-
const storageId: string = generateStorageId();
42-
console.log(storageId);
43-
4425
const uploadFile = async (file: File): Promise<string> => {
4526
const formData = new FormData();
4627
formData.append('file', file);

src/shared/components/post-form/post-tag/ui/PostTag.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ export const PostTag = ({ tag }: PostTagProps) => {
2323

2424
const toggleTag = (tagId: number) => {
2525
const updatedTags = selectedTags.includes(tagId)
26-
? selectedTags.filter((id) => id !== tagId) // 이미 선택된 태그는 제거
27-
: [...selectedTags, tagId]; // 새로운 태그 추가
26+
? selectedTags.filter((id) => id !== tagId)
27+
: [...selectedTags, tagId];
2828

29-
setValue('tag', updatedTags); // ✅ 다중 선택된 태그 배열을 `setValue`에 저장
29+
setValue('tag', updatedTags);
3030
};
3131

3232
return (
@@ -64,7 +64,7 @@ export const PostTag = ({ tag }: PostTagProps) => {
6464
borderColor={
6565
selectedTags.includes(tag.id) ? `${tag.color}.400` : `${tag.color}.500`
6666
}
67-
onClick={() => toggleTag(tag.id)} // ✅ 클릭 시 `toggleTag` 호출
67+
onClick={() => toggleTag(tag.id)}
6868
>
6969
{tag.label}
7070
</Button>

src/widgets/modals/PostModal.tsx

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ type PostModalProps = {
4141
contents: string;
4242
thumbnail: string;
4343
summary: string;
44-
}) => void;
44+
}) => Promise<void>;
4545
imageUrl?: string;
4646
};
4747

@@ -63,6 +63,7 @@ export const PostModal = ({
6363
}: PostModalProps) => {
6464
const imgRef = useRef<HTMLInputElement | null>(null);
6565
const [isUploading, setIsUploading] = useState(false);
66+
const [isPosting, setIsPosting] = useState(false);
6667
const MAX_IMAGE_SIZE_BYTES = 1024 * 1024 * 2;
6768
const customToast = useCustomToast();
6869

@@ -136,13 +137,18 @@ export const PostModal = ({
136137
setValue('thumbnail', '');
137138
};
138139

139-
const onSubmit = (data: PostModalForm) => {
140-
onConfirmButton({
141-
title,
142-
contents: postContent,
143-
thumbnail: data.thumbnail,
144-
summary: data.summary,
145-
});
140+
const onSubmit = async (data: PostModalForm) => {
141+
setIsPosting(true);
142+
try {
143+
await onConfirmButton({
144+
title,
145+
contents: postContent,
146+
thumbnail: data.thumbnail,
147+
summary: data.summary,
148+
});
149+
} finally {
150+
setIsPosting(false);
151+
}
146152
};
147153

148154
return (
@@ -152,7 +158,7 @@ export const PostModal = ({
152158
<ModalHeader mt={5} textAlign='left' ml='3'>
153159
포스트 미리보기
154160
</ModalHeader>
155-
<ModalCloseButton />
161+
{!isPosting && <ModalCloseButton />}
156162

157163
<Form {...form}>
158164
<form onSubmit={handleSubmit(onSubmit)}>
@@ -198,6 +204,7 @@ export const PostModal = ({
198204
color: 'white',
199205
transition: 'all 0.2s ease-in-out',
200206
}}
207+
isDisabled={isPosting}
201208
>
202209
썸네일 업로드
203210
<Input
@@ -233,6 +240,7 @@ export const PostModal = ({
233240
maxLength={150}
234241
placeholder='나의 포스트를 짧게 소개해보아요.'
235242
fontSize='sm'
243+
isDisabled={isPosting}
236244
/>
237245
<Flex w='full' justify='flex-end' mt='2px'>
238246
<Text as='b' fontSize='sm' color='customGray.500'>
@@ -256,6 +264,7 @@ export const PostModal = ({
256264
h='40px'
257265
colorScheme='custom.blue'
258266
onClick={onClose}
267+
isDisabled={isPosting}
259268
>
260269
취소
261270
</Button>
@@ -267,8 +276,9 @@ export const PostModal = ({
267276
colorScheme='custom.blue'
268277
_hover={{}}
269278
type='submit'
279+
isDisabled={isPosting}
270280
>
271-
{buttonTitle}
281+
{isPosting ? '저장 중...' : buttonTitle}
272282
</Button>
273283
</HStack>
274284
</ModalFooter>

0 commit comments

Comments
 (0)