Kaynağa Gözat

update

tags/Baseline_30082024_FRONTEND_UAT
MSI\derek 1 yıl önce
ebeveyn
işleme
168053150d
7 değiştirilmiş dosya ile 244 ekleme ve 109 silme
  1. +20
    -0
      src/app/api/salarys/actions.ts
  2. +10
    -2
      src/app/api/staff/actions.ts
  3. +1
    -1
      src/components/CreateStaff/CreateStaffForm.tsx
  4. +12
    -9
      src/components/CustomInputForm/CustomInputForm.tsx
  5. +178
    -92
      src/components/EditStaff/EditStaff.tsx
  6. +20
    -3
      src/components/EditStaffForm/EditStaffForm.tsx
  7. +3
    -2
      src/components/StaffSearch/StaffSearch.tsx

+ 20
- 0
src/app/api/salarys/actions.ts Dosyayı Görüntüle

@@ -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<combo>(`${BASE_API_URL}/salary/combo`, {
next: { tags: ["salary"] },
});
});

+ 10
- 2
src/app/api/staff/actions.ts Dosyayı Görüntüle

@@ -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" },
});
};


+ 1
- 1
src/components/CreateStaff/CreateStaffForm.tsx Dosyayı Görüntüle

@@ -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 {


+ 12
- 9
src/components/CustomInputForm/CustomInputForm.tsx Dosyayı Görüntüle

@@ -121,6 +121,7 @@ const CustomInputForm: React.FC<CustomInputFormProps> = ({
...dateObj,
};

console.log(data);
console.log(finalData);
onSubmit(finalData);
};
@@ -279,19 +280,23 @@ const CustomInputForm: React.FC<CustomInputFormProps> = ({
</Grid>
);
} else if (field.type === "multiDate") {
console.log(dayjs(field.value))
return (
<Grid item xs={field.size ?? 6} key={field.id}>
<LocalizationProvider dateAdapter={AdapterDayjs}>
<DemoItem>
<DatePicker
{...register(field.id)}
key={field.id}
label={field.label}
value={
!dateObj
? null
: !dateObj[field.id]
defaultValue={
field.value
? dayjs(field.value)
: !dateObj
? null
: dayjs(dateObj[field.id])
: !dateObj[field.id]
? null
: dayjs(dateObj[field.id])
} // Set initial value or use a default value from state
onChange={(newValue) => {
handleDateChange(field.id, newValue);
@@ -348,9 +353,7 @@ const CustomInputForm: React.FC<CustomInputFormProps> = ({
: option
}
>
{option.id
? option.label
: ""}
{option.id ? option.label : ""}
</MenuItem>
))}
</Select>
@@ -455,7 +458,7 @@ const CustomInputForm: React.FC<CustomInputFormProps> = ({
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}


+ 178
- 92
src/components/EditStaff/EditStaff.tsx Dosyayı Görüntüle

@@ -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<comboProp>();
const [gradeCombo, setGradeCombo] = useState<comboProp>();
const [skillCombo, setSkillCombo] = useState<comboProp>();
// 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<comboProp>();
// 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 (
<>
<EditStaffForm id={id} fieldLists={fieldLists || [[]]} />
{/* {console.log(fieldLists)} */}
<EditStaffForm Title={title} id={id} fieldLists={fieldLists as Field[][] || [[]]} />
</>
);
};


+ 20
- 3
src/components/EditStaffForm/EditStaffForm.tsx Dosyayı Görüntüle

@@ -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<formProps> = ({ id, Title, fieldLists }) => {
const onSubmit = useCallback<SubmitHandler<CreateStaffInputs>>(
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."));
}


+ 3
- 2
src/components/StaffSearch/StaffSearch.tsx Dosyayı Görüntüle

@@ -73,8 +73,9 @@ const StaffSearch: React.FC<Props> = ({ 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]);



Yükleniyor…
İptal
Kaydet