|
- "use client";
- import React, { useCallback, useEffect, useMemo, useState } from "react";
- import CustomInputForm from "../CustomInputForm";
- import { useRouter, useSearchParams } from "next/navigation";
- import { useTranslation } from "react-i18next";
- import {
- FieldErrors,
- FormProvider,
- SubmitErrorHandler,
- SubmitHandler,
- useForm,
- useFormContext,
- } from "react-hook-form";
- import { CreateTeamInputs } from "@/app/api/team/actions";
- import { Staff4TransferList, fetchStaffCombo } from "@/app/api/staff/actions";
- import { StaffResult, StaffTeamTable } from "@/app/api/staff";
- import SearchResults, { Column } from "../SearchResults";
- import { Clear, PersonAdd, PersonRemove, Search } from "@mui/icons-material";
- import {
- Card,
- Box,
- CardContent,
- Grid,
- IconButton,
- InputAdornment,
- Stack,
- Tab,
- Tabs,
- TabsProps,
- TextField,
- Typography,
- } from "@mui/material";
- import { differenceBy } from "lodash";
- import StarsIcon from "@mui/icons-material/Stars";
-
- export interface Props {
- allStaffs: StaffResult[];
- teamLead: number;
- }
-
- const Allocation: React.FC<Props> = ({ allStaffs: staff, teamLead }) => {
- const { t } = useTranslation();
- const searchParams = useSearchParams();
- const idString = searchParams.get("id");
- const {
- setValue,
- getValues,
- formState: { defaultValues },
- reset,
- resetField,
- } = useFormContext<CreateTeamInputs>();
-
- const initialStaffs = staff.map((s) => ({ ...s }));
- const [filteredStaff, setFilteredStaff] = useState(initialStaffs);
- const [selectedStaff, setSelectedStaff] = useState<typeof filteredStaff>(() => {
- const rearrangedStaff = filteredStaff.sort((a, b) => {
- if (a.id === teamLead) return -1;
- if (b.id === teamLead) return 1;
- return 0;
- });
- return rearrangedStaff.filter((s) => getValues("addStaffIds")?.includes(s.id))
- }
- );
- const [seletedTeamLead, setSeletedTeamLead] = useState<number>();
- const [deletedStaffIds, setDeletedStaffIds] = useState<number[]>([]);
-
- // Adding / Removing staff
- const addStaff = useCallback((staff: StaffResult) => {
- setSelectedStaff((s) => [...s, staff]);
- // setDeletedStaffIds((s) => s.filter((s) => s === selectedStaff.id))
- }, []);
-
- const removeStaff = useCallback((staff: StaffResult) => {
- setSelectedStaff((s) => s.filter((s) => s.id !== staff.id));
- // setDeletedStaffIds((s) => s)
- setDeletedStaffIds((prevIds) => [...prevIds, staff.id]);
- }, []);
-
- const setTeamLead = useCallback(
- (staff: StaffResult) => {
- setSeletedTeamLead(staff.id);
- const rearrangedList = getValues("addStaffIds").reduce<number[]>(
- (acc, num, index) => {
- if (num === staff.id && index !== 0) {
- acc.splice(index, 1);
- acc.unshift(num);
- }
- return acc;
- },
- getValues("addStaffIds")
- );
- // console.log(rearrangedList);
- // console.log(selectedStaff);
-
- const rearrangedStaff = rearrangedList.map((id) => {
- return selectedStaff.find((staff) => staff.id === id);
- });
- console.log(rearrangedStaff);
- setSelectedStaff(rearrangedStaff as StaffResult[]);
-
- setValue("addStaffIds", rearrangedList);
- },
- [addStaff, selectedStaff]
- );
-
- const clearSubsidiary = useCallback(() => {
- if (defaultValues !== undefined) {
- resetField("addStaffIds");
- setSelectedStaff(
- initialStaffs.filter((s) => defaultValues.addStaffIds?.includes(s.id))
- );
- }
- }, [defaultValues]);
-
- // Sync with form
- useEffect(() => {
- setValue(
- "addStaffIds",
- selectedStaff.map((s) => s.id)
- );
- }, [selectedStaff, setValue]);
-
- useEffect(() => {
- setValue("deleteStaffIds", deletedStaffIds)
- console.log(deletedStaffIds)
- }, [deletedStaffIds]);
-
- const StaffPoolColumns = useMemo<Column<StaffResult>[]>(
- () => [
- {
- label: t("Add"),
- name: "id",
- onClick: addStaff,
- buttonIcon: <PersonAdd />,
- },
- { label: t("Staff Id"), name: "staffId" },
- { label: t("Staff Name"), name: "name" },
- { label: t("Current Position"), name: "currentPosition" },
- ],
- [addStaff, t]
- );
-
- const allocatedStaffColumns = useMemo<Column<StaffResult>[]>(
- () => [
- {
- label: t("Remove"),
- name: "action",
- onClick: removeStaff,
- buttonIcon: <PersonRemove />,
- },
- { label: t("Staff Id"), name: "staffId" },
- { label: t("Staff Name"), name: "name" },
- { label: t("Current Position"), name: "currentPosition" },
- {
- label: t("Team Lead"),
- name: "action",
- onClick: setTeamLead,
- buttonIcon: <StarsIcon />,
- },
- ],
- [removeStaff, selectedStaff, t]
- );
-
- const [query, setQuery] = React.useState("");
- const onQueryInputChange = React.useCallback<
- React.ChangeEventHandler<HTMLInputElement>
- >((e) => {
- setQuery(e.target.value);
- }, []);
- const clearQueryInput = React.useCallback(() => {
- setQuery("");
- }, []);
-
- React.useEffect(() => {
- // setFilteredStaff(
- // initialStaffs.filter((s) => {
- // const q = query.toLowerCase();
- // // s.staffId.toLowerCase().includes(q)
- // // const q = query.toLowerCase();
- // // return s.name.toLowerCase().includes(q);
- // // s.code.toString().includes(q) ||
- // // (s.brNo != null && s.brNo.toLowerCase().includes(q))
- // })
- // );
- }, [staff, query]);
-
- useEffect(() => {
- // console.log(getValues("addStaffIds"))
- }, [initialStaffs]);
-
- const resetStaff = React.useCallback(() => {
- clearQueryInput();
- clearSubsidiary();
- }, [clearQueryInput, clearSubsidiary]);
-
- const formProps = useForm({});
-
- // Tab related
- const [tabIndex, setTabIndex] = React.useState(0);
- const handleTabChange = React.useCallback<NonNullable<TabsProps["onChange"]>>(
- (_e, newValue) => {
- setTabIndex(newValue);
- },
- []
- );
- return (
- <>
- <FormProvider {...formProps}>
- <Card sx={{ display: "block" }}>
- <CardContent
- sx={{ display: "flex", flexDirection: "column", gap: 1 }}
- >
- <Stack gap={2}>
- <Typography variant="overline" display="block">
- {t("staff")}
- </Typography>
- <Grid container spacing={2} columns={{ xs: 6, sm: 12 }}>
- <Grid item xs={6} display="flex" alignItems="center">
- <Search sx={{ marginInlineEnd: 1 }} />
- <TextField
- variant="standard"
- fullWidth
- onChange={onQueryInputChange}
- value={query}
- placeholder={t("Search by staff ID, name or position.")}
- InputProps={{
- endAdornment: query && (
- <InputAdornment position="end">
- <IconButton onClick={clearQueryInput}>
- <Clear />
- </IconButton>
- </InputAdornment>
- ),
- }}
- />
- </Grid>
- </Grid>
- <Tabs value={tabIndex} onChange={handleTabChange}>
- <Tab label={t("Staff Pool")} />
- <Tab
- label={`${t("Allocated Staff")} (${selectedStaff.length})`}
- />
- </Tabs>
- <Box sx={{ marginInline: -3 }}>
- {tabIndex === 0 && (
- <SearchResults
- noWrapper
- items={differenceBy(filteredStaff, selectedStaff, "id")}
- columns={StaffPoolColumns}
- />
- )}
- {tabIndex === 1 && (
- <SearchResults
- noWrapper
- items={selectedStaff}
- columns={allocatedStaffColumns}
- />
- )}
- </Box>
- </Stack>
- </CardContent>
- </Card>
- </FormProvider>
- </>
- );
- };
-
- export default Allocation;
|