diff --git a/api/wishes/getPresignedURL.ts b/api/wishes/getPresignedURL.ts
new file mode 100644
index 00000000..9ecce474
--- /dev/null
+++ b/api/wishes/getPresignedURL.ts
@@ -0,0 +1,17 @@
+import { client } from '../common/axios';
+import PATH from '../common/path';
+
+export const getPresignedURL = async (fileName: string | undefined) => {
+ const accessToken = localStorage.getItem('accessToken');
+ const data = await client.get(
+ `${PATH.API}/${PATH.V1}/${PATH.FILE}?${PATH.FILE_NAME}=${fileName}`,
+ {
+ headers: {
+ 'Content-Type': 'application/json',
+ Authorization: `Bearer ${accessToken}`,
+ },
+ },
+ );
+
+ return data;
+};
diff --git a/api/wishes/uploadPresignedURL.ts b/api/wishes/uploadPresignedURL.ts
new file mode 100644
index 00000000..7af5fff1
--- /dev/null
+++ b/api/wishes/uploadPresignedURL.ts
@@ -0,0 +1,13 @@
+import axios from 'axios';
+
+export const uploadPresignedURL = async (signedURL: string, file: File | Blob | null) => {
+ console.log(decodeURIComponent(signedURL));
+ const data = await axios.put(signedURL, file, {
+ headers: {
+ 'Content-Type': file?.type,
+ },
+ });
+
+ console.log(data);
+ return data;
+};
diff --git a/components/common/mainHeader.tsx b/components/common/mainHeader.tsx
index 46620ebd..3613b52c 100644
--- a/components/common/mainHeader.tsx
+++ b/components/common/mainHeader.tsx
@@ -24,7 +24,7 @@ export default function MainHeader(props: MainHeaderProps) {
const Styled = {
Container: styled.div`
display: flex;
- margin: 2rem 0 0;
+ margin: 2rem 0 0rem;
`,
SideContainer: styled.div`
diff --git a/components/common/progressBar.tsx b/components/common/progressBar.tsx
index aa415e4e..ca830bfe 100644
--- a/components/common/progressBar.tsx
+++ b/components/common/progressBar.tsx
@@ -19,8 +19,8 @@ export default function ProgressBar(props: ProgressBarProps) {
const Styled = {
Container: styled.div<{ vertical: boolean }>`
- width: 27rem;
- height: 1rem;
+ width: 1rem;
+ height: 27rem;
background-color: ${theme.colors.pastel_blue};
diff --git a/components/main/cake.tsx b/components/main/cake.tsx
index 77b342b0..1fd98ca6 100644
--- a/components/main/cake.tsx
+++ b/components/main/cake.tsx
@@ -40,53 +40,49 @@ export default function Cake(props: CakeProps) {
const CakeImg = () => (wishStatus === 'end' ? MainEndCakeImg : PillCakeImg);
return (
- <>
-
-
-
-
-
-
-
-
- {wishStatus === 'while' || wishStatus === 'end' ? (
-
- 모인 케이크 보러가기 {'>'}
-
- ) : (
- 모인 케이크 금액
- )}
-
- 총 {priceData}원
-
-
- {/* 수정 필요 */}
-
- {percent && }
-
- {percent}%
- {percent && }
-
-
-
-
- {(wishStatus === 'while' || wishStatus === 'end') && (
-
- 펀딩 종료 후 3일내에 송금이 완료됩니다.
-
- 계좌번호를 확인해주세요!
-
- )}
-
- >
+
+
+
+
+
+
+
+
+ {wishStatus === 'while' || wishStatus === 'end' ? (
+
+ 모인 케이크 보러가기 {'>'}
+
+ ) : (
+ 모인 케이크 금액
+ )}
+
+ 총 {priceData}원
+
+
+
+ {percent}%
+
+
+
+
+
+
+
+
+ {(wishStatus === 'while' || wishStatus === 'end') && (
+
+ 펀딩 종료 후 3일내에 송금이 완료됩니다.
+
+ 계좌번호를 확인해주세요!
+
+ )}
+
);
}
const Styled = {
Container: styled.div`
margin: 9rem 0 0;
- display: flex;
- flex-direction: column;
`,
ImageContainer: styled.div`
@@ -96,9 +92,6 @@ const Styled = {
AboutButton: styled.button`
width: 100%;
- display: flex;
- justify-content: center;
- align-items: center;
margin: 0 0 1rem;
${theme.fonts.headline24_100};
color: ${theme.colors.main_blue};
@@ -122,37 +115,70 @@ const Styled = {
`,
CenterContainer: styled.div`
+ width: 100%;
display: flex;
- justify-content: space-between;
- align-items: flex-start;
+ justify-content: right;
+ align-items: center;
+ padding: 0 1rem 0 0;
`,
ContentContainer: styled.div`
- width: 100%;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
`,
- // progress bar
- BarContainer: styled.div``,
-
ProgressBox: styled.div`
height: 27rem;
display: flex;
flex-direction: column;
+ justify-content: right;
`,
PercentWrapper: styled.div<{ percent: number }>`
height: ${(props) => props.percent}%;
- /* ${(props) =>
+ ${(props) =>
props.percent > 3 &&
css`
- margin-left: -1.7rem;
- `} */
+ margin-top: -2rem;
+ `}
`,
Percent: styled.div`
${theme.fonts.button16};
color: ${theme.colors.main_blue};
margin-top: auto;
+ margin-right: 0.5rem;
+ `,
+
+ // Progressbar
+ BarContainer: styled.div`
+ width: 1rem;
+ height: 27rem;
+
+ background-color: ${theme.colors.pastel_blue};
+
+ border-bottom-right-radius: 5rem;
+ border-bottom-left-radius: 5rem;
+ border-top-right-radius: 5rem;
+ border-top-left-radius: 5rem;
+
+ -ms-transform: rotate(180deg); /* IE 9 */
+ -webkit-transform: rotate(180deg); /* Chrome, Safari, Opera */
+ transform: rotate(180deg);
+ `,
+
+ Progress: styled.div<{ percent: number }>`
+ height: ${(props) => props.percent}%;
+ max-height: 100%;
+ width: 100%;
+
+ background-color: ${theme.colors.main_blue};
+
+ border-bottom-right-radius: 5rem;
+ border-bottom-left-radius: 5rem;
+ border-top-right-radius: 5rem;
+ border-top-left-radius: 5rem;
`,
};
diff --git a/components/mypage/letters/[id].tsx b/components/mypage/letters/[id].tsx
index b6169a48..d5d4db33 100644
--- a/components/mypage/letters/[id].tsx
+++ b/components/mypage/letters/[id].tsx
@@ -9,8 +9,6 @@ import { useEffect, useState } from 'react';
import { ArrowLeftIc, ArrowRightIc } from '@/public/assets/icons';
import { useRouter } from 'next/router';
import { useGetCakesLetters } from '@/hooks/queries/letters/useGetCakeLetters';
-import { useRecoilValue } from 'recoil';
-import { CakesCountData } from '@/recoil/cakesCountData';
import { CAKE_LIST } from '@/constant/cakeList';
export default function LettersContainer() {
@@ -25,11 +23,11 @@ export default function LettersContainer() {
setCakeId(router.query.cakeId);
}, [router.isReady]);
+ // 케이크 정보, 개수
+ const { cake } = router.query;
const cakeData = CAKE_LIST.find((cake) => cake.cakeNumber === Number(cakeId));
- const selectedCake = useRecoilValue(CakesCountData).find(
- (cake) => cake.cakeId === Number(cakeId),
- );
+ // 편지
const { lettersData, lettersSum } = useGetCakesLetters(wishId, cakeId);
const handleNameBoxClick = (index: number) => {
@@ -60,7 +58,7 @@ export default function LettersContainer() {
fonts={theme.fonts.headline20}
image={cakeData ? cakeData.smallImage : ''}
cakeName={cakeData?.name}
- cakeNum={selectedCake?.count}
+ cakeNum={Number(cake)}
/>
diff --git a/components/mypage/letters/lettersMain.tsx b/components/mypage/letters/lettersMain.tsx
index 984c5b9d..b76aec8c 100644
--- a/components/mypage/letters/lettersMain.tsx
+++ b/components/mypage/letters/lettersMain.tsx
@@ -43,7 +43,16 @@ export default function LettersMainContainer() {
const handleMoveToLetters = (cakeId: number) => {
- router.push(`/mypage/letters/${wishId}/${cakeId}`);
+ const cake = CAKE_LIST.find(cake => cake.cakeNumber === cakeId);
+
+ if (cake) {
+ router.push({
+ pathname: `/mypage/letters/${wishId}/${cakeId}`,
+ query: {
+ cake: getCakeNum(cake.cakeNumber, cakesCount)
+ },
+ });
+ }
};
const title = (
diff --git a/constant/path.ts b/constant/path.ts
index 1ff7db1d..aad224fd 100644
--- a/constant/path.ts
+++ b/constant/path.ts
@@ -16,6 +16,8 @@ const PATH = {
USER: 'user',
ACCOUNT: 'account',
PROGRESS: 'progress',
+ FILE: 'file',
+ FILE_NAME: 'fileName',
PUBLIC: 'public',
};
diff --git a/constant/queryKey.ts b/constant/queryKey.ts
index 5413b26e..baf3f1ed 100644
--- a/constant/queryKey.ts
+++ b/constant/queryKey.ts
@@ -1,6 +1,4 @@
-import { QueryKeyType } from '@/types/queryKeyType';
-
-export const QUERY_KEY: QueryKeyType = {
+export const QUERY_KEY = {
ITEM_DATA: 'itemData',
WISHES_DATA: 'wishesData',
PAYREADY: 'payReady',
@@ -12,4 +10,5 @@ export const QUERY_KEY: QueryKeyType = {
CAKE_LETTERS: 'cakeLetters',
WISH_LINKS: 'wishLinks',
ONE_WISH: 'oneWish',
+ PRE_SIGNED_URL: 'preSignedURL',
};
diff --git a/hooks/queries/letters/useGetCakesCount.ts b/hooks/queries/letters/useGetCakesCount.ts
index ae2b4b48..93f3735b 100644
--- a/hooks/queries/letters/useGetCakesCount.ts
+++ b/hooks/queries/letters/useGetCakesCount.ts
@@ -1,20 +1,20 @@
import { useQuery } from 'react-query';
import { QUERY_KEY } from '@/constant/queryKey';
import { getCakesCount } from '@/api/letters/getCakesCount';
-import { CakesCountData } from '@/recoil/cakesCountData';
-import { useSetRecoilState } from 'recoil';
+// import { CakesCountData } from '@/recoil/cakesCountData';
+// import { useSetRecoilState } from 'recoil';
import { useState } from 'react';
export function useGetCakesCount(wishId: string | string[] | undefined) {
const [total, setTotal] = useState(0);
- const setCakesCountData = useSetRecoilState(CakesCountData);
+ // const setCakesCountData = useSetRecoilState(CakesCountData);
const { data: cakesCount } = useQuery(
QUERY_KEY.CAKES_COUNT,
async () => getCakesCount(wishId),
{
onSuccess: (data) => {
- setCakesCountData(data);
+ // setCakesCountData(data);
if (Array.isArray(data)) {
const cakesTotal = calculateTotal(data.map((cake: { count: any; }) => cake.count));
setTotal(cakesTotal);
diff --git a/hooks/wishes/useUploadItemInfo.ts b/hooks/wishes/useUploadItemInfo.ts
new file mode 100644
index 00000000..c6d1e503
--- /dev/null
+++ b/hooks/wishes/useUploadItemInfo.ts
@@ -0,0 +1,44 @@
+import { getPresignedURL } from '@/api/wishes/getPresignedURL';
+import { uploadPresignedURL } from '@/api/wishes/uploadPresignedURL';
+import { QUERY_KEY } from '@/constant/queryKey';
+import { useEffect, useState } from 'react';
+import { useMutation, useQuery } from 'react-query';
+
+export default function useUploadItemInfo() {
+ const [imageFile, setImageFile] = useState(null);
+ const [previewImage, setPreviewImage] = useState('');
+ const [preSignedURL, setPreSignedURL] = useState('');
+
+ const { data } = useQuery(QUERY_KEY.PRE_SIGNED_URL, () => getPresignedURL(imageFile?.name), {
+ enabled: imageFile !== null && imageFile?.name !== '',
+ });
+
+ useEffect(() => {
+ if (data?.data?.success) {
+ mutate();
+ }
+ }, [data]);
+
+ const { mutate } = useMutation(() => uploadPresignedURL(data?.data?.data?.signedUrl, imageFile), {
+ onSuccess: () => {
+ // setPreSignedURL()
+ },
+ });
+
+ console.log(data);
+
+ function uploadImageFile(e: React.ChangeEvent) {
+ const imageFile = e.target.files && e.target.files[0];
+
+ if (imageFile) {
+ setImageFile(imageFile);
+ const reader = new FileReader();
+ imageFile && reader.readAsDataURL(imageFile);
+ reader.onloadend = () => {
+ setPreviewImage(reader.result);
+ };
+ }
+ }
+
+ return { imageFile, previewImage, setPreviewImage, uploadImageFile };
+}
diff --git a/hooks/wishes/useWisehsStep.tsx b/hooks/wishes/useWisehsStep.ts
similarity index 100%
rename from hooks/wishes/useWisehsStep.tsx
rename to hooks/wishes/useWisehsStep.ts
diff --git a/recoil/cakesCountData.ts b/recoil/cakesCountData.ts
deleted file mode 100644
index 7c026b1d..00000000
--- a/recoil/cakesCountData.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { CakesCountType } from '@/types/letters/cakesCountType';
-import { atom } from 'recoil';
-
-export const CakesCountData = atom({
- key: 'CakesCount',
- default:
- [
- {
- cakeId: 0,
- count: 0,
- }
- ],
-});
diff --git a/types/letters/cakesCountType.ts b/types/letters/cakesCountType.ts
deleted file mode 100644
index 5d0f30ac..00000000
--- a/types/letters/cakesCountType.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-export interface CakesCountType {
- cakeId: number;
- count: number;
-}
-
diff --git a/types/queryKeyType.ts b/types/queryKeyType.ts
deleted file mode 100644
index 10270b02..00000000
--- a/types/queryKeyType.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-export interface QueryKeyType {
- ITEM_DATA: string;
- WISHES_DATA: string;
- PAYREADY: string;
- PG_TOKEN: string;
- USER: string;
- ACCOUNT: string;
- PROGRESS: string;
- CAKES_COUNT: string;
- CAKE_LETTERS: string;
- WISH_LINKS: string;
- ONE_WISH: string;
-}