diff --git a/src/pages/input-page/auth/components/Agreement.jsx b/src/pages/input-page/auth/components/Agreement.jsx
index b63aac4..08af65f 100644
--- a/src/pages/input-page/auth/components/Agreement.jsx
+++ b/src/pages/input-page/auth/components/Agreement.jsx
@@ -29,14 +29,14 @@ const AGREEMENT_ITEMS = [
},
{
id: "thirdParty",
- type: "선택",
+ type: "필수",
label: "개인정보 제3자 제공에 동의합니다.",
modalTitle: "Pertineo 개인정보 제3자 제공 동의서",
url: "https://d2qlxukzyb0szn.cloudfront.net/terms-of-service/v1/third-party-data-sharing.html",
},
];
-const REQUIRED_IDS = ["terms", "privacy", "policy"];
+const REQUIRED_IDS = ["terms", "privacy", "policy", "thirdParty"];
const AGREEMENT_CHECKED_KEY = "agreementChecked";
function Agreement({ isEmailVerified = false, email = "" }) {
diff --git a/src/pages/input-page/company/layouts/CompanySection.jsx b/src/pages/input-page/company/layouts/CompanySection.jsx
index 915eebc..f35a2e3 100644
--- a/src/pages/input-page/company/layouts/CompanySection.jsx
+++ b/src/pages/input-page/company/layouts/CompanySection.jsx
@@ -3,7 +3,10 @@ import { useNavigate } from "react-router-dom";
import EntrySection from "../components/EntrySection";
import Button from "../../components/Button";
import TempSaveModal from "../../components/TempSaveModal";
-import { useFetchCompanies, useFetchPositions } from "api/setupApi";
+import {
+ useFetchCompanies,
+ // useFetchPositions
+} from "api/setupApi";
function CompanySection() {
const navigate = useNavigate();
@@ -11,10 +14,10 @@ function CompanySection() {
// API 자동완성 데이터
const { data: companiesData } = useFetchCompanies();
- const { data: positionsData } = useFetchPositions();
+ // const { data: positionsData } = useFetchPositions();
const companiesList = useMemo(() => companiesData?.data?.list ?? [], [companiesData]);
- const positionsList = useMemo(() => positionsData?.data?.list ?? [], [positionsData]);
+ // const positionsList = useMemo(() => positionsData?.data?.list ?? [], [positionsData]);
// 1. 상태 정의
const [companyName, setCompanyName] = useState(() => sessionStorage.getItem('company_companyName') || '');
@@ -48,7 +51,6 @@ function CompanySection() {
caption="지원 회사명"
value={companyName}
onChange={setCompanyName}
- placeholder="pertineo"
width={530}
required={true}
autocompleteResults={companyResults}
@@ -58,11 +60,10 @@ function CompanySection() {
caption="지원 직무"
value={jobTitle}
onChange={setJobTitle}
- placeholder="소프트웨어 엔지니어"
width={530}
required={true}
- autocompleteResults={positionsList}
- selectOnly={true}
+ // autocompleteResults={positionsList}
+ // selectOnly={true}
/>
@@ -70,7 +71,6 @@ function CompanySection() {
caption="지원 공고 사이트 URL"
value={noticeUrl}
onChange={setNoticeUrl}
- placeholder="https://pertineo.khu.ac.kr/"
width={1080}
/>
diff --git a/src/pages/input-page/resume/layouts/ResumeSection.jsx b/src/pages/input-page/resume/layouts/ResumeSection.jsx
index b447d9e..449faac 100644
--- a/src/pages/input-page/resume/layouts/ResumeSection.jsx
+++ b/src/pages/input-page/resume/layouts/ResumeSection.jsx
@@ -144,6 +144,49 @@ function ResumeSection() {
);
};
+ // GPA 범위 검증 함수
+ const validateGPA = (gpa) => {
+ if (!gpa) return null;
+ const gpaNum = parseFloat(gpa);
+ if (isNaN(gpaNum)) return "범위가 벗어났습니다";
+ if (gpaNum < 0.0 || gpaNum > 4.3) return "범위가 벗어났습니다";
+ return null;
+ };
+
+ // 각 education 행의 GPA 에러 상태
+ const educationGPAErrors = education.map((row) => validateGPA(row.gpa));
+
+ // Education 변경 핸들러 (GPA 필터링 포함)
+ const handleEducationChange = (newEducation) => {
+ const filteredEducation = newEducation.map((row) => {
+ let gpa = row.gpa;
+
+ // 숫자와 첫 번째 점 이외의 모든 것 제거
+ let numericPart = '';
+ let hasDot = false;
+
+ for (let char of gpa) {
+ if (char === '.' && !hasDot) {
+ numericPart += '.';
+ hasDot = true;
+ } else if (/[0-9]/.test(char)) {
+ numericPart += char;
+ }
+ }
+
+ // 점으로 시작하는 경우만 제거 (끝나는 경우는 허용)
+ if (numericPart.startsWith('.')) {
+ numericPart = numericPart.slice(1);
+ }
+
+ return {
+ ...row,
+ gpa: numericPart
+ };
+ });
+ setEducation(filteredEducation);
+ };
+
// 행별 자동완성 결과 동적 계산
const eduAutocomplete = useMemo(() => {
return education.map((row) => ({
@@ -168,10 +211,17 @@ function ResumeSection() {
// 학력사항(required)의 필수 필드가 모두 입력된 경우에만 다음 버튼 활성화
const canProceed = education.every(
- (row) =>
- row.university?.trim() !== "" &&
- row.major?.trim() !== "" &&
- row.gpa?.trim() !== "",
+ (row) => {
+ const gpa = parseFloat(row.gpa);
+ return (
+ row.university?.trim() !== "" &&
+ row.major?.trim() !== "" &&
+ row.gpa?.trim() !== "" &&
+ !isNaN(gpa) &&
+ gpa >= 0.0 &&
+ gpa <= 4.3
+ );
+ }
);
return (
@@ -183,7 +233,7 @@ function ResumeSection() {