Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] 대시보드 2차 MVP DTO에 맞게 뷰를 수정해요. #57

Merged
merged 28 commits into from
Jul 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
05035b3
chore: 패키지 매니저 pnpm으로 변경
eugene028 Jun 26, 2024
cfc6b9e
chore: yaml파일 삭제
eugene028 Jun 26, 2024
3327777
feature: 새롭게 바뀐 DTO 반영
eugene028 Jun 29, 2024
7c6ec3c
Merge branch 'dev' into feature/#51
eugene028 Jun 29, 2024
0a8cf24
Merge branch 'fix/eslint-prettier' into feature/#51
eugene028 Jun 29, 2024
698298d
chore: 컴포넌트 단순화 분리 작업
eugene028 Jun 29, 2024
0485687
feature: Mypage status 생성
eugene028 Jun 29, 2024
b7d501c
Merge branch 'dev' into chore/apply-wds
eugene028 Jun 30, 2024
1687fc3
feature: wowds로 마이그레이션
eugene028 Jun 30, 2024
7be88f8
fix: 디자인 시스템 마이그레이션
eugene028 Jun 30, 2024
be358e7
feature: wow design system으로 마이그레이션
eugene028 Jun 30, 2024
1d8eca9
Merge branch 'chore/apply-wds' into feature/#51
eugene028 Jun 30, 2024
97d3cca
fix: 이것저것 반영
eugene028 Jun 30, 2024
dade33b
feature: 대시보드 2차 MVP 틀 구현
eugene028 Jul 1, 2024
4e9b568
fix: 메인화면 네임 수정
eugene028 Jul 1, 2024
bff8c2d
#51: #51: WIP on feature/#51
eugene028 Jul 3, 2024
46dbbeb
Merge branch 'dev' into feature/#51
eugene028 Jul 3, 2024
b52857e
feature: helpBox 생성
eugene028 Jul 3, 2024
9d3e0eb
fix: 서버 번경 사항 챙기기
eugene028 Jul 3, 2024
dbb8e7c
feat: 정회원 버튼 생성
eugene028 Jul 6, 2024
468401d
feat: react-hook-form 기본 세팅
eugene028 Jul 10, 2024
ee00d39
feat: signup 페이지 완성
eugene028 Jul 10, 2024
ed49203
fix: 백엔드 DTO 변경에 따른 반영
eugene028 Jul 13, 2024
59f7e9e
fix: 코드리뷰 반영
eugene028 Jul 13, 2024
9830aa5
fix: 코드리뷰 반영 - 랜더링 최적화
eugene028 Jul 13, 2024
ecae2bf
Merge branch 'dev' into feature/#51
eugene028 Jul 13, 2024
79035d2
Merge branch 'dev' into feature/#51
eugene028 Jul 13, 2024
6212380
fix: 패키지 변경사항 반영
eugene028 Jul 13, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ module.exports = {
'plugin:react-hooks/recommended',
'plugin:react/recommended',
'plugin:import/recommended',
'plugin:jsx-a11y/recommended',
'eslint-config-prettier',
'plugin:prettier/recommended'
],
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
"react-toastify": "^10.0.4",
"zustand": "^4.5.0",
"wowds-tokens": "^0.0.9",
"wowds-ui": "^0.1.3"
"wowds-ui": "^0.1.3",
"wowds-icons": "^0.0.4"
},
"devDependencies": {
"@storybook/addon-essentials": "^7.6.14",
Expand Down
7 changes: 7 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/apis/auth/verifyStudentEmailApi.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import apiClient from '@/apis';

//TODO: 객체로 바꾸기
export default async function verifyStudentEmailApi(token: string) {
return (await apiClient.get(`/onboarding/verify-email?token=${token}`)).data;
}
15 changes: 15 additions & 0 deletions src/apis/member/createBasicInfoApi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import apiClient from '@/apis';

import { MemberBasicInfoType } from './memberType';

const createBasicInfoApi = {
BASIC_INFO: async (payload: MemberBasicInfoType) => {
const response = await apiClient.post(
'/onboarding/members/me/basic-info',
payload
);
return response.data;
}
};

export default createBasicInfoApi;
4 changes: 2 additions & 2 deletions src/apis/member/memberApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import apiClient from '@/apis';
import { MemberInfoResponse } from '@/apis/member/memberType';

const memberApi = {
GET_MEMBERS_ME: async (): Promise<MemberInfoResponse> => {
const response = await apiClient.get(`/onboarding/members/me`);
GET_DASHBOARD: async (): Promise<MemberInfoResponse> => {
const response = await apiClient.get(`/onboarding/members/me/dashboard`);
return response.data;
}
};
Expand Down
43 changes: 36 additions & 7 deletions src/apis/member/memberType.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,40 @@
import { Status } from '@/types/status';
import { User } from '@/types/user';

export interface MemberInfoResponse extends User {
export interface MemberBasicInfoType {
studentId: string;
name: string;
phone: string;
department: string;
email: string;
}

export interface MemberInfoResponse {
member: User;
currentRecruitmentRound: CurrentRecruitmentType;
currentMembership: CurrentMembershipType;
}

export interface CurrentRecruitmentType {
recruitmentId: number;
name: string;
period: {
startDate: string;
endDate: string;
open: boolean;
};
fee: number;
roundType: 'FIRST' | 'SECOND';
roundTypeValue: string;
}

export interface CurrentMembershipType {
membershipId: number;
memberId: number;
paymentStatus: 'PENDING' | 'VERIFIED';
discordStatus: 'PENDING' | 'VERIFIED';
bevyStatus: 'PENDING' | 'VERIFIED';
role: 'GUEST' | 'USER' | 'ADMIN';
depositorName: string;
registrationStatus: 'APPLIED' | 'PENDING' | 'GRANTED';
recruitmentId: number;
regularRequirement: {
paymentStatus: Status;
allSatisfied: boolean;
paymentSatisfied: boolean;
};
}
44 changes: 32 additions & 12 deletions src/components/auth/DepartmentSelect.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,49 @@
import { Select } from '@/components/common/Select';
import React from 'react';
import { useGetDepartmentList } from '@/hooks/query';
import { Control, Controller, FieldValues } from 'react-hook-form';
import { Control, Controller } from 'react-hook-form';
import DropDown from 'wowds-ui/DropDown';
import DropDownOption from 'wowds-ui/DropDownOption';
import { FormStateType } from '@/pages';

type DepartmentSelectProps = {
control: Control<FieldValues, any, FieldValues>;
control: Control<FormStateType, unknown, FormStateType>;
};

export default function DepartmentSelect({ control }: DepartmentSelectProps) {
const DepartmentSelect = ({ control }: DepartmentSelectProps) => {
const { departmentList } = useGetDepartmentList();

return (
<Controller
name="department"
control={control}
defaultValue=""
rules={{
required: {
value: true,
message: '* 정보를 입력해주세요.'
}
}}
render={({ field }) => (
<Select
<DropDown
{...field}
onChange={field.onChange}
value={field.value}
label="학과"
required
items={departmentList}
idField="code"
displayField="name"
/>
placeholder="선택하세요">
<React.Fragment key=".0">
{departmentList.map((department, index) => {
return (
<DropDownOption
key={`${index}-dropdownOption`}
text={department.name}
value={department.code}
/>
);
})}
</React.Fragment>
</DropDown>
)}
/>
);
}
};

export default DepartmentSelect;
2 changes: 1 addition & 1 deletion src/components/auth/guard/MypageAccessGuard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Navigate, Outlet } from 'react-router-dom';
export default function MypageAccessGuard() {
const { landingStatus } = useLandingStatus();

if (landingStatus !== LandingStatus.MyPage) {
if (landingStatus !== LandingStatus.Dashboard) {
return <Navigate to={getAuthRedirectPath(landingStatus)} />;
}

Expand Down
15 changes: 6 additions & 9 deletions src/components/auth/guard/SignupAccessGuard.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import LandingStatus from '@/constants/landingStatus';
import { Navigate, Outlet } from 'react-router-dom';
import useLandingStatus from '@/hooks/zustand/useLandingStatus';
import { getAuthRedirectPath } from '@/utils/auth';
import { Outlet } from 'react-router-dom';

//deprecated: 추후 삭제 필요한 파일임
export default function SignupAccessGuard() {
const { landingStatus } = useLandingStatus();

if (landingStatus !== LandingStatus.Signup) {
return <Navigate to={getAuthRedirectPath(landingStatus)} />;
}
//TODO: 추후 보안 정책에 따라 수정 필요
// if (landingStatus !== LandingStatus.Signup) {
// return <Navigate to={getAuthRedirectPath(landingStatus)} />;
// }

return <Outlet />;
}
121 changes: 64 additions & 57 deletions src/components/myPage/ApproveBox.tsx
Original file line number Diff line number Diff line change
@@ -1,67 +1,74 @@
import { Flex, Text } from '@/components/common/Wrapper';
import { color } from 'wowds-tokens';
import styled from '@emotion/styled';
import Box from 'wowds-ui/Box';

type TextKey = 'APPLIED' | 'PENDING' | 'GRANTED';
import { CurrentRecruitmentType } from '@/apis/member/memberType';
import { formatDate } from '@/utils/mypage/formatDate';

const text: Record<
TextKey,
{
title: string;
description: string;
}
> = {
APPLIED: {
title: '가입 조건을 아직 충족시키지 못했어요.',
description:
'아래 가입 조건을 모두 완료하시면, 운영진이 검토 후 가입 신청을 승인해 드릴 예정이에요.'
},
PENDING: {
title: '제출해주신 가입 신청서를 검토하고 있어요.',
description:
'마지막으로 가입 조건에 문제가 없는지 운영진이 꼼꼼히 확인 중이에요. 조금만 기다려주세요!'
},
GRANTED: {
title: '가입 신청이 승인되었어요.',
description:
'/가입하기 명령어를 통해 GDSC Hongik 디스코드의 모든 채널을 둘러보실 수 있어요.'
}
type MemberRole = 'GUEST' | 'ASSOCIATE' | 'REGULAR' | 'ADMIN';
type BoxVariantType = 'arrow' | 'checkbox' | 'text' | 'warn';
type BoxStatusType = 'default' | 'success' | 'error';
const convertRecruitmentName = (name: string) => {
const [period, round] = name.split(' ');
const [year, semester] = period.split('-');
return `${year}년 ${semester}학기 ${round} 정회원 지원하기`;
};

const convertRecruitmentPeriod = (period: {
startDate: string;
endDate: string;
}) => {
const startDate = formatDate(period.startDate);
const endDate = formatDate(period.endDate);
return `지원 기간 : ${startDate} ~ ${endDate}`;
};

export const ApproveBox = ({
registrationStatus = 'APPLIED',
count
role,
currentRecruitment
}: {
registrationStatus: 'APPLIED' | 'PENDING' | 'GRANTED';
count: number;
role: MemberRole;
currentRecruitment: CurrentRecruitmentType;
}) => {
const command = '/가입하기';
const boxContent: Record<
MemberRole,
{
title: string;
description?: string;
boxVariant: BoxVariantType;
status: BoxStatusType;
}
> = {
GUEST: {
title: `${convertRecruitmentName(currentRecruitment.name)}`,
description: '하단의 준회원 가입 조건을 완료해주세요.',
boxVariant: 'warn',
status: 'error'
},
ASSOCIATE: {
title: `${convertRecruitmentName(currentRecruitment.name)}`,
description: `${convertRecruitmentPeriod(currentRecruitment.period)}`,
boxVariant: 'arrow',
status: 'error'
},
REGULAR: {
title: '모든 가입 절차를 완료했어요.',
boxVariant: 'text',
status: 'success'
},
//TODO: 어드민 가입 상태 논의하기
ADMIN: {
title: '모든 가입 절차를 완료했어요.',
boxVariant: 'text',
status: 'success'
}
};
return (
<Wrapper gap="sm">
<Flex direction="column" align="flex-start" gap="sm">
<Text typo="label1" color="black">
{text[registrationStatus]?.title}
{registrationStatus === 'APPLIED' && `(${count}/3)`}
</Text>
<Text typo="body1" color="mono700">
{text[registrationStatus].description
.split(command)
.reduce<React.ReactNode[]>((prev, current, index) => {
if (index) prev.push(<strong key={index}>{command}</strong>);
prev.push(current);
return prev;
}, [])}
</Text>
</Flex>
</Wrapper>
<>
<Box
variant={boxContent[role].boxVariant}
text={boxContent[role].title}
subText={boxContent[role].description}
status={boxContent[role].status}
/>
</>
);
};

const Wrapper = styled(Flex)`
padding: 24px 11px 20px 24px;
box-sizing: border-box;

background-color: ${color.white};
border-radius: 8px;
border: 1px solid ${color.primary};
`;
Loading