diff --git a/src/app/api/salarys/actions.ts b/src/app/api/salarys/actions.ts new file mode 100644 index 0000000..386f919 --- /dev/null +++ b/src/app/api/salarys/actions.ts @@ -0,0 +1,20 @@ +"use server" + +import { serverFetchJson } from "@/app/utils/fetchUtil"; +import { BASE_API_URL } from "@/config/api"; +import { cache } from "react"; + +export interface comboProp { + id: any; + label: string; +} + +export interface combo { + records: comboProp; +} + +export const fetchSalaryCombo = cache(async () => { + return serverFetchJson(`${BASE_API_URL}/salary/combo`, { + next: { tags: ["salary"] }, + }); + }); \ No newline at end of file diff --git a/src/app/api/staff/actions.ts b/src/app/api/staff/actions.ts index 7328af9..8eb5ff3 100644 --- a/src/app/api/staff/actions.ts +++ b/src/app/api/staff/actions.ts @@ -34,7 +34,15 @@ export interface CreateStaffInputs { } export const saveStaff = async (data: CreateStaffInputs) => { - return serverFetchJson(`${BASE_API_URL}/staffs/save`, { + return serverFetchJson(`${BASE_API_URL}/staffs/save`, { + method: "POST", + body: JSON.stringify(data), + headers: { "Content-Type": "application/json" }, + }); + }; + +export const testing = async (data: CreateStaffInputs) => { + return serverFetchJson(`${BASE_API_URL}/staffs/testing`, { method: "POST", body: JSON.stringify(data), headers: { "Content-Type": "application/json" }, @@ -44,7 +52,7 @@ export const saveStaff = async (data: CreateStaffInputs) => { export const deleteStaff = async (data: StaffResult) => { return serverFetchJson(`${BASE_API_URL}/staffs/delete/${data.id}`, { method: "DELETE", - body: JSON.stringify(data), + // body: JSON.stringify(data), headers: { "Content-Type": "application/json" }, }); }; diff --git a/src/components/CreateStaff/CreateStaffForm.tsx b/src/components/CreateStaff/CreateStaffForm.tsx index 555ca86..fef41e4 100644 --- a/src/components/CreateStaff/CreateStaffForm.tsx +++ b/src/components/CreateStaff/CreateStaffForm.tsx @@ -10,7 +10,7 @@ import { SubmitHandler, useForm, } from "react-hook-form"; -import { CreateStaffInputs, saveStaff } from "@/app/api/staff/actions"; +import { CreateStaffInputs, saveStaff, testing } from "@/app/api/staff/actions"; import { Typography } from "@mui/material"; interface Field { diff --git a/src/components/CustomInputForm/CustomInputForm.tsx b/src/components/CustomInputForm/CustomInputForm.tsx index 06eee14..fc36538 100644 --- a/src/components/CustomInputForm/CustomInputForm.tsx +++ b/src/components/CustomInputForm/CustomInputForm.tsx @@ -121,6 +121,7 @@ const CustomInputForm: React.FC = ({ ...dateObj, }; + console.log(data); console.log(finalData); onSubmit(finalData); }; @@ -279,19 +280,23 @@ const CustomInputForm: React.FC = ({ ); } else if (field.type === "multiDate") { + console.log(dayjs(field.value)) return ( { handleDateChange(field.id, newValue); @@ -348,9 +353,7 @@ const CustomInputForm: React.FC = ({ : option } > - {option.id - ? option.label - : ""} + {option.id ? option.label : ""} ))} @@ -455,7 +458,7 @@ const CustomInputForm: React.FC = ({ rows={4} variant="filled" {...register(field.id)} - defaultValue={!field.value ? `${field.value}` : ""} + defaultValue={field.value ? `${field.value}` : ""} id={field.id} label={field.label} required={field.required} diff --git a/src/components/EditStaff/EditStaff.tsx b/src/components/EditStaff/EditStaff.tsx index e07a3e0..2dfd4e0 100644 --- a/src/components/EditStaff/EditStaff.tsx +++ b/src/components/EditStaff/EditStaff.tsx @@ -12,18 +12,18 @@ 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 { Field } from "react-hook-form"; interface dataType { [key: string]: any; } - interface Options { - id: any; - label: string; - [key: string]: any; - } + id: any; + label: string; + [key: string]: any; +} // interface Field { // id: string; // label: string; @@ -35,19 +35,19 @@ interface Options { // } 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[]; - } + // 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(); @@ -61,95 +61,113 @@ const EditStaff: React.FC = async () => { const [positionCombo, setPositionCombo] = useState(); const [gradeCombo, setGradeCombo] = useState(); const [skillCombo, setSkillCombo] = useState(); -// const employTypeCombo = [{id: "FT", label: t("FT")}, {id: "PT", label: t("PT")}]; - const employTypeCombo = [{id: "FT", label: t("FT")}, {id: "PT", label: t("PT")}]; + 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", + "salaryEffective", + "hourlyRate", + "employType", + "email", + "phone1", + "phone2", + ]; + + const keyOrder2 = [ + "emergContactName", + "emergContactPhone", + "joinDate", + "joinPosition", + "departDate", + "departPosition", + "departReason", + "remark", + ]; //fetch all combo useEffect(() => { fetchCompanyCombo().then((data) => { - console.log(data.records); - setCompanyCombo(data.records); + if (data) setCompanyCombo(data.records); }); fetchTeamCombo().then((data) => { - setTeamCombo(data.records); - }) + if (data) setTeamCombo(data.records); + }); fetchDepartmentCombo().then((data) => { - setDepartmentCombo(data.records); - }) + if (data) setDepartmentCombo(data.records); + }); fetchPositionCombo().then((data) => { - setPositionCombo(data.records); - }) + if (data) setPositionCombo(data.records); + }); fetchGradeCombo().then((data) => { - setGradeCombo(data.records); - }) + if (data) setGradeCombo(data.records); + }); fetchSkillCombo().then((data) => { - setSkillCombo(data.records); - }) + if (data) setSkillCombo(data.records); + }); + fetchSalaryCombo().then((data) => { + if (data) setSalaryCombo(data.records); + }); }, [searchParams]); useEffect(() => { let id = 0; if (idString) { id = parseInt(idString); - setId(id) + setId(id); } fetchStaffEdit(id).then((staff) => { console.log(staff.data); const data = staff.data; - const keyOrder = [ - "staffId", - "name", - "company", - "team", - "department", - "grade", - "skill", - "currentPosition", - "salaryEffective", - "hourlySalary", - "employType", - "email", - "phone1", - "phone2", - ]; - const list1 = keyOrder + ///////////////////// list 1 ///////////////////// + const list1 = keyOrder1 .map((key) => { switch (key) { case "staffId": return { id: `${key}`, - label: t(`${key}`), + label: t(`Staff ID`), type: "text", - value: data[key], + value: data[key] ?? "", }; case "name": return { id: `${key}`, - label: t(`${key}`), + label: t(`Staff Name`), type: "text", - value: data[key], + value: data[key] ?? "", }; case "company": return { - id: `${key}`, - label: t(`${key}`), + id: `${key}Id`, + label: t(`Company`), type: "combo-Obj", options: companyCombo, - value: data[key].id, + value: data[key].id ?? "", }; case "team": return { - id: `${key}`, - label: t(`${key}`), + id: `${key}Id`, + label: t(`Team`), type: "combo-Obj", options: teamCombo, - value: data[key].id, + value: data[key].id ?? "", }; case "department": - // console.log(data[key]) return { - id: `${key}`, - label: t(`${key}`), + id: `${key}Id`, + label: t(`Department`), type: "combo-Obj", options: departmentCombo, value: data[key]?.id ?? "", @@ -157,86 +175,154 @@ const EditStaff: React.FC = async () => { }; case "grade": return { - id: `${key}`, - label: t(`${key}`), + id: `${key}Id`, + label: t(`Grade`), type: "combo-Obj", options: gradeCombo, - value: data[key].id, + value: data[key].id ?? "", }; case "skill": return { - id: `${key}`, - label: t(`${key}`), + id: `${key}SetId`, + label: t(`Skillset`), type: "combo-Obj", options: skillCombo, - value: data[key].id, + value: data[key].id ?? "", }; case "currentPosition": return { - id: `${key}`, - label: t(`${key}`), + id: `${key}Id`, + label: t(`Current Position`), type: "combo-Obj", options: positionCombo, - value: data[key].id, + value: data[key].id ?? "", }; case "salaryEffective": return { - id: `${key}`, - label: t(`${key}`), - type: "text", - value: data[key], + id: `salaryEffId`, + label: t(`Salary Point`), + type: "combo-Obj", + options: salaryCombo, + value: data[key].salary.id ?? "", }; - case "hourlySalary": + case "hourlyRate": return { id: `${key}`, - label: t(`${key}`), + label: t(`hourlyRate`), type: "text", + value: "", // value: data[key], - readOnly: true + readOnly: true, }; case "employType": return { id: `${key}`, - label: t(`${key}`), + label: t(`Employ Type`), type: "combo-Obj", options: employTypeCombo, - value: data[key], + value: data[key] ?? "", }; case "email": return { id: `${key}`, - label: t(`${key}`), + label: t(`Email`), type: "text", - value: data[key], + value: data[key] ?? "", + pattern: "^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$", + message: t("input matching format"), }; case "phone1": return { id: `${key}`, - label: t(`${key}`), + label: t(`Phone1`), type: "text", - value: data[key], + pattern: "^\\d{8}$", + message: t("input correct phone no."), + value: data[key] ?? "", }; case "phone2": return { id: `${key}`, - label: t(`${key}`), + label: t(`Phone2`), type: "text", - value: data[key], + 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] ?? "", + } as Field; + case "emergContactPhone": + return { + id: `${key}`, + label: t(`Emergency Contact Phonee`), + type: "text", + pattern: "^\\d{8}$", + message: t("input correct phone no."), + value: data[key] ?? "", + } as Field; + case "joinDate": + return { + id: `${key}`, + label: t(`Join Date`), + type: "multiDate", + value: data[key] ?? "", + } as Field; + case "joinPosition": + return { + id: `${key}Id`, + label: t(`Join Position`), + type: "combo-Obj", + options: positionCombo, + value: data[key].id ?? "", + } 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; - // Add more cases for each property default: return null; } - }) - .filter((item): item is Field => item !== null); + }).filter((item): item is Field => item !== null); + console.log(list2); console.log([list1]); - setFieldLists([list1]); + setFieldLists([list1,list2]); }); }, [companyCombo]); return ( <> - + {/* {console.log(fieldLists)} */} + ); }; diff --git a/src/components/EditStaffForm/EditStaffForm.tsx b/src/components/EditStaffForm/EditStaffForm.tsx index 66af7b4..a02ca88 100644 --- a/src/components/EditStaffForm/EditStaffForm.tsx +++ b/src/components/EditStaffForm/EditStaffForm.tsx @@ -3,9 +3,10 @@ import { useRouter, useSearchParams } from "next/navigation"; import { useCallback, useEffect, useState } from "react"; import CustomInputForm from "../CustomInputForm"; import { SubmitErrorHandler, SubmitHandler } from "react-hook-form"; -import { CreateStaffInputs, saveStaff } from "@/app/api/staff/actions"; +import { CreateStaffInputs, saveStaff, testing } from "@/app/api/staff/actions"; import { Typography } from "@mui/material"; import { useTranslation } from "react-i18next"; +import dayjs from "dayjs"; interface Options { id: any; @@ -38,14 +39,30 @@ const EditStaffForm: React.FC = ({ id, Title, fieldLists }) => { const onSubmit = useCallback>( async (data) => { try { - console.log(data); + let formatJoinDate = data.joinDate + let formatDepartDate = data.departDate + if (data.joinDate && /^\d{2}\/\d{2}\/\d{4}$/.test(data.joinDate)) { + const formattedDate = dayjs(data.joinDate, 'MM/DD/YYYY').format('YYYY-MM-DD'); + formatJoinDate = formattedDate; + } + if (data.departDate && data.departDate.length > 0 && /^\d{2}\/\d{2}\/\d{4}$/.test(data.departDate)) { + const formattedDate = dayjs(data.departDate, 'MM/DD/YYYY').format('YYYY-MM-DD'); + formatDepartDate = formattedDate; + } + // console.log(data); const temp = { id: id, - ...data + ...data, + emergContactPhone: data.emergContactPhone.toString(), + phone1: data.phone1.toString(), + phone2: data.phone1.toString(), + joinDate: formatJoinDate, + departDate: formatDepartDate, } console.log(temp) setServerError(""); await saveStaff(temp); + router.replace("/settings/staff"); } catch (e) { setServerError(t("An error has occurred. Please try again later.")); } diff --git a/src/components/StaffSearch/StaffSearch.tsx b/src/components/StaffSearch/StaffSearch.tsx index 99dc950..18db617 100644 --- a/src/components/StaffSearch/StaffSearch.tsx +++ b/src/components/StaffSearch/StaffSearch.tsx @@ -73,8 +73,9 @@ const StaffSearch: React.FC = ({ staff }) => { const onConfirm = useCallback(async (staff: StaffResult) => { console.log(staff); - // if (data) - // await deleteStaff(data) + if (data) + await deleteStaff(data) + setIsOpen(false) window.location.reload; }, [deleteStaff, data]);