From afbfdfc9b340ccb4c4b2f9899dcf2b398d709052 Mon Sep 17 00:00:00 2001 From: jungwoo3490 Date: Mon, 15 Jan 2024 07:43:44 +0900 Subject: [PATCH 1/4] =?UTF-8?q?feat:=20=EB=A0=88=ED=81=90=EB=B6=81=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20=ED=8E=98=EC=9D=B4=EC=A7=80=20Presigned=20?= =?UTF-8?q?URL=20=ED=9A=8D=EB=93=9D=20API=20=EC=97=B0=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/FavoriteImageInput/index.tsx | 31 +++++++++++---- src/Target/page/TargetPage/index.tsx | 8 +++- src/Target/util/api.ts | 39 +++++++++++++++++++ 3 files changed, 70 insertions(+), 8 deletions(-) create mode 100644 src/Target/util/api.ts diff --git a/src/Target/components/FavoriteImageInput/index.tsx b/src/Target/components/FavoriteImageInput/index.tsx index 78e8aa30..ec3cd824 100644 --- a/src/Target/components/FavoriteImageInput/index.tsx +++ b/src/Target/components/FavoriteImageInput/index.tsx @@ -1,28 +1,45 @@ import { useRef } from 'react'; import { IcCamera, ImgBook } from '../../../assets'; +import { getPresignedUrl, uploadFile } from '../../util/api'; import * as S from './FavoriteImageInput.style'; interface FavoriteImageInputProps { imgFile: string; uploadImage: (file: string) => void; + changePresignedFileName: (filename: string) => void; } -function FavoriteImageInput({ imgFile, uploadImage }: FavoriteImageInputProps) { +function FavoriteImageInput({ + imgFile, + uploadImage, + changePresignedFileName, +}: FavoriteImageInputProps) { const imgRef = useRef(null); - const handleImageUpload = () => { + const handleImageUpload = async (): Promise => { const fileInput = imgRef.current; if (fileInput && fileInput.files && fileInput.files.length > 0) { const file = fileInput.files[0]; - const reader = new FileReader(); - reader.readAsDataURL(file); + // reader1: 파일을 base64로 읽어서 업로드 + const reader1 = new FileReader(); + reader1.readAsDataURL(file); + reader1.onloadend = () => { + if (reader1.result !== null) { + uploadImage(reader1.result as string); + } + }; - reader.onloadend = () => { - if (reader.result !== null) { - uploadImage(reader.result as string); + // reader2: 파일을 ArrayBuffer로 읽어서 PUT 요청 수행 + const reader2 = new FileReader(); + reader2.readAsArrayBuffer(file); + reader2.onloadend = async () => { + if (reader2.result !== null) { + const { url, filename } = await getPresignedUrl('/api/images/book'); + await uploadFile(url, reader2.result as ArrayBuffer, file.type); + changePresignedFileName(filename); } }; } diff --git a/src/Target/page/TargetPage/index.tsx b/src/Target/page/TargetPage/index.tsx index fb1b272d..79c10104 100644 --- a/src/Target/page/TargetPage/index.tsx +++ b/src/Target/page/TargetPage/index.tsx @@ -1,4 +1,5 @@ import { useState } from 'react'; +import { useNavigate } from 'react-router-dom'; import Header from '../../../components/common/Header'; import CompleteButton from '../../components/CompleteButton'; @@ -8,10 +9,12 @@ import * as S from './TargetPage.style'; function TargetPage() { const [imgFile, setImgFile] = useState(''); + const [presignedFileName, setPresignedFileName] = useState(''); const [name, setName] = useState(''); + const navigate = useNavigate(); const handleClickCompleteButton = () => { - // API 쏘기... + navigate('/selectBtn'); }; return ( @@ -28,6 +31,9 @@ function TargetPage() { setImgFile(file)} + changePresignedFileName={(filename) => + setPresignedFileName(filename) + } /> diff --git a/src/Target/util/api.ts b/src/Target/util/api.ts new file mode 100644 index 00000000..09aca02a --- /dev/null +++ b/src/Target/util/api.ts @@ -0,0 +1,39 @@ +import { AxiosResponse } from 'axios'; + +import { api } from '../../libs/api'; + +interface PresignedUrlResponse { + data: { + url: string; + filename: string; + }; +} + +const getPresignedUrl = async ( + endpoint: string, +): Promise<{ url: string; filename: string }> => { + const response: AxiosResponse = await api.get(endpoint); + console.log(response); + return { + url: response.data.data.url, + filename: response.data.data.filename, + }; +}; + +const uploadFile = async ( + url: string, + data: ArrayBuffer, + contentType: string, +): Promise => { + await api + .put(url, data, { + headers: { + 'Content-Type': contentType, + }, + }) + .then((res) => { + console.log(res); + }); +}; + +export { getPresignedUrl, uploadFile }; From afb24a8d78a4c09c8a78e1edefd98688d822aced Mon Sep 17 00:00:00 2001 From: jungwoo3490 Date: Mon, 15 Jan 2024 08:15:09 +0900 Subject: [PATCH 2/4] =?UTF-8?q?feat:=20=EA=B8=88=EC=95=A1=20=EC=84=A0?= =?UTF-8?q?=ED=83=9D=20=ED=8E=98=EC=9D=B4=EC=A7=80=EB=A1=9C=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99=ED=95=A0=20=EC=8B=9C=20state=EB=A1=9C=20=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=20=EB=84=98=EA=B2=A8=EC=A3=BC=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Target/page/TargetPage/index.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Target/page/TargetPage/index.tsx b/src/Target/page/TargetPage/index.tsx index 79c10104..7e49baa7 100644 --- a/src/Target/page/TargetPage/index.tsx +++ b/src/Target/page/TargetPage/index.tsx @@ -14,7 +14,9 @@ function TargetPage() { const navigate = useNavigate(); const handleClickCompleteButton = () => { - navigate('/selectBtn'); + navigate('/select-book', { + state: { presignedFileName: presignedFileName, name: name }, + }); }; return ( From 9f225a60ca1a678804d09db45024241b56f0c60e Mon Sep 17 00:00:00 2001 From: jungwoo3490 Date: Mon, 15 Jan 2024 13:44:30 +0900 Subject: [PATCH 3/4] =?UTF-8?q?fix:=20=ED=8E=98=EC=9D=B4=EC=A7=80=20?= =?UTF-8?q?=EC=A7=84=EC=9E=85=20=EC=8B=9C=20GET=20=EC=9A=94=EC=B2=AD?= =?UTF-8?q?=ED=95=98=EA=B3=A0=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=97=85?= =?UTF-8?q?=EB=A1=9C=EB=93=9C=20=EC=8B=9C=20PUT=ED=95=98=EB=8F=84=EB=A1=9D?= =?UTF-8?q?=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/FavoriteImageInput/index.tsx | 47 ++++++++++++------- src/Target/util/api.ts | 6 +-- 2 files changed, 34 insertions(+), 19 deletions(-) diff --git a/src/Target/components/FavoriteImageInput/index.tsx b/src/Target/components/FavoriteImageInput/index.tsx index ec3cd824..9e912f47 100644 --- a/src/Target/components/FavoriteImageInput/index.tsx +++ b/src/Target/components/FavoriteImageInput/index.tsx @@ -1,4 +1,4 @@ -import { useRef } from 'react'; +import { useEffect, useRef, useState } from 'react'; import { IcCamera, ImgBook } from '../../../assets'; import { getPresignedUrl, uploadFile } from '../../util/api'; @@ -7,7 +7,7 @@ import * as S from './FavoriteImageInput.style'; interface FavoriteImageInputProps { imgFile: string; uploadImage: (file: string) => void; - changePresignedFileName: (filename: string) => void; + changePresignedFileName: (fileName: string) => void; } function FavoriteImageInput({ @@ -16,6 +16,21 @@ function FavoriteImageInput({ changePresignedFileName, }: FavoriteImageInputProps) { const imgRef = useRef(null); + const [presignedData, setPresignedData] = useState({ + url: '', + fileName: '', + }); + + useEffect(() => { + const fetchPresignedData = async () => { + const { url, fileName } = await getPresignedUrl('/api/images/book'); + console.log(url, fileName); + setPresignedData({ url, fileName }); + changePresignedFileName(fileName); + }; + + fetchPresignedData(); + }, []); const handleImageUpload = async (): Promise => { const fileInput = imgRef.current; @@ -23,23 +38,23 @@ function FavoriteImageInput({ if (fileInput && fileInput.files && fileInput.files.length > 0) { const file = fileInput.files[0]; - // reader1: 파일을 base64로 읽어서 업로드 - const reader1 = new FileReader(); - reader1.readAsDataURL(file); - reader1.onloadend = () => { - if (reader1.result !== null) { - uploadImage(reader1.result as string); + const base64Reader = new FileReader(); + base64Reader.readAsDataURL(file); + base64Reader.onloadend = () => { + if (base64Reader.result !== null) { + uploadImage(base64Reader.result as string); } }; - // reader2: 파일을 ArrayBuffer로 읽어서 PUT 요청 수행 - const reader2 = new FileReader(); - reader2.readAsArrayBuffer(file); - reader2.onloadend = async () => { - if (reader2.result !== null) { - const { url, filename } = await getPresignedUrl('/api/images/book'); - await uploadFile(url, reader2.result as ArrayBuffer, file.type); - changePresignedFileName(filename); + const binaryReader = new FileReader(); + binaryReader.readAsArrayBuffer(file); + binaryReader.onloadend = async () => { + if (binaryReader.result !== null) { + await uploadFile( + presignedData.url, + binaryReader.result as ArrayBuffer, + file.type, + ); } }; } diff --git a/src/Target/util/api.ts b/src/Target/util/api.ts index 09aca02a..44278bda 100644 --- a/src/Target/util/api.ts +++ b/src/Target/util/api.ts @@ -5,18 +5,18 @@ import { api } from '../../libs/api'; interface PresignedUrlResponse { data: { url: string; - filename: string; + fileName: string; }; } const getPresignedUrl = async ( endpoint: string, -): Promise<{ url: string; filename: string }> => { +): Promise<{ url: string; fileName: string }> => { const response: AxiosResponse = await api.get(endpoint); console.log(response); return { url: response.data.data.url, - filename: response.data.data.filename, + fileName: response.data.data.fileName, }; }; From 15aa55c57d7c3b76f0435a59cf1f36897947264b Mon Sep 17 00:00:00 2001 From: jungwoo3490 Date: Mon, 15 Jan 2024 13:45:41 +0900 Subject: [PATCH 4/4] =?UTF-8?q?chore:=20console=EB=AC=B8=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/FavoriteImageInput/index.tsx | 1 - src/Target/util/api.ts | 15 +++++---------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src/Target/components/FavoriteImageInput/index.tsx b/src/Target/components/FavoriteImageInput/index.tsx index 9e912f47..c8903f6d 100644 --- a/src/Target/components/FavoriteImageInput/index.tsx +++ b/src/Target/components/FavoriteImageInput/index.tsx @@ -24,7 +24,6 @@ function FavoriteImageInput({ useEffect(() => { const fetchPresignedData = async () => { const { url, fileName } = await getPresignedUrl('/api/images/book'); - console.log(url, fileName); setPresignedData({ url, fileName }); changePresignedFileName(fileName); }; diff --git a/src/Target/util/api.ts b/src/Target/util/api.ts index 44278bda..476db6cc 100644 --- a/src/Target/util/api.ts +++ b/src/Target/util/api.ts @@ -13,7 +13,6 @@ const getPresignedUrl = async ( endpoint: string, ): Promise<{ url: string; fileName: string }> => { const response: AxiosResponse = await api.get(endpoint); - console.log(response); return { url: response.data.data.url, fileName: response.data.data.fileName, @@ -25,15 +24,11 @@ const uploadFile = async ( data: ArrayBuffer, contentType: string, ): Promise => { - await api - .put(url, data, { - headers: { - 'Content-Type': contentType, - }, - }) - .then((res) => { - console.log(res); - }); + await api.put(url, data, { + headers: { + 'Content-Type': contentType, + }, + }); }; export { getPresignedUrl, uploadFile };