diff --git a/src/api/resumes.ts b/src/api/resumes.ts index 68fc3e9c..3488b67c 100644 --- a/src/api/resumes.ts +++ b/src/api/resumes.ts @@ -130,3 +130,16 @@ export const deleteEtcLanguageLevel = async (id: number) => { return response.data; }; +// 9.1 (유학생) 학교 검색하기 +export const getSearchSchools = async ({ + search, + page, + size +}:{ + search: string; + page: string; + size: string; +}) => { + const response = await api.get(`/api/v1/users/schools/brief?search=${search}&page=${page}&size=${size}`); + return response.data; +}; \ No newline at end of file diff --git a/src/assets/icons/ManageResume/GraySearchIcon.svg b/src/assets/icons/ManageResume/GraySearchIcon.svg new file mode 100644 index 00000000..fd7ce72c --- /dev/null +++ b/src/assets/icons/ManageResume/GraySearchIcon.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/components/ManageResume/ResumeEditSection.tsx b/src/components/ManageResume/ResumeEditSection.tsx index 2cc7a402..27e09d16 100644 --- a/src/components/ManageResume/ResumeEditSection.tsx +++ b/src/components/ManageResume/ResumeEditSection.tsx @@ -41,10 +41,6 @@ const ResumeEditSection = ({ // 삭제 핸들러 (데이터 삭제 시 해당 API 호출) const handleDeleteIntroduction = () => { deleteIntroductionMutation.mutate(undefined, { - onSuccess: () => { - console.log('Introduction 삭제'); - // 필요 시 상태 업데이트나 추가 로직 실행 - }, onError: (error) => { console.error('Introduction 삭제 실패', error); }, @@ -53,9 +49,6 @@ const ResumeEditSection = ({ const handleDeleteEducation = (id: number) => { deleteEducationMutation.mutate(id, { - onSuccess: () => { - console.log(`Education 삭제: ${id}`); - }, onError: (error) => { console.error(`Education 삭제 실패: ${id}`, error); }, @@ -64,10 +57,6 @@ const ResumeEditSection = ({ const handleDeleteWorkExperience = (id: number) => { deleteWorkExperienceMutation.mutate(id, { - onSuccess: () => { - console.log(`Work experience 삭제: ${id}`); - // 필요 시 상태 업데이트나 추가 로직 실행 - }, onError: (error) => { console.error(`Work experience 삭제 실패: ${id}`, error); }, diff --git a/src/components/Profile/EditProfilePicture.tsx b/src/components/Profile/EditProfilePicture.tsx index 254f7102..989f37cc 100644 --- a/src/components/Profile/EditProfilePicture.tsx +++ b/src/components/Profile/EditProfilePicture.tsx @@ -24,7 +24,6 @@ const EditProfilePicture = ({ // 파일이 이미지 형식인지 확인 if (file && file.type.startsWith('image/')) { onImageUpdate(file); - // console.log('components : ' + file); const objectUrl = URL.createObjectURL(file); // 이미지 미리보기 URL 생성 setImagePreviewUrl(objectUrl); // 미리보기 URL 업데이트 diff --git a/src/components/SetEducation/EducationPatch.tsx b/src/components/SetEducation/EducationPatch.tsx new file mode 100644 index 00000000..2f8295f7 --- /dev/null +++ b/src/components/SetEducation/EducationPatch.tsx @@ -0,0 +1,157 @@ +import { InputType } from '@/types/common/input'; +import Input from '@/components/Common/Input'; +import Dropdown from '@/components/Common/Dropdown'; +import { PostEducationType } from '@/types/postResume/postEducation'; +import { EducationLevels } from '@/constants/manageResume'; +import GraySearchIcon from '@/assets/icons/ManageResume/GraySearchIcon.svg?react'; +import { useState } from 'react'; +import SearchSchools from '@/components/SetEducation/SearchSchools'; +import { School } from '@/types/api/document'; + +type EducationPatchProps = { + educationData: PostEducationType; + setEducationData: React.Dispatch>; + schoolData: School; +}; + +const EducationPatch = ({ + educationData, + setEducationData, + schoolData, +}: EducationPatchProps) => { + const [searchOpen, setSearchOpen] = useState(false); + const [school, setSchool] = useState(schoolData); + + const handleSchoolChange = (school: School) => { + setSchool(school); + }; + + const handleInputChange = ( + field: keyof PostEducationType, + value: string | number, + ) => { + setEducationData((prev) => ({ ...prev, [field]: value })); + }; + + const handleDateChange = ( + field: 'start_date' | 'end_date', + value: string, + ) => { + handleInputChange(field, value.replace(/\//g, '-')); + }; + + return ( + <> + {searchOpen && ( + + )} + + Modify Education + {/* 교육 기관 타입 선택 */} + + + Education Levels* + + + handleInputChange('education_level', value)} + /> + + {/* absolute 만큼의 공간 차지 */} + + {/* 학교명 선택 */} + + + Name Of School* + + setSearchOpen(true)} + > + + {/* 선택되었다면, 선택한 학교명 */} + + {school ? school.name : 'Search Name of school'} + + + + {/* 전공 입력 */} + + + Department (major)* + + handleInputChange('major', value)} + canDelete={false} + /> + + {/* 학년 입력 */} + + + Grade* + + handleInputChange('grade', value)} + canDelete={false} + /> + + {/* 학점 입력 */} + + + Credit* + + handleInputChange('gpa', value)} + canDelete={false} + /> + + {/* 입학 날짜 입력 */} + + + Entrance Date * + + handleDateChange('start_date', value)} + /> + + {/* 졸업 날짜 입력 */} + + + Graduation Date * + + handleDateChange('end_date', value)} + /> + + + > + ); +}; + +export default EducationPatch; diff --git a/src/components/SetEducation/EducationPost.tsx b/src/components/SetEducation/EducationPost.tsx new file mode 100644 index 00000000..77bfc3b5 --- /dev/null +++ b/src/components/SetEducation/EducationPost.tsx @@ -0,0 +1,155 @@ +import { InputType } from '@/types/common/input'; +import Input from '@/components/Common/Input'; +import Dropdown from '@/components/Common/Dropdown'; +import { InitailEducationType } from '@/types/postResume/postEducation'; +import { EducationLevels } from '@/constants/manageResume'; +import GraySearchIcon from '@/assets/icons/ManageResume/GraySearchIcon.svg?react'; +import { useState } from 'react'; +import SearchSchools from '@/components/SetEducation/SearchSchools'; +import { School } from '@/types/api/document'; + +type EducationPostProps = { + educationData: InitailEducationType; + setEducationData: React.Dispatch>; +}; + +const EducationPost = ({ + educationData, + setEducationData, +}: EducationPostProps) => { + const [searchOpen, setSearchOpen] = useState(false); + const [school, setSchool] = useState(); + + const handleSchoolChange = (school: School) => { + setSchool(school); + }; + + const handleInputChange = ( + field: keyof InitailEducationType, + value: string | number, + ) => { + setEducationData((prev) => ({ ...prev, [field]: value })); + }; + + const handleDateChange = ( + field: 'start_date' | 'end_date', + value: string, + ) => { + handleInputChange(field, value.replace(/\//g, '-')); + }; + + return ( + <> + {searchOpen && ( + + )} + + Add Education + {/* 교육 기관 타입 선택 */} + + + Education Levels* + + + handleInputChange('education_level', value)} + /> + + {/* absolute 만큼의 공간 차지 */} + + {/* 학교명 선택 */} + + + Name Of School* + + setSearchOpen(true)} + > + + {/* 선택되었다면, 선택한 학교명 */} + + {school ? school.name : 'Search Name of school'} + + + + {/* 전공 입력 */} + + + Department (major)* + + handleInputChange('major', value)} + canDelete={false} + /> + + {/* 학년 입력 */} + + + Grade* + + handleInputChange('grade', value)} + canDelete={false} + /> + + {/* 학점 입력 */} + + + Credit* + + handleInputChange('gpa', value)} + canDelete={false} + /> + + {/* 입학 날짜 입력 */} + + + Entrance Date * + + handleDateChange('start_date', value)} + /> + + {/* 졸업 날짜 입력 */} + + + Graduation Date * + + handleDateChange('end_date', value)} + /> + + + > + ); +}; + +export default EducationPost; diff --git a/src/components/SetEducation/SearchSchools.tsx b/src/components/SetEducation/SearchSchools.tsx new file mode 100644 index 00000000..bedb6338 --- /dev/null +++ b/src/components/SetEducation/SearchSchools.tsx @@ -0,0 +1,129 @@ +import { useState, useEffect } from 'react'; +import BaseHeader from '@/components/Common/Header/BaseHeader'; +import Input from '@/components/Common/Input'; +import { InputType } from '@/types/common/input'; +import Button from '@/components/Common/Button'; +import { buttonTypeKeys } from '@/constants/components'; +import { School } from '@/types/api/document'; +import { SearchSchollsList } from '@/constants/manageResume'; +import { InitailEducationType } from '@/types/postResume/postEducation'; +// import { useGetSearchSchools } from '@/hooks/api/useResume'; + +type SearchSchoolsProps = { + setSchool: (school: School) => void; + setSearchOpen: (value: boolean) => void; + handleInputChange: (field: keyof InitailEducationType, value: number) => void; +}; + +const SearchSchools = ({ + setSchool, + setSearchOpen, + handleInputChange, +}: SearchSchoolsProps) => { + // 학교명 검색어 상태 관리 + const [searchSchool, setSearchSchool] = useState(''); + // 선택한 학교 상태 관리 + const [selectedSchool, setSelectedSchool] = useState(null); + + // 학교 목록의 페이지(서버 요청) + // ===== API 연결 후 주석 해제(현재 학교 더미데이터로 대체) ===== + // const [page, setPage] = useState(1); + // const size = 10; + + const schoolList = SearchSchollsList; + // ===== API 연결 후 주석 해제(현재 학교 더미데이터로 대체) ===== + // const { data: schoolList = [], isLoading } = useGetSearchSchools( + // searchSchool, + // page, + // size, + // ); + + // 선택 버튼 + const handleSubmit = () => { + if (selectedSchool) { + setSchool(selectedSchool); + setSearchOpen(false); + handleInputChange('school_id', selectedSchool.id); + } + }; + + const handleSelectSchool = (school: School) => { + setSelectedSchool(school); + }; + + const handleSearchChange = (value: string) => { + setSearchSchool(value); + + // ===== API 연결 후 주석 해제(현재 학교 더미데이터로 대체) ===== + // setPage(1); // 새로운 검색어가 들어오면 페이지를 초기화 + }; + + // 모달이 열렸을 떄 스크롤 방지 + useEffect(() => { + document.body.style.overflow = 'hidden'; + return () => { + document.body.style.overflow = ''; + }; + }, []); + + return ( + + setSearchOpen(false)} + hasMenuButton={false} + title="Education" + /> + + + Search for + + educational institutions + + setSearchSchool('')} + /> + + {/* API 연결 후 아래 주석 해제 */} + {/* {isLoading ? ( + Loading... + ) : ( */} + {/* 검색된 학교 목록 */} + { + schoolList.map((school: School) => ( + handleSelectSchool(school)} + > + {school.name} + + )) + // )} + } + + + + + + + ); +}; + +export default SearchSchools; diff --git a/src/constants/manageResume.ts b/src/constants/manageResume.ts index 1540f62c..e271901a 100644 --- a/src/constants/manageResume.ts +++ b/src/constants/manageResume.ts @@ -1,4 +1,6 @@ +import { School } from "@/types/api/document"; import { ResumeDetailItemType } from "@/types/postApply/resumeDetailItem"; +import { GetEducationType } from "@/types/postResume/postEducation"; export const enum ManageResumeType { VISA = 'VISA', @@ -9,6 +11,8 @@ export const enum ManageResumeType { LANGUAGE = 'Language', } +export const EducationLevels = ['BACHELOR','ASSOCIATE', 'HIGHSCHOOL']; + // 더미데이터 - TODO : 연결 후 삭제 export const ResumeData: ResumeDetailItemType = { profile_img_url: @@ -83,4 +87,47 @@ export const ResumeData: ResumeDetailItemType = { }, ], }, +}; + +export const SearchSchollsList: School[] = [ + { id: 1, name: 'University of Oxford', phone_number: '000-0000' }, + { + id: 2, + name: 'National University of Lesotho International School', + phone_number: '000-0000', + }, + { id: 3, name: 'University of Chester CE Academy', phone_number: '000-0000' }, + { + id: 4, + name: 'University of Chester Academy Northwich', + phone_number: '000-0000', + }, + { id: 5, name: 'University of Birmingham School', phone_number: '000-0000' }, + { id: 6, name: 'University of Oxford', phone_number: '000-0000' }, + { + id: 7, + name: 'National University of Lesotho International School', + phone_number: '000-0000', + }, + { id: 8, name: 'University of Chester CE Academy', phone_number: '000-0000' }, + { + id: 9, + name: 'University of Chester Academy Northwich', + phone_number: '000-0000', + }, + { id: 10, name: 'University of Birmingham School', phone_number: '000-0000' }, +]; + +export const GetEducationData: GetEducationType = { + education_level: 'BACHELOR', // Enum(BACHELOR, ASSOCIATE, HIGHSCHOOL), + school:{ + id: 1, + name: 'University of Chester Academy Northwich', + phone_number: '000-0000' + }, + major: 'Department of Computer Engineering', + gpa: 3.5, + start_date: '2021-03-01', // yyyy-MM-dd + end_date: '2026-03-01', // yyyy-MM-dd + grade: 4, }; \ No newline at end of file diff --git a/src/hooks/api/useResume.ts b/src/hooks/api/useResume.ts index 5dd0ba4f..59de581e 100644 --- a/src/hooks/api/useResume.ts +++ b/src/hooks/api/useResume.ts @@ -1,4 +1,4 @@ -import { deleteEducation, deleteEtcLanguageLevel, deleteIntroduction, deleteWorkExperience, getEducation, getLanguagesSummaries, getResume, getWorkExperience, patchIntroduction, patchWorkExperience, postEducation, postEtcLanguageLevel, postWorkExperience } from "@/api/resumes"; +import { deleteEducation, deleteEtcLanguageLevel, deleteIntroduction, deleteWorkExperience, getEducation, getLanguagesSummaries, getResume, getSearchSchools, getWorkExperience, patchIntroduction, patchWorkExperience, postEducation, postEtcLanguageLevel, postWorkExperience } from "@/api/resumes"; import { useMutation, useQuery } from "@tanstack/react-query"; import { useNavigate } from "react-router-dom"; @@ -30,9 +30,6 @@ export const useDeleteIntroduction = () => { export const useDeleteWorkExperience = () => { return useMutation({ mutationFn: deleteWorkExperience, - onSuccess: () => { - console.log('경력 삭제 성공'); - }, onError: (error) => { console.error('경력 삭제 실패', error); }, @@ -43,9 +40,6 @@ export const useDeleteWorkExperience = () => { export const useDeleteEducation = () => { return useMutation({ mutationFn: deleteEducation, - onSuccess: () => { - console.log('학력 삭제 성공'); - }, onError: (error) => { console.error('학력 삭제 실패', error); }, @@ -166,13 +160,19 @@ export const usePostEtcLanguageLevel = () => { export const useDeleteEtcLanguageLevel = () => { return useMutation({ mutationFn: deleteEtcLanguageLevel, - onSuccess: () => { - console.log('ETC 삭제 성공'); - }, onError: (error) => { console.error('ETC 삭제 실패', error); }, }); }; -// TODO: ETC 수정하기 추가 \ No newline at end of file +// TODO: ETC 수정하기 추가 + +// 9.1 (유학생) 학교 검색하기 +export const useGetSearchSchools = (search: string, page: number, size: number) => { + return useQuery({ + queryKey: ['searchSchools', search, page, size], + queryFn: () => getSearchSchools({ search, page: page.toString(), size: size.toString() }), + enabled: !!search, // 검색어가 있을 때만 쿼리 활성화 + }); +}; \ No newline at end of file diff --git a/src/pages/Introduction/IntroductionPage.tsx b/src/pages/Introduction/IntroductionPage.tsx index a4e0b70b..e3ae896b 100644 --- a/src/pages/Introduction/IntroductionPage.tsx +++ b/src/pages/Introduction/IntroductionPage.tsx @@ -33,7 +33,6 @@ const IntroductionPage = () => { const handleSubmit = () => { // TODO: API - 7.8 (유학생) 자기소개 수정하기 - // console.log('introduction : ' + data); navigate('/profile/manage-resume'); }; diff --git a/src/pages/Profile/EditProfilePage.tsx b/src/pages/Profile/EditProfilePage.tsx index 4d1ad275..db7c276d 100644 --- a/src/pages/Profile/EditProfilePage.tsx +++ b/src/pages/Profile/EditProfilePage.tsx @@ -54,7 +54,6 @@ const EditProfilePage = () => { profileImage, Boolean(profileImage), // 이미지 변경 여부 확인 ); - // console.log('transformedData: ', transformedData); try { const formData = new FormData(); @@ -70,14 +69,6 @@ const EditProfilePage = () => { type: 'application/json', }), ); - /* - const response = await axios.patch('/api/v1/users', formData, { - headers: { - 'Content-Type': 'multipart/form-data', - }, - }); - console.log('API 성공:', response.data); - */ navigate('/profile'); } catch (error) { console.error('API 호출 중 에러 발생:', error); @@ -117,7 +108,7 @@ const EditProfilePage = () => { hasMenuButton={false} title="Edit Profile" /> - + { - + { - return PatchEducationPage; + const handleBackButtonClick = useNavigateBack(); + const navigate = useNavigate(); + const [educationData, setEducationData] = useState({ + education_level: 'BACHELOR', + school_id: 0, + major: '', + gpa: 0, + start_date: '', + end_date: '', + grade: 2, + }); + + // get form의 학력 데이터 + const [fetchData, setFetchData] = useState(); + + // reset 버튼을 대비하여 patch form 의 초기 데이터를 저장하는 상태 + const [initialData, setInitialData] = useState(); + + // 초기 값에서 수정된 내용이 있는지 확인 + const [isEditing, setIsEditing] = useState(false); + + const handleSubmit = () => { + // TODO: API - 7.6 학력 생성하기 + navigate('/profile/manage-resume'); + }; + + const handleReset = () => { + // Reset 버튼 클릭 시 초기 데이터로 되돌리기 + if (initialData) setEducationData(initialData); + }; + + // TODO: API - 7.3 학력 상세 조회하기 + // Get API 연결 + useEffect(() => { + const fetchDataFromApi = async () => { + const data = GetEducationData; + setFetchData(data); + + // patch 타입 initialData 설정 + const transformedData = transformToPostEducation(data); + setInitialData(transformedData); + }; + + fetchDataFromApi(); + }, []); + + // initialData가 설정된 후에 educationData를 설정 + useEffect(() => { + if (initialData) { + setEducationData(initialData); + } + }, [initialData]); + + // 편집 중인지 여부 확인 + useEffect(() => { + if (educationData == initialData) { + setIsEditing(false); + } else { + setIsEditing(true); + } + }, [educationData]); + + return ( + <> + {fetchData ? ( + <> + + + + + + + + + > + ) : ( + 로딩 중 + )} + > + ); }; export default PatchEducationPage; diff --git a/src/pages/SetEducation/PostEducationPage.tsx b/src/pages/SetEducation/PostEducationPage.tsx index 4f044347..854a2f40 100644 --- a/src/pages/SetEducation/PostEducationPage.tsx +++ b/src/pages/SetEducation/PostEducationPage.tsx @@ -1,5 +1,66 @@ +import { useState, useEffect } from 'react'; +import { useNavigate } from 'react-router-dom'; +import BaseHeader from '@/components/Common/Header/BaseHeader'; +import Button from '@/components/Common/Button'; +import EducationPost from '@/components/SetEducation/EducationPost'; +import { buttonTypeKeys } from '@/constants/components'; +import useNavigateBack from '@/hooks/useNavigateBack'; +import { InitailEducationType } from '@/types/postResume/postEducation'; +import { isPostEducationType } from '@/utils/introduction'; + +// input 기본값 설정 +const InitailEducation = (): InitailEducationType => ({ + education_level: '', + school_id: 0, + major: '', + gpa: 0.0, + start_date: '', + end_date: '', + grade: 0, +}); + const PostEducationPage = () => { - return PostEducationPage; + const handleBackButtonClick = useNavigateBack(); + const navigate = useNavigate(); + const [educationData, setEducationData] = + useState(InitailEducation()); + const [isValid, setIsValid] = useState(false); + + const handleSubmit = () => { + // TODO: API - 7.6 학력 생성하기 + navigate('/profile/manage-resume'); + }; + + useEffect(() => { + setIsValid(isPostEducationType(educationData)); + }, [educationData]); + + return ( + <> + + + + + + + + > + ); }; export default PostEducationPage; diff --git a/src/pages/SetWorkExperience/PatchWorkExperiencePage.tsx b/src/pages/SetWorkExperience/PatchWorkExperiencePage.tsx index 2a88196a..92d67a28 100644 --- a/src/pages/SetWorkExperience/PatchWorkExperiencePage.tsx +++ b/src/pages/SetWorkExperience/PatchWorkExperiencePage.tsx @@ -70,18 +70,20 @@ const PatchWorkExperiencePage = () => { return ( - - {/* input 영역 */} - - + + + {/* input 영역 */} + + + {/* 리셋 버튼 */} { return ( - - {/* input 컴포넌트 */} - - + + + {/* input 컴포넌트 */} + + + {/* post 버튼 */} { const handleSignUp = async () => { // 임의 로직 API 연동 후 삭제 handleSignUpClick(); - - /* - try { - const response = await axios.post('/api/v1/auth/sign-up', { - id: id, - password: password, - email: email, - account_type: accountType, - }); - - if (response.status === 200) { - // 이메일 인증 요청 성공 시 인증 단계로 이동 - handleSignUpClick(); - } else { - console.error('이메일 인증 실패:', response.statusText); - } - } catch (error) { - if (axios.isAxiosError(error)) { - console.error('이메일 인증 중 오류 발생:', error.message); - } else { - console.error('예상치 못한 오류 발생:', error); - } - } - */ }; // API - 2.7 이메일 인증코드 검증 const handleVerify = async () => { // 임의 로직 API 연동 후 삭제 handleSignUpClick(); - - /* - try { - const response = await axios.patch( - '/api/v1/auth/validations/authentication-code', - { - id: id, - password: password, - email: email, - authentication_code: authenticationCode, - }, - ); - - if (response.status === 200) { - const { temporary_token } = response.data; - console.log('인증 성공, 임시 토큰:', temporary_token); - handleSignUpClick(); - } else { - console.error('이메일 인증 실패:', response.statusText); - } - } catch (error) { - if (axios.isAxiosError(error)) { - console.error('이메일 인증 중 오류 발생:', error.message); - alert('이메일 인증 실패: ' + error.response?.data?.message); - } else { - console.error('예상치 못한 오류 발생:', error); - } - } - */ }; return ( diff --git a/src/types/postResume/postEducation.ts b/src/types/postResume/postEducation.ts new file mode 100644 index 00000000..844b96eb --- /dev/null +++ b/src/types/postResume/postEducation.ts @@ -0,0 +1,32 @@ +import { School } from "@/types/api/document" +import { EducationLevelType } from "@/types/postApply/resumeDetailItem" + +export type PostEducationType = { + education_level : EducationLevelType // Enum(BACHELOR, ASSOCIATE, HIGHSCHOOL), + school_id : number, + major : string, + gpa : number, + start_date : string // yyyy-MM-dd + end_date : string // yyyy-MM-dd + grade : number +} + +export type GetEducationType = { + education_level : EducationLevelType // Enum(BACHELOR, ASSOCIATE, HIGHSCHOOL), + school: School, + major : string, + gpa : number, + start_date : string // yyyy-MM-dd + end_date : string // yyyy-MM-dd + grade : number +} + +export type InitailEducationType = { + education_level : EducationLevelType | '' // Enum(BACHELOR, ASSOCIATE, HIGHSCHOOL), + school_id : number, + major : string, + gpa : number, + start_date : string // yyyy-MM-dd + end_date : string // yyyy-MM-dd + grade : number +} diff --git a/src/utils/editResume.ts b/src/utils/editResume.ts index f5f4186d..53997252 100644 --- a/src/utils/editResume.ts +++ b/src/utils/editResume.ts @@ -1,4 +1,5 @@ import { MypageCardData } from "@/types/manageResume/manageResume"; +import { GetEducationType, PostEducationType } from "@/types/postResume/postEducation"; export const isEmptyData = (data: MypageCardData) => { return ( @@ -19,4 +20,18 @@ export const formatDate = (dateString: string) => { // 날짜 형식 포맷팅(서버 데이터와 랜딩되는 데이터간의 변환 export const formatDateToDash = (date: string) => date.replace(/\//g, '-'); -export const formatDateToSlash = (date: string) => date.replace(/-/g, '/'); \ No newline at end of file +export const formatDateToSlash = (date: string) => date.replace(/-/g, '/'); + + +// 변환 함수 +export const transformToPostEducation = (data: GetEducationType): PostEducationType => { + return { + education_level: data.education_level, + school_id: data.school.id, // school 객체에서 id 추출 + major: data.major, + gpa: data.gpa, + start_date: data.start_date, + end_date: data.end_date, + grade: data.grade, + }; +}; \ No newline at end of file diff --git a/src/utils/introduction.ts b/src/utils/introduction.ts new file mode 100644 index 00000000..10126616 --- /dev/null +++ b/src/utils/introduction.ts @@ -0,0 +1,31 @@ +import { EducationLevels } from "@/constants/manageResume"; +import { InitailEducationType } from "@/types/postResume/postEducation"; + +export const isPostEducationType = (data?: InitailEducationType) => { + if (!data) return false; + const { + education_level, + school_id, + major, + gpa, + start_date, + end_date, + grade, + } = data; + + return ( + // 학력 input 유효성 검사 + Object.values(EducationLevels).includes(education_level) && // education_level이 유효한 값인지 확인 + school_id > 0 && + typeof major === 'string' && + major.trim() !== '' && + typeof gpa === 'string' && + !isNaN(parseFloat(gpa)) && + parseFloat(gpa) >= 0 && + start_date.trim() !== '' && + end_date.trim() !== '' && + typeof grade === 'string' && + !isNaN(parseInt(grade)) && + parseInt(gpa) > 0 + ); +};
+ Education Levels* +
+ Name Of School* +
+ {school ? school.name : 'Search Name of school'} +
+ Department (major)* +
+ Grade* +
+ Credit* +
+ Entrance Date * +
+ Graduation Date * +