-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* [TINU-77] install: use-funnel 라이브러리 설치 * chore: svg 폴더 생성 및 이미지파일 추가 * chore: 상수 폴더 생성 * feat: 회원가입 Step1 페이지 퍼블리싱 1차 작업 * style: 버튼 컴포넌트 cursor-pointer 추가 * style: 글로벌스타일 수정 및 이미지파일 export * fix: Step1 퍼블리싱 수정 * chore: <br/> 태그 추가 * 버튼 컴포넌트 cursor-pointer 삭제 * style: svg 파일 대체 * refactor: Step1 컴포넌트 리팩토링 및 체크박스 추가 * fix: 불필요한 코드 제거 * feat: 체크박스 컴포넌트 1차 작업 * chore: svg 아이콘 추가 * feat: step 4단계에 따른 아이콘 분리 * chore: export 수정 및 svg파일 추가 * fix: 체크박스 코드 수정 및 파일위치 변경 * feat: Step1 컴포넌트 구현 및 리팩토링 * chore: 체크박스 컴포넌트 위치 변경 * fix: 불필요한 패키지 삭제 * fix: 리뷰반영-StepIcon 로직 수정 * fix: 리뷰 반영- 이용약관 데이터 상수로 관리 * chore: 체크박스 아이콘명 변경 * chore: 리뷰 반영- 불필요한 주석 제거 * chore: IcCheckComplete 아이콘명 변경 * fix: yarn.lock 변경사항 반영 * fix: 리뷰 반영-네이밍 Screaming Snake Case로 통일 * fix: 리뷰 반영 1차 작업 * fix: 체크박스 리뷰 반영 1차 작업
- Loading branch information
1 parent
cad18ec
commit 26da7b1
Showing
21 changed files
with
338 additions
and
6 deletions.
There are no files selected for viewing
This file contains 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 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 |
---|---|---|
@@ -1,9 +1,14 @@ | ||
import { createBrowserRouter } from "react-router-dom"; | ||
import Home from "./pages/Home"; | ||
import Step1 from "./components/Register/Step1"; | ||
|
||
export const router = createBrowserRouter([ | ||
{ | ||
path: "/", | ||
element: <Home />, | ||
}, | ||
{ | ||
path: "/register", | ||
element: <Step1 />, | ||
}, | ||
]); |
This file contains 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 |
---|---|---|
@@ -1,5 +1,32 @@ | ||
/// <reference types="vite-plugin-svgr/client" /> | ||
|
||
import IcRabbit from "./icons/ic_rabbit.svg?react"; | ||
import IcCheckGrey from "./svg/check/ic_check-grey.svg?react"; | ||
import IcCheckMint from "./svg/check/ic_check-mint.svg?react"; | ||
import IcCheckComplete from "./svg/check/ic_check-complete.svg?react"; | ||
import IcCheckWhiteGrey from "./svg/check/ic_check-whitegrey.svg?react"; | ||
import IcCheckTransparent from "./svg/check/ic_check-transparent.svg?react"; | ||
|
||
export { IcRabbit }; | ||
import IcStep1 from "./svg/register/ic_step1.svg?react"; | ||
import IcStep2 from "./svg/register/ic_step2.svg?react"; | ||
import IcStep3 from "./svg/register/ic_step3.svg?react"; | ||
import IcStep4 from "./svg/register/ic_step4.svg?react"; | ||
import IcGreyCircle from "./svg/register/ic_grey-circle.svg?react"; | ||
import IcBack from "./svg/ic_back.svg?react"; | ||
import IcNext from "./svg/ic_next.svg?react"; | ||
|
||
export { | ||
IcRabbit, | ||
IcCheckGrey, | ||
IcCheckMint, | ||
IcCheckComplete, | ||
IcCheckWhiteGrey, | ||
IcCheckTransparent, | ||
IcStep1, | ||
IcStep2, | ||
IcStep3, | ||
IcStep4, | ||
IcBack, | ||
IcNext, | ||
IcGreyCircle, | ||
}; |
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.
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.
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.
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.
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.
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 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,38 @@ | ||
import styled from "@emotion/styled"; | ||
import { InputHTMLAttributes } from "react"; | ||
import { IcCheckComplete, IcCheckWhiteGrey } from "../../assets"; | ||
|
||
interface CheckBoxProps extends InputHTMLAttributes<HTMLInputElement> { | ||
onClick?: () => void; | ||
} | ||
|
||
function CheckBox({ onClick, checked }: CheckBoxProps): JSX.Element { | ||
return ( | ||
<CheckBoxWrapper isChecked={checked} onClick={onClick}> | ||
<CheckBoxContent> | ||
{checked ? <IcCheckComplete /> : <IcCheckWhiteGrey />} | ||
<CheckBoxText>네, 동의합니다.</CheckBoxText> | ||
</CheckBoxContent> | ||
</CheckBoxWrapper> | ||
); | ||
} | ||
|
||
const CheckBoxWrapper = styled.div<{ disabled?: boolean; isChecked?: boolean }>` | ||
padding: 1.5rem; | ||
background-color: ${({ theme }) => theme.colors.light_6}; | ||
border-radius: 1.2rem; | ||
`; | ||
|
||
const CheckBoxContent = styled.div` | ||
display: flex; | ||
align-items: center; | ||
gap: 1rem; | ||
`; | ||
|
||
const CheckBoxText = styled.span` | ||
${({ theme }) => theme.fonts.subtitle2}; | ||
color: ${({ theme }) => theme.colors.black_2}; | ||
`; | ||
|
||
export default CheckBox; |
This file contains 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,129 @@ | ||
import styled from "@emotion/styled"; | ||
import { IcBack, IcCheckGrey, IcCheckWhiteGrey, IcNext, IcCheckComplete, IcCheckMint } from "../../assets"; | ||
import Button from "../Common/Button/Button"; | ||
import { AGREE_DATA, REGISTER_TEXT } from "../../constant"; | ||
import { useState } from "react"; | ||
import CheckBox from "./CheckBox"; | ||
import StepIcon from "../../utils/StepIcon"; | ||
import { useNavigate } from "react-router-dom"; | ||
|
||
interface AgreeTextProps { | ||
isRequired: boolean; | ||
} | ||
|
||
function Step1() { | ||
const navigate = useNavigate(); | ||
const [checkedItems, setCheckedItems] = useState<string[]>([]); | ||
|
||
const handleClickNextButton = () => { | ||
navigate("/register/step2"); | ||
}; | ||
|
||
// 전체 선택 | ||
const handleAllChecked = (checked: boolean) => { | ||
setCheckedItems(checked ? AGREE_DATA.map((item) => item.key) : []); | ||
}; | ||
|
||
// 개별 선택 | ||
const handleSingleChecked = (checked: boolean, key: string) => { | ||
setCheckedItems((prev) => (checked ? [...prev, key] : prev.filter((item) => item !== key))); | ||
}; | ||
|
||
return ( | ||
<Step1Container> | ||
<Step1Wrapper> | ||
<IcBack /> | ||
<StepIcon step={1} /> | ||
<TitleWrapper dangerouslySetInnerHTML={{ __html: REGISTER_TEXT.STEP1 }} /> | ||
|
||
<AgreeContainer> | ||
<CheckBox | ||
onClick={() => handleAllChecked(checkedItems.length !== AGREE_DATA.length)} | ||
checked={checkedItems.length === AGREE_DATA.length} | ||
> | ||
{checkedItems.length === AGREE_DATA.length ? <IcCheckComplete /> : <IcCheckWhiteGrey />} | ||
</CheckBox> | ||
|
||
<OptionalAgreeContainer> | ||
{AGREE_DATA.map((data) => ( | ||
<OptionalAgreeWrapper | ||
key={data.text} | ||
onClick={() => handleSingleChecked(!checkedItems.includes(data.key), data.key)} | ||
> | ||
<AgreeWrapper> | ||
{checkedItems.includes(data.key) ? <IcCheckMint /> : <IcCheckGrey />} | ||
<AgreeText isRequired={data.key === "required"}>{data.text}</AgreeText> | ||
</AgreeWrapper> | ||
<IcNext /> | ||
</OptionalAgreeWrapper> | ||
))} | ||
</OptionalAgreeContainer> | ||
</AgreeContainer> | ||
|
||
<NextButton | ||
disabled={AGREE_DATA.some(({ key }) => key.includes("required") && !checkedItems.includes(key))} | ||
onClick={handleClickNextButton} | ||
> | ||
<span>다음</span> | ||
</NextButton> | ||
</Step1Wrapper> | ||
</Step1Container> | ||
); | ||
} | ||
|
||
export default Step1; | ||
|
||
const Step1Container = styled.div` | ||
height: 100dvh; | ||
padding: 2rem; | ||
position: relative; | ||
`; | ||
|
||
const Step1Wrapper = styled.div` | ||
display: flex; | ||
flex-direction: column; | ||
gap: 3rem; | ||
`; | ||
|
||
const TitleWrapper = styled.div` | ||
margin-left: 1rem; | ||
${({ theme }) => theme.fonts.title1}; | ||
`; | ||
|
||
const AgreeContainer = styled.div` | ||
display: flex; | ||
flex-direction: column; | ||
gap: 2rem; | ||
`; | ||
|
||
const NextButton = styled(Button)<{ disabled?: boolean }>` | ||
width: calc(100% - 4rem); | ||
position: absolute; | ||
bottom: 3rem; | ||
`; | ||
|
||
const OptionalAgreeContainer = styled.div` | ||
display: flex; | ||
flex-direction: column; | ||
gap: 1.8rem; | ||
padding: 0 2rem; | ||
`; | ||
|
||
const OptionalAgreeWrapper = styled.div` | ||
display: flex; | ||
align-items: center; | ||
justify-content: space-between; | ||
`; | ||
|
||
const AgreeWrapper = styled.div` | ||
display: flex; | ||
align-items: center; | ||
gap: 1.5rem; | ||
`; | ||
|
||
const AgreeText = styled.div<AgreeTextProps>` | ||
${({ theme }) => theme.fonts.body2}; | ||
color: ${({ theme, isRequired }) => (isRequired ? theme.colors.main_mint : theme.colors.gray_3)}; | ||
`; |
This file contains 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,15 @@ | ||
export const REGISTER_TEXT = { | ||
STEP1: "간편 회원가입을 위해<br /> 약관 동의가 필요해요", | ||
STEP2: " 학교 계정 인증을 위한<br /> 이메일을 입력하세요", | ||
DESCRIPTION_STEP2: " 최초 1회 이메일 인증이 필요해요.", | ||
STEP3: "나만의 프로필을<br /> 설정하세요", | ||
DESCRIPTION_STEP3: "마이페이지에서 언제든 수정 가능해요.", | ||
STEP4: "추가적인 정보를<br /> 입력하세요", | ||
DESCRIPTION_STEP4: "추가정보를 입력하고 신뢰도를 높여보세요!", | ||
} as const; | ||
|
||
export const AGREE_DATA = [ | ||
{ text: "[필수] TinU 서비스 이용약관", key: "required1" }, | ||
{ text: "[필수] 개인정보 수집 및 이용 동의", key: "required2" }, | ||
{ text: "[선택] 광고성 정보 수신 동의", key: "optional" }, | ||
]; |
This file contains 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 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,56 @@ | ||
import styled from "@emotion/styled"; | ||
import { memo } from "react"; | ||
import { IcStep1, IcStep2, IcStep3, IcStep4, IcCheckTransparent, IcGreyCircle } from "../assets"; | ||
|
||
interface StepIconProps { | ||
step: 1 | 2 | 3 | 4; | ||
} | ||
|
||
const STEP_CONFIG = { | ||
1: { text: "약관동의", Icon: IcStep1 }, | ||
2: { text: "메일인증", Icon: IcStep2 }, | ||
3: { text: "정보입력", Icon: IcStep3 }, | ||
4: { text: "상세정보", Icon: IcStep4 }, | ||
} as const; | ||
|
||
function StepIcon({ step }: StepIconProps) { | ||
const renderIcons = () => { | ||
return Array(4) | ||
.fill(null) | ||
.map((_, index) => { | ||
const currentStep = index + 1; | ||
|
||
if (currentStep === step) { | ||
const StepComponent = STEP_CONFIG[step].Icon; | ||
return ( | ||
<StepIconWrapper key={index}> | ||
<StepComponent /> | ||
<StepText>{STEP_CONFIG[step].text}</StepText> | ||
</StepIconWrapper> | ||
); | ||
} | ||
|
||
return currentStep < step ? <IcCheckTransparent key={index} /> : <IcGreyCircle key={index} />; | ||
}); | ||
}; | ||
return <StepIconContainer>{renderIcons()}</StepIconContainer>; | ||
} | ||
|
||
const StepIconContainer = styled.div` | ||
display: flex; | ||
gap: 0.5rem; | ||
`; | ||
|
||
const StepIconWrapper = styled.div` | ||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
`; | ||
|
||
const StepText = styled.span` | ||
margin-top: 0.3rem; | ||
${({ theme }) => theme.fonts.description3}; | ||
color: ${({ theme }) => theme.colors.gray_3}; | ||
`; | ||
|
||
export default memo(StepIcon); |
Oops, something went wrong.