Skip to content

Commit

Permalink
fix: 한글 첨부파일 깨지는 문제 수정, 게시물 수정시 게시물로 redirect
Browse files Browse the repository at this point in the history
  • Loading branch information
yeolyi committed Mar 10, 2024
1 parent 32f0a56 commit de208cd
Show file tree
Hide file tree
Showing 15 changed files with 69 additions and 31 deletions.
7 changes: 5 additions & 2 deletions actions/news.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,19 @@ import { deleteNews, patchNews, postNews } from '@/apis/news';

import { getPath } from '@/utils/page';
import { news } from '@/utils/segmentNode';
import { decodeFormDataFileName } from '@/utils/string';

const newsPath = getPath(news);

export const postNewsAction = async (formData: FormData) => {
await postNews(formData);
decodeFormDataFileName(formData, 'attachments');
const resp = await postNews(formData);
revalidateNewsTag();
redirect(newsPath);
redirect(`${newsPath}/${resp.id}`);
};

export const patchNewsAction = async (id: number, formData: FormData) => {
decodeFormDataFileName(formData, 'newAttachments');
await patchNews(id, formData);
revalidateNewsTag();
redirect(`${newsPath}/${id}`);
Expand Down
7 changes: 5 additions & 2 deletions actions/notice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,19 @@ import {
import { errorToStr } from '@/utils/error';
import { getPath } from '@/utils/page';
import { notice } from '@/utils/segmentNode';
import { decodeFormDataFileName } from '@/utils/string';

const noticePath = getPath(notice);

export const postNoticeAction = async (formData: FormData) => {
await postNotice(formData);
decodeFormDataFileName(formData, 'attachments');
const resp = await postNotice(formData);
revalidateNoticeTag();
redirect(noticePath);
redirect(`${noticePath}/${resp.id}`);
};

export const patchNoticeAction = async (id: number, formData: FormData) => {
decodeFormDataFileName(formData, 'newAttachments');
await patchNotice(id, formData);
revalidateNoticeTag();
redirect(`${noticePath}/${id}`);
Expand Down
7 changes: 5 additions & 2 deletions actions/seminar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,19 @@ import { deleteSeminar, patchSeminar, postSeminar } from '@/apis/seminar';

import { getPath } from '@/utils/page';
import { seminar } from '@/utils/segmentNode';
import { decodeFormDataFileName } from '@/utils/string';

const seminarPath = getPath(seminar);

export const postSeminarAction = async (formData: FormData) => {
await postSeminar(formData);
decodeFormDataFileName(formData, 'attachments');
const resp = await postSeminar(formData);
revalidateSeminarTag();
redirect(seminarPath);
redirect(`${seminarPath}/${resp.id}`);
};

export const patchSeminarAction = async (id: number, formData: FormData) => {
decodeFormDataFileName(formData, 'newAttachments');
await patchSeminar(id, formData);
revalidateSeminarTag();
redirect(`${seminarPath}/${id}`);
Expand Down
2 changes: 1 addition & 1 deletion apis/news.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const getNewsDetail = (id: number, params?: PostSearchQueryParams) =>
// POST

export const postNews = async (formData: FormData) => {
await postRequest(newsPath, { body: formData });
return postRequest(newsPath, { body: formData }) as Promise<{ id: number }>;
};

// PATCH
Expand Down
2 changes: 1 addition & 1 deletion apis/notice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const getNoticePostDetail = (id: number, params: PostSearchQueryParams) =
// POST

export const postNotice = async (formData: FormData) => {
await postRequest('/notice', { body: formData });
return postRequest('/notice', { body: formData }) as Promise<{ id: number }>;
};

// PATCH
Expand Down
10 changes: 7 additions & 3 deletions apis/seminar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,21 @@ const seminarPath = '/seminar';
// GET

export const getSeminarPosts = async (params: PostSearchQueryParams) => {
return await getRequest<SeminarList>(seminarPath, params, { next: { tags: ['seminar'] } });
return getRequest(seminarPath, params, {
next: { tags: ['seminar'] },
}) as Promise<SeminarList>;
};

export const getSeminarPost = async (id: number, params: PostSearchQueryParams) => {
return await getRequest<Seminar>(`${seminarPath}/${id}`, params, { next: { tags: ['seminar'] } });
return getRequest(`${seminarPath}/${id}`, params, {
next: { tags: ['seminar'] },
}) as Promise<Seminar>;
};

// POST

export const postSeminar = async (formData: FormData) => {
await postRequest(seminarPath, { body: formData });
return postRequest(seminarPath, { body: formData }) as Promise<{ id: number }>;
};

// PATCH
Expand Down
1 change: 1 addition & 0 deletions app/[locale]/admin/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const getAdminData = async (selectedMenu: string, pageNum: number) => {
export default function AdminPage({ searchParams: { selected, page } }: AdminPageProps) {
const selectedMenu = selected ? replaceDashWithSpace(selected) : DEFAULT_MENU;
const pageNum = (page && parseInt(page)) || 1;

const { data } = useSWR(['/admin', selectedMenu, pageNum], () =>
getAdminData(selectedMenu, pageNum),
);
Expand Down
6 changes: 3 additions & 3 deletions app/[locale]/community/news/[id]/edit/EditNewsPageContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { News } from '@/types/news';
import { validateNewsForm } from '@/utils/formValidation';
import { getPath } from '@/utils/page';
import { news } from '@/utils/segmentNode';
import { encodeFormDataFileName } from '@/utils/string';

const newsPath = getPath(news);

Expand Down Expand Up @@ -110,13 +111,12 @@ const contentToFormData = (prevNews: News, content: PostEditorContent) => {
),
);

// TOOD: 이미지 이름 깨지는지 확인
if (mainImage) {
formData.append('newMainImage', mainImage);
}

for (const attachment of localAttachments) {
formData.append('newAttachments', attachment);
}
encodeFormDataFileName(formData, 'newAttachments', localAttachments);

return formData;
};
9 changes: 6 additions & 3 deletions app/[locale]/community/news/create/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { NEWS_TAGS } from '@/constants/tag';
import { validateNewsForm } from '@/utils/formValidation';
import { getPath } from '@/utils/page';
import { news } from '@/utils/segmentNode';
import { encodeFormDataFileName } from '@/utils/string';

const newsPath = getPath(news);

Expand Down Expand Up @@ -72,9 +73,11 @@ const contentToFormData = (content: PostEditorContent) => {
formData.append('mainImage', content.mainImage.file);
}

for (const attachment of content.attachments.filter(isLocalFile).map((x) => x.file)) {
formData.append('attachments', attachment);
}
encodeFormDataFileName(
formData,
'attachments',
content.attachments.filter(isLocalFile).map((x) => x.file),
);

return formData;
};
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { Notice } from '@/types/notice';
import { validateNoticeForm } from '@/utils/formValidation';
import { getPath } from '@/utils/page';
import { notice } from '@/utils/segmentNode';
import { encodeFormDataFileName } from '@/utils/string';
import { errorToast, successToast } from '@/utils/toast';

const noticePath = getPath(notice);
Expand Down Expand Up @@ -109,9 +110,7 @@ const contentToFormData = (prevNotice: Notice, content: PostEditorContent) => {
),
);

for (const attachment of localAttachments) {
formData.append('newAttachments', attachment);
}
encodeFormDataFileName(formData, 'newAttachments', localAttachments);

return formData;
};
10 changes: 6 additions & 4 deletions app/[locale]/community/notice/create/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { NOTICE_TAGS } from '@/constants/tag';
import { validateNoticeForm } from '@/utils/formValidation';
import { getPath } from '@/utils/page';
import { notice } from '@/utils/segmentNode';
import { encodeFormDataFileName } from '@/utils/string';

const noticePath = getPath(notice);

Expand Down Expand Up @@ -66,10 +67,11 @@ const contentToForm = (content: PostEditorContent) => {
),
);

content.attachments
.filter(isLocalFile)
.map((x) => x.file)
.forEach((attachment) => formData.append('attachments', attachment));
encodeFormDataFileName(
formData,
'attachments',
content.attachments.filter(isLocalFile).map((x) => x.file),
);

return formData;
};
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { Seminar } from '@/types/seminar';
import { validateSeminarForm } from '@/utils/formValidation';
import { getPath } from '@/utils/page';
import { seminar } from '@/utils/segmentNode';
import { encodeFormDataFileName } from '@/utils/string';
import { errorToast } from '@/utils/toast';

const seminarPath = getPath(seminar);
Expand Down Expand Up @@ -124,9 +125,7 @@ const contentToFormData = (prevSeminar: Seminar, content: SeminarEditorContent)
formData.append('newMainImage', image);
}

for (const attachment of localAttachments) {
formData.append('newAttachments', attachment);
}
encodeFormDataFileName(formData, 'newAttachments', localAttachments);

return formData;
};
5 changes: 2 additions & 3 deletions app/[locale]/community/seminar/create/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import PageLayout from '@/components/layout/pageLayout/PageLayout';
import { validateSeminarForm } from '@/utils/formValidation';
import { getPath } from '@/utils/page';
import { seminar } from '@/utils/segmentNode';
import { encodeFormDataFileName } from '@/utils/string';

const seminarPath = getPath(seminar);

Expand Down Expand Up @@ -80,9 +81,7 @@ const contentToFormData = (content: SeminarEditorContent) => {
formData.append('mainImage', image);
}

for (const attachment of attachments) {
formData.append('attachments', attachment);
}
encodeFormDataFileName(formData, 'attachments', attachments);

return formData;
};
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"compilerOptions": {
"target": "es5",
"target": "es6",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
Expand Down
22 changes: 22 additions & 0 deletions utils/string.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,25 @@
export const replaceSpaceWithDash = (words: string) => words.replace(/\s+/g, '-');

export const replaceDashWithSpace = (words: string) => words.replace(/-/g, ' ');

// server action에서 한글 파일이 깨지는 문제가 있어 수동으로 해결
// TODO: 없어도 되게
export const decodeFormDataFileName = (formData: FormData, key: FormDataFileName) => {
const list = formData.getAll(key);
formData.delete(key);

list.filter(isFile).forEach((file) => formData.append(key, file, decodeURI(file.name)));
};

// TODO: 없어도 되게
export const encodeFormDataFileName = (
formData: FormData,
key: FormDataFileName,
fileList: File[],
) => {
fileList.forEach((file) => formData.append(key, file, encodeURI(file.name)));
};

type FormDataFileName = 'attachments' | 'newAttachments';

const isFile = (x: unknown): x is File => x instanceof File;

0 comments on commit de208cd

Please sign in to comment.