Skip to content

Commit

Permalink
Merge pull request #22 from ddok-ddak/feature/DD-19-회원가입
Browse files Browse the repository at this point in the history
Feature/dd 19 회원가입
  • Loading branch information
HanaHww2 authored Aug 20, 2023
2 parents dce3e89 + 34317c1 commit fa77b39
Show file tree
Hide file tree
Showing 18 changed files with 1,084 additions and 26 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
"react-app-polyfill": "^3.0.0",
"react-chartjs-2": "^5.1.0",
"react-color": "^2.19.3",
"react-countdown": "^2.3.5",
"react-dev-utils": "^12.0.1",
"react-dom": "^18.2.0",
"react-material-ui-carousel": "^3.4.2",
Expand Down
3 changes: 2 additions & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import { BrowserRouter, Navigate, Route, Routes } from 'react-router-dom';
import './App.css';
import BottomNav from './components/layout/BottomNav';
import FindID from './pages/auth/FindID';
import ResetPW from './pages/auth/ResetPW';
import ResetPW from './pages/auth/SetPW';

import SignUp from './pages/auth/SignUp';
import Login from './pages/auth/login/Login';
import CategoryPage from './pages/category/CategoryPage';
Expand Down
52 changes: 52 additions & 0 deletions src/api/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { UserData } from '@/store/userData';
import { callAPI } from './common/api';
import CommonResponse from './http';

/**
* check duplicated email
* @param email email
* @returns response
*/
export const checkDuplicatedEmail = async (email: string) => {
const response = await callAPI({
url: '/api/v1/members/duplicatedEmail',
method: 'GET',
params: {
email
},
});

return response as CommonResponse;
};

/**
* check duplicated nickname
* @param nickname nickname
* @returns response
*/
export const checkDuplicatedNickname = async (nickname: string) => {
const response = await callAPI({
url: '/api/v1/members/duplicateNickname',
method: 'GET',
params: {
nickname
}
});

return response as CommonResponse;
};

/**
* user sign up
* @param request: UserData
* @returns response
*/
export const addUser = async (request: UserData) => {
const response = await callAPI({
url: '/api/v1/auth/signup',
method: 'POST',
body: request,
});

return response as CommonResponse;
};
76 changes: 70 additions & 6 deletions src/components/common/Modal.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Box, Modal as MuiModal } from '@mui/material';
import { Box, Button, Container, Divider, Modal as MuiModal } from '@mui/material';
import { useRecoilState } from 'recoil';

import { modalState } from '@/store/common';
Expand All @@ -20,15 +20,79 @@ const Modal = () => {
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
width: 400,
width: 290,
height: 153,
bgcolor: 'background.paper',
border: '2px solid #000',
borderRadius: '5px',
boxShadow: 24,
p: 4,
display: 'flex',
flexDirection: 'column',
}}
>
<h2 id="modal-modal-title">{modalInfo.title}</h2>
<p id="modal-modal-description">{modalInfo.msg}</p>
<Box
sx={{
flex: '1 0 auto',
display: 'flex',
flexDirection: 'column',
justifyContent: 'stretch',
minHeight: 0,
}}
>
<h2
id="modal-modal-title"
style={{
fontSize: '13px',
fontWeight: '600',
textAlign: 'center',
margin: '2em 2.3em 0.6em 2.3em'
}}
>
{modalInfo.title}
</h2>
<p
id="modal-modal-description"
style={{
fontSize: '12px',
fontWeight: '400',
textAlign: 'center',
margin: '0.4em 2.3em 0.4em 2em'
}}
>
{modalInfo.msg}
</p>
</Box>
<Divider
orientation='horizontal'
flexItem
variant='fullWidth'
sx={{ flex: '0 0 auto', gridArea: 'divider' }}
/>
<Box
sx={{
gridArea: 'btn-box',
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-evenly'
}}
>
<Button
sx={{ gridArea: 'btn-a', flex: '1 1 49%', color: '#4F75FF' }}
onClick={modalInfo.btn1ClickHandler}
>
{modalInfo.btn1Text}
</Button>
<Divider
orientation='vertical'
flexItem
sx={{ gridArea: 'btn-divider', flex: '0 0 auto' }}
/>
<Button
sx={{ gridArea: 'btn-b', flex: '1 1 49%', color: '#4F75FF', fontWeight: '600' }}
onClick={modalInfo.btn2ClickHandler}
>
{modalInfo.btn2Text}
</Button>
</Box>
</Box>
</MuiModal>
);
Expand Down
32 changes: 32 additions & 0 deletions src/hooks/signUpSteps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { ReactElement } from 'react';
import { useRecoilState } from 'recoil';
import { SignUpStepState } from '@/store/signUp';

export function useSignUpStepForm(steps: ReactElement[]) {

const [currentStepIndex, setCurrentStepIndex] = useRecoilState(SignUpStepState);

/**
* handle next button
*/
function handleNextButton() {
const currIdx = currentStepIndex;
setCurrentStepIndex(() => (currIdx < steps.length - 1) ? (currIdx + 1) : currIdx);
}

/**
* handle prev button
*/
function handlePrevButton() {
const currIdx = currentStepIndex;
setCurrentStepIndex(() => (currIdx <= 0) ? currIdx : currIdx - 1);
}

return {
currentStepIndex,
step: steps[currentStepIndex],
steps,
handleNextButton,
handlePrevButton
}
};
147 changes: 147 additions & 0 deletions src/pages/auth/CheckTermsAndConditions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
import React, { useState, useEffect } from 'react';
import { useRecoilState, useSetRecoilState, useRecoilValue } from 'recoil';
import {
Box,
List,
ListItem,
ListItemButton,
ListItemIcon,
ListItemText,
Checkbox,
Divider,
} from '@mui/material';
import { SignUpNextButtonState, SignUpStepInstruction, SignUpStepNextButton } from '@/store/signUp';

import FormWrapper from './FormWrapper';

type ItemType = {
required: boolean,
desc: string,
checked: boolean,
}

const termsAndConditionsArray: ItemType[] = [
{
required: false,
desc: '모두 동의합니다.',
checked: false,
},
{
required: true,
desc: '만 14세 이상입니다',
checked: false,
},
{
required: true,
desc: '[필수] 이용 약관 동의',
checked: false,
},
{
required: true,
desc: '[필수] 개인정보 수집 및 이용 동의',
checked: false,
},
{
required: false,
desc: '[선택] 광고, 마케팅 활용 정보수신 동의',
checked: false,
}
];

const CheckTermsAndConditions = (props: any) => {
const [signUpNextButtonProps, setSignUpNextButtonProps] = useRecoilState(SignUpNextButtonState);
const setSignUpStepInstruction = useSetRecoilState(SignUpStepInstruction);
const signUpStepNextButton = useRecoilValue(SignUpStepNextButton);

const [checked, setChecked] = useState([false, false, false, false, false]);
const [isNextButtonDisabled, setIsNextButtonDisabled] = useState(true);

const handleCheckboxToggle = (idx: number) => () => {
const currentIndex = idx;
const newChecked: boolean[] = [...checked];
let newValue = !newChecked[idx];
let isRequiredCheck = false;

if (currentIndex === 0) {
// 모두 동의
newChecked.fill(newValue);
} else {
newChecked[idx] = newValue;
}
setChecked(newChecked);
isRequiredCheck = !(newChecked[1] && newChecked[2] && newChecked[3]);
setIsNextButtonDisabled(isRequiredCheck);
setSignUpNextButtonProps({
...signUpNextButtonProps,
isDisabled: isRequiredCheck,
});
};
const CheckboxItem = (item: ItemType, idx: number) => {
const labelId = `checkbox-list-label-${idx}`;
return (
<ListItem disablePadding>
<ListItemButton
role={undefined}
onClick={handleCheckboxToggle(idx)}
dense
>
<ListItemIcon>
<Checkbox
required={item.required}
edge="start"
sx={{ width: '21px', height: '21px' }}
checked={checked[idx]}
tabIndex={-1}
disableRipple
inputProps={{ 'aria-labelledby': labelId }}
/>
</ListItemIcon>
<ListItemText id={labelId} primary={item.desc} />
</ListItemButton>
</ListItem>
);
};

useEffect(() => {
setSignUpStepInstruction('서비스를 이용하기 위해 약관에 동의 해주세요.');
setSignUpNextButtonProps({
...signUpNextButtonProps,
isDisabled: true,
clickHandler: props.handleNextButton
})
}, []);

return (
<FormWrapper>
<List
sx={{
width: '100%',
maxWidth: 360,
bgcolor: 'background.paper',
}}
>
{Object.values(termsAndConditionsArray).map((item: ItemType, idx: number) => {
return (
<Box key={idx}>
{idx === 1 && (
<Divider
variant="middle"
sx={{
backgroundColor: '#DDDDDD',
height: '3px',
border: 'none',
margin: '10px 0 10px 5px',
width: '95%',
}}
/>
)}
{CheckboxItem(item, idx)}
</Box>
);
})}
</List>
</FormWrapper>
);
};

export default CheckTermsAndConditions;
Loading

0 comments on commit fa77b39

Please sign in to comment.