|
- "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, useMemo, useState } from "react";
- import { CreateStaffInputs } from "@/app/api/staff/actions";
- import {
- Button,
- 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";
- import SalaryEffectiveModel from "./SalaryEffectiveModel";
- import { SalaryEffectiveInfo } from "@/app/api/staff";
-
- interface Props {
- combos: comboItem;
- }
-
- const StaffInfo: React.FC<Props> = ({ combos }) => {
- const {
- t,
- i18n: { language },
- } = useTranslation();
- const {
- register,
- formState: { errors, defaultValues },
- control,
- reset,
- resetField,
- setValue,
- getValues,
- watch,
- clearErrors,
- } = useFormContext<CreateStaffInputs & { salaryEffectiveInfo: SalaryEffectiveInfo[] }>();
-
- 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 }),
- {}
- );
-
- // Salary Effiective History edit modal related
- const [salaryEffectiveModelOpen, setSalaaryEffectiveModelOpen] = useState(false);
- const closeSalaryEffectiveModel = useCallback(() => {
- setSalaaryEffectiveModelOpen(false);
- }, []);
- const openSalaryEffectiveModel = useCallback(() => {
- setSalaaryEffectiveModelOpen(true);
- }, []);
- const onSalaryEffectiveSave = useCallback(async () => {
- console.log(getValues())
- setSalaaryEffectiveModelOpen(false);
- }, []);
-
-
-
- const resetStaff = useCallback(() => {
- console.log(defaultValues);
- if (defaultValues !== undefined) {
- resetField("joinDate");
- resetField("departDate");
- }
- }, [defaultValues]);
-
- useEffect(() => {
- resetStaff()
- }, [defaultValues]);
-
- const joinDate = watch("joinDate");
- const departDate = watch("departDate");
-
- useEffect(() => {
- if (joinDate) clearErrors("joinDate");
- if (departDate) clearErrors("departDate");
- }, [joinDate, departDate]);
-
- const salaryCols = useMemo(
- () => [
- {
- field: 'salaryPoint',
- headerName: 'salaryPoint',
- flex: 1,
- editable: true,
- type: 'singleSelect',
- valueOptions: combos?.salary.map(item => item.label),
- // valueOptions: [],
- // width: 150
- },
- {
- field: 'date',
- headerName: 'date',
- flex: 1,
- editable: true,
- type: 'date',
- // width: 150
- },
- ], [combos])
-
- return (
- <Card sx={{ display: "block" }}>
- <CardContent component={Stack} spacing={4}>
- <Box>
- <Typography variant="overline" display="block" marginBlockEnd={1}>
- {t("Staff")}
- </Typography>
- <Grid container spacing={2} columns={{ xs: 6, sm: 12 }}>
- <Grid item xs={6}>
- <TextField
- label={t("Staff ID")}
- fullWidth
- required
- {...register("staffId", {
- required: "Staff Id required!",
- })}
- error={Boolean(errors.name)}
- helperText={
- Boolean(errors.name) &&
- (errors.name?.message
- ? t(errors.name.message)
- : t("Please input correct staffId"))
- }
- />
- </Grid>
- <Grid item xs={6}>
- <TextField
- label={t("Staff Name")}
- fullWidth
- required
- {...register("name", {
- required: "Staff Name required!",
- })}
- error={Boolean(errors.name)}
- helperText={
- Boolean(errors.name) &&
- (errors.name?.message
- ? t(errors.name.message)
- : t("Please input correct name"))
- }
- />
- </Grid>
- <Grid item xs={6}>
- <FormControl fullWidth>
- <InputLabel required>{t("Company")}</InputLabel>
- <Controller
- control={control}
- name="companyId"
- render={({ field }) => (
- <Select
- label={t("Company")}
- {...field}
- error={Boolean(errors.companyId)}
- >
- {combos.company.map((company, index) => (
- <MenuItem
- key={`${company.id}-${index}`}
- value={company.id}
- >
- {t(company.label)}
- </MenuItem>
- ))}
- </Select>
- )}
- />
- </FormControl>
- </Grid>
- <Grid item xs={6}>
- <FormControl fullWidth>
- <InputLabel>{t("Team")}</InputLabel>
- <Controller
- control={control}
- name="teamId"
- render={({ field }) => (
- <Select
- label={t("Team")}
- {...field}
- // error={Boolean(errors.teamId)}
- >
- {combos.team.map((team, index) => (
- <MenuItem key={`${team.id}-${index}`} value={team.id}>
- {t(team.label)}
- </MenuItem>
- ))}
- </Select>
- )}
- />
- </FormControl>
- </Grid>
- <Grid item xs={6}>
- <FormControl fullWidth>
- <InputLabel>{t("Department")}</InputLabel>
- <Controller
- control={control}
- name="departmentId"
- render={({ field }) => (
- <Select
- label={t("Department")}
- {...field}
- // error={Boolean(errors.departmentId)}
- >
- {combos.department.map((department, index) => (
- <MenuItem
- key={`${department.id}-${index}`}
- value={department.id}
- >
- {t(department.label)}
- </MenuItem>
- ))}
- </Select>
- )}
- />
- </FormControl>
- </Grid>
- <Grid item xs={6}>
- <FormControl fullWidth>
- <InputLabel>{t("Grade")}</InputLabel>
- <Controller
- control={control}
- name="gradeId"
- render={({ field }) => (
- <Select
- label={t("Grade")}
- {...field}
- error={Boolean(errors.gradeId)}
- >
- {combos.grade.map((grade, index) => (
- <MenuItem key={`${grade.id}-${index}`} value={grade.id}>
- {t(grade.label)}
- </MenuItem>
- ))}
- </Select>
- )}
- />
- </FormControl>
- </Grid>
- <Grid item xs={6}>
- <FormControl fullWidth>
- <InputLabel>{t("Skillset")}</InputLabel>
- <Controller
- defaultValue={[]}
- control={control}
- name="skillSetId"
- render={({ field }) => (
- <Select
- // error={Boolean(errors.skillSetId)}
- renderValue={(types) =>
- types.map((type) => skillIdNameMap[type]).join(", ")
- }
- multiple
- label={t("Skillset")}
- {...field}
- >
- {combos.skill.map((skill, index) => {
- // console.log(field)
- return (
- <MenuItem
- key={`${skill.id}-${index}`}
- value={skill.id}
- >
- <Checkbox
- checked={field.value!.indexOf(skill.id) > -1}
- />
- <ListItemText primary={skill.label} />
- </MenuItem>
- );
- })}
- </Select>
- )}
- />
- </FormControl>
- </Grid>
- <Grid item xs={6}>
- <FormControl fullWidth>
- <InputLabel required>{t("Current Position")}</InputLabel>
- <Controller
- control={control}
- name="currentPositionId"
- render={({ field }) => (
- <Select
- label={t("Current Position")}
- {...field}
- error={Boolean(errors.currentPositionId)}
- >
- {combos.position.map((position, index) => (
- <MenuItem
- key={`${position.id}-${index}`}
- value={position.id}
- >
- {t(position.label)}
- </MenuItem>
- ))}
- </Select>
- )}
- />
- </FormControl>
- </Grid>
- <Grid item xs={6}>
- <FormControl fullWidth>
- <InputLabel required>{t("Salary Point")}</InputLabel>
- <Controller
- control={control}
- name="salaryId"
- render={({ field }) => (
- <Box display="flex" justifyContent="space-between" alignItems="center">
- <Select
- label={t("Salary Point")}
- {...field}
- error={Boolean(errors.salaryId)}
- style={{ flex: 1, marginRight: '8px' }}
- disabled
- >
- {combos.salary.map((salary, index) => (
- <MenuItem
- key={`${salary.id}-${index}`}
- value={salary.id}
- >
- {t(salary.label)}
- </MenuItem>
- ))}
- </Select>
- <Button variant="contained" size="small" onClick={openSalaryEffectiveModel}>
- {t("Edit")}
- </Button>
- </Box>
- )}
- />
- </FormControl>
- </Grid>
- <Grid item xs={6}>
- <FormControl fullWidth>
- <InputLabel required>{t("Employ Type")}</InputLabel>
- <Controller
- control={control}
- name="employType"
- render={({ field }) => (
- <Select
- label={t("Employ Type")}
- {...field}
- error={Boolean(errors.employType)}
- >
- {employType.map((type, index) => (
- <MenuItem
- key={`${type.id}-${index}`}
- value={type.label}
- >
- {t(type.label)}
- </MenuItem>
- ))}
- </Select>
- )}
- />
- </FormControl>
- </Grid>
- <Grid item xs={6}>
- <TextField
- label={t("Email")}
- fullWidth
- required
- {...register("email", {
- required: "Email required!",
- })}
- error={Boolean(errors.email)}
- helperText={
- Boolean(errors.email) &&
- (errors.email?.message
- ? t(errors.email.message)
- : t("Please input correct email"))
- }
- />
- </Grid>
- <Grid item xs={6}>
- <TextField
- label={t("Phone1")}
- fullWidth
- required
- {...register("phone1", {
- required: "phone1 required!",
- })}
- error={Boolean(errors.phone1)}
- helperText={
- Boolean(errors.phone1) &&
- (errors.phone1?.message
- ? t(errors.phone1.message)
- : t("Please input correct phone1"))
- }
- />
- </Grid>
- <Grid item xs={6}>
- <TextField
- label={t("Phone2")}
- fullWidth
- {...register("phone2")}
- error={Boolean(errors.phone2)}
- helperText={
- Boolean(errors.phone2) &&
- (errors.phone2?.message
- ? t(errors.phone2.message)
- : t("Please input correct phone2"))
- }
- />
- </Grid>
- </Grid>
- <Grid container spacing={2} columns={{ xs: 6, sm: 12 }} marginTop={3}>
- <Grid item xs={6}>
- <TextField
- label={t("Emergency Contact Name")}
- fullWidth
- {...register("emergContactName"
- // , {
- // required: "Emergency Contact Name required!",
- // }
- )}
- // error={Boolean(errors.emergContactName)}
- helperText={
- Boolean(errors.emergContactName) &&
- (errors.emergContactName?.message
- ? t(errors.emergContactName.message)
- : t("Please input correct Emergency Contact Name"))
- }
- />
- </Grid>
- <Grid item xs={6}>
- <TextField
- label={t("Emergency Contact Phone")}
- fullWidth
- {...register("emergContactPhone"
- // , {
- // required: "Emergency Contact Phone required!",
- // }
- )}
- // error={Boolean(errors.emergContactPhone)}
- helperText={
- Boolean(errors.emergContactPhone) &&
- (errors.emergContactPhone?.message
- ? t(errors.emergContactPhone.message)
- : t("Please input correct Emergency Contact Phone"))
- }
- />
- </Grid>
- <Grid item xs={6}>
- <LocalizationProvider
- dateAdapter={AdapterDayjs}
- adapterLocale={`${language}-hk`}
- >
- <DatePicker
- sx={{ width: "100%" }}
- label={t("Join Date")}
- // defaultValue={dayjs(getValues("joinDate"))}
- value={joinDate ? dayjs(joinDate) : null}
- onChange={(date) => {
- if (!date) return;
- setValue("joinDate", date.format(INPUT_DATE_FORMAT));
- }}
- slotProps={{
- textField: {
- // required: true,
- error:
- joinDate === "Invalid Date",
- // value: errors.joinDate?.message,
- },
- }}
- />
- </LocalizationProvider>
- </Grid>
- <Grid item xs={6}>
- <FormControl fullWidth>
- <InputLabel>{t("Join Position")}</InputLabel>
- <Controller
- control={control}
- name="joinPositionId"
- render={({ field }) => (
- <Select
- label={t("Join Position")}
- {...field}
- error={Boolean(errors.joinPositionId)}
- >
- {combos.position.map((position, index) => (
- <MenuItem
- key={`${position.id}-${index}`}
- value={position.id}
- >
- {t(position.label)}
- </MenuItem>
- ))}
- </Select>
- )}
- />
- </FormControl>
- </Grid>
- <Grid item xs={6}>
- <LocalizationProvider
- dateAdapter={AdapterDayjs}
- adapterLocale={`${language}-hk`}
- >
- <DatePicker
- sx={{ width: "100%" }}
- label={t("Depart Date")}
- value={departDate ? dayjs(departDate) : null}
- onChange={(date) => {
- if (!date) return;
- setValue("departDate", date.format(INPUT_DATE_FORMAT));
- }}
- slotProps={{
- textField: {
- error: joinDate && departDate
- ? new Date(joinDate) > new Date(departDate)
- : false,
- },
- }}
- />
- </LocalizationProvider>
- </Grid>
- <Grid item xs={6}>
- <TextField
- label={t("Depart Reason")}
- fullWidth
- {...register("departReason")}
- error={Boolean(errors.departReason)}
- helperText={
- Boolean(errors.departReason) &&
- (errors.departReason?.message
- ? t(errors.departReason.message)
- : t("Please input correct departReason"))
- }
- />
- </Grid>
- <Grid item xs={12}>
- <TextField
- label={t("Remark")}
- fullWidth
- multiline
- rows={4}
- {...register("remark")}
- error={Boolean(errors.remark)}
- helperText={
- Boolean(errors.remark) &&
- (errors.remark?.message
- ? t(errors.remark.message)
- : t("Please input correct remark"))
- }
- />
- </Grid>
- </Grid>
- </Box>
- </CardContent>
- <SalaryEffectiveModel
- open={salaryEffectiveModelOpen}
- onClose={closeSalaryEffectiveModel}
- onSave={onSalaryEffectiveSave}
- columns={salaryCols}
- />
- </Card>
- );
- };
-
- export default StaffInfo;
|