Skip to content

Commit

Permalink
Merge pull request #21 from ApptiveDev/develop/register-page-contents
Browse files Browse the repository at this point in the history
Feat: Develop/register page contents
  • Loading branch information
cla6shade authored Dec 13, 2023
2 parents 67b564d + 1c37a71 commit 59f31d1
Show file tree
Hide file tree
Showing 21 changed files with 736 additions and 49 deletions.
9 changes: 9 additions & 0 deletions src/assets/icons/customer.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions src/assets/icons/stylist.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 9 additions & 5 deletions src/components/button/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,19 @@ import {ButtonHTMLAttributes} from 'react';

interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
label: string;
disabled?: boolean;
}

const Button = ({label, ...rest}: ButtonProps) => {
const Button = ({label, disabled, ...rest}: ButtonProps) => {
let btnClass =
`h-[52px] px-5 rounded-md
transition duration-300 ease-in-out hover:bg-primary-transition
text-[18px] focus:outline-none
focus:ring-grey-200 font-apple `;
btnClass += disabled? 'bg-light_grey text-grey' : 'bg-primary text-white';
return (
<button
className='bg-primary text-white h-[52px] px-5 rounded-md
transition duration-300 ease-in-out hover:bg-primary-transition
text-[18px] focus:outline-none focus:ring
focus:ring-blue-200 font-apple'{...rest}>
className={btnClass} {...rest}>
{label}
</button>
);
Expand Down
45 changes: 45 additions & 0 deletions src/components/button/RegisterStepButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import {useSelector} from 'react-redux';
import {RootState} from '@/modules';
import Button from '@components/button/Button.tsx';
import {getRequiredInfo} from '@modules/registerReducer.ts';
import {useEffect, useState} from 'react';
import {useNavigate} from 'react-router-dom';
import Constants from '@/constants';

type RegisterStepButtonProps = {
currentProgress: number;
};

const RegisterStepButton = ({currentProgress}: RegisterStepButtonProps) => {
const navigate = useNavigate();
const registerState =
useSelector((state: RootState) => state.register);
const [disabled, setDisabled] = useState(true);

const constant = Constants.register;
useEffect(() => {
if (Object.keys(registerState).length === 0) {
return;
}
const requiredInfo = getRequiredInfo(currentProgress);

let disabledChange = false;
for (const key of requiredInfo) {
if (typeof registerState[key] === 'undefined' || registerState[key] ===
null) {
disabledChange = true;
}
}
if (currentProgress === constant.page_nums.PAGE_USER_AGREEMENT &&
!registerState.tos_agreed) {
disabledChange = true;
}
setDisabled(disabledChange);
}, [currentProgress, registerState]);
return <Button label={'다음'} disabled={disabled} onClick={() => {
if (!disabled) {
navigate(constant.getNextUrlHash(currentProgress));
}
}} />;
};
export default RegisterStepButton;
2 changes: 1 addition & 1 deletion src/components/container/ScrollableContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {ContainerProps} from '@components/container/Container.ts';

const ScrollableContainer = (props: ContainerProps) => {
return <div className={`flex flex-col items-center
max-h-[calc(100%-145px)] w-[100%] overflow-y-auto`}>
max-h-[calc(100%-145px)] h-full w-[100%] overflow-y-auto`}>
{props.children}
</div>;
};
Expand Down
43 changes: 16 additions & 27 deletions src/components/input/Checkbox.tsx
Original file line number Diff line number Diff line change
@@ -1,36 +1,25 @@
import React from 'react';

import checkIcon from '@assets/icons/check.svg';

interface CheckboxProps {
checked: boolean;
label?: string;
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
setChecked: (checked: boolean) => void;
}

const Checkbox = ({checked, onChange, label}: CheckboxProps) => {
const Checkbox = ({checked, setChecked}: CheckboxProps) => {
return (
<>
<label className='flex'>

<input type='checkbox'
className='appearance-none w-[24px] h-[24px]
border rounded-full border-gray-400
checked:bg-blue-600 checked:border-transparent
focus:outline-none'
style={{
backgroundImage: 'url("' + checkIcon + '")',
backgroundSize: '70%',
backgroundRepeat: 'no-repeat',
backgroundPosition: '50% 55%',
}}
checked={checked}
onChange={onChange}
/>

<p className='text-primary font-bold font-apple ml-[4px]'>
{label && label}</p>
</label>
<div
className={checked ?
'flex justify-center items-center rounded-full w-[24px] h-[24px] bg-primary' :
'flex justify-center items-center rounded-full w-[24px] h-[24px] bg-middle_grey'}
onClick={() => {
setChecked(! checked);
}}>
<svg width='13' height='10' viewBox='0 0 14 10' fill='none'
xmlns='http://www.w3.org/2000/svg'>
<path d='M12.3327 1L4.99935 8.33333L1.66602 5'
stroke={checked ? 'white' : 'black'}
strokeWidth='2' strokeLinecap='round' strokeLinejoin='round' />
</svg>
</div>
</>
);
};
Expand Down
4 changes: 2 additions & 2 deletions src/components/input/Input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
}

const Input = ({label, errorMessage, ...rest}: InputProps) => {
return <div className='mb-[8px]'>
return <div className='mb-[8px] w-full'>
{label && <label>{label}</label>}

<input className='w-full h-10 px-3 py-2 border border-middle_grey
rounded-md leading-tight focus:outline-none
focus:border-blue-500 focus:ring text-[16px]' {...rest} />

{errorMessage &&
<span className='text-red-500 text-[16px] mt-[8px] ml-[4px]'>
<span className='text-red-500 text-[14px] mt-[8px] ml-[4px]'>
{errorMessage}
</span>}
</div>;
Expand Down
38 changes: 38 additions & 0 deletions src/components/input/LoginCheckbox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React from 'react';

import checkIcon from '@assets/icons/check.svg';

interface CheckboxProps {
checked: boolean;
label?: string;
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
}

const LoginCheckbox = ({checked, onChange, label}: CheckboxProps) => {
return (
<>
<label className='flex'>

<input type='checkbox'
className='appearance-none w-[24px] h-[24px]
border rounded-full border-gray-400
checked:bg-blue-600 checked:border-transparent
focus:outline-none'
style={{
backgroundImage: 'url("' + checkIcon + '")',
backgroundSize: '70%',
backgroundRepeat: 'no-repeat',
backgroundPosition: '50% 55%',
}}
checked={checked}
onChange={onChange}
/>

<p className='text-primary font-bold font-apple ml-[4px]'>
{label && label}</p>
</label>
</>
);
};

export default LoginCheckbox;
6 changes: 5 additions & 1 deletion src/components/navbar/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {ReactNode} from 'react';
import IconButton from '@components/button/IconButton.tsx';
import backward from '@assets/icons/backward.svg';
import NavProgressBar from '@components/navbar/NavProgressBar.tsx';
import {useNavigate} from 'react-router-dom';

type NavbarProps = {
children?: ReactNode;
Expand All @@ -12,12 +13,15 @@ type NavbarProps = {
progressDominator?: number;
};
const Navbar = (props: NavbarProps) => {
const navigate = useNavigate();
return (
<div className='flex w-full flex-col shadow shadow-[rgba(0, 0, 0, 0.25)]'>
<div className='flex w-full h-[60px] items-center'>
<div className='w-[48px] h-[46px] flex justify-center items-center'>
{props.hasBackwardButton ?
<IconButton icon={backward}> </IconButton> : null}
<IconButton icon={backward} onClick={() => {
navigate(-1);
}}> </IconButton> : null}
</div>
<div className='flex flex-1 h-[46px] justify-center items-center'>
<p className='font-apple text-[18px] mt-[3px] font-bold'>
Expand Down
30 changes: 29 additions & 1 deletion src/constants/register.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const registerConstants = {
PAGE_AUTHORIZATION: 3,
PAGE_INPUT_INFORMATION: 4,

PAGE_EULA: 5,
PAGE_TOS: 5,
PAGE_PRIVACY_POLICY: 6,

PAGE_REGISTRATION_COMPLETE: 7,
Expand All @@ -21,5 +21,33 @@ const registerConstants = {
'회원가입 완료'],
max_pages: 4,
page_start: 1,
progresses: [
null, '#register-selection',
'#user-agreement',
'#authorization',
'#input-information',
'#tos', '#privacy-policy',
'#complete'],
getProgressFromHash: (hash: string) => {
const progresses = registerConstants.progresses;
return progresses.indexOf(hash) === -1 ? 1 : progresses.indexOf(hash);
},
getNextProgress: (currentProgress: number) => {
const pageNums = registerConstants.page_nums;
if (currentProgress < pageNums.PAGE_INPUT_INFORMATION) {
return currentProgress + 1;
}
return 0;
},
getNextUrlHash: (currentProgress: number): string => {
return <string>registerConstants.progresses[registerConstants.getNextProgress(
currentProgress)];
},
infos: {
GENDER_MALE: '남',
GENDER_FEMALE: '여',
TYPE_CUSTOMER: 0,
TYPE_STYLIST: 1,
},
};
export default registerConstants;
3 changes: 3 additions & 0 deletions src/modules/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import {configureStore} from '@reduxjs/toolkit';
import authReducer from '@modules/authReducer.ts';
import registerReducer from '@modules/registerReducer.ts';

export const rootStore = configureStore({
reducer: {
auth: authReducer,
register: registerReducer,
},
devTools: true,
});
export type RootState = ReturnType<typeof rootStore.getState>;
89 changes: 89 additions & 0 deletions src/modules/registerReducer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import Constants from '@/constants';

const REGISTER_SET_INFO = 'register/SET_INFO';
const REGISTER_CLEAR_INFO = 'register/CLEAR_INFO';

interface SetInfoAction {
type: typeof REGISTER_SET_INFO;
payload: RegisterState;
}

interface ClearInfoAction {
type: typeof REGISTER_CLEAR_INFO;
}

type RegisterState = {
register_type?: number;
tos_agreed?: boolean;
name?: string;
email?: string;
authorized?: boolean;
nickname?: string;
loginid?: string;
password?: string;
passwordConfirm?: string;
gender?: number;
};

const registerFields: (keyof RegisterState)[] = [
'register_type',
'tos_agreed',
'name',
'email',
'authorized',
'nickname',
'loginid',
'password',
'passwordConfirm',
'gender',
];

const pageNums = Constants.register.page_nums;

export const getRequiredInfo = (progress: number): (keyof RegisterState)[] => {
switch (progress) {
case pageNums.PAGE_REGISTER_SELECTION:
return registerFields.slice(0, 1);
case pageNums.PAGE_USER_AGREEMENT:
return registerFields.slice(0, 2);
case pageNums.PAGE_AUTHORIZATION:
return registerFields.slice(0, 5);
case pageNums.PAGE_INPUT_INFORMATION:
return registerFields;
}
return [];
};

// 모두 undefined
const initialState: RegisterState = {};

export const setRegisterInfo = (info: RegisterState): SetInfoAction => ({
type: REGISTER_SET_INFO,
payload: info,
});

export const clearRegisterInfo = (): ClearInfoAction => ({
type: REGISTER_CLEAR_INFO,
});

// Reducer
const registerReducer = (
state = initialState,
action: SetInfoAction | ClearInfoAction,
): RegisterState => {
switch (action.type) {
case REGISTER_SET_INFO:
return {
...state,
...action.payload,
};
case REGISTER_CLEAR_INFO:
return {
...initialState,
};
default:
return state;
}
};

export default registerReducer;
4 changes: 2 additions & 2 deletions src/pages/LoginPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {Link, Navigate} from 'react-router-dom';
import Input from '@components/input/Input.tsx';
import {limitInputNumber} from '@/utils';
import Button from '@components/button/Button.tsx';
import Checkbox from '@components/input/Checkbox.tsx';
import LoginCheckbox from '@components/input/LoginCheckbox.tsx';
import ResponsiveContainer from '@components/container/ResponsiveContainer.tsx';

const LoginPage = (): ReactNode => {
Expand Down Expand Up @@ -53,7 +53,7 @@ const LoginPage = (): ReactNode => {
></Input>
</div>
<div className='flex mt-[16px] pl-[4px]'>
<Checkbox checked={autologinChecked}
<LoginCheckbox checked={autologinChecked}
onChange={() => setAutoLoginChecked(!autologinChecked)}
label='로그인 상태 유지'
/>
Expand Down
Loading

0 comments on commit 59f31d1

Please sign in to comment.