Skip to content

Commit

Permalink
♻ refactor: 작성/수정페이지 이미지 관련 데이터 구조 리펙토링
Browse files Browse the repository at this point in the history
  • Loading branch information
rkdcodus committed Sep 14, 2024
1 parent d1e1a16 commit 9a24dd6
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 112 deletions.
1 change: 1 addition & 0 deletions grass-diary/src/hooks/api/usePatchDiary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export const usePatchDiary = (diaryId: Id) => {
mutationFn: (request: DiaryRequest) => fetchAxios({ diaryId, request }),
onSuccess() {
navigate(`/diary/${diaryId}`, { replace: true, state: 'editcomplete' });
localStorage.removeItem('diary_draft');
},
onError(error) {
console.error(error.response.data.description);
Expand Down
16 changes: 15 additions & 1 deletion grass-diary/src/hooks/api/usePostImage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,21 @@ import { END_POINT } from '@constants/api';

export const usePostImage = () => {
return useMutation({
mutationFn: (formData: FormData) => API.post(END_POINT.image, formData),
mutationFn: async (imageURL: string) => {
// base64 형식을 객체로 변환.
const formData = await fetch(imageURL)
.then(res => res.blob())
.then(blob => {
const file = new File([blob], 'image.jpg', { type: 'image/jpeg' });
const formData = new FormData();
formData.append('image', file);
return formData;
});

formData.forEach(i => console.log(i));

return API.post(END_POINT.image, formData);
},
onError: error => {
console.error(error.message);
},
Expand Down
72 changes: 13 additions & 59 deletions grass-diary/src/pages/CreateDiary/CreateDiary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,9 @@ const CreateDiary = () => {
);

// 이미지 state
const [file, setFile] = useState<FormData>();
const [image, setImage] = useState<DiaryImage>({
const [image, setImage] = useState<ImageInfo>({
imageId: 0,
imageURL: '',
});

// 이미지 정보 state
const [imageInfo, setImageInfo] = useState({
name: '',
size: '',
});
Expand Down Expand Up @@ -172,8 +167,9 @@ const CreateDiary = () => {
setImage({
imageId: 0,
imageURL: '',
name: '',
size: '',
});
setImageInfo({ name: '', size: '' });
};

const handleSave = async () => {
Expand All @@ -185,8 +181,8 @@ const CreateDiary = () => {
return;
}
// 사용자가 이미지를 첨부할 경우 postImage -> createDiary 실행
if (file) {
postImage(file, {
if (image.imageURL) {
postImage(image.imageURL, {
onSuccess: res => {
const request = {
content: quillContent,
Expand Down Expand Up @@ -243,16 +239,6 @@ const CreateDiary = () => {
}
}, [date]);

const handleImageChange = (file: File) => {
const fileName = file.name;
const fileSize = (file.size / 1024).toFixed(2); // KB 단위로 변환

setImageInfo({
name: fileName,
size: fileSize,
});
};

// Quill 내용 유무 확인
const handleContentChange = (content: string) => {
setDiaryField({ quillContent: content });
Expand All @@ -261,28 +247,10 @@ const CreateDiary = () => {
};

// 로컬 스토리지 임시 저장

useEffect(() => {
const savedDraft = localStorage.getItem('diary_draft');
if (savedDraft) {
const parsedDraft = JSON.parse(savedDraft);
setDiaryInfo(parsedDraft);

const checkText = parsedDraft.quillContent.replace(/<\/?[^>]+(>|$)/g, '');
setIsContentEmpty(checkText.trim().length === 0);
}
}, []);

const handleSaveDraft = () => {
if (isContentEmpty) return; // 일기 내용이 비어 있으면 저장 요청 불가
const draftData = {
...diaryInfo,
imageBase64: image.imageURL,
imageInfo: {
name: imageInfo.name,
size: imageInfo.size,
},
};

const draftData = { ...diaryInfo, imageInfo: image };
localStorage.setItem('diary_draft', JSON.stringify(draftData));
toast(CREATE_MESSAGES.toast.temp_save);
};
Expand All @@ -291,23 +259,11 @@ const CreateDiary = () => {
const savedDraft = localStorage.getItem('diary_draft');
if (savedDraft) {
const parsedDraft = JSON.parse(savedDraft);
const img = parsedDraft.imageInfo;

setDiaryInfo(parsedDraft);
if (parsedDraft.imageBase64) {
setImage({
imageId: 0,
imageURL: parsedDraft.imageBase64,
});
setImageInfo(parsedDraft.imageInfo || { name: '', size: '' });
// Base64를 File 객체로 변환
fetch(parsedDraft.imageBase64)
.then(res => res.blob())
.then(blob => {
const file = new File([blob], 'image.jpg', { type: 'image/jpeg' });
const formData = new FormData();
formData.append('image', file);
setFile(formData);
});
}
if (img) setImage(img);

const checkText = parsedDraft.quillContent.replace(/<\/?[^>]+(>|$)/g, '');
setIsContentEmpty(checkText.trim().length === 0);
}
Expand Down Expand Up @@ -404,8 +360,8 @@ const CreateDiary = () => {
<S.Image>
<img src={image.imageURL} alt="image file" />
</S.Image>
<S.ImageName>{imageInfo.name}</S.ImageName>
<S.ImageData>{imageInfo.size} KB</S.ImageData>
<S.ImageName>{image.name}</S.ImageName>
<S.ImageData>{image.size} KB</S.ImageData>
<button onClick={removeImage}>
<S.ImageDelete>
<Close />
Expand All @@ -420,8 +376,6 @@ const CreateDiary = () => {
onContentChange={handleContentChange}
quillContent={diaryInfo.quillContent}
setImage={setImage}
setFile={setFile}
handleImageChange={handleImageChange}
selectedMode={selectedMode}
/>
</S.MainContainer>
Expand Down
24 changes: 12 additions & 12 deletions grass-diary/src/pages/CreateDiary/QuillEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,15 @@ import 'react-quill/dist/quill.snow.css';

import { useState, useEffect, useMemo } from 'react';
import { END_POINT } from '@constants/api';
import { CONSOLE_ERROR } from '@constants/message';
import { CONSOLE_ERROR, TOAST } from '@constants/message';
import { QUILL_MESSAGE } from '@constants/message';
import { useToast } from '@state/toast/useToast';

type QuillEditorProps = {
onContentChange: (content: string) => void;
handleImageChange: (file: File) => void;
selectedMode: string;
quillContent: string;
setImage: React.Dispatch<React.SetStateAction<DiaryImage>>;
setFile: React.Dispatch<React.SetStateAction<FormData | undefined>>;
setImage: React.Dispatch<React.SetStateAction<ImageInfo>>;
};

type QuestionResponse = {
Expand All @@ -25,8 +24,6 @@ const QuillEditor = ({
onContentChange,
quillContent,
setImage,
setFile,
handleImageChange,
selectedMode,
}: QuillEditorProps) => {
const handleChange = (
Expand All @@ -39,6 +36,7 @@ const QuillEditor = ({
};

const [todayQuestion, setTodayQuestion] = useState<string>();
const { redToast } = useToast();

const placeholderText =
selectedMode === `customEntry`
Expand All @@ -53,21 +51,23 @@ const QuillEditor = ({

input.onchange = () => {
const file = input.files ? input.files[0] : null;
const maxSize = 5 * 1024 * 1024;

if (file) {
const formData = new FormData();
formData.append('image', file);
setFile(formData);

handleImageChange(file);
if (file && file.size > maxSize) {
return redToast(TOAST.image_capacity_limit);
}

if (file) {
const reader = new FileReader();
reader.readAsDataURL(file);

reader.onloadend = () => {
const base64String = reader.result as string;
setImage({
imageId: 0,
imageURL: base64String,
name: file.name,
size: (file.size / 1024).toFixed(2), // KB 단위로 변환
});
};
}
Expand Down
58 changes: 18 additions & 40 deletions grass-diary/src/pages/EditDiary/EditDiary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,10 @@ const EditDiary = () => {
);

// 이미지 state
const [file, setFile] = useState<FormData>();
const { mutate: postImage } = usePostImage();
const [image, setImage] = useState<DiaryImage>({
const [image, setImage] = useState<ImageInfo>({
imageId: 0,
imageURL: '',
});

// 이미지 정보 state
const [imageInfo, setImageInfo] = useState({
name: '',
size: '',
});
Expand Down Expand Up @@ -168,8 +163,9 @@ const EditDiary = () => {
setImage({
imageId: 0,
imageURL: '',
name: '',
size: '',
});
setImageInfo({ name: '', size: '' });
};

const handleSave = async () => {
Expand All @@ -184,8 +180,9 @@ const EditDiary = () => {
imageId: image.imageId,
};

if (file) {
postImage(file, {
console.log(image.imageId, image.imageURL);
if (!image.imageId && image.imageURL) {
postImage(image.imageURL, {
onSuccess: res => {
const request = {
content: quillContent,
Expand All @@ -199,21 +196,8 @@ const EditDiary = () => {
});
return;
}
patchDiary(request, {
onSuccess: () => {
localStorage.removeItem('diary_draft');
},
});
};

const handleImageChange = (file: File) => {
const fileName = file.name;
const fileSize = (file.size / 1024).toFixed(2); // KB 단위로 변환

setImageInfo({
name: fileName,
size: fileSize,
});
patchDiary(request);
};

const handleContentChange = (content: string) => {
Expand All @@ -224,6 +208,8 @@ const EditDiary = () => {

// 일기 불러오기
useEffect(() => {
const savedDraft = localStorage.getItem('diary_draft');

if (date) {
setDiaryField({
year: date.year,
Expand All @@ -233,11 +219,12 @@ const EditDiary = () => {
});
}

const savedDraft = localStorage.getItem('diary_draft');

if (savedDraft) {
const parsedDraft = JSON.parse(savedDraft);
const img = parsedDraft.imageInfo;

setDiaryInfo(parsedDraft);
if (img) setImage(img);

const checkText = parsedDraft.quillContent.replace(/<\/?[^>]+(>|$)/g, '');
setIsContentEmpty(checkText.trim().length === 0);
Expand All @@ -258,27 +245,20 @@ const EditDiary = () => {
setImage({
imageId: detail.image[0].imageId,
imageURL: detail.image[0].imageURL,
name: '',
size: '',
});
}
}
}, [date, detail]);

// 로컬 스토리지 임시 저장
// useEffect(() => {
// const savedDraft = localStorage.getItem('diary_draft');
// if (savedDraft) {
// const parsedDraft = JSON.parse(savedDraft);
// setDiaryInfo(parsedDraft);

// const checkText = parsedDraft.quillContent.replace(/<\/?[^>]+(>|$)/g, '');
// setIsContentEmpty(checkText.trim().length === 0);
// }
// }, []);

const handleSaveDraft = () => {
if (isContentEmpty) return; // 일기 내용이 비어 있으면 저장 요청 불가

localStorage.setItem('diary_draft', JSON.stringify(diaryInfo));
const draftData = { ...diaryInfo, imageInfo: image };
localStorage.setItem('diary_draft', JSON.stringify(draftData));
toast(CREATE_MESSAGES.toast.temp_save);
};

Expand Down Expand Up @@ -372,8 +352,8 @@ const EditDiary = () => {
<S.Image>
<img src={image.imageURL} alt="image file" />
</S.Image>
<S.ImageName>{imageInfo.name}</S.ImageName>
<S.ImageData>{imageInfo.size} KB</S.ImageData>
<S.ImageName>{image.name}</S.ImageName>
<S.ImageData>{image.size} KB</S.ImageData>
<button onClick={removeImage}>
<S.ImageDelete>
<Close />
Expand All @@ -388,8 +368,6 @@ const EditDiary = () => {
onContentChange={handleContentChange}
quillContent={diaryInfo.quillContent}
setImage={setImage}
setFile={setFile}
handleImageChange={handleImageChange}
selectedMode={selectedMode}
/>
</S.MainContainer>
Expand Down
5 changes: 5 additions & 0 deletions grass-diary/src/types/diary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ interface DiaryImage {
imageURL: string;
}

interface ImageInfo extends DiaryImage {
name: string;
size: string;
}

// DiaryDetail Type
interface IDiaryDetail extends IDiary {
memberId: Id;
Expand Down

0 comments on commit 9a24dd6

Please sign in to comment.