diff --git a/src/app/(main)/settings/skill/edit/page.tsx b/src/app/(main)/settings/skill/edit/page.tsx index 7834b4f..6e53ab2 100644 --- a/src/app/(main)/settings/skill/edit/page.tsx +++ b/src/app/(main)/settings/skill/edit/page.tsx @@ -1,5 +1,4 @@ import { Edit } from "@mui/icons-material"; -import { useSearchParams } from "next/navigation"; // import EditStaff from "@/components/EditStaff"; import { Suspense } from "react"; import { I18nProvider, getServerI18n } from "@/i18n"; @@ -8,10 +7,7 @@ import { Metadata } from "next"; import EditSkill from "@/components/EditSkill"; import { Typography } from "@mui/material"; import { fetchSkill } from "@/app/api/skill"; - -export interface searchParamsProps { - searchParams: { [key: string]: string | string[] | undefined }; -} +import { searchParamsProps } from "@/app/utils/fetchUtil"; const EditSkillPage: React.FC = async ({ searchParams, diff --git a/src/app/(main)/settings/staff/edit/page.tsx b/src/app/(main)/settings/staff/edit/page.tsx index 92278cf..bb2b759 100644 --- a/src/app/(main)/settings/staff/edit/page.tsx +++ b/src/app/(main)/settings/staff/edit/page.tsx @@ -6,12 +6,15 @@ import { Suspense } from "react"; import { I18nProvider } from "@/i18n"; import EditStaffWrapper from "@/components/EditStaff/EditStaffWrapper"; import { Metadata } from "next"; +import { searchParamsProps } from "@/app/utils/fetchUtil"; // export const metadata: Metadata = { // title: "staff-edit", // }; -const EditStaffPage: React.FC = () => { +const EditStaffPage: React.FC = async ({ + searchParams, +}) => { // const searchParams = useSearchParams(); // const userId = searchParams.get('param'); // console.log(userId); // Access the value of the "user_id" parameter @@ -20,7 +23,7 @@ const EditStaffPage: React.FC = () => { <> }> - + {/* */} diff --git a/src/app/api/staff/index.ts b/src/app/api/staff/index.ts index 6b15f42..b899341 100644 --- a/src/app/api/staff/index.ts +++ b/src/app/api/staff/index.ts @@ -26,6 +26,35 @@ export interface StaffTeamTable { currentPosition: string; } +export type IndivStaff = { + data: IndividualStaff +} + +export type IndividualStaff = { + id: number + staffId: string + name: string + company: data + team: data + department: data + grade: data + skill: data + skillset: any + currentPosition: data + salary: data + employType: string + email: string + phone1: string + phone2?: string + emergContactName: string; + emergContactPhone: string; + joinDate: string; + joinPosition: data; + departDate?: string; + departReason?: string; + remark?: string; +} + export interface StaffResult { action: any; id: number; @@ -35,10 +64,11 @@ export interface StaffResult { grade: string; joinPosition: string; currentPosition: string; - data: data; teamId: number; staffName: string; userId: number; + companyId: number; + data: data; } export interface searchInput { staffId: string; @@ -68,6 +98,12 @@ export const fetchStaff = cache(async () => { }); }); +export const fetchIndivStaff = cache(async (id: number) => { + return serverFetchJson(`${BASE_API_URL}/staffs/${id}`, { + next: { tags: ["staffs"] }, + }); +}); + export const fetchStaffWithoutTeam = cache(async () => { return serverFetchJson(`${BASE_API_URL}/staffs/noteam`, { next: { tags: ["staffs"] }, diff --git a/src/app/utils/fetchUtil.ts b/src/app/utils/fetchUtil.ts index 5e4533e..a97a09c 100644 --- a/src/app/utils/fetchUtil.ts +++ b/src/app/utils/fetchUtil.ts @@ -3,6 +3,10 @@ import { getServerSession } from "next-auth"; import { headers } from "next/headers"; import { redirect } from "next/navigation"; +export interface searchParamsProps { + searchParams: { [key: string]: string | string[] | undefined }; +} + export class ServerFetchError extends Error { public readonly response: Response | undefined; constructor(message?: string, response?: Response) { diff --git a/src/components/CreateStaff/StaffInfo.tsx b/src/components/CreateStaff/StaffInfo.tsx index 30aca1a..b0c072b 100644 --- a/src/components/CreateStaff/StaffInfo.tsx +++ b/src/components/CreateStaff/StaffInfo.tsx @@ -55,6 +55,7 @@ const StaffInfo: React.FC = ({ combos }) => { (acc, skill) => ({ ...acc, [skill.id]: skill.label }), {} ); + console.log(skillIdNameMap) const resetStaff = useCallback(() => { console.log(defaultValues); @@ -235,6 +236,7 @@ const StaffInfo: React.FC = ({ combos }) => { > -1} + // checked={true} /> diff --git a/src/components/EditStaff/EditStaff.tsx b/src/components/EditStaff/EditStaff.tsx index 0aa3428..4864504 100644 --- a/src/components/EditStaff/EditStaff.tsx +++ b/src/components/EditStaff/EditStaff.tsx @@ -1,11 +1,18 @@ "use client"; -import EditStaffForm from "../EditStaffForm"; -import { useSearchParams } from "next/navigation"; -import { useEffect, useState } from "react"; -import { BASE_API_URL } from "@/config/api"; -import { fetchStaffEdit } from "@/app/api/staff/actions"; -import { getServerI18n } from "@/i18n"; +import { useCallback, useEffect, useState } from "react"; +import CustomInputForm from "../CustomInputForm"; +import { useRouter, useSearchParams } from "next/navigation"; import { useTranslation } from "react-i18next"; +import { + FieldErrors, + FormProvider, + SubmitErrorHandler, + SubmitHandler, + useForm, +} from "react-hook-form"; +import { CreateStaffInputs, saveStaff, testing } from "@/app/api/staff/actions"; +import { Button, Stack, Typography } from "@mui/material"; +// import CreateStaffForm from "../CreateStaffForm"; import { comboProp, fetchCompanyCombo } from "@/app/api/companys/actions"; import { fetchTeamCombo } from "@/app/api/team/actions"; import { fetchDepartmentCombo } from "@/app/api/departments/actions"; @@ -13,346 +20,234 @@ import { fetchPositionCombo } from "@/app/api/positions/actions"; import { fetchGradeCombo } from "@/app/api/grades/actions"; import { fetchSkillCombo } from "@/app/api/skill/actions"; import { fetchSalaryCombo } from "@/app/api/salarys/actions"; -// import { Field } from "react-hook-form"; +// import StaffInfo from "./StaffInfo"; +import { Check, Close } from "@mui/icons-material"; +import { ServerFetchError } from "@/app/utils/fetchUtil"; +import StaffInfo from "./StaffInfo"; +import { IndividualStaff } from "@/app/api/staff"; +import dayjs from "dayjs"; +import { INPUT_DATE_FORMAT } from "@/app/utils/formatUtil"; +import { List, differenceBy } from "lodash"; - -interface skill { - id: number; - name: string; - code: string; -} -interface skillObj { - id: number; - skill: skill; +export interface comboItem { + company: comboProp[]; + team: comboProp[]; + department: comboProp[]; + position: comboProp[]; + grade: comboProp[]; + skill: comboProp[]; + salary: comboProp[]; } -interface Options { - id: any; - label: string; - [key: string]: any; +interface formProps { + Staff: IndividualStaff + combos: comboItem; } -// interface Field { -// id: string; -// label: string; -// type: string; -// value: any; -// required?: boolean; -// options?: comboProp[] | undefined | null; -// readOnly?: boolean; -// } -export interface Field { - // subtitle: string; - id: string; - label: string; - type: string; - value?: any; - required?: boolean; - pattern?: string; - message?: string; - options?: Options[] | null; - readOnly?: boolean; - size?: number; - setValue?: any[]; -} -const EditStaff: React.FC = async () => { - const searchParams = useSearchParams(); +const EditStaff: React.FC = ({ Staff, combos }) => { + const defaultSkillset = Staff.skillset.map((s: any) => s.skill.id) const { t } = useTranslation(); - const idString = searchParams.get("id"); - const [fieldLists, setFieldLists] = useState(); - const [companyCombo, setCompanyCombo] = useState(); - const [teamCombo, setTeamCombo] = useState(); - const [departmentCombo, setDepartmentCombo] = useState(); - const [positionCombo, setPositionCombo] = useState(); - const [gradeCombo, setGradeCombo] = useState(); - const [skillCombo, setSkillCombo] = useState(); - const [salaryCombo, setSalaryCombo] = useState(); - // const employTypeCombo = [{id: "FT", label: t("FT")}, {id: "PT", label: t("PT")}]; - const title = ["", t('Additional Info')] - const employTypeCombo = [ - { id: "FT", label: t("FT") }, - { id: "PT", label: t("PT") }, - ]; - const keyOrder1 = [ - "staffId", - "name", - "company", - "team", - "department", - "grade", - "skill", - "currentPosition", - "salary", - "hourlyRate", - "employType", - "email", - "phone1", - "phone2", - ]; + const searchParams = useSearchParams() + const id = parseInt(searchParams.get("id") || "0"); + const formProps = useForm({ + defaultValues: { + staffId: Staff.staffId, + name: Staff.name, + companyId: Staff.company.id, + teamId: Staff.team?.id, + departmentId: Staff.department.id, + gradeId: Staff.department.id, + skillSetId: defaultSkillset, + // removeSkillSetId: [], + currentPositionId: Staff.currentPosition.id, + salaryId: Staff.salary.id, + employType: Staff.employType, + email: Staff.email, + phone1: Staff.phone1, + phone2: Staff.phone2, + emergContactName: Staff.emergContactName, + emergContactPhone: Staff.emergContactPhone, + joinDate: dayjs(Staff.joinDate).toString() || "", + joinPositionId: Staff.joinPosition.id, + departDate: dayjs(Staff.departDate).toString() || "", + departReason: Staff.departReason, + remark: Staff.remark, + }}); + const [serverError, setServerError] = useState(""); + const router = useRouter(); + // const [tabIndex, setTabIndex] = useState(0); - const keyOrder2 = [ - "emergContactName", - "emergContactPhone", - "joinDate", - "joinPosition", - "departDate", - "departPosition", - "departReason", - "remark", - ]; + const errors = formProps.formState.errors; - //fetch all combo - useEffect(() => { - fetchCompanyCombo().then((data) => { - if (data) setCompanyCombo(data.records); - }); - fetchTeamCombo().then((data) => { - if (data) setTeamCombo(data.records); - }); - fetchDepartmentCombo().then((data) => { - if (data) setDepartmentCombo(data.records); - }); - fetchPositionCombo().then((data) => { - if (data) setPositionCombo(data.records); - }); - fetchGradeCombo().then((data) => { - if (data) setGradeCombo(data.records); - }); - fetchSkillCombo().then((data) => { - if (data) { - }setSkillCombo(data.records); - console.log(data.records) - }); - fetchSalaryCombo().then((data) => { - if (data) setSalaryCombo(data.records); - }); - }, [searchParams]); + const checkDuplicates = (str1: string, str2: string, str3: string) => { + return str1 === str2 || str1 === str3 || str2 === str3; + } + + const onSubmit = useCallback>( + async (data) => { + try { + console.log(data); + let haveError = false; + let regex_email = /^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/ + let regex_phone = /^\d{8}$/ + // let removeSkillSetId: List = [] + // if (data.skillSetId && defaultSkillset.length > data.skillSetId) { + // removeSkillSetId = differenceBy(defaultSkillset, data.skillSetId) + // } + console.log(data.skillSetId) + console.log(defaultSkillset) + console.log(differenceBy(data.skillSetId, defaultSkillset)) + + if (!regex_email.test(data.email)) { + haveError = true + formProps.setError("email", { message: t("Please Enter Correct Email."), type: "required" }) + } + if(!regex_phone.test(data.phone1)) { + haveError = true + formProps.setError("phone1", { message: t("Please Enter Correct Phone No.."), type: "required" }) + } + if(!regex_phone.test(data.emergContactPhone)) { + haveError = true + formProps.setError("emergContactPhone", { message: t("Please Enter Correct Phone No.."), type: "required" }) + } + if (data.phone2 && data.phone2?.length > 0) { + if(!regex_phone.test(data.phone2)) { + haveError = true + formProps.setError("phone2", { message: t("Please Enter Correct Phone No.."), type: "required" }) + } + } + if (data.phone1 === data.phone2 || data.phone1 === data.emergContactPhone || data.phone2 === data.emergContactPhone) { + haveError = true + formProps.setError("phone1", { message: t("Please Enter Different Phone No.."), type: "required" }) + if (data.phone2!.length > 0) { + formProps.setError("phone2", { message: t("Please Enter Different Phone No.."), type: "required" }) + } + formProps.setError("emergContactPhone", { message: t("Please Enter Different Phone No.."), type: "required" }) + } + if (!regex_email.test(data.email)) { + haveError = true + formProps.setError("email", { message: t("Please Enter Correct Email."), type: "required" }) + } + if (!data.companyId) { + haveError = true + formProps.setError("companyId", { message: t("Please Enter Company."), type: "required" }) + } + if (!data.employType) { + haveError = true + formProps.setError("employType", { message: t("Please Enter Employ Type."), type: "required" }) + } + if (!data.departmentId) { + haveError = true + formProps.setError("departmentId", { message: t("Please Enter Department."), type: "required" }) + } + if (!data.salaryId) { + haveError = true + formProps.setError("salaryId", { message: t("Please Enter Salary."), type: "required" }) + } + if (!data.joinDate) { + haveError = true + formProps.setError("joinDate", { message: t("Please Enter Join Date."), type: "required" }) + } + if (data.departDate && new Date(data.departDate) <= new Date(data.joinDate)) { + haveError = true + formProps.setError("departDate", { message: t("Depart Date cannot be earlier than Join Date."), type: "required" }) + } + if (haveError) { + return + } + console.log("passed") + const postData = { + id: id, + ...data, + // removeSkillSetId: removeSkillSetId + } + await saveStaff(postData) + router.replace("/settings/staff") + } catch (e: any) { + console.log(e); + formProps.setError("staffId", { message: t("Please Enter Employ Type."), type: "required" }) + let msg = "" + if (e.message === "Duplicated StaffId Found") { + msg = t("Duplicated StaffId Found") + } + setServerError(`${t("An error has occurred. Please try again later.")} ${msg} `); + } + }, + [router] + ); + + const handleCancel = () => { + router.back(); + }; + + const resetStaff = useCallback(() => { + formProps.reset({ + staffId: Staff.staffId, + name: Staff.name, + companyId: Staff.company.id, + teamId: Staff.team?.id, + departmentId: Staff.department.id, + gradeId: Staff.department.id, + skillSetId: defaultSkillset, + // removeSkillSetId: [], + currentPositionId: Staff.currentPosition.id, + salaryId: Staff.salary.id, + employType: Staff.employType, + email: Staff.email, + phone1: Staff.phone1, + phone2: Staff.phone2, + emergContactName: Staff.emergContactName, + emergContactPhone: Staff.emergContactPhone, + joinDate: dayjs(Staff.joinDate).format(INPUT_DATE_FORMAT) || "", + joinPositionId: Staff.joinPosition.id, + departDate: !Staff.departDate ? "" : dayjs(Staff.departDate).format(INPUT_DATE_FORMAT), + departReason: Staff.departReason, + remark: Staff.remark, + }); + }, []); + useEffect(() => { - let id = 0; - if (idString) { - id = parseInt(idString); - console.log(id) - fetchStaffEdit(id).then((staff) => { - console.log(staff.data); - const skillset = staff.data.skillset - console.log(skillset); - const skillIds = skillset.map((item: skillObj) => item.skill.id); - console.log(skillIds) - const data = staff.data; - ///////////////////// list 1 ///////////////////// - const list1 = keyOrder1 - .map((key) => { - switch (key) { - case "staffId": - return { - id: `${key}`, - label: t(`Staff ID`), - type: "text", - value: data[key] ?? "", - required: true, - }; - case "name": - return { - id: `${key}`, - label: t(`Staff Name`), - type: "text", - value: data[key] ?? "", - required: true, - }; - case "company": - return { - id: `${key}Id`, - label: t(`Company`), - type: "combo-Obj", - options: companyCombo, - value: data[key].id ?? "", - required: true, - }; - case "team": - return { - id: `${key}Id`, - label: t(`Team`), - type: "combo-Obj", - options: teamCombo, - value: data[key]?.id ?? "", - }; - case "department": - return { - id: `${key}Id`, - label: t(`Department`), - type: "combo-Obj", - options: departmentCombo, - value: data[key]?.id ?? "", - required: true, - // later check - }; - case "grade": - return { - id: `${key}Id`, - label: t(`Grade`), - type: "combo-Obj", - options: gradeCombo, - value: data[key]?.id ?? "", - }; - case "skill": - console.log(skillIds) - return { - id: `${key}SetId`, - label: t(`Skillset`), - type: "multiSelect-Obj", - options: skillCombo, - value: skillIds ?? [], - //array problem - }; - case "currentPosition": - return { - id: `${key}Id`, - label: t(`Current Position`), - type: "combo-Obj", - options: positionCombo, - value: data[key].id ?? "", - required: true, - }; - case "salary": - // console.log("salary", data[key]) - return { - id: `salaryId`, - label: t(`Salary Point`), - type: "combo-Obj", - options: salaryCombo, - value: data[key]?.salaryPoint ?? "", - required: true, - }; - // case "hourlyRate": - // return { - // id: `${key}`, - // label: t(`hourlyRate`), - // type: "text", - // value: "", - // // value: data[key], - // readOnly: true, - // }; - case "employType": - return { - id: `${key}`, - label: t(`Employ Type`), - type: "combo-Obj", - options: employTypeCombo, - value: data[key] ?? "", - required: true, - }; - case "email": - return { - id: `${key}`, - label: t(`Email`), - type: "text", - value: data[key] ?? "", - pattern: "^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$", - message: t("input matching format"), - required: true, - }; - case "phone1": - return { - id: `${key}`, - label: t(`Phone1`), - type: "text", - // pattern: "^\\d{8}$", - message: t("input correct phone no."), - value: data[key] ?? "", - required: true, - }; - case "phone2": - return { - id: `${key}`, - label: t(`Phone2`), - type: "text", - // pattern: "^\\d{8}$", - message: t("input correct phone no."), - value: data[key] ?? "", - } as Field; - default: - return null; - } - }).filter((item): item is Field => item !== null); - ///////////////////// list 2 ///////////////////// - const list2 = keyOrder2 - .map((key) => { - switch (key) { - case "emergContactName": - return { - id: `${key}`, - label: t(`Emergency Contact Name`), - type: "text", - value: data[key] ?? "", - required: true, - } as Field; - case "emergContactPhone": - return { - id: `${key}`, - label: t(`Emergency Contact Phone`), - type: "text", - // pattern: "^\\d{8}$", - message: t("input correct phone no."), - value: data[key] ?? "", - required: true, - } as Field; - case "joinDate": - return { - id: `${key}`, - label: t(`Join Date`), - type: "multiDate", - value: data[key] ?? "", - required: true, - } as Field; - case "joinPosition": - return { - id: `${key}Id`, - label: t(`Join Position`), - type: "combo-Obj", - options: positionCombo, - value: data[key]?.id ?? "", - required: true, - } as Field; - case "departDate": - return { - id: `${key}`, - label: t(`Depart Date`), - type: "multiDate", - value: data[key] ?? "", - } as Field; - case "departReason": - return { - id: `${key}`, - label: t(`Depart Reason`), - type: "text", - value: data[key] ?? "", - } as Field; - case "remark": - return { - id: `remark`, - label: t(`Remark`), - type: "remarks", - value: data[key] ?? "", - } as Field; - default: - return null; - } - }).filter((item): item is Field => item !== null); - console.log(list2); - console.log([list1]); - setFieldLists([list1,list2]); - }); - } - - }, [companyCombo, teamCombo, departmentCombo, positionCombo, gradeCombo, skillCombo, salaryCombo, idString]); + console.log(Staff) + resetStaff() + }, [Staff, combos]); return ( <> - + + + {serverError && ( + + {serverError} + + )} + {Staff && } + + + + + + ); }; -export default EditStaff; +export default EditStaff; \ No newline at end of file diff --git a/src/components/EditStaff/EditStaffWrapper.tsx b/src/components/EditStaff/EditStaffWrapper.tsx index 6d2e2e6..dfb3e9d 100644 --- a/src/components/EditStaff/EditStaffWrapper.tsx +++ b/src/components/EditStaff/EditStaffWrapper.tsx @@ -1,17 +1,60 @@ import React from "react"; -import EditStaff from "./EditStaff"; +import EditStaff, { comboItem } from "./EditStaff"; import EditStaffLoading from "./EditStaffLoading"; -import { fetchStaff, fetchTeamLeads } from "@/app/api/staff"; +import { StaffResult, fetchIndivStaff, fetchStaff, fetchTeamLeads, preloadStaff } from "@/app/api/staff"; import { useSearchParams } from "next/navigation"; +import { fetchTeamCombo } from "@/app/api/team/actions"; +import { fetchDepartmentCombo } from "@/app/api/departments/actions"; +import { fetchPositionCombo } from "@/app/api/positions/actions"; +import { fetchGradeCombo } from "@/app/api/grades/actions"; +import { fetchSkillCombo } from "@/app/api/skill/actions"; +import { fetchSalaryCombo } from "@/app/api/salarys/actions"; +import { fetchCompanyCombo } from "@/app/api/companys/actions"; interface SubComponents { Loading: typeof EditStaffLoading; } -const EditStaffWrapper: React.FC & SubComponents = async () => { +interface Props { + id: number +} +const EditStaffWrapper: React.FC & SubComponents = async ({ + id + }) => { + preloadStaff() + const [ + Staff, + CompanyCombo, + TeamCombo, + DepartmentCombo, + PositionCombo, + GradeCombo, + SkillCombo, + SalaryCombo, + ] = await Promise.all([ + fetchIndivStaff(id), + fetchCompanyCombo(), + fetchTeamCombo(), + fetchDepartmentCombo(), + fetchPositionCombo(), + fetchGradeCombo(), + fetchSkillCombo(), + fetchSalaryCombo(), + ]); + const combos: comboItem = { + company: CompanyCombo.records, + team: TeamCombo.records, + department: DepartmentCombo.records, + position: PositionCombo.records, + grade: GradeCombo.records, + skill: SkillCombo.records, + salary: SalaryCombo.records, + } - return ; +console.log(Staff.data) + + return ; }; EditStaffWrapper.Loading = EditStaffLoading; diff --git a/src/components/EditStaff/StaffInfo.tsx b/src/components/EditStaff/StaffInfo.tsx new file mode 100644 index 0000000..92ebccf --- /dev/null +++ b/src/components/EditStaff/StaffInfo.tsx @@ -0,0 +1,514 @@ +"use client"; +import Stack from "@mui/material/Stack"; +import Box from "@mui/material/Box"; +import Card from "@mui/material/Card"; +import CardContent from "@mui/material/CardContent"; +import Grid from "@mui/material/Grid"; +import TextField from "@mui/material/TextField"; +import Typography from "@mui/material/Typography"; +import { CreateGroupInputs } from "@/app/api/group/actions"; +import { Controller, useFormContext } from "react-hook-form"; +import { useTranslation } from "react-i18next"; +import { useCallback, useEffect } from "react"; +import { CreateStaffInputs } from "@/app/api/staff/actions"; +import { + Checkbox, + FormControl, + InputLabel, + ListItemText, + MenuItem, + Select, +} from "@mui/material"; +import { comboItem } from "./EditStaff"; +import { DatePicker, LocalizationProvider } from "@mui/x-date-pickers"; +import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs"; +import { DemoItem } from "@mui/x-date-pickers/internals/demo"; +import dayjs from "dayjs"; +import { INPUT_DATE_FORMAT } from "@/app/utils/formatUtil"; + +interface Props { + combos: comboItem; +} + +const StaffInfo: React.FC = ({ combos }) => { + const { + t, + i18n: { language }, + } = useTranslation(); + const { + register, + formState: { errors, defaultValues }, + control, + reset, + resetField, + setValue, + getValues, + clearErrors, + } = useFormContext(); + + const employType = [ + { id: 1, label: "FT" }, + { id: 2, label: "PT" }, + ]; + + const skillIdNameMap = combos.skill.reduce<{ [id: number]: string }>( + (acc, skill) => ({ ...acc, [skill.id]: skill.label }), + {} + ); + + const resetStaff = useCallback(() => { + console.log(defaultValues); + if (defaultValues !== undefined) { + // resetField("description"); + } + }, [defaultValues]); + + const joinDate = getValues("joinDate"); + const departDate = getValues("departDate"); + + useEffect(() => { + if (joinDate) clearErrors("joinDate"); + if (departDate) clearErrors("departDate"); + }, [joinDate, departDate]); + + return ( + + + + + {t("Staff")} + + + + + + + + + + + {t("Company")} + ( + + )} + /> + + + + + {t("Team")} + ( + + )} + /> + + + + + {t("Department")} + ( + + )} + /> + + + + + {t("Grade")} + ( + + )} + /> + + + + + {t("Skillset")} + ( + + )} + /> + + + + + {t("Current Position")} + ( + + )} + /> + + + + + {t("Salary Point")} + ( + + )} + /> + + + + + {t("Employ Type")} + ( + + )} + /> + + + + + + + + + + + + + + + + + + + + + + { + if (!date) return; + setValue("joinDate", date.format(INPUT_DATE_FORMAT)); + }} + slotProps={{ + textField: { + required: true, + error: + joinDate === "Invalid Date" || Boolean(errors.joinDate), + // value: errors.joinDate?.message, + }, + }} + /> + + + + + {t("Join Position")} + ( + + )} + /> + + + + + { + if (!date) return; + setValue("departDate", date.format(INPUT_DATE_FORMAT)); + }} + slotProps={{ + textField: { + error: departDate + ? new Date(joinDate) > new Date(departDate) + : false, + }, + }} + /> + + + + + + + + + + + + + ); +}; + +export default StaffInfo;