-
Notifications
You must be signed in to change notification settings - Fork 0
feat : 결제 페이지,카드 정보 입력 페이지 퍼블리싱 #53
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
bfb2321
feat:결제를 위한 등록된 카드 컴포넌트 분리 생성
HSCHEOL c657a79
feat:카드 등록 페이지 생성 및 라우트 설정
HSCHEOL 5765be0
feat:새 카드 추가 페이지 퍼블리싱
HSCHEOL 15cc9eb
feat:결제 페이지 생성 및 라우트 설정
HSCHEOL f988868
feat:결제 페이지 퍼블리싱
HSCHEOL 76c10ed
feat:PaymentCard 컴포넌트 카드 등록 버튼 수정
HSCHEOL 5ab04be
feat:누락시킨 결제하기 버튼 추가
HSCHEOL 41c0cce
feat:PaymentPage Header 뒤로 가기 Navigate 설정
HSCHEOL 25f2d42
feat:CardRegisterPage 누락시킨 저장하기 버튼 추가
HSCHEOL 8bd6942
feat:CardRegisterPage Button h 수정
HSCHEOL c2ad0ce
remove:불필요한 파일 삭제
HSCHEOL 39e6420
feat:Payment 메인 라우트 설정
HSCHEOL 6b964cb
refact:PaymentCard 컴포넌트 , 카드 등록 버튼을 VerticalCardButton 으로 대체
HSCHEOL e7c7cbb
chore:react-hook-form install
HSCHEOL 82de401
refact:CardRegisterPage 카드 등록 상태를 react-hook-form로 관리하도록 변경
HSCHEOL File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,127 @@ | ||
| import React from 'react'; | ||
| import TicketHostLayout from '../../../shared/ui/backgrounds/TicketHostLayout'; | ||
| import CreditCard from '../../../../public/assets/payment/CreditCard.svg'; | ||
| import DefaultTextField from '../../../../design-system/ui/textFields/DefaultTextField'; | ||
| import Button from '../../../../design-system/ui/Button'; | ||
| import { useForm } from 'react-hook-form'; | ||
|
|
||
| type CardFormValues = { | ||
| cardNumber: string; | ||
| cardHolder: string; | ||
| expiryMonth: string; | ||
| expiryYear: string; | ||
| cvc: string; | ||
| }; | ||
|
|
||
| const CardRegisterPage = () => { | ||
| const { | ||
| register, | ||
| handleSubmit, | ||
| setValue, | ||
| formState: { errors }, | ||
| } = useForm<CardFormValues>(); | ||
|
|
||
| // 공통 포맷 함수 | ||
| const formatValue = (type: keyof CardFormValues, value: string): string => { | ||
| switch (type) { | ||
| case 'cardNumber': | ||
| return value | ||
| .replace(/\D/g, '') | ||
| .slice(0, 16) | ||
| .replace(/(\d{4})/g, '$1 ') | ||
| .trim(); | ||
| case 'expiryMonth': | ||
| return value.replace(/\D/g, '').slice(0, 2); | ||
| case 'expiryYear': | ||
| return value.replace(/\D/g, '').slice(0, 4); | ||
| case 'cvc': | ||
| return value.replace(/\D/g, '').slice(0, 3); | ||
| default: | ||
| return value; | ||
| } | ||
| }; | ||
|
|
||
| // 공통 핸들러 | ||
| const handleInputChange = (type: keyof CardFormValues) => (e: React.ChangeEvent<HTMLInputElement>) => { | ||
| const formattedValue = formatValue(type, e.target.value); | ||
| setValue(type, formattedValue, { shouldValidate: true }); | ||
| }; | ||
|
|
||
| const onSubmit = (data: CardFormValues) => { | ||
| console.log('폼 전체 데이터 객체:', data); | ||
| }; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 현재는 |
||
|
|
||
| return ( | ||
| <TicketHostLayout centerContent="새 카드 추가" image={CreditCard}> | ||
| <div className="p-10 flex flex-col gap-16 mt-20 min-h-[80vh]"> | ||
| <p className="text-gray-400 text-sm">안전한 결제를 위해 카드 정보를 입력해주세요.</p> | ||
|
|
||
| <div> | ||
| <DefaultTextField | ||
| label="카드 번호" | ||
| className={`h-12 ${errors.cardNumber ? 'border-2 border-red-500' : ''}`} | ||
| placeholder="1234 5678 9012 3456" | ||
| {...register('cardNumber', { | ||
| required: '카드 번호를 입력하세요.', | ||
| pattern: { | ||
| value: /^\d{4} \d{4} \d{4} \d{4}$/, | ||
| message: '올바른 카드 번호 형식이 아닙니다.', | ||
| }, | ||
| })} | ||
| onChange={handleInputChange('cardNumber')} | ||
| /> | ||
| {errors.cardNumber && <p className="text-red-500 text-xs md:text-sm">{errors.cardNumber.message}</p>} | ||
| </div> | ||
|
|
||
| <div> | ||
| <DefaultTextField | ||
| label="카드 소지자 이름" | ||
| className={`h-12 ${errors.cardHolder ? 'border-2 border-red-500' : ''}`} | ||
| placeholder="홍길동" | ||
| {...register('cardHolder', { required: '카드 소지자 이름을 입력하세요. ' })} | ||
| /> | ||
| {errors.cardHolder && <p className="text-red-500 text-xs md:text-sm">{errors.cardHolder.message}</p>} | ||
| </div> | ||
|
|
||
| <div className="flex gap-3"> | ||
| <div> | ||
| <DefaultTextField | ||
| label="만료 월" | ||
| className={`h-12 ${errors.expiryMonth ? 'border-2 border-red-500' : ''}`} | ||
| placeholder="월" | ||
| {...register('expiryMonth', { required: '만료 월을 입력하세요.' })} | ||
| onChange={handleInputChange('expiryMonth')} | ||
| /> | ||
| {errors.expiryMonth && <p className="text-red-500 text-xs md:text-sm">{errors.expiryMonth.message}</p>} | ||
| </div> | ||
| <div> | ||
| <DefaultTextField | ||
| label="만료 년도" | ||
| className={`h-12 ${errors.expiryYear ? 'border-2 border-red-500' : ''}`} | ||
| placeholder="년도" | ||
| {...register('expiryYear', { required: '만료 년도를 입력하세요.' })} | ||
| onChange={handleInputChange('expiryYear')} | ||
| /> | ||
| {errors.expiryYear && <p className="text-red-500 text-xs md:text-sm">{errors.expiryYear.message}</p>} | ||
| </div> | ||
| <div> | ||
| <DefaultTextField | ||
| label="CVC/CVV" | ||
| className={`h-12 ${errors.cvc ? 'border-2 border-red-500' : ''}`} | ||
| placeholder="123" | ||
| {...register('cvc', { required: 'cvc를 입력하세요.' })} | ||
| onChange={handleInputChange('cvc')} | ||
| /> | ||
| {errors.cvc && <p className="text-red-500 text-xs md:text-sm">{errors.cvc.message}</p>} | ||
| </div> | ||
| </div> | ||
| <div className="flex-grow"></div> | ||
| <form onSubmit={handleSubmit(onSubmit)}> | ||
| <Button label="저장하기" onClick={() => console.log()} className="rounded-full w-full h-12" /> | ||
| </form> | ||
| </div> | ||
| </TicketHostLayout> | ||
| ); | ||
| }; | ||
|
|
||
| export default CardRegisterPage; | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| import Header from '../../../../design-system/ui/Header'; | ||
| import ticket from '../../../../public/assets/dashboard/create_ticket/Ticket(horizon).svg'; | ||
| import PaymentCard from '../../../widgets/payment/ui/PaymentCard'; | ||
| import Button from '../../../../design-system/ui/Button'; | ||
| import { useNavigate } from 'react-router-dom'; | ||
|
|
||
| const PaymentPage = () => { | ||
| const navigate = useNavigate(); | ||
|
|
||
| return ( | ||
| <div className="relative flex flex-col gap-2 min-h-screen"> | ||
HSCHEOL marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| {/*헤더 영역*/} | ||
| <div className="absolute top-0 w-full h-36 md:h-40 bg-gradient-to-br from-[#FF5593] to-[rgb(255,117,119)] rounded-b-[60px] z-10"> | ||
| <Header | ||
| centerContent="결제하기" | ||
| leftButtonLabel="<" | ||
| color="white" | ||
| leftButtonClassName="text-xl z-30" | ||
| leftButtonClick={() => navigate(-1)} | ||
| /> | ||
| </div> | ||
| {/*티켓 정보*/} | ||
| <div className="flex flex-col justify-between w-[90%] h-40 bg-white rounded-md mt-24 mx-auto z-10 shadow-md p-6"> | ||
| <div className="flex flex-col"> | ||
| <p className="font-bold text-sm md:text-base">티켓 정보</p> | ||
| <p className="text-gray-400 text-xs md:text-sm">티켓 수량을 선택하고 결제 수단을 선택하세요</p> | ||
| </div> | ||
| <div className="flex flex-row justify-between items-center"> | ||
| <div className="flex gap-2"> | ||
| <img src={ticket} alt="ticket logo" /> | ||
| <div> | ||
| <p className="font-bold text-sm md:text-base">콘서트 티켓</p> | ||
| <p className="text-gray-400 text-xs md:text-sm">50,000원 / 장</p> | ||
| </div> | ||
| </div> | ||
| <p className="font-bold text-sm md:text-base">2매</p> | ||
| </div> | ||
| </div> | ||
| {/*결제 카드 선택 */} | ||
| <div className="px-1"> | ||
| <PaymentCard title="결제 수단 선택" /> | ||
| </div> | ||
| <div className="w-full flex flex-col p-6 gap-5"> | ||
| <div className="w-full h-[2px] bg-gray-200"></div> | ||
| <div className="flex flex-col gap-5"> | ||
| <p className="font-semibold md:text-xl text-base">결제 금액</p> | ||
| <div className="flex flex-row w-full justify-between"> | ||
| <p className="md:text-base text-sm">총 결제 금액</p> | ||
| <p className="font-semibold md:text-base text-sm">100,000원</p> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| <div className="flex flex-grow"></div> | ||
| <div className="p-7"> | ||
| <Button label="결제하기" onClick={() => console.log('결제 진행')} className="rounded-full h-12 w-full" /> | ||
| </div> | ||
| </div> | ||
| ); | ||
| }; | ||
|
|
||
| export default PaymentPage; | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| import { useNavigate } from 'react-router-dom'; | ||
| import PlusButton from '../../../../public/assets/payment/PlusButton.svg'; | ||
| import VerticalCardButton from '../../../../design-system/ui/buttons/VerticalCardButton'; | ||
|
|
||
| const PaymentCard = ({ title }: { title: string }) => { | ||
| const navigate = useNavigate(); | ||
|
|
||
| const cardData = [ | ||
| { id: 1, name: 'Card 1', color: 'bg-blue-500' }, | ||
| { id: 2, name: 'Card 2', color: 'bg-red-500' }, | ||
| { id: 3, name: 'Card 3', color: 'bg-green-500' }, | ||
| { id: 4, name: 'Card 4', color: 'bg-yellow-500' }, | ||
| ]; | ||
|
|
||
| return ( | ||
| <div className="flex flex-col px-5 mt-12 md:mt-16 gap-6"> | ||
| <h1 className="text-base md:text-xl font-semibold">{title}</h1> | ||
| <div className="flex w-full h-32 md:h-40"> | ||
| <div className="flex w-full gap-4 overflow-x-scroll scrollbar-hide snap-x snap-mandatory items-center"> | ||
| {cardData.map((card, index) => ( | ||
| <div | ||
| key={card.id} | ||
| className={`flex items-center justify-center w-[60%] h-full text-white text-2xl snap-center shrink-0 rounded-xl ${ | ||
| card.color | ||
| } ${index === 0 ? 'ml-40' : ''}`} | ||
| > | ||
| {card.name} | ||
| </div> | ||
| ))} | ||
| {/* 카드 추가 버튼 */} | ||
| <div | ||
| className={`flex flex-col items-center justify-center w-[60%] h-full border-2 border-dashed border-gray-400 rounded-xl p-6 text-center bg-white snap-center shrink-0 mr-40 gap-5 ${ | ||
| cardData.length == 0 ? 'ml-40' : '' | ||
| }`} | ||
| > | ||
| <VerticalCardButton | ||
| iconPath={ | ||
| <div className="w-full h-full flex justify-center"> | ||
| <img src={PlusButton} alt="카드 등록 버튼" className="md:w-5 w-4" /> | ||
| </div> | ||
| } | ||
| label="카드 등록" | ||
| onClick={() => navigate(`/payment/cardRegister`)} | ||
| size="lg" | ||
| className="font-semibold w-full h-full" | ||
| /> | ||
|
|
||
| <p className="md:text-sm text-xs text-gray-500"> | ||
| 계좌를 한번만 등록해놓으면 <br /> | ||
| 매번 쉽게 결제할 수 있어요! | ||
| </p> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| ); | ||
| }; | ||
|
|
||
| export default PaymentCard; |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.