From 89ebc8793f75e5e574dcc08f3478c0f50c672d0b Mon Sep 17 00:00:00 2001 From: naarang Date: Mon, 20 Jan 2025 16:09:26 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20fix:=20constant=EB=A1=9C=20?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=EB=90=98=EC=96=B4=20=EC=9E=88=EB=8D=98=20?= =?UTF-8?q?=EB=B6=80=EB=B6=84=20=EB=B3=80=EC=88=98=ED=99=94=20#127?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Common/Input.tsx | 18 +- src/components/Document/DocumentCard.tsx | 17 +- .../write/IntegratedApplicationPreview.tsx | 2 +- .../DocumentCardDispenserEmployer.tsx | 167 +++++++++--------- src/components/Employer/PostCreate/Step1.tsx | 14 +- .../EmployerLaborContractForm.tsx | 4 + .../EmployerPartTimePermitForm.tsx | 6 +- .../IntegratedApplicationWriteForm.tsx | 9 +- .../ApplicationDocumentsPage.tsx | 3 +- .../ApplicantDocumentsDetailPage.tsx | 9 - .../WriteDocuments/RequestModifyPage.tsx | 2 +- src/types/api/document.ts | 6 +- src/utils/document.ts | 19 +- 13 files changed, 144 insertions(+), 132 deletions(-) diff --git a/src/components/Common/Input.tsx b/src/components/Common/Input.tsx index f00f3fd..195de7e 100644 --- a/src/components/Common/Input.tsx +++ b/src/components/Common/Input.tsx @@ -18,6 +18,7 @@ type InputProps = { placeholder: string; // 플레이스홀더 텍스트 value: string | null; // 입력 필드의 현재 값 onChange: (value: string) => void; // 입력값 변경 시 호출될 함수 + onBlur?: (value: string) => boolean; // 입력 필드에서 포커스가 빠져나갈 때 호출될 함수 (선택적) canDelete: boolean; // 삭제 버튼 표시 여부 clearInvalid?: () => void; // 토글 시 invalid 상태를 해제할 함수 (선택적) isInvalid?: boolean; // 유효하지 않은 입력 상태 여부 (선택적) @@ -45,6 +46,7 @@ const Input = ({ inputType, placeholder, onChange, + onBlur, canDelete, onDelete, clearInvalid, @@ -83,6 +85,14 @@ const Input = ({ setCurrentStatus(INPUT_STATUS.DISABLED); }; + const handleBlur = (e: React.FocusEvent) => { + if (onBlur && onBlur(e.target.value) === true) { + setCurrentStatus(INPUT_STATUS.INVALID); + return; + } + setCurrentStatus(INPUT_STATUS.DISABLED); + }; + return (
handleFocus('click')} - onBlur={() => handleFocus('blur')} + onBlur={handleBlur} onChange={handleInputChange} type={ inputType === 'PASSWORD' @@ -114,7 +124,11 @@ const Input = ({ {/* 입력값 삭제 가능한 경우 삭제 아이콘을 표시합니다. */} {canDelete && } {/* 단위가 존재할 경우 표시합니다. */} - {isUnit &&
{unit}
} + {isUnit && ( +
+
{unit}
+
+ )}
); }; diff --git a/src/components/Document/DocumentCard.tsx b/src/components/Document/DocumentCard.tsx index f90d6e2..08111ef 100644 --- a/src/components/Document/DocumentCard.tsx +++ b/src/components/Document/DocumentCard.tsx @@ -288,7 +288,7 @@ const ConfirmationCard = ({
{title}
- {!documentInfo.hwp_url && !documentInfo.word_url ? ( + {!documentInfo.word_url ? ( ) : ( @@ -322,21 +322,6 @@ const ConfirmationCard = ({
)} - {documentInfo.hwp_url && ( -
-
-
- -
-
- smth file download -
-
-
onDownload(documentInfo.hwp_url as string)}> - -
-
- )} ); diff --git a/src/components/Document/write/IntegratedApplicationPreview.tsx b/src/components/Document/write/IntegratedApplicationPreview.tsx index 1a87602..d1ca938 100644 --- a/src/components/Document/write/IntegratedApplicationPreview.tsx +++ b/src/components/Document/write/IntegratedApplicationPreview.tsx @@ -142,7 +142,7 @@ const IntegratedApplicationPreview = ({ - {/* 사업등록번호 입력 */} + {/* 사업자 등록번호 입력 */} { const TemporarySaveCard = ({ title, - onNext, + onCheck, + onSubmit, onEdit, onPreview, }: { title: string; - onNext: () => void; + onCheck: () => Promise< + EmployerInformation | LaborContractEmployerInfo | null + >; + onSubmit: () => void; onEdit: () => void; onPreview: () => void; }) => { + const [isEmployerWrote, setIsEmployerWrote] = useState(null); + useEffect(() => { + const checkDocuments = async () => { + const result = await onCheck(); + setIsEmployerWrote(result !== null); + }; + checkDocuments(); + }, []); return (
@@ -110,68 +132,29 @@ const TemporarySaveCard = ({
); }; -{ - /* - const BeforeConfirmationCard = ({ title }: { title: string }) => { - return ( -
-
-
- 대기 ... -
-
-
-
-
-
{title}
-
-
- -
-
- -
-
-

유학생이 서류를 검토 중이에요.

-
-
-
- -
-
-
-
- -
-
검토 중 ...
-
-
-
-
- ); -}; - */ -} - const SubmittedCard = ({ title }: { title: string }) => { return (
@@ -213,17 +196,29 @@ const SubmittedCard = ({ title }: { title: string }) => { const RewritingCard = ({ title, - onNext, + onCheck, + onSubmit, onEdit, onPreview, reason, }: { title: string; - onNext: () => void; + onCheck: () => Promise< + EmployerInformation | LaborContractEmployerInfo | null + >; + onSubmit: () => void; onEdit: () => void; onPreview: () => void; reason: string; }) => { + const [isEmployerWrote, setIsEmployerWrote] = useState(null); + useEffect(() => { + const checkDocuments = async () => { + const result = await onCheck(); + setIsEmployerWrote(result !== null); + }; + checkDocuments(); + }, []); return (
@@ -262,19 +257,23 @@ const RewritingCard = ({
@@ -304,11 +303,7 @@ const ConfirmationCard = ({
{title}
- {!documentInfo.hwp_url && !documentInfo.word_url ? ( - - ) : ( - - )} + {!documentInfo.word_url ? : }
@@ -335,19 +330,6 @@ const ConfirmationCard = ({
)} - {documentInfo.hwp_url && ( -
-
-
- -
-
hwp로 다운로드
-
-
onDownload(documentInfo.hwp_url as string)}> - -
-
- )} ); @@ -364,14 +346,13 @@ const DocumentCardDispenserEmployer = ({ const handleDownload = (url: string) => { // 웹뷰 환경인지 체크 const isWebView = Boolean(window.ReactNativeWebView); - if (isWebView) { // 웹뷰에서는 DocumentViewer로 이동 navigate('/document-view/123', { state: { url, - filename: url.split('/').pop() // URL에서 파일명 추출 - } + filename: url.split('/').pop(), // URL에서 파일명 추출 + }, }); } else { // 웹 환경에서는 직접 다운로드 @@ -393,16 +374,41 @@ const DocumentCardDispenserEmployer = ({ setIsLoading(false); }, }); + const { mutateAsync: getPartTimeDocument } = useGetPartTimeEmployPermit({ + onSuccess: (data) => { + return data.data.employer_information; + }, + }); + const { mutateAsync: getLaborContractDocument } = useGetStandardLaborContract( + { + onSuccess: (data) => { + return data.data.employer_information; + }, + }, + ); + + const checkEmployerWriteDocuments = async () => { + if (type === DocumentType.PART_TIME_PERMIT) { + const result = await getPartTimeDocument(documentInfo.id); + return result?.data.employer_information || null; + } else { + const result = await getLaborContractDocument(documentInfo.id); + return result?.data.employer_information || null; + } + }; + if (!documentInfo.status) return ; switch (documentInfo.status) { case DocumentStatusEmployer.TEMPORARY_SAVE: return ( submitDocument(Number(documentInfo.id))} // 고용주가 서류 제출 + onCheck={checkEmployerWriteDocuments} + onSubmit={() => submitDocument(Number(documentInfo.id))} // 고용주가 서류 제출 onEdit={() => { updateCurrentDocumentId(documentInfo.id); navigate(`/employer/write-documents/${documentInfo.id}`, { + // EmployerWriteDocumentPage.tsx state: { type: type, isEdit: true, @@ -427,7 +433,8 @@ const DocumentCardDispenserEmployer = ({ submitDocument(Number(documentInfo.id))} // 고용주가 서류 제출 + onCheck={checkEmployerWriteDocuments} + onSubmit={() => submitDocument(Number(documentInfo.id))} // 고용주가 서류 제출 onEdit={() => { updateCurrentDocumentId(documentInfo.id); navigate(`/employer/write-documents/${documentInfo.id}`, { diff --git a/src/components/Employer/PostCreate/Step1.tsx b/src/components/Employer/PostCreate/Step1.tsx index 918eb3d..12b974b 100644 --- a/src/components/Employer/PostCreate/Step1.tsx +++ b/src/components/Employer/PostCreate/Step1.tsx @@ -21,7 +21,11 @@ import { } from '@/utils/post'; import WorkDayTimeBottomSheet from '@/components/Common/WorkDayTimeBottomSheet'; import { WorkDayTime, WorkPeriod } from '@/types/api/document'; -import { parseStringToSafeNumber } from '@/utils/document'; +import { + handleHourlyRateBlur, + MINIMUM_HOURLY_RATE, + parseStringToSafeNumber, +} from '@/utils/document'; import { WorkPeriodInfo, WorkPeriodNames } from '@/constants/documents'; const Step1 = ({ @@ -33,7 +37,6 @@ const Step1 = ({ }) => { // 현재 step내에서 입력받는 정보를 따로 관리할 state, 추후 다음 step으로 넘어갈 때 funnel 관리 페이지의 state로 통합된다. const [newPostInfo, setNewPostInfo] = useState(postInfo); - // 버튼 활성화 여부를 위한 플래그 const [isInvalid, setIsInvalid] = useState(true); // 근무 시간 모달 활성화 여부 위한 플래그 @@ -49,7 +52,7 @@ const Step1 = ({ job_category !== '' && work_day_times.length && work_period !== '' && - hourly_rate !== 0; + hourly_rate >= MINIMUM_HOURLY_RATE; setIsInvalid(!isFormValid); }, [newPostInfo]); @@ -134,12 +137,15 @@ const Step1 = ({ }, }) } + onBlur={() => + handleHourlyRateBlur(String(newPostInfo.body.hourly_rate)) + } canDelete={false} isUnit unit="원" />
- 2024년 기준 최저시급은 9,860원입니다. + 2025년 기준 최저시급은 10,030원입니다.
{/* 타입 선택 */} diff --git a/src/components/Employer/WriteDocument/EmployerLaborContractForm.tsx b/src/components/Employer/WriteDocument/EmployerLaborContractForm.tsx index 50fa5a9..8d85336 100644 --- a/src/components/Employer/WriteDocument/EmployerLaborContractForm.tsx +++ b/src/components/Employer/WriteDocument/EmployerLaborContractForm.tsx @@ -24,6 +24,7 @@ import BottomButtonPanel from '@/components/Common/BottomButtonPanel'; import Button from '@/components/Common/Button'; import { usePutLaborContractEmployer } from '@/hooks/api/useDocument'; import { + handleHourlyRateBlur, parseStringToSafeNumber, validateLaborContractEmployerInformation, } from '@/utils/document'; @@ -432,6 +433,9 @@ const EmployerLaborContractForm = ({ hourly_rate: parseStringToSafeNumber(value), }) } + onBlur={() => + handleHourlyRateBlur(String(newDocumentData.hourly_rate)) + } canDelete={false} isUnit unit="원" diff --git a/src/components/Employer/WriteDocument/EmployerPartTimePermitForm.tsx b/src/components/Employer/WriteDocument/EmployerPartTimePermitForm.tsx index 76d6bcf..4a2b0e3 100644 --- a/src/components/Employer/WriteDocument/EmployerPartTimePermitForm.tsx +++ b/src/components/Employer/WriteDocument/EmployerPartTimePermitForm.tsx @@ -22,6 +22,7 @@ import Button from '@/components/Common/Button'; import { usePutPartTimeEmployPermitEmployer } from '@/hooks/api/useDocument'; import { useParams } from 'react-router-dom'; import { + handleHourlyRateBlur, parseStringToSafeNumber, validateEmployerInformation, } from '@/utils/document'; @@ -352,12 +353,15 @@ const EmployerPartTimePermitForm = ({ hourly_rate: parseStringToSafeNumber(value), }) } + onBlur={() => + handleHourlyRateBlur(String(newDocumentData.hourly_rate)) + } canDelete={false} isUnit unit="원" />
- 2024년 기준 최저시급은 9,860원입니다. + 2025년 기준 최저시급은 10,030원입니다.
{/* 근무 시간(평일) 입력 */} diff --git a/src/components/WriteDocuments/IntegratedApplicationWriteForm.tsx b/src/components/WriteDocuments/IntegratedApplicationWriteForm.tsx index 92a42ab..32d1c77 100644 --- a/src/components/WriteDocuments/IntegratedApplicationWriteForm.tsx +++ b/src/components/WriteDocuments/IntegratedApplicationWriteForm.tsx @@ -24,7 +24,7 @@ import { usePostIntegratedApplicants, usePutIntegratedApplicants, } from '@/hooks/api/useDocument'; -import { formatPhoneNumber, parsePhoneNumber } from '@/utils/information'; +import { formatCompanyRegistrationNumber, formatPhoneNumber, parsePhoneNumber } from '@/utils/information'; import { useCurrentPostIdEmployeeStore } from '@/store/url'; import LoadingItem from '../Common/LoadingItem'; import { useAddressSearch } from '@/hooks/api/useAddressSearch'; @@ -493,19 +493,20 @@ const IntegratedApplicationWriteForm = ({ canDelete={false} /> - {/* 사업등록번호 입력 */} + {/* 사업자등록번호 입력 */} setNewDocumentData({ ...newDocumentData, - new_work_place_registration_number: value, + new_work_place_registration_number: + formatCompanyRegistrationNumber(value), }) } canDelete={false} diff --git a/src/pages/ApplicationDocuments/ApplicationDocumentsPage.tsx b/src/pages/ApplicationDocuments/ApplicationDocumentsPage.tsx index c38a938..0c52bef 100644 --- a/src/pages/ApplicationDocuments/ApplicationDocumentsPage.tsx +++ b/src/pages/ApplicationDocuments/ApplicationDocumentsPage.tsx @@ -32,7 +32,8 @@ const ApplicationDocumentsPage = () => { {data?.data.part_time_employment_permits?.status === 'CONFIRMATION' && data?.data.standard_labor_contract?.status === 'CONFIRMATION' && - data?.data.integrated_application?.hwp_url ? ( + data?.data.integrated_application?.word_url && + data?.data.is_completed === false ? (