diff --git a/service-apply/src/apis/dtos/registration.dtos.ts b/service-apply/src/apis/dtos/registration.dtos.ts index feb27092..d89cd953 100644 --- a/service-apply/src/apis/dtos/registration.dtos.ts +++ b/service-apply/src/apis/dtos/registration.dtos.ts @@ -6,6 +6,7 @@ export interface TemporarySaveRequestProps extends RegistrationEventIdResponse { name: string; studentNumber: string; affiliation: string; + department: string; carNumber: string; isLightCar: boolean; phoneNumber: string; @@ -16,6 +17,7 @@ export class TemporarySaveRequest { name: string; studentNum: string; affiliation: string; + department: string; carNum: string; isLight: boolean; phoneNum: string; @@ -26,6 +28,7 @@ export class TemporarySaveRequest { name, studentNumber, affiliation, + department, carNumber, isLightCar, phoneNumber, @@ -35,6 +38,7 @@ export class TemporarySaveRequest { this.name = name; this.studentNum = studentNumber; this.affiliation = affiliation; + this.department = department; this.carNum = carNumber; this.isLight = isLightCar; this.phoneNum = phoneNumber; @@ -56,6 +60,7 @@ export class RegistrationRequest extends TemporarySaveRequest { name, studentNumber, affiliation, + department, carNumber, isLightCar, phoneNumber, @@ -68,6 +73,7 @@ export class RegistrationRequest extends TemporarySaveRequest { name, studentNumber, affiliation, + department, carNumber, isLightCar, phoneNumber, @@ -100,6 +106,7 @@ interface RegistrationResponseProps { sectorName: string; }[]; affiliation: string; + department: string; selectSectorId?: number; } @@ -111,6 +118,7 @@ export class RegistrationOptionsResponse { phoneNumber: string; studentNumber: string; affiliation: string; + department: string; sector: { sectorId: number; sectorNum: string; @@ -127,6 +135,7 @@ export class RegistrationOptionsResponse { studentNum, selectSectorId, affiliation, + department, }: RegistrationResponseProps) { this.carNumber = carNum || ''; this.email = email || ''; @@ -137,6 +146,7 @@ export class RegistrationOptionsResponse { this.studentNumber = studentNum || ''; this.selectSectorId = selectSectorId; this.affiliation = affiliation || ''; + this.department = department || ''; } } diff --git a/service-apply/src/apis/registration.apis.ts b/service-apply/src/apis/registration.apis.ts index bcc8d5e9..e3df9908 100644 --- a/service-apply/src/apis/registration.apis.ts +++ b/service-apply/src/apis/registration.apis.ts @@ -63,6 +63,7 @@ export const getRegistration = async ({ name: '', selectSectorId: -1, affiliation: '', + department: '', }); } return new RegistrationOptionsResponse(response); @@ -79,6 +80,7 @@ export const getCaptcha = async () => { export const getRegistrationPeriod = async (): Promise => { const response = await https.get('/v1/events/period'); + if (isErrorResponse(response)) { const errorContent = getErrorContent(response.code); switch (errorContent.type) { diff --git a/service-apply/src/components/apply/ApplyForm.tsx b/service-apply/src/components/apply/ApplyForm.tsx index 67acc449..9a9d22b7 100644 --- a/service-apply/src/components/apply/ApplyForm.tsx +++ b/service-apply/src/components/apply/ApplyForm.tsx @@ -13,6 +13,7 @@ import { ApplyCaptchaModal } from './ApplyCaptchaModal'; import { Suspense } from 'react'; import ErrorBoundary from '../common/ErrorBoundary'; import { AFFILIATION_LIST } from '../../constants/affiliation'; +import { DEPARTMENT_LIST } from '../../constants/department'; import { PrivacyCheckModal } from './PrivacyCheckModal'; import { Spinner } from '../../assets/Spinner'; @@ -124,7 +125,6 @@ export const ApplyForm = () => { @@ -132,6 +132,16 @@ export const ApplyForm = () => { } required /> + + dispatch({ type: 'department', payload: e.target.value }) + } + required + /> { )?.value ?? '선택' } label="구간" - type="text" options={parkingSectionOptions} onChange={(e) => dispatch({ type: 'section', payload: e.target.value }) diff --git a/service-apply/src/components/apply/ApplySelector.tsx b/service-apply/src/components/apply/ApplySelector.tsx index 2678031b..d47450c0 100644 --- a/service-apply/src/components/apply/ApplySelector.tsx +++ b/service-apply/src/components/apply/ApplySelector.tsx @@ -4,7 +4,6 @@ import { Txt } from '@quokka/design-system'; interface ApplySelectorProps extends Omit, 'value'> { label: string; - type: string; options: { label: string; value: string; @@ -14,7 +13,6 @@ interface ApplySelectorProps export const ApplySelector = ({ label, - type, options, value, ...props diff --git a/service-apply/src/constants/department.ts b/service-apply/src/constants/department.ts new file mode 100644 index 00000000..8320471a --- /dev/null +++ b/service-apply/src/constants/department.ts @@ -0,0 +1,87 @@ +export const DEPARTMENT_LIST = [ + { value: '', label: '선택' }, + { value: '가정교육과', label: '가정교육과' }, + { value: '간호학과', label: '간호학과' }, + { value: '건축학부', label: '건축학부' }, + { value: '경영학부', label: '경영학부' }, + { value: '경제학부', label: '경제학부' }, + { value: '고분자융합소재공학부', label: '고분자융합소재공학부' }, + { value: '교육학과', label: '교육학과' }, + { value: '국악학과', label: '국악학과' }, + { value: '국어교육과', label: '국어교육과' }, + { value: '국어국문학과', label: '국어국문학과' }, + { value: '농생명화학과', label: '농생명화학과' }, + { value: '농업경제학과', label: '농업경제학과' }, + { value: '독일언어문학과', label: '독일언어문학과' }, + { value: '동물자원학부', label: '동물자원학부' }, + { value: '디자인학과', label: '디자인학과' }, + { value: '문헌정보학과', label: '문헌정보학과' }, + { value: '문화인류고고학과', label: '문화인류고고학과' }, + { value: '미디어커뮤니케이션학과', label: '미디어커뮤니케이션학과' }, + { value: '미래모빌리티학과', label: '미래모빌리티학과' }, + { value: '미술학과', label: '미술학과' }, + { value: '바이오에너지공학과', label: '바이오에너지공학과' }, + { value: '빅데이터융합학과', label: '빅데이터융합학과' }, + { value: '불어불문학과', label: '불어불문학과' }, + { value: '사학과', label: '사학과' }, + { value: '사회학과', label: '사회학과' }, + { value: '산림자원학과', label: '산림자원학과' }, + { value: '산업공학과', label: '산업공학과' }, + { value: '생명과학기술학부', label: '생명과학기술학부' }, + { value: '생물교육과', label: '생물교육과' }, + { value: '생물공학과', label: '생물공학과' }, + { value: '생물학과', label: '생물학과' }, + { value: '생활복지학과', label: '생활복지학과' }, + { value: '소프트웨어공학과', label: '소프트웨어공학과' }, + { value: '수의예과', label: '수의예과' }, + { value: '수의학과', label: '수의학과' }, + { value: '수학과', label: '수학과' }, + { value: '수학교육과', label: '수학교육과' }, + { value: '식품공학과', label: '식품공학과' }, + { value: '식품영양과학부', label: '식품영양과학부' }, + { value: '신소재공학부', label: '신소재공학부' }, + { value: '심리학과', label: '심리학과' }, + { value: '약학부', label: '약학부' }, + { value: '에너지자원공학과', label: '에너지자원공학과' }, + { value: '역사교육과', label: '역사교육과' }, + { value: '영어교육과', label: '영어교육과' }, + { value: '영어영문학과', label: '영어영문학과' }, + { + value: '융합바이오시스템기계공학과', + label: '융합바이오시스템기계공학과', + }, + { value: '유아교육과', label: '유아교육과' }, + { value: '윤리교육과', label: '윤리교육과' }, + { value: '음악교육과', label: '음악교육과' }, + { value: '음악학과', label: '음악학과' }, + { value: '응용생물학과', label: '응용생물학과' }, + { value: '응용식물학과', label: '응용식물학과' }, + { value: '의류학과', label: '의류학과' }, + { value: '의예과', label: '의예과' }, + { value: '인공지능학부', label: '인공지능학부' }, + { value: '일어일문학과', label: '일어일문학과' }, + { value: '임산공학과', label: '임산공학과' }, + { value: '자율전공학부', label: '자율전공학부' }, + { value: '전기공학과', label: '전기공학과' }, + { value: '전자공학과', label: '전자공학과' }, + { value: '전자컴퓨터공학부', label: '전자컴퓨터공학부' }, + { value: '정치외교학과', label: '정치외교학과' }, + { value: '조경학과', label: '조경학과' }, + { value: '지구과학교육과', label: '지구과학교육과' }, + { value: '지구환경과학부', label: '지구환경과학부' }, + { value: '지리교육과', label: '지리교육과' }, + { value: '지리학과', label: '지리학과' }, + { value: '지역·바이오시스템공학과', label: '지역·바이오시스템공학과' }, + { value: '중어중문학과', label: '중어중문학과' }, + { value: '체육교육과', label: '체육교육과' }, + { value: '컴퓨터정보통신공학과', label: '컴퓨터정보통신공학과' }, + { value: '통계학과', label: '통계학과' }, + { value: '특수교육학부', label: '특수교육학부' }, + { value: '토목공학과', label: '토목공학과' }, + { value: '철학과', label: '철학과' }, + { value: '행정학과', label: '행정학과' }, + { value: '화학과', label: '화학과' }, + { value: '화학교육과', label: '화학교육과' }, + { value: '화학공학부', label: '화학공학부' }, + { value: '환경에너지공학과', label: '환경에너지공학과' }, +]; diff --git a/service-apply/src/functions/validator.ts b/service-apply/src/functions/validator.ts index dfb763a5..5b73190c 100644 --- a/service-apply/src/functions/validator.ts +++ b/service-apply/src/functions/validator.ts @@ -25,8 +25,7 @@ export const isSection = ({ export const isCarNumber = (carNumber: string) => /\d{2,3}[가-힣]{1}\d{4}/gm.test(carNumber.replace(' ', '')); -export const isAffiliation = (affiliation: string) => - !!affiliation.replace(' ', ''); +export const isApplyDropDown = (dropDownValue: string) => !!dropDownValue; export interface ApplyFormInput { phoneNumber: string; @@ -34,6 +33,7 @@ export interface ApplyFormInput { email: string; studentName: string; affiliation: string; + department: string; section: number; carNumber: string; isCompact: boolean; @@ -65,9 +65,12 @@ export const applyFormValidator = ({ if (!isStudentNumber(input.studentNumber)) { return submitFailure('올바른 형식의 학번을 입력해 주세요.'); } - if (!isAffiliation(input.affiliation)) { + if (!isApplyDropDown(input.affiliation)) { return submitFailure('소속대학을 입력해 주세요.'); } + if (!isApplyDropDown(input.department)) { + return submitFailure('소속학과를 입력해 주세요.'); + } if (!isSection({ array: sectionNumberArray, selected: input.section })) { return submitFailure('올바른 구간을 선택해 주세요.'); } diff --git a/service-apply/src/hooks/apply/useApplyForm.tsx b/service-apply/src/hooks/apply/useApplyForm.tsx index 62f843ba..04e28d53 100644 --- a/service-apply/src/hooks/apply/useApplyForm.tsx +++ b/service-apply/src/hooks/apply/useApplyForm.tsx @@ -9,10 +9,12 @@ import { usePeriodQuery } from '../react-query/usePeriodQuery'; export const useApplyForm = () => { const { eventId } = usePeriodQuery(); const { registrationData } = useApplyQuery({ eventId }); - const { sector, selectSectorId, affiliation, ...rest } = registrationData; + const { sector, selectSectorId, affiliation, department, ...rest } = + registrationData; const { state, dispatch } = useApplyFormContext({ section: selectSectorId ?? 0, affiliation: affiliation ?? '', + department: department ?? '', ...rest, }); @@ -23,6 +25,7 @@ export const useApplyForm = () => { payload: { section: selectSectorId ?? 0, affiliation: affiliation ?? '', + department: department ?? '', ...rest, }, }); diff --git a/service-apply/src/hooks/apply/useApplyFormContext.tsx b/service-apply/src/hooks/apply/useApplyFormContext.tsx index a6ead439..00a156fd 100644 --- a/service-apply/src/hooks/apply/useApplyFormContext.tsx +++ b/service-apply/src/hooks/apply/useApplyFormContext.tsx @@ -44,6 +44,7 @@ const applyFormReducer = ( ...initApplyFormValue, }; case 'affiliation': + case 'department': case 'email': case 'studentName': case 'section': diff --git a/service-apply/src/hooks/apply/useCaptchaForm.tsx b/service-apply/src/hooks/apply/useCaptchaForm.tsx index 05ccd56e..c2e29e71 100644 --- a/service-apply/src/hooks/apply/useCaptchaForm.tsx +++ b/service-apply/src/hooks/apply/useCaptchaForm.tsx @@ -34,6 +34,7 @@ export const useCaptchaForm = ({ closeModal }: { closeModal: () => void }) => { name: state.studentName, studentNumber: state.studentNumber, affiliation: state.affiliation, + department: state.department, isLightCar: state.isCompact, carNumber: state.carNumber, phoneNumber: state.phoneNumber, diff --git a/service-apply/src/store/ApplyFormContext.tsx b/service-apply/src/store/ApplyFormContext.tsx index a00ff893..301be4b1 100644 --- a/service-apply/src/store/ApplyFormContext.tsx +++ b/service-apply/src/store/ApplyFormContext.tsx @@ -6,6 +6,7 @@ export interface ApplyFormContextType { email: string; studentName: string; affiliation: string; + department: string; section: number; carNumber: string; isCompact: boolean; @@ -17,6 +18,7 @@ export const initApplyFormValue = { email: '', studentName: '', affiliation: '', + department: '', section: 0, carNumber: '', isCompact: false, diff --git a/service-manager/src/apis/dtos/registration.dto.ts b/service-manager/src/apis/dtos/registration.dto.ts index 364fae1b..c2ab8b22 100644 --- a/service-manager/src/apis/dtos/registration.dto.ts +++ b/service-manager/src/apis/dtos/registration.dto.ts @@ -1,5 +1,6 @@ interface Registration { affiliation: string; + department: string; sectorNum: string; carNum: string; email: string; @@ -19,6 +20,7 @@ export class RegistrationResponse { isCompact: boolean; carNumber: string; affiliation: string; + department: string; sectorNum: string; constructor(data: Registration) { @@ -30,6 +32,7 @@ export class RegistrationResponse { this.isCompact = data.isLight; this.carNumber = data.carNum; this.affiliation = data.affiliation; + this.department = data.department; this.sectorNum = data.sectorNum; } } diff --git a/service-manager/src/components/apply-list/ApplyList.tsx b/service-manager/src/components/apply-list/ApplyList.tsx index c3b46fcc..45afc940 100644 --- a/service-manager/src/components/apply-list/ApplyList.tsx +++ b/service-manager/src/components/apply-list/ApplyList.tsx @@ -1,11 +1,12 @@ +import { useState } from 'react'; import { Button } from '@quokka/design-system'; + import { useAllRegistrationQuery, useTransmitEmail, } from '../../hooks/react-query/useRegistration'; -import { useState } from 'react'; -import { ApplyCount } from './ApplyCount'; import { useSectorQueryById } from '../../hooks/react-query/useSetting'; +import { ApplyCount } from './ApplyCount'; interface ApplyListProps { eventId: string; @@ -13,6 +14,7 @@ interface ApplyListProps { export const ApplyList = ({ eventId }: ApplyListProps) => { const { registrations } = useAllRegistrationQuery(eventId); + const sectors = Array.from( new Set(registrations.map((registration) => registration.sectorNum)), ).sort(); @@ -31,6 +33,7 @@ export const ApplyList = ({ eventId }: ApplyListProps) => { 구간: registration.sectorNum, 순서: index + 1, 이름: registration.name, + 학과: registration.department, 차량번호: registration.carNumber, 학생번호: registration.studentNumber, 경차여부: registration.isCompact ? '경차' : '경차 아님', @@ -84,9 +87,11 @@ export const ApplyList = ({ eventId }: ApplyListProps) => { 순서 이름 + 단과 대학 + 학과 차량 번호 - 학생번호 - 경차여부 + 학생 번호 + 경차 여부 휴대폰 번호 이메일 @@ -105,6 +110,8 @@ export const ApplyList = ({ eventId }: ApplyListProps) => { ) + 1} {registration.name} + {registration.affiliation} + {registration.department} {registration.carNumber} {registration.studentNumber} {registration.isCompact ? '경차' : '경차 아님'}