Skip to content

Commit

Permalink
feat: 카드사 선택 자유도 높이도록 UX 수정
Browse files Browse the repository at this point in the history
  • Loading branch information
jeonjeunghoon committed May 2, 2023
1 parent 6100006 commit 4fdb79a
Show file tree
Hide file tree
Showing 13 changed files with 146 additions and 70 deletions.
1 change: 0 additions & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
{
"printWidth": 100,
"singleQuote": true,
"semi": true,
"trailingComma": "es5",
Expand Down
4 changes: 2 additions & 2 deletions docs/REQUIREMENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
- [ ] 컴포넌트 분리의 기준 세우기
- [ ] viewport 메타태그 학습, safe area 학습
- [ ] inputmode라는 속성에 대해 알아보셔도 좋을 것 같아요! 가상키보드가 어떻게 떠야하는지 지정
- [ ] 자유도를 좀 더 생각해서 스킵이 가능하게 하되 제출만 막는 경험 구현하기
- [x] 자유도를 좀 더 생각해서 스킵이 가능하게 하되 제출만 막는 경험 구현하기
- [x] src/GlobalStyles.ts
100vw 에서 100%로 변경한 이유는 어떤 것인가요?
- [ ] src/components/BottomSheet/BottomSheet.tsx
- [x] src/components/BottomSheet/BottomSheet.tsx
CardCompanyContents를 바텀싯이 알아야할것같진 않아서 children정도여도 좋을 것 같아요~
- [ ] src/components/Card/Card.styled.ts
테마여서 프리셋으로 지정된 문자열으로 예상했는데 컬러값이네요! backgroundColor로 명확하게 변경해줘도 좋을 것 같아요
Expand Down
14 changes: 0 additions & 14 deletions src/components/BottomSheet/BottomSheet.tsx

This file was deleted.

29 changes: 28 additions & 1 deletion src/components/Card/Card.styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export const Card = styled.div`
width: 220px;
height: 140px;
padding: 12px 16px;
padding: ${props => (props.theme === COLOR.DEFAULT ? '' : '12px 16px')};
background-color: ${props => props.theme ?? COLOR.DEFAULT};
box-shadow: 3px 3px 5px rgba(0, 0, 0, 0.25);
Expand All @@ -16,13 +16,40 @@ export const Card = styled.div`
font-size: 12px;
letter-spacing: 0.1em;
cursor: pointer;
`;

export const EmptyCardCover = styled.div<Record<'cardCompany', string>>`
display: ${props => (props.cardCompany ? 'none' : 'flex')};
justify-content: center;
align-items: center;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: 5px;
background-color: ${COLOR.GREY200};
opacity: 0.6;
& > p {
font-size: x-large;
font-weight: 700;
}
`;

export const CardName = styled.p`
position: absolute;
`;

export const Rectangle = styled.div`
display: ${props => (props.theme === COLOR.DEFAULT ? 'none' : 'block')};
width: 40px;
height: 26px;
Expand Down
22 changes: 18 additions & 4 deletions src/components/Card/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,28 @@ export interface CardProps {
const Card = ({ cardInfo, theme }: CardProps) => {
return (
<styled.Card theme={theme}>
<styled.EmptyCardCover cardCompany={cardInfo.cardCompany.name}>
<p>카드사 등록하기</p>
</styled.EmptyCardCover>
<styled.CardName>{cardInfo.cardCompany.name}</styled.CardName>
<styled.Rectangle />
<styled.Rectangle theme={theme} />
<styled.CardInformationContainer>
<styled.CardNumber theme={theme}>
<input disabled defaultValue={cardInfo.cardNumbers.firstCardNumber} />
<input disabled defaultValue={cardInfo.cardNumbers.secondCardNumber} />
<input disabled type="password" defaultValue={cardInfo.cardNumbers.thirdCardNumber} />
<input disabled type="password" defaultValue={cardInfo.cardNumbers.fourthCardNumber} />
<input
disabled
defaultValue={cardInfo.cardNumbers.secondCardNumber}
/>
<input
disabled
type="password"
defaultValue={cardInfo.cardNumbers.thirdCardNumber}
/>
<input
disabled
type="password"
defaultValue={cardInfo.cardNumbers.fourthCardNumber}
/>
</styled.CardNumber>
<styled.CardNameAndExpirationDateContainer>
<styled.OwnerName>{cardInfo.ownerName ?? 'NAME'}</styled.OwnerName>
Expand Down
7 changes: 6 additions & 1 deletion src/components/CardCompanyButton/CardCompanyButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@ interface CardCompanyButtonProps {
setCardCompany: setCardCompany;
}

const CardCompanyButton = ({ Logo, name, theme, setCardCompany }: CardCompanyButtonProps) => {
const CardCompanyButton = ({
Logo,
name,
theme,
setCardCompany,
}: CardCompanyButtonProps) => {
const handleClick = () => {
setCardCompany({
name: name,
Expand Down
31 changes: 15 additions & 16 deletions src/components/CardCompanyContents/CardCompanyContents.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { useContext } from 'react';

import CardInfoContext from '../../contexts/CardInfoContext';

import { CARD_COMPANY_INFO } from '../../constants/cardCompany';

import * as styled from './CardCompanyContents.styled';
Expand All @@ -10,21 +9,21 @@ import CardCompanyButton from '../CardCompanyButton/CardCompanyButton';
const CardCompanyContents = () => {
const { setCardCompany } = useContext(CardInfoContext);

const generateCardCompanyList = () => {
return CARD_COMPANY_INFO.map(companyInfo => {
return (
<CardCompanyButton
key={companyInfo.NAME}
Logo={<companyInfo.LOGO />}
name={companyInfo.NAME}
theme={companyInfo.THEME}
setCardCompany={setCardCompany}
/>
);
});
};

return <styled.CardCompanyContents>{generateCardCompanyList()}</styled.CardCompanyContents>;
return (
<styled.CardCompanyContents>
{CARD_COMPANY_INFO.map(companyInfo => {
return (
<CardCompanyButton
key={companyInfo.NAME}
Logo={<companyInfo.LOGO />}
name={companyInfo.NAME}
theme={companyInfo.THEME}
setCardCompany={setCardCompany}
/>
);
})}
</styled.CardCompanyContents>
);
};

export default CardCompanyContents;
15 changes: 11 additions & 4 deletions src/components/CardPreview/CardPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,19 @@ import CardInfoContext from '../../contexts/CardInfoContext';
import * as styled from './CardPreview.styled';
import Card from '../Card/Card';

const CardPreview = () => {
const { cardNumbers, expirationDate, ownerName, securityCode, password, cardCompany, cardAlias } =
useContext(CardInfoContext);
const CardPreview = ({ handleOpenModal }: { handleOpenModal?: () => void }) => {
const {
cardNumbers,
expirationDate,
ownerName,
securityCode,
password,
cardCompany,
cardAlias,
} = useContext(CardInfoContext);

return (
<styled.CardPreview>
<styled.CardPreview onClick={handleOpenModal}>
<Card
cardInfo={{
cardNumbers,
Expand Down
22 changes: 15 additions & 7 deletions src/components/Pages/CardRegisterPage/CardRegisterPage.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,31 @@
import { useContext } from 'react';
import { createPortal } from 'react-dom';
import { useContext, useEffect } from 'react';

import { useModal } from '../../../hooks/useModal';

import * as styled from './CardRegisterPage.styled';
import CardPreview from '../../CardPreview/CardPreview';
import CardRegisterForm from '../../CardRegisterForm/CardRegisterForm';
import BottomSheet from '../../BottomSheet/BottomSheet';
import PortalBottomSheet from '../../PortalBottomSheet/PortalBottomSheet';
import CardCompanyContents from '../../CardCompanyContents/CardCompanyContents';
import CardInfoContext from '../../../contexts/CardInfoContext';

const CardRegisterPage = () => {
const { cardCompany } = useContext(CardInfoContext);
const isOpenBottomSheet = !cardCompany.name;
const { isOpenModal, handleCloseModal, handleOpenModal } = useModal();

useEffect(() => {
if (cardCompany.name) handleCloseModal();
}, [cardCompany.name]);

return (
<styled.CardRegisterPage>
<CardPreview />
<CardPreview handleOpenModal={handleOpenModal} />
<CardRegisterForm />
{isOpenBottomSheet &&
createPortal(<BottomSheet CardCompanyContents={<CardCompanyContents />} />, document.body)}
{isOpenModal && (
<PortalBottomSheet handleCloseModal={handleCloseModal}>
<CardCompanyContents />
</PortalBottomSheet>
)}
</styled.CardRegisterPage>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import styled from 'styled-components';
import { COLOR } from '../../constants/cardInfo';

export const BottomSheet = styled.div`
export const PortalBottomSheet = styled.div`
position: fixed;
top: 0;
left: 0;
Expand All @@ -21,28 +21,14 @@ export const BottomSheet = styled.div`
`;

export const Backdrop = styled.div`
position: fixed;
top: 0;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 100%;
height: 100%;
width: 100vw;
height: 100vh;
background-color: ${COLOR.BLACK};
opacity: 0.6;
@media (min-width: 992px) {
width: 50%;
}
@media (min-width: 1200px) {
width: 30%;
}
`;

export const BottomSheetContainer = styled.div`
export const Contents = styled.div`
display: flex;
justify-content: center;
align-items: center;
Expand Down
26 changes: 26 additions & 0 deletions src/components/PortalBottomSheet/PortalBottomSheet.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { ReactNode } from 'react';
import { createPortal } from 'react-dom';

import * as styled from './PortalBottomSheet.styled';

const PortalBottomSheet = ({
handleCloseModal,
children,
}: {
handleCloseModal: () => void;
children: ReactNode;
}) => {
return (
<>
{createPortal(
<styled.PortalBottomSheet>
<styled.Backdrop onClick={handleCloseModal} />
<styled.Contents>{children}</styled.Contents>;
</styled.PortalBottomSheet>,
document.body
)}
</>
);
};

export default PortalBottomSheet;
8 changes: 6 additions & 2 deletions src/hooks/useIsFilledForm.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { useContext } from 'react';

import CardInfoContext from '../contexts/CardInfoContext';
import { COLOR } from '../constants/cardInfo';

export const useIsFilledForm = () => {
const { cardNumbers, expirationDate, securityCode, password } = useContext(CardInfoContext);
const { cardNumbers, expirationDate, securityCode, password, cardCompany } =
useContext(CardInfoContext);

return (
cardNumbers.firstCardNumber.length === 4 &&
Expand All @@ -16,6 +18,8 @@ export const useIsFilledForm = () => {
expirationDate.year.length === 2 &&
securityCode.length === 3 &&
password.firstPassword.length === 1 &&
password.secondPassword.length === 1
password.secondPassword.length === 1 &&
cardCompany.name !== '' &&
cardCompany.theme !== COLOR.DEFAULT
);
};
15 changes: 15 additions & 0 deletions src/hooks/useModal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { useState } from 'react';

export const useModal = (modalInitState = true) => {
const [isOpenModal, setIsOpenModal] = useState(modalInitState);

const handleCloseModal = () => {
setIsOpenModal(false);
};

const handleOpenModal = () => {
setIsOpenModal(true);
};

return { isOpenModal, handleCloseModal, handleOpenModal };
};

0 comments on commit 4fdb79a

Please sign in to comment.