Skip to content

Commit

Permalink
[비즈니스] 회원가입, 비밀번호 찾기 공통 레이아웃 완성 (#341)
Browse files Browse the repository at this point in the history
* feat: auth 단계를 조절하는 훅 추가

* feat: 비밀번호 찾기, 회원가입 공통 레이아웃 추가

* feat: 회원가입, 비밀번호 찾기 완성 페이지 추가

* feat: 공통 레이아웃 적용

* refactor: outlet에 props로 steps 전달

* fix: 오타 수정
  • Loading branch information
chaeseungyun authored Jun 4, 2024
1 parent 6f62b89 commit 26b7cfe
Show file tree
Hide file tree
Showing 7 changed files with 400 additions and 3 deletions.
11 changes: 8 additions & 3 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import useUserTypeStore from 'store/useUserTypeStore';
import AddingEvent from 'page/ManageEvent/AddingEvent';
import ModifyEvent from 'page/ManageEvent/ModifyEvent';
import LogPage from 'component/common/PageLog';
import CommonLayout from 'page/Auth/components/Common';

interface ProtectedRouteProps {
userTypeRequired: UserType;
Expand Down Expand Up @@ -74,9 +75,13 @@ function App() {
<Route element={<AuthLayout />}>
<Route element={<ProtectedRoute userTypeRequired={null} />}>
<Route path="/login" element={<Login />} />
<Route path="/signup" element={<Signup />} />
<Route path="/find-id" element={<PageNotFound />} />
<Route path="/find-password" element={<FindPassword />} />
<Route element={<CommonLayout />}>
<Route path="/signup" element={<Signup />} />
<Route path="/find-id" element={<PageNotFound />} />
<Route path="/find-password" element={<FindPassword />} />
</Route>
<Route path="/find" element={<CommonLayout />} />
<Route path="/register" element={<CommonLayout />} />
</Route>
<Route path="/new-password" element={<NewPassword />} />
<Route path="/complete-change-password" element={<CompleteChangePassword />} />
Expand Down
101 changes: 101 additions & 0 deletions src/assets/svg/auth/done.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
88 changes: 88 additions & 0 deletions src/page/Auth/components/Common/index.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
@use "src/utils/styles/mediaQuery" as media;

.container {
display: flex;
align-items: center;
flex-direction: column;
}

.top {
display: flex;
position: relative;
justify-content: center;
align-items: center;
width: 50%;
margin-top: 20px;

@include media.media-breakpoint-down(mobile) {
width: 90%;
}

&__back {
position: absolute;
left: 0px;
cursor: pointer;

@include media.media-breakpoint-up(mobile) {
display: none;
}
}
}

.step {
display: flex;
flex-direction: column;
width: 50%;
margin-top: 20px;

@include media.media-breakpoint-down(mobile) {
width: 90%;
}

&__progress {
display: flex;
justify-content: space-between;
color: #175C8E;
font-weight: 600;
margin: 10px 0;
}
}

.step-container {
position: relative;
}

.progress-bar {
border: none;
height: 4px;
background-color: #eeeeee;
}

.title {
font-weight: 600;
font-size: 20px;
}

.content {
height: calc(100vh - 40vh);

@include media.media-breakpoint-down(mobile) {
height: calc(100vh - 28vh);
}
}

.button {
width: 100%;
background-color: #e1e1e1;
height: 50px;
border-radius: 4px;
font-weight: 600;

&__active {
width: 100%;
background-color: #175C8E;
height: 50px;
border-radius: 4px;
font-weight: 600;
}
}
111 changes: 111 additions & 0 deletions src/page/Auth/components/Common/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import { ReactComponent as BackArrow } from 'assets/svg/common/back-arrow.svg';
import { FormProvider, useForm } from 'react-hook-form';
import { Outlet, useLocation, useNavigate } from 'react-router-dom';
import cn from 'utils/ts/className';
// eslint-disable-next-line
import { useStep } from '../../hook/useStep';
// eslint-disable-next-line
import Done from '../Done/index';
import styles from './index.module.scss';

interface FindPassword {
phone_number: string;
certification_code: string;
password: string;
}

interface Register extends FindPassword {
company_number: string,
name: string,
shop_id: number,
shop_name: string,
attachment_urls: {
file_url: string
}[]
}

export default function CommonLayout() {
const location = useLocation();
const navigate = useNavigate();

const isFindPassword = location.pathname.includes('find');
const title = isFindPassword ? '비밀번호 찾기' : '회원가입';

const method = useForm<Register>({
mode: 'onChange',
});
const { formState: { errors } } = method;

const steps = useStep(isFindPassword ? 'find' : 'register');
const {
nextStep, previousStep, currentStep, index, totalStep, isComplete,
} = steps;

// eslint-disable-next-line
const progressPercentage = (index + 1) / totalStep * 100;

// form에 error가 없으면 다음 단계로 넘어감
const stepCheck = () => {
if (isComplete) navigate('/login');
if (!errors.root) {
nextStep();
}
};

return (
<div className={styles.container}>
<FormProvider {...method}>
<div className={styles.top}>
<BackArrow className={styles.top__back} onClick={previousStep} />
<div className={styles.title}>{title}</div>
</div>
<div className={styles.step}>
<div className={styles.step__progress}>
<div>
<span>
{index + 1}
.
{' '}
</span>
{currentStep}
</div>
<div>
{`${index + 1}/${totalStep}`}
</div>
</div>
<div className={styles['step-container']}>
<hr className={styles['progress-bar']} />
<hr style={{
width: `${progressPercentage}%`,
backgroundColor: '#175C8E',
position: 'absolute',
top: '0',
left: '0',
height: '3px',
border: 'none',
}}
/>
</div>
<div className={styles.content}>
{isComplete ? <Done isFindPassword={isFindPassword} /> : <Outlet context={steps} />}
</div>
<button
type="button"
onClick={stepCheck}
disabled={!!errors.root}
className={
cn({
[styles.button__active]: !!errors.root,
[styles.button]: true,
})
}
>
{!isComplete
? <div>{!isComplete && (index + 1 === totalStep) ? '완료' : '다음'}</div>
: '로그인 화면 바로 가기'}
</button>
</div>
</FormProvider>
</div>
);
}
21 changes: 21 additions & 0 deletions src/page/Auth/components/Done/index.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
@use "src/utils/styles/mediaQuery" as media;

.container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
gap: 3vh;
}

.title {
color: #175C8E;
font-weight: bold;
}

.content {
color: #8e8e8e;
text-align: center;
}
37 changes: 37 additions & 0 deletions src/page/Auth/components/Done/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { ReactComponent as Success } from 'assets/svg/auth/done.svg';
import styles from './index.module.scss';

const completeFindPassword = {
title: '비밀번호 변경 완료',
content: '비밀번호 변경이 완료되었습니다!',
final: '새로운 비밀번호로 로그인해주세요:)',
};

const completeRegister = {
title: '회원가입 완료',
content: '회원가입이 완료되었습니다!',
final: '가입 승인 시 로그인이 가능합니다.',
};

interface Props {
isFindPassword: boolean;
}
export default function Done({ isFindPassword }: Props) {
const completeObject = isFindPassword ? completeFindPassword : completeRegister;
return (
<div className={styles.container}>
<Success />
<div className={styles.title}>
{completeObject.title}
</div>
<div className={styles.content}>
<div>
{completeObject.content}
</div>
<div>
{completeObject.final}
</div>
</div>
</div>
);
}
34 changes: 34 additions & 0 deletions src/page/Auth/hook/useStep.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { useState } from 'react';
import { useNavigate } from 'react-router-dom';

type Type = 'find' | 'register';

const findPassword = [
'계정 인증', '비밀번호 변경',
];

const register = ['약관 동의', '기본 정보 입력', '사업자 인증'];

export const useStep = (type: Type) => {
const target = type === 'find' ? findPassword : register;
const [index, setIndex] = useState(0);
const [isComplete, setIsComplete] = useState<boolean>(false);
const navigate = useNavigate();

const nextStep = () => {
if (index + 1 < target.length) setIndex((prev) => prev + 1);
};

const previousStep = () => {
if (index > 0) setIndex((prev) => prev - 1);
else navigate(-1);
};

const currentStep = target[index];

const totalStep = target.length;

return {
nextStep, previousStep, currentStep, index, totalStep, isComplete, setIsComplete,
};
};

0 comments on commit 26b7cfe

Please sign in to comment.