From 37a74d65701367cd3d93fc7ba84005896a1d2af5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=ED=97=A4=EC=9D=B8?= Date: Tue, 20 Aug 2024 05:15:57 +0900 Subject: [PATCH 1/4] =?UTF-8?q?refactor(src):=20=EC=97=90=EB=9F=AC?= =?UTF-8?q?=EB=A9=94=EC=84=B8=EC=A7=80=20=EC=8A=A4=EB=8B=88=ED=8E=AB=20=3D?= =?UTF-8?q?>=20=EC=86=8C=EC=8A=A4=EC=BD=94=EB=93=9C=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/hooks/template/useTemplateEdit.ts | 6 +++--- frontend/src/hooks/template/useTemplateUpload.ts | 6 +++--- frontend/src/pages/MyTemplatesPage/MyTemplatePage.spec.tsx | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/frontend/src/hooks/template/useTemplateEdit.ts b/frontend/src/hooks/template/useTemplateEdit.ts index d109d0d60..8a5eefc6f 100644 --- a/frontend/src/hooks/template/useTemplateEdit.ts +++ b/frontend/src/hooks/template/useTemplateEdit.ts @@ -63,7 +63,7 @@ export const useTemplateEdit = ({ template, toggleEditButton }: Props) => { const deletedSourceCodeId = sourceCodes[index].id; if (!sourceCodes[index]) { - console.error('존재하지 않는 스니펫 인덱스입니다.'); + console.error('존재하지 않는 소스코드 인덱스입니다.'); } if (deletedSourceCodeId) { @@ -79,11 +79,11 @@ export const useTemplateEdit = ({ template, toggleEditButton }: Props) => { } if (sourceCodes.filter((sourceCode) => !sourceCode.filename).length) { - return '파일 명을 입력해주세요'; + return '파일명을 입력해주세요'; } if (sourceCodes.filter((sourceCode) => !sourceCode.content).length) { - return '스니펫 내용을 입력해주세요'; + return '소스코드 내용을 입력해주세요'; } return ''; diff --git a/frontend/src/hooks/template/useTemplateUpload.ts b/frontend/src/hooks/template/useTemplateUpload.ts index f68e57911..98e593ea4 100644 --- a/frontend/src/hooks/template/useTemplateUpload.ts +++ b/frontend/src/hooks/template/useTemplateUpload.ts @@ -56,7 +56,7 @@ export const useTemplateUpload = () => { const handleDeleteSourceCode = (index: number) => { if (!sourceCodes[index]) { - console.error('존재하지 않는 스니펫 인덱스입니다.'); + console.error('존재하지 않는 소스코드 인덱스입니다.'); } setSourceCodes((prevSourceCodes) => prevSourceCodes.filter((_, idx) => index !== idx)); @@ -72,11 +72,11 @@ export const useTemplateUpload = () => { } if (sourceCodes.filter((sourceCode) => !sourceCode.filename).length) { - return '파일 명을 입력해주세요'; + return '파일명을 입력해주세요'; } if (sourceCodes.filter((sourceCode) => !sourceCode.content).length) { - return '스니펫 내용을 입력해주세요'; + return '소스코드 내용을 입력해주세요'; } return ''; diff --git a/frontend/src/pages/MyTemplatesPage/MyTemplatePage.spec.tsx b/frontend/src/pages/MyTemplatesPage/MyTemplatePage.spec.tsx index 9d758b3fe..c5065818b 100644 --- a/frontend/src/pages/MyTemplatesPage/MyTemplatePage.spec.tsx +++ b/frontend/src/pages/MyTemplatesPage/MyTemplatePage.spec.tsx @@ -60,7 +60,7 @@ describe('MyTemplatePage', () => { }); }); - test('키워드 검색 (스니펫): "Hello, World"를 검색하면 템플릿의 sourceCode에 "Hello, World"이 포함되어 있는지 확인', async () => { + test('키워드 검색 (소스코드): "Hello, World"를 검색하면 템플릿의 sourceCode에 "Hello, World"이 포함되어 있는지 확인', async () => { const { getByPlaceholderText, getAllByText } = renderWithProviders(); const searchInput = getByPlaceholderText('검색'); From 92a9026280051beaecc29cb0d25330a96b1d109b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=ED=97=A4=EC=9D=B8?= Date: Tue, 20 Aug 2024 14:17:28 +0900 Subject: [PATCH 2/4] chore: codemirror-theme-material install --- frontend/package-lock.json | 8 ++++---- frontend/package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 4b6a31f9f..3c8bde535 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -16,7 +16,7 @@ "@sentry/webpack-plugin": "^2.21.1", "@tanstack/react-query": "^5.51.1", "@uiw/codemirror-extensions-langs": "^4.23.0", - "@uiw/codemirror-theme-vscode": "^4.23.0", + "@uiw/codemirror-theme-material": "^4.23.0", "@uiw/react-codemirror": "^4.23.0", "react": "^18.3.1", "react-dom": "^18.3.1", @@ -7636,10 +7636,10 @@ "@codemirror/legacy-modes": ">=6.0.0" } }, - "node_modules/@uiw/codemirror-theme-vscode": { + "node_modules/@uiw/codemirror-theme-material": { "version": "4.23.0", - "resolved": "https://registry.npmjs.org/@uiw/codemirror-theme-vscode/-/codemirror-theme-vscode-4.23.0.tgz", - "integrity": "sha512-zl1FD7U1b58tqlF216jYv2okvVkTe+FP1ztqO/DF129bcH99QjszkakshyfxQEvvF4ys3zyzqZ7vU3VYBir8tg==", + "resolved": "https://registry.npmjs.org/@uiw/codemirror-theme-material/-/codemirror-theme-material-4.23.0.tgz", + "integrity": "sha512-n1S6g0fhFIu12tCO7PC6LyPk0MxS747Hmp5ZBA3+lp3NHm/47EoZTl0SHr7+Qg5PxBRc1TkHD7YyXTN7TSWOsA==", "dependencies": { "@uiw/codemirror-themes": "4.23.0" }, diff --git a/frontend/package.json b/frontend/package.json index 1e4019089..8ab291a98 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -23,7 +23,7 @@ "@sentry/webpack-plugin": "^2.21.1", "@tanstack/react-query": "^5.51.1", "@uiw/codemirror-extensions-langs": "^4.23.0", - "@uiw/codemirror-theme-vscode": "^4.23.0", + "@uiw/codemirror-theme-material": "^4.23.0", "@uiw/react-codemirror": "^4.23.0", "react": "^18.3.1", "react-dom": "^18.3.1", From f96b9a09e1ba4c982212204809cc2369951cb3e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=ED=97=A4=EC=9D=B8?= Date: Tue, 20 Aug 2024 14:18:43 +0900 Subject: [PATCH 3/4] =?UTF-8?q?feat(src):=20=EC=BD=94=EB=93=9C=20=EC=97=90?= =?UTF-8?q?=EB=94=94=ED=84=B0=20=ED=85=8C=EB=A7=88=20=EB=B3=80=EA=B2=BD=20?= =?UTF-8?q?=EB=B0=8F=20=EC=86=8C=EC=8A=A4=EC=BD=94=EB=93=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=EC=8B=9C=20=ED=8C=8C=EC=9D=BC=EB=AA=85=20autoFocus=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SourceCodeEditor/SourceCodeEditor.tsx | 14 ++++++++++---- .../src/components/TemplateEdit/TemplateEdit.tsx | 1 + 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/frontend/src/components/SourceCodeEditor/SourceCodeEditor.tsx b/frontend/src/components/SourceCodeEditor/SourceCodeEditor.tsx index 8053c3b29..fdd1218e1 100644 --- a/frontend/src/components/SourceCodeEditor/SourceCodeEditor.tsx +++ b/frontend/src/components/SourceCodeEditor/SourceCodeEditor.tsx @@ -1,5 +1,5 @@ import { type LanguageName, loadLanguage } from '@uiw/codemirror-extensions-langs'; -import { vscodeDark } from '@uiw/codemirror-theme-vscode'; +import { materialLight } from '@uiw/codemirror-theme-material'; import ReactCodeMirror from '@uiw/react-codemirror'; import { ChangeEvent } from 'react'; @@ -7,13 +7,14 @@ import { getLanguageByFilename } from '@/utils'; import * as S from './style'; interface Props { + index: number; fileName: string; content: string; onChangeContent: (newContent: string) => void; onChangeFileName: (newFileName: string) => void; } -const SourceCodeEditor = ({ fileName, content, onChangeContent, onChangeFileName }: Props) => { +const SourceCodeEditor = ({ index, fileName, content, onChangeContent, onChangeFileName }: Props) => { const handleFileNameChange = (event: ChangeEvent) => { onChangeFileName(event.target.value); }; @@ -24,7 +25,12 @@ const SourceCodeEditor = ({ fileName, content, onChangeContent, onChangeFileName return ( - + diff --git a/frontend/src/components/TemplateEdit/TemplateEdit.tsx b/frontend/src/components/TemplateEdit/TemplateEdit.tsx index 6b42b2bb8..cd29fd577 100644 --- a/frontend/src/components/TemplateEdit/TemplateEdit.tsx +++ b/frontend/src/components/TemplateEdit/TemplateEdit.tsx @@ -107,6 +107,7 @@ const TemplateEdit = ({ handleCodeChange(newContent, idx)} From 92129a0004566619fe51418e53cab260f3ee8d64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=ED=97=A4=EC=9D=B8?= Date: Tue, 20 Aug 2024 14:37:47 +0900 Subject: [PATCH 4/4] =?UTF-8?q?feat(src):=20=ED=8C=8C=EC=9D=BC=EB=AA=85=20?= =?UTF-8?q?validation=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SourceCodeEditor/SourceCodeEditor.tsx | 12 ++++++++++ frontend/src/service/validates.ts | 22 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/frontend/src/components/SourceCodeEditor/SourceCodeEditor.tsx b/frontend/src/components/SourceCodeEditor/SourceCodeEditor.tsx index fdd1218e1..2cd1fb871 100644 --- a/frontend/src/components/SourceCodeEditor/SourceCodeEditor.tsx +++ b/frontend/src/components/SourceCodeEditor/SourceCodeEditor.tsx @@ -3,6 +3,9 @@ import { materialLight } from '@uiw/codemirror-theme-material'; import ReactCodeMirror from '@uiw/react-codemirror'; import { ChangeEvent } from 'react'; +import { ToastContext } from '@/contexts'; +import { useCustomContext } from '@/hooks/utils'; +import { validateFileName } from '@/service/validates'; import { getLanguageByFilename } from '@/utils'; import * as S from './style'; @@ -15,6 +18,8 @@ interface Props { } const SourceCodeEditor = ({ index, fileName, content, onChangeContent, onChangeFileName }: Props) => { + const { failAlert } = useCustomContext(ToastContext); + const handleFileNameChange = (event: ChangeEvent) => { onChangeFileName(event.target.value); }; @@ -23,11 +28,18 @@ const SourceCodeEditor = ({ index, fileName, content, onChangeContent, onChangeF onChangeContent(value); }; + const handleValidateFileName = (event: React.FocusEvent) => { + if (validateFileName(event.target.value)) { + failAlert(validateFileName(event.target.value)); + } + }; + return ( diff --git a/frontend/src/service/validates.ts b/frontend/src/service/validates.ts index 8a291ec23..f96389aa1 100644 --- a/frontend/src/service/validates.ts +++ b/frontend/src/service/validates.ts @@ -17,3 +17,25 @@ export const validatePassword = (password: string) => { export const validateConfirmPassword = (password: string, confirmPassword: string) => password === confirmPassword ? '' : '비밀번호가 일치하지 않습니다.'; + +export const validateFileName = (fileName: string) => { + const fileNamePattern = /^[가-힣a-zA-Z0-9_-]+\.[a-zA-Z]+$/; + + const invalidChars = /[<>:"/\\|?*]/; + + const maxLength = 255; + + if (fileName.length > maxLength || fileName.length === 0) { + return '파일명의 길이는 1~255자로 입력해주세요!'; + } + + if (invalidChars.test(fileName)) { + return '특수 문자 (<, >, :, ", /, , |, ?, *)는 사용할 수 없습니다!'; + } + + if (!fileNamePattern.test(fileName)) { + return '확장자를 입력해주세요!'; + } + + return ''; +};