Skip to content

Commit

Permalink
feat: 비밀번호 찾기 페이지 구현 (#87)
Browse files Browse the repository at this point in the history
  • Loading branch information
selfishAltruism committed Mar 3, 2024
1 parent 5eef91c commit a102a88
Show file tree
Hide file tree
Showing 10 changed files with 51 additions and 106 deletions.
6 changes: 6 additions & 0 deletions src/@types/user.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,12 @@ declare namespace User {
refreshToken: string;
}

export interface FindPasswordReqestDto {
name: string;
studentId: string;
email: string;
}

// ==

export interface FindPostsResponse {
Expand Down
1 change: 1 addition & 0 deletions src/configs/path.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export enum PAGE_URL {
Auth = '/auth',
SignIn = '/auth/signin',
SignUp = '/auth/singup',
FindPassword = '/auth/findPassword',
Admission = '/auth/admission',

Home = '/home',
Expand Down
2 changes: 2 additions & 0 deletions src/pages/auth/AuthPageSwitch.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Route, Switch } from 'react-router-dom';

import { Admission } from './admission';
import { FindPassword } from './findPassword';
import { SignIn } from './signIn';
import { SignUp } from './signUp';

Expand All @@ -11,5 +12,6 @@ export const AuthPageSwitch: React.FC = () => (
<Route path={PAGE_URL.SignIn} component={SignIn} />
<Route path={PAGE_URL.Admission} component={Admission} />
<Route path={PAGE_URL.SignUp} component={SignUp} />
<Route path={PAGE_URL.FindPassword} component={FindPassword} />
</Switch>
);
124 changes: 30 additions & 94 deletions src/pages/auth/findPassword/FindPasswordPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import React, { useEffect } from 'react';
import { useForm } from 'react-hook-form';
import { useHistory } from 'react-router-dom';

import { PageUiStoreImpl } from './BoardCreatePageUiStore';
import { PageUiStoreImpl } from './FindPasswordPageUiStore';

import {
BodyScreen,
Expand All @@ -21,129 +21,65 @@ import { useRootStore } from '@/stores/RootStore';

const FindPasswordPage: React.FC = observer(() => {
const { replace } = useHistory();
const { create } = usePageUiStore<PageUiStore.BoardCreate>();
const { findPassword } = usePageUiStore<PageUiStore.FindPassword>();
const {
ui: { alert },
auth: { fetch, me },
} = useRootStore();
const {
handleSubmit,
control,
formState: { errors },
setValue,
} = useForm({
defaultValues: {
name: undefined,
description: undefined,
category: '공지 게시판',
circleName: '전체',
},
});

const handleSelectChange = (name: string, selectedValue: string) => {
setValue(name as 'category' | 'circleName', selectedValue);
};
} = useForm<User.FindPasswordReqestDto>();

if (
(errors.name && errors.name.type === 'required') ||
(errors.description && errors.description.type === 'required')
(errors.studentId && errors.studentId.type === 'required') ||
(errors.email && errors.email.type === 'required')
) {
alert({ message: '모든 항목을 다 입력해주세요.' });
}

const onSubmit = async (data: {
name: string;
description: string;
category: string;
circleName?: string;
}) => {
const body: Board.CreateRequestDto = {
name: data.name,
description: data.description,
category: data.category,
createRoleList: [],
circleId: null,
};
if (me?.isCircleLeader && data.circleName !== '전체') {
//동아리장이 동아리 게시판을 생성하는 경우
if (data.category === '공지 게시판') {
body.createRoleList = ['ADMIN', 'VICE_PRESIDENT', 'PRESIDENT', 'LEADER_CIRCLE'];
body.circleId =
me.circleIds![me.circleNames!.findIndex(circleName => circleName === data.circleName)];
} else if (data.category === '자유 게시판') {
body.createRoleList = [
'ADMIN',
'VICE_PRESIDENT',
'PRESIDENT',
'LEADER_CIRCLE',
'LEADER_1',
'LEADER_2',
'LEADER_3',
'LEADER_4',
'COMMON',
];
body.circleId =
me.circleIds![me.circleNames!.findIndex(circleName => circleName === data.circleName)];
}
} else {
//학생회장 혹은 관리자가 동아리 게시판을 생성하는 경우
if (data.category === '공지 게시판') {
body.createRoleList = ['ADMIN', 'VICE_PRESIDENT', 'PRESIDENT'];
} else if (data.category === '자유 게시판') {
body.createRoleList = [
'ADMIN',
'VICE_PRESIDENT',
'PRESIDENT',
'LEADER_CIRCLE',
'LEADER_1',
'LEADER_2',
'LEADER_3',
'LEADER_4',
'COMMON',
];
}
}
const { success } = (await create(body)) as unknown as StoreAPI;
const onSubmit = async (body: User.FindPasswordReqestDto) => {
const { success } = (await findPassword(body)) as unknown as StoreAPI;
if (success) {
replace(PAGE_URL.Board);
alert({ message: '게시판이 생성되었습니다.' });
replace(PAGE_URL.SignIn);
alert({ message: '이메일로 임시 비밀번호가 전송되었습니다. 로그인 이후 변경해주세요.' });
} else {
alert({ message: '잘못된 정보를 입력하였습니다.' });
}
};

useEffect(() => {
fetch();
if (me?.isCircleLeader && !(me.isAdmin || me.isPresident))
setValue('circleName', me.circleNames![0]);
}, []);

return (
<>
<Header title="게시판 생성" withBack={PAGE_URL.Board} />
<PageBody>
<BodyScreen>
<Input name="name" label="게시판 이름" required control={control} />
<Input name="description" label="게시판 설명" required control={control} />
<SelectInput
name="category"
label="게시판 카테고리"
<Input
name="email"
label="이메일"
placeholder="이메일을 입력하세요"
required
control={control}
/>
<Input
name="name"
label="이름"
placeholder="이름을 입력하세요"
required
control={control}
/>
<Input
name="studentId"
label="학번"
placeholder="학번을 입력하세요 (ex. 20201234)"
required
options={['공지 게시판', '자유 게시판']}
control={control}
/>
{me?.isCircleLeader ? (
<SelectInput
name="circleName"
label="게시판 생성 동아리"
control={control}
required
options={me.isAdmin || me.isPresident ? ['전체', ...me.circleNames!] : me.circleNames}
/>
) : null}
</BodyScreen>
</PageBody>

<PageFooter>
<NavButton onClick={handleSubmit(onSubmit)}>게시판 생성</NavButton>
<NavButton onClick={handleSubmit(onSubmit)}>임시 비밀번호 생성</NavButton>
</PageFooter>
</>
);
Expand Down
8 changes: 4 additions & 4 deletions src/pages/auth/findPassword/FindPasswordPageUiStore.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
import { makeAutoObservable } from 'mobx';

import { BoardRepoImpl as Repo } from '@/stores/repositories/BoardRepo';
import { AuthRepoImpl as Repo } from '@/stores/repositories/AuthRepo';

export class FindPasswordPageUiStore {
constructor() {
makeAutoObservable(this, {}, { autoBind: true });
}

// TODO: 게시판 관리 화면 구현 시 추가 검증 필요
*create(body: Board.CreateRequestDto): Generator {
*findPassword(body: User.FindPasswordReqestDto): Generator {
try {
(yield Repo.create(body)) as Model.Board;
yield Repo.findPassword(body);
return { success: true };
} catch (error) {
return error;
}
}
}

export const PageUiStoreImpl = new BoardCreatePageUiStore();
export const PageUiStoreImpl = new FindPasswordPageUiStore();
1 change: 1 addition & 0 deletions src/pages/auth/findPassword/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as FindPassword } from './FindPasswordPage';
5 changes: 1 addition & 4 deletions src/pages/auth/signIn/SignInPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,7 @@ const SignInPage: React.FC = observer(() => {

<SubLink>
<Link to={PAGE_URL.SignUp}>회원가입</Link>
{/* TODO: 개발
<Link to={PAGE_URL.SignUp}>이메일 찾기</Link> */}
{/* TODO: 개발
<Link to={PAGE_URL.SignUp}>비밀번호 찾기</Link> */}
<Link to={PAGE_URL.FindPassword}>비밀번호를 잃어버리셨나요?</Link>
</SubLink>
</PageWrapper>
);
Expand Down
4 changes: 0 additions & 4 deletions src/pages/board/boardCreate/BoardCreatePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,6 @@ const BoardCreatePage: React.FC = observer(() => {
},
});

const handleSelectChange = (name: string, selectedValue: string) => {
setValue(name as 'category' | 'circleName', selectedValue);
};

if (
(errors.name && errors.name.type === 'required') ||
(errors.description && errors.description.type === 'required')
Expand Down
4 changes: 4 additions & 0 deletions src/stores/repositories/AuthRepo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ class AuthRepo {
updatePassword = async (body: User.PasswordUpdateRequestDto) => {
return API.put(`${this.URI}/password`, body);
};

findPassword = async (body: User.FindPasswordReqestDto) => {
return API.put(`${this.URI}/findPassword`, body);
};
}

export const AuthRepoImpl = new AuthRepo();
2 changes: 2 additions & 0 deletions src/vite-env.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/// <reference types="vite/client" />

import type { AdmissionPageUiStore } from './pages/auth/admission/AdmissionPageUiStore';
import type { FindPasswordPageUiStore } from './pages/auth/findPassword/FindPasswordPageUiStore';
import type { SignInPageUiStore } from './pages/auth/signIn/SignInPageUiStore';
import type { SignUpPageUiStore } from './pages/auth/signUp/SignUpPageUiStore';
import type { BoardCreatePageUiStore } from './pages/board/boardCreate/BoardCreatePageUiStore';
Expand Down Expand Up @@ -73,6 +74,7 @@ declare global {
type SignIn = SignInPageUiStore;
type SignUp = SignUpPageUiStore;
type Admission = AdmissionPageUiStore;
type FindPassword = FindPasswordPageUiStore;
type Home = HomePageUiStore;
type CircleHome = CircleHomePageUiStore;
type CircleJoin = CircleJoinPageUiStore;
Expand Down

0 comments on commit a102a88

Please sign in to comment.