Skip to content

Commit

Permalink
[ feat ] 케이크 결제수단 이동 페이지 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
myeongheonhong committed Dec 22, 2023
1 parent 955b3cc commit 90193c1
Show file tree
Hide file tree
Showing 17 changed files with 620 additions and 116 deletions.
21 changes: 20 additions & 1 deletion api/public.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { PublicWishesDataResponseType } from '@/types/api/response';
import { PostPublicCakesResponseType, PublicWishesDataResponseType } from '@/types/api/response';
import { client } from './common/axios';
import { API_VERSION_01, PATH_PUBLIC } from './path';
import { PostPublicCakesRequestType } from '@/types/api/request';
import { getAccessToken } from '@/utils/common/token';

const ACCESS_TOKEN = getAccessToken();

export const getPublicWishes = async (wishId: string | string[] | undefined) => {
const data = await client.get<PublicWishesDataResponseType>(
Expand All @@ -9,3 +13,18 @@ export const getPublicWishes = async (wishId: string | string[] | undefined) =>

return data.data.data;
};

export const postPublicCakes = async (parameter: PostPublicCakesRequestType) => {
const data = await client.post<PostPublicCakesResponseType>(
`${API_VERSION_01}${PATH_PUBLIC.CAKES}`,
parameter,
{
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${ACCESS_TOKEN}`,
},
},
);

return data.data.data;
};
125 changes: 125 additions & 0 deletions components/cakes/CakesForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import { useEffect } from 'react';
import TextareaBox from '../common/input/textareaBox';
import styled from 'styled-components';
import theme from '@/styles/theme';
import { LIMIT_TEXT } from '@/constant/limitText';
import SelectCakes from './SelectCakes';
import Button from '../common/button';
import Input from '../common/input/input';
import { UseFormReturn } from 'react-hook-form';
import InputContainer from '../common/input/inputContainer';
import { CakesDataInputType } from '@/types/common/input/cakesInput';
import { StyledBox } from '../common/box';
import BackBtn from '../common/button/backBtn';
import { CakeListType } from '@/types/cakes/cakeListType';
import { useGetPublicWishes, usePostPublicCakes } from '@/hooks/queries/public';
import { UseMutateFunction } from 'react-query';

interface CakesFormProps {
methods: UseFormReturn<CakesDataInputType, any, undefined>;
selectedCake: CakeListType;
selectedIndex: number;
selectCake: (index: number) => void;
wishesId: string | string[] | undefined;
postPublicCakesData: UseMutateFunction<
{
cakeId: number;
imageUrl: string;
hint: string;
initial: string;
contribute: string;
wisher: string;
},
unknown,
void,
unknown
>;
}

export default function CakesForm(props: CakesFormProps) {
const { methods, selectedCake, selectedIndex, selectCake, wishesId, postPublicCakesData } = props;

const { publicWishesData } = useGetPublicWishes(wishesId);

return (
<>
<div>
<Styled.Header>
<BackBtn />
{`D-${publicWishesData?.dayCount}`}
</Styled.Header>

<Styled.Title>{publicWishesData?.title}</Styled.Title>

<InputContainer title={`${publicWishesData?.name}님이 남긴 선물에 대한 힌트`}>
<Styled.HintBox className={'pastelBlue_darkBlue'}>
{publicWishesData?.hint}
</Styled.HintBox>
{/* <TextareaBox value={publicWishesData?.hint} readOnly /> */}
</InputContainer>

<InputContainer title={'본인의 실명 작성하기'}>
<Input
placeholder="이름을 정확하게 작성해주세요. ex. 홍길동"
register={methods.register('giverName')}
/>
</InputContainer>

<SelectCakes
selectedCake={selectedCake}
selectedIndex={selectedIndex}
selectCake={selectCake}
/>

<InputContainer title={'친구에게 편지 남기기'}>
<TextareaBox
placeholder={`ex. 너 도대체 원하는 게 모야?\n나 넘 궁금해. 일단 몸보신 한우 케이크 보태겠어`}
inputLength={methods.watch('letter').length}
limitLength={LIMIT_TEXT.DESCRIPTION}
register={methods.register('letter')}
></TextareaBox>
</InputContainer>
</div>
<Styled.ButtonWrapper>
<Button
boxType="btn--large"
colorSystem="mainBlue_white"
handleClickFn={postPublicCakesData}
>
{'케이크 주문하기'}
</Button>
</Styled.ButtonWrapper>
</>
);
}

const Styled = {
Header: styled.header`
display: flex;
justify-content: space-between;
width: 100%;
color: ${theme.colors.main_blue};
${theme.fonts.headline20};
`,

Title: styled.h1`
${theme.fonts.headline24_100};
color: ${theme.colors.main_blue};
margin: 2.4rem 0 3rem;
`,

HintBox: styled(StyledBox)`
width: 100%;
height: 12.6rem;
${theme.fonts.body14};
padding: 1.2rem 1rem 1.2rem 1.2rem;
`,

ButtonWrapper: styled.div`
padding-bottom: 4.6rem;
`,
};
151 changes: 151 additions & 0 deletions components/cakes/CakesPay.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
import styled from 'styled-components';
import theme from '@/styles/theme';
import { BackBtnIc } from '@/public/assets/icons';
import Image from 'next/image';
import { CakeListType } from '@/types/cakes/cakeListType';
import { convertMoneyText } from '@/utils/common/convertMoneyText';
import PaymentItemSelect from '../common/Select/PaymentItemSelect';
import { BANK_LIST } from '@/constant/bankList';
import { BankListType } from '@/types/bankListType';
import Button from '../common/button';
import { useState } from 'react';
import { useGetPublicWishes } from '@/hooks/queries/public';
import router from 'next/router';

interface CakesPayProps {
handlePrevStep: () => void;
handleNextStep: () => void;
selectedCake: CakeListType;
wishesId: string | string[] | undefined;
}

export default function CakesPay(props: CakesPayProps) {
const { handlePrevStep, handleNextStep, selectedCake, wishesId } = props;

const { publicWishesData } = useGetPublicWishes(wishesId);

const PAYMENTS: BankListType[] = [BANK_LIST[5], BANK_LIST[1]];
const [selectedPayment, setSelected] = useState<BankListType>();

const handlePaymentSelect = (payment: BankListType) => {
setSelected(payment);
};

const handleDeepLink = (payment: BankListType | undefined) => {
const ua = navigator.userAgent.toLowerCase();

if (!selectedPayment) {
alert('결제수단을 선택해주세요!');
return;
}

if (window.confirm(`${payment?.name}(으)로 이동할까요?`)) {
if (payment?.name === '토스뱅크') {
window.open(
ua.indexOf('android') > -1
? 'https://play.google.com/store/apps/details?id=viva.republica.toss'
: 'https://apps.apple.com/app/id839333328',
);
}

if (payment?.name === '카카오뱅크') {
window.open(
ua.indexOf('android') > -1
? 'https://play.google.com/store/apps/details?id=com.kakaobank.channel'
: 'https://apps.apple.com/app/id1258016944',
);
}
handleNextStep();
}
};

return (
<>
<Styled.Header>
<Image src={BackBtnIc} alt="뒤로가기" onClick={handlePrevStep} />
</Styled.Header>
<Styled.Container>
<Styled.TitleText>주문 확인 내역</Styled.TitleText>
<Styled.TextWrapper>{`${selectedCake.name} ${convertMoneyText(
String(selectedCake.price),
)}원을\n${publicWishesData?.name}님께 보내시겠습니까?`}</Styled.TextWrapper>

<Styled.ImageWrapper>
<Image src={selectedCake.detailImage} alt="케이크 이미지" width={285} />
</Styled.ImageWrapper>

<Styled.TitleText>결제수단 선택</Styled.TitleText>

<Styled.PaymentWrapper>
{PAYMENTS.map((payment: BankListType) => (
<PaymentItemSelect
payment={payment}
handleClickFn={handlePaymentSelect}
selectedPayment={selectedPayment}
key={payment.name}
/>
))}
</Styled.PaymentWrapper>
</Styled.Container>

<Styled.ButtonWrapper>
<Button
boxType="btn--large"
colorSystem="mainBlue_white"
handleClickFn={() => handleDeepLink(selectedPayment)}
>
{'친구 계좌로 케이크 쏘기'}
</Button>
</Styled.ButtonWrapper>
</>
);
}

const Styled = {
Header: styled.header`
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
height: 3rem;
`,

Container: styled.section`
width: 100%;
height: 100%;
margin: 2.4rem 0 2rem;
`,

TitleText: styled.h1`
${theme.fonts.headline24_130};
color: ${theme.colors.main_blue};
`,

TextWrapper: styled.div`
${theme.fonts.headline24_130};
color: ${theme.colors.black};
margin-top: 0.7rem;
white-space: pre-line;
`,

ImageWrapper: styled.div`
margin: 1.5rem 0 2rem;
`,

PaymentWrapper: styled.ul`
display: flex;
flex-direction: column;
gap: 1.4rem;
margin-top: 2rem;
`,

ButtonWrapper: styled.div`
padding-bottom: 4.6rem;
`,
};
Loading

0 comments on commit 90193c1

Please sign in to comment.