From 5c9415eaedc220af22c86f579341c9d4200f5f1e Mon Sep 17 00:00:00 2001 From: sonji406 Date: Mon, 21 Aug 2023 18:23:44 +0900 Subject: [PATCH 1/8] =?UTF-8?q?Fix:=20=EB=94=94=EB=A0=89=ED=86=A0=EB=A6=AC?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD=EC=9C=BC=EB=A1=9C=20pramas=20=EA=B0=80?= =?UTF-8?q?=EC=A0=B8=EC=98=A4=EB=8A=94=20=EB=B0=A9=EC=8B=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/post/editor/[userId]/page.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/post/editor/[userId]/page.jsx b/src/app/post/editor/[userId]/page.jsx index 7a02ada..25f1cb1 100644 --- a/src/app/post/editor/[userId]/page.jsx +++ b/src/app/post/editor/[userId]/page.jsx @@ -13,8 +13,8 @@ function PostEditPage({ params }) { const [content, setContent] = useState({}); const [error, setError] = useState(null); - const userId = params.userId; - const postId = params.postId || null; + const userId = params[0]; + const postId = params[1] || null; const isModify = Boolean(postId); From 6f5406a07d818248a491211b4ef9150603edd47f Mon Sep 17 00:00:00 2001 From: sonji406 Date: Mon, 21 Aug 2023 18:24:34 +0900 Subject: [PATCH 2/8] =?UTF-8?q?Fix:=20api=20=ED=98=B8=EC=B6=9C=20=EB=B6=80?= =?UTF-8?q?=EB=B6=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Editor.jsx | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/components/Editor.jsx b/src/components/Editor.jsx index 973146b..d55f464 100644 --- a/src/components/Editor.jsx +++ b/src/components/Editor.jsx @@ -11,6 +11,10 @@ function Editor({ author, postId, title, content, error, setError, isModify }) { const router = useRouter(); useEffect(() => { + if (ref.current) { + return; + } + const editor = new EditorJS({ holder: 'editorjs', data: content, @@ -31,7 +35,7 @@ function Editor({ author, postId, title, content, error, setError, isModify }) { ref.current = editor; return () => { - if (ref.current) { + if (ref.current && typeof ref.current.destroy === 'function') { ref.current.destroy(); } }; @@ -52,13 +56,19 @@ function Editor({ author, postId, title, content, error, setError, isModify }) { }; try { + let response = {}; + if (isModify) { - await axios.put(`/api/v1/posts/${postId}`, postData); - router.push(`/posts/${author}`); + response = await axios.put(`/api/v1/posts/${postId}`, postData); + } else { + response = await axios.post('/api/v1/posts', postData); + } + + if (response.data.status !== 'success') { + setError(response.data.message); return; } - await axios.post('/api/v1/posts', postData); router.push(`/posts/${author}`); } catch { const errorMessage = isModify From 75e96a10e5b985e4fcfd857f4eb90c0a0c24fe79 Mon Sep 17 00:00:00 2001 From: sonji406 Date: Mon, 21 Aug 2023 18:32:24 +0900 Subject: [PATCH 3/8] =?UTF-8?q?Fix:=20S3=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=EC=A0=80=EC=9E=A5=20=EB=B6=80=EB=B6=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/api/v1/image/uploadFile/route.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/app/api/v1/image/uploadFile/route.js b/src/app/api/v1/image/uploadFile/route.js index 4770ed8..386baec 100644 --- a/src/app/api/v1/image/uploadFile/route.js +++ b/src/app/api/v1/image/uploadFile/route.js @@ -59,6 +59,8 @@ async function POST(request) { fileBuffer = Buffer.concat([fileBuffer, chunk]); } + await s3Data.putObject(s3Params); + const fileUrl = `https://${bucketName}.s3.amazonaws.com/${fileName}`; return NextResponse.json({ From d65a176b06826e7685063f3fde28b0f322822e9e Mon Sep 17 00:00:00 2001 From: sonji406 Date: Mon, 21 Aug 2023 18:58:06 +0900 Subject: [PATCH 4/8] =?UTF-8?q?Fix:=20editor.js=20=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20=EB=B6=88=EB=9F=AC=EC=98=A4=EA=B8=B0=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Editor.jsx | 45 ++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/src/components/Editor.jsx b/src/components/Editor.jsx index d55f464..1281a9c 100644 --- a/src/components/Editor.jsx +++ b/src/components/Editor.jsx @@ -11,34 +11,31 @@ function Editor({ author, postId, title, content, error, setError, isModify }) { const router = useRouter(); useEffect(() => { - if (ref.current) { - return; - } - - const editor = new EditorJS({ - holder: 'editorjs', - data: content, - tools: { - image: { - class: ImageTool, - config: { - endpoints: { - byFile: 'http://localhost:3000/api/v1/image/uploadFile', + const initEditor = async () => { + if (!ref.current) { + ref.current = new EditorJS({ + holder: 'editorjs', + data: content, + tools: { + image: { + class: ImageTool, + config: { + endpoints: { + byFile: 'http://localhost:3000/api/v1/image/uploadFile', + }, + types: 'image/*', + captionPlaceholder: 'Enter caption', + }, }, - types: 'image/*', - captionPlaceholder: 'Enter caption', }, - }, - }, - }); - - ref.current = editor; - - return () => { - if (ref.current && typeof ref.current.destroy === 'function') { - ref.current.destroy(); + }); + } else { + await ref.current.isReady; + ref.current.render(content); } }; + + initEditor(); }, [content]); const postSave = async () => { From 52b884a74114c5cef5fd7e0f78879828c16bc07d Mon Sep 17 00:00:00 2001 From: sonji406 Date: Mon, 21 Aug 2023 19:14:41 +0900 Subject: [PATCH 5/8] =?UTF-8?q?Fix:=20S3=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20A?= =?UTF-8?q?PI=20=EC=88=98=EC=A0=95=20=EB=B0=8F=20=EC=97=90=EB=9F=AC=20?= =?UTF-8?q?=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/api/v1/image/uploadFile/route.js | 54 ++++++++++++++++-------- utils/errors.js | 6 +++ 2 files changed, 42 insertions(+), 18 deletions(-) diff --git a/src/app/api/v1/image/uploadFile/route.js b/src/app/api/v1/image/uploadFile/route.js index 386baec..0023752 100644 --- a/src/app/api/v1/image/uploadFile/route.js +++ b/src/app/api/v1/image/uploadFile/route.js @@ -12,10 +12,10 @@ const s3Data = new S3({ const bucketName = process.env.AWS_S3_BUCKET_NAME; -function GET(request) { - const { file: fileName, fileType } = request.query; +async function GET(request) { + try { + const { file: fileName, fileType } = request.query; - return new Promise((resolve) => { const s3Params = { Bucket: bucketName, Key: fileName, @@ -24,22 +24,28 @@ function GET(request) { ACL: 'public-read', }; - s3Data.getSignedUrl('putObject', s3Params, (err, data) => { - if (err) { - throw createError( - ERRORS.SIGNED_URL_CREATION_ERROR.STATUS_CODE, - ERRORS.SIGNED_URL_CREATION_ERROR.MESSAGE, - ); - } + const signedUrl = await new Promise((resolve, reject) => { + s3Data.getSignedUrl('putObject', s3Params, (err, data) => { + if (err) { + reject( + createError( + ERRORS.SIGNED_URL_CREATION_ERROR.STATUS_CODE, + ERRORS.SIGNED_URL_CREATION_ERROR.MESSAGE, + ), + ); + } else { + resolve(data); + } + }); + }); - resolve( - NextResponse.json({ - signedRequest: data, - url: `https://${bucketName}.s3.amazonaws.com/${fileName}`, - }), - ); + return NextResponse.json({ + signedRequest: signedUrl, + url: `https://${bucketName}.s3.amazonaws.com/${fileName}`, }); - }); + } catch (error) { + return sendErrorResponse(error); + } } async function POST(request) { @@ -48,10 +54,14 @@ async function POST(request) { const file = formData.get('image'); if (!file) { - throw new Error('요청에서 파일을 찾을 수 없습니다.'); + throw createError( + ERRORS.FILE_NOT_FOUND.STATUS_CODE, + ERRORS.FILE_NOT_FOUND.MESSAGE, + ); } const fileName = file.name; + const fileType = file.type; const fileStream = file.stream(); let fileBuffer = Buffer.alloc(0); @@ -59,6 +69,14 @@ async function POST(request) { fileBuffer = Buffer.concat([fileBuffer, chunk]); } + const s3Params = { + Bucket: bucketName, + Key: fileName, + Body: fileBuffer, + ContentType: fileType, + ACL: 'public-read', + }; + await s3Data.putObject(s3Params); const fileUrl = `https://${bucketName}.s3.amazonaws.com/${fileName}`; diff --git a/utils/errors.js b/utils/errors.js index ceae47d..4c78575 100644 --- a/utils/errors.js +++ b/utils/errors.js @@ -38,6 +38,11 @@ const SIGNED_URL_CREATION_ERROR = { MESSAGE: 'signed URL 생성 오류입니다.', }; +const FILE_NOT_FOUND = { + STATUS_CODE: 400, // 예: 400은 잘못된 요청을 나타냅니다. + MESSAGE: '요청에서 파일을 찾을 수 없습니다.', +}; + export const ERRORS = { INVALID_USER_ID, USER_NOT_FOUND, @@ -47,4 +52,5 @@ export const ERRORS = { MISSING_PARAMETERS, POST_NOT_FOUND, SIGNED_URL_CREATION_ERROR, + FILE_NOT_FOUND, }; From d11d13cc778e1bf93a54bf510c7646e4d46041f5 Mon Sep 17 00:00:00 2001 From: sonji406 Date: Mon, 21 Aug 2023 19:49:47 +0900 Subject: [PATCH 6/8] =?UTF-8?q?Fix:=20postId=20=EC=97=AC=EB=B6=80=20params?= =?UTF-8?q?=20=EB=B0=A9=EB=B2=95=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/post/editor/[userId]/page.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/post/editor/[userId]/page.jsx b/src/app/post/editor/[userId]/page.jsx index 25f1cb1..c413b68 100644 --- a/src/app/post/editor/[userId]/page.jsx +++ b/src/app/post/editor/[userId]/page.jsx @@ -13,7 +13,7 @@ function PostEditPage({ params }) { const [content, setContent] = useState({}); const [error, setError] = useState(null); - const userId = params[0]; + const userId = Array.isArray(params) ? params[0] : params.userId; const postId = params[1] || null; const isModify = Boolean(postId); From d2b9ba21cc45316a5892d6661f924aa67a401182 Mon Sep 17 00:00:00 2001 From: sonji406 Date: Mon, 21 Aug 2023 20:49:36 +0900 Subject: [PATCH 7/8] =?UTF-8?q?Refactor:=20=EC=BD=94=EB=93=9C=20=EB=A6=AC?= =?UTF-8?q?=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Editor.jsx | 47 ++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/src/components/Editor.jsx b/src/components/Editor.jsx index 1281a9c..1fd5041 100644 --- a/src/components/Editor.jsx +++ b/src/components/Editor.jsx @@ -12,27 +12,28 @@ function Editor({ author, postId, title, content, error, setError, isModify }) { useEffect(() => { const initEditor = async () => { - if (!ref.current) { - ref.current = new EditorJS({ - holder: 'editorjs', - data: content, - tools: { - image: { - class: ImageTool, - config: { - endpoints: { - byFile: 'http://localhost:3000/api/v1/image/uploadFile', - }, - types: 'image/*', - captionPlaceholder: 'Enter caption', - }, - }, - }, - }); - } else { + if (ref.current) { await ref.current.isReady; ref.current.render(content); + return; } + + ref.current = new EditorJS({ + holder: 'editorjs', + data: content, + tools: { + image: { + class: ImageTool, + config: { + endpoints: { + byFile: 'http://localhost:3000/api/v1/image/uploadFile', + }, + types: 'image/*', + captionPlaceholder: 'Enter caption', + }, + }, + }, + }); }; initEditor(); @@ -53,13 +54,9 @@ function Editor({ author, postId, title, content, error, setError, isModify }) { }; try { - let response = {}; - - if (isModify) { - response = await axios.put(`/api/v1/posts/${postId}`, postData); - } else { - response = await axios.post('/api/v1/posts', postData); - } + const response = isModify + ? await axios.put(`/api/v1/posts/${postId}`, postData) + : await axios.post('/api/v1/posts', postData); if (response.data.status !== 'success') { setError(response.data.message); From cddb4169475a8f3744b6b2499ba9834bde25f33a Mon Sep 17 00:00:00 2001 From: sonji406 Date: Mon, 21 Aug 2023 20:57:11 +0900 Subject: [PATCH 8/8] =?UTF-8?q?Chore:=20=ED=81=AC=EA=B8=B0=EC=97=90=20?= =?UTF-8?q?=EB=A7=9E=EA=B2=8C=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=9E=90?= =?UTF-8?q?=EB=A5=B4=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/postlist/PostItem.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/postlist/PostItem.jsx b/src/components/postlist/PostItem.jsx index fe2d055..15b5a1c 100644 --- a/src/components/postlist/PostItem.jsx +++ b/src/components/postlist/PostItem.jsx @@ -14,7 +14,7 @@ function PostItem({ post }) { return (
{imageUrl ? ( -
+
{textValue}
) : (