|
- "use client";
- 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, teamHistory } from "@/app/api/staff/actions";
- import { Button, Stack, Tab, Tabs, TabsProps, Typography } from "@mui/material";
- // import CreateStaffForm from "../CreateStaffForm";
- import { comboProp } from "@/app/api/companys/actions";
- // import StaffInfo from "./StaffInfo";
- import { Check, Close, ConstructionOutlined, RestartAlt } from "@mui/icons-material";
- import StaffInfo from "./StaffInfo";
- import { IndividualStaff, projects, SalaryEffectiveInfo } from "@/app/api/staff";
- import dayjs from "dayjs";
- import ProjectHistory from "./ProjectHistory";
- import { InfoHistory } from "./EditStaffWrapper";
- import { fetchIndivTeam } from "@/app/api/team";
- // import { useGridApiContext } from '@mui/x-data-grid';
-
- export interface comboItem {
- company: comboProp[];
- team: comboProp[];
- department: comboProp[];
- position: comboProp[];
- grade: comboProp[];
- skill: comboProp[];
- salary: comboProp[];
- }
-
- interface formProps {
- Staff: IndividualStaff
- combos: comboItem;
- SalaryEffectiveInfo: SalaryEffectiveInfo[];
- InvolvedProject?: projects[]
- InfoHistory: InfoHistory
- }
-
-
-
- const EditStaff: React.FC<formProps> = ({ Staff, combos, SalaryEffectiveInfo, InvolvedProject, InfoHistory }) => {
- const defaultSkillset = Staff.skillset.map((s: any) => s.skill.id)
- const { t } = useTranslation();
- const searchParams = useSearchParams()
- const [tabIndex, setTabIndex] = useState(0);
- const id = parseInt(searchParams.get("id") || "0");
- const formProps = useForm<CreateStaffInputs
- & { salaryEffectiveInfo: SalaryEffectiveInfo[] }
- & { delSalaryEffectiveInfo: number[] }>({
- defaultValues: {
- staffId: Staff.staffId,
- name: Staff.name,
- companyId: Staff.company.id,
- teamId: Staff.team?.id,
- departmentId: Staff.department?.id,
- gradeId: Staff.grade?.id,
- skillSetId: defaultSkillset,
- // removeSkillSetId: [],
- currentPositionId: Staff.currentPosition?.id,
- salaryId: Staff.salary.salaryPoint,
- employType: Staff.employType,
- email: Staff.email,
- phone1: Staff.phone1,
- phone2: Staff.phone2,
- emergContactName: Staff.emergContactName,
- emergContactPhone: Staff.emergContactPhone,
- joinDate: Staff.joinDate ? dayjs(Staff.joinDate as string).format("YYYY-MM-DD") : null,
- joinPositionId: Staff.joinPosition?.id || null,
- departDate: Staff.departDate ? dayjs(Staff.departDate as string).format("YYYY-MM-DD") : null,
- departReason: Staff.departReason,
- remark: Staff.remark,
- salaryEffectiveInfo: SalaryEffectiveInfo.map(item => {
- return ({
- id: item.id,
- salaryPoint: combos.salary.filter(sal => sal.id === item.salaryPoint)[0].label,
- date: dayjs(item.date).toDate(),
- })}),
- delSalaryEffectiveInfo: [],
- teamHistory: InfoHistory.teamLog ? InfoHistory.teamLog.map(item => {
- return ({
- id: item.id,
- team: item.team.name,
- from: dayjs(item.from.join()).toDate(),
- to: item.to ? dayjs(item.to.join()).toDate() : "",
- })
- }) : [],
- delTeamHistory: [],
- gradeHistory: InfoHistory.gradeLog ? InfoHistory.gradeLog.map(item => {
- return ({
- id: item.id,
- grade: item.grade.name,
- from: dayjs(item.from.join()).toDate(),
- to: item.to ? dayjs(item.to.join()).toDate() : "",
- })
- }) : [],
- delGradeHistory: [],
- positionHistory: InfoHistory.positionLog ? InfoHistory.positionLog.map(item => {
- return ({
- id: item.id,
- position: item.position.name,
- from: dayjs(item.from.join()).toDate(),
- to: item.to ? dayjs(item.to.join()).toDate() : "",
- })
- }) : [],
- delPositionHistory: [],
- }});
-
-
- const [serverError, setServerError] = useState("");
- const router = useRouter();
-
- const errors = formProps.formState.errors;
-
- const onSubmit = useCallback<SubmitHandler<CreateStaffInputs & { salaryEffectiveInfo: SalaryEffectiveInfo[] } >>(
- async (data) => {
- try {
- // console.log(data);
- let haveError = false;
- const regex_email = /^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/
- const regex_phone = /^\d{8}$/
-
- 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 (data.emergContactPhone && !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.phone2 === data.emergContactPhone && data.phone2.length > 0) {
- 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.salaryId) {
- haveError = true
- formProps.setError("salaryId", { message: t("Please Enter Salary."), type: "required" })
- }
- // if (data.joinDate && 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
- }
-
- const teamHistory = data.teamHistory.map((item) => ({
- id: item.id,
- team: combos.team.filter(team => team.label === item.team)[0].id,
- from: dayjs(item.from).format('YYYY-MM-DD'),
- to: (item.to as string).length != 0 ? dayjs(item.to).format('YYYY-MM-DD') : undefined,
- }))
- const gradeHistory = data.gradeHistory.map((item) => ({
- id: item.id,
- grade: combos.grade.filter(grade => grade.label === item.grade)[0].id,
- from: dayjs(item.from).format('YYYY-MM-DD'),
- to: (item.to as string).length != 0 ? dayjs(item.to).format('YYYY-MM-DD') : undefined,
- }))
- const positionHistory = data.positionHistory.map((item) => ({
- id: item.id,
- position: combos.position.filter(position => position.label === item.position)[0].id,
- from: dayjs(item.from).format('YYYY-MM-DD'),
- to: (item.to as string).length != 0 ? dayjs(item.to).format('YYYY-MM-DD') : undefined,
- }))
-
- const salaryEffectiveInfo = data.salaryEffectiveInfo.map((item: SalaryEffectiveInfo) => ({
- id: item.id,
- salaryPoint: chopSalaryPoints(item.salaryPoint),
- date: dayjs(item.date).format('YYYY-MM-DD').toString()
- }))
-
- const postData: CreateStaffInputs = {
- id: id,
- ...data,
- salaryEffectiveInfo: salaryEffectiveInfo,
- teamHistory: teamHistory ?? [],
- gradeHistory: gradeHistory ?? [],
- positionHistory: positionHistory ?? [],
- delTeamHistory: data.delTeamHistory ? data.delTeamHistory : [],
- delGradeHistory: data.delGradeHistory ? data.delGradeHistory : [],
- delPositionHistory: data.delPositionHistory ? data.delPositionHistory : [],
- }
- if (postData.joinDate) {
- postData.joinDate = dayjs(postData.joinDate).format("YYYY-MM-DD")
- }
- if (postData.departDate) {
- postData.departDate = dayjs(postData.departDate).format("YYYY-MM-DD")
- }
- console.log(postData)
- 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();
- };
-
- function chopSalaryPoints(input: string | number): number | null {
- if (typeof input === 'string') {
- const match = input.match(/(\d+) \((\d+) - (\d+)\)/);
- if (match) {
- return parseInt(match[1], 10);
- }
- } else if (typeof input === 'number') {
- return input;
- }
- return null;
- }
-
- const handleTabChange = useCallback<NonNullable<TabsProps["onChange"]>>(
- (_e, newValue) => {
- setTabIndex(newValue);
- },
- []
- );
-
- return (
- <>
- <FormProvider {...formProps}>
- <Stack
- spacing={2}
- component="form"
- onSubmit={formProps.handleSubmit(onSubmit)}
- >
- {serverError && (
- <Typography variant="body2" color="error" alignSelf="flex-end">
- {serverError}
- </Typography>
- )}
- <Stack
- direction="row"
- justifyContent="space-between"
- flexWrap="wrap"
- rowGap={2}
- >
- <Tabs
- value={tabIndex}
- onChange={handleTabChange}
- variant="scrollable"
- >
- <Tab label={t("Info")}/>
- <Tab label={t("Info History")} />
- <Tab label={t("Involved Project History")} />
- </Tabs>
- </Stack>
- {tabIndex == 0 && Staff && <StaffInfo combos={combos} />}
- {tabIndex == 2 && <ProjectHistory InvolvedProject={InvolvedProject}/>}
- {tabIndex == 0 &&
- <Stack direction="row" justifyContent="flex-end" gap={1}>
- <Button
- variant="text"
- startIcon={<RestartAlt />}
- onClick={()=> window.location.reload()}
- >
- {t("Reset")}
- </Button>
- <Button
- variant="outlined"
- startIcon={<Close />}
- onClick={handleCancel}
- >
- {t("Cancel")}
- </Button>
- <Button
- variant="contained"
- startIcon={<Check />}
- type="submit"
- // disabled={Boolean(formProps.watch("isGridEditing"))}
- >
- {t("Confirm")}
- </Button>
- </Stack>
- }
- </Stack>
- </FormProvider>
- </>
- );
- };
-
- export default EditStaff;
|