"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 FormControl from "@mui/material/FormControl"; import Grid from "@mui/material/Grid"; import InputLabel from "@mui/material/InputLabel"; import MenuItem from "@mui/material/MenuItem"; import Select from "@mui/material/Select"; import TextField from "@mui/material/TextField"; import Typography from "@mui/material/Typography"; import { useTranslation } from "react-i18next"; import CardActions from "@mui/material/CardActions"; import RestartAlt from "@mui/icons-material/RestartAlt"; import Button from "@mui/material/Button"; import { Controller, useFormContext } from "react-hook-form"; import { CreateProjectInputs } from "@/app/api/projects/actions"; import { BuildingType, ContractType, FundingType, LocationType, MainProject, ProjectCategory, ServiceType, WorkNature, } from "@/app/api/projects"; import { StaffResult } from "@/app/api/staff"; import { Contact, Customer, Subsidiary } from "@/app/api/customer"; import Link from "next/link"; import React, { useEffect, useMemo, useState } from "react"; import { fetchCustomer } from "@/app/api/customer/actions"; import { Autocomplete, Checkbox, ListItemText } from "@mui/material"; import uniq from "lodash/uniq"; import ControlledAutoComplete from "../ControlledAutoComplete/ControlledAutoComplete"; interface Props { isActive: boolean; isSubProject: boolean; isEditMode: boolean; mainProjects?: MainProject[]; projectCategories: ProjectCategory[]; teamLeads: StaffResult[]; allCustomers: Customer[]; allSubsidiaries: Subsidiary[]; serviceTypes: ServiceType[]; contractTypes: ContractType[]; fundingTypes: FundingType[]; locationTypes: LocationType[]; buildingTypes: BuildingType[]; workNatures: WorkNature[]; } const ProjectClientDetails: React.FC = ({ isActive, isSubProject, isEditMode, mainProjects, projectCategories, teamLeads, allCustomers, allSubsidiaries, serviceTypes, contractTypes, fundingTypes, locationTypes, buildingTypes, workNatures, }) => { const { t } = useTranslation(); const { register, formState: { errors, defaultValues }, watch, control, setValue, getValues, reset, resetField, } = useFormContext(); const subsidiaryMap = useMemo<{ [id: Subsidiary["id"]]: Subsidiary; }>( () => allSubsidiaries.reduce((acc, sub) => ({ ...acc, [sub.id]: sub }), {}), [allSubsidiaries], ); const selectedCustomerId = watch("clientId"); const selectedCustomer = useMemo( () => allCustomers.find((c) => c.id === selectedCustomerId), [allCustomers, selectedCustomerId], ); const [customerContacts, setCustomerContacts] = useState([]); const [subsidiaryContacts, setSubsidiaryContacts] = useState([]); const [customerSubsidiaryIds, setCustomerSubsidiaryIds] = useState( [], ); const selectedCustomerContactId = watch("clientContactId"); const selectedCustomerContact = useMemo( () => subsidiaryContacts.length > 0 ? subsidiaryContacts.find((contact) => contact.id === selectedCustomerContactId) : customerContacts.find( (contact) => contact.id === selectedCustomerContactId, ), [subsidiaryContacts, customerContacts, selectedCustomerContactId], ); // get customer (client) contact combo const clientSubsidiaryId = watch("clientSubsidiaryId") const [firstCustomerLoaded, setFirstCustomerLoaded] = useState(false) useEffect(() => { if (selectedCustomerId !== undefined) { fetchCustomer(selectedCustomerId).then(({ contacts, subsidiaryIds }) => { setCustomerContacts(contacts); setCustomerSubsidiaryIds(subsidiaryIds); // if (subsidiaryIds.length > 0) setValue("clientSubsidiaryId", subsidiaryIds[0]) // else if (isEditMode && !firstCustomerLoaded) { setFirstCustomerLoaded(true) } else if (subsidiaryIds.length > 0) setValue("clientSubsidiaryId", clientSubsidiaryId !== undefined && clientSubsidiaryId !== null ? subsidiaryIds.includes(clientSubsidiaryId) ? clientSubsidiaryId : null : null) // if (contacts.length > 0) setValue("clientContactId", contacts[0].id) // else setValue("clientContactId", undefined) }); } }, [selectedCustomerId]); useEffect(() => { if (Boolean(clientSubsidiaryId)) { // get subsidiary contact combo const contacts = allSubsidiaries.find(subsidiary => subsidiary.id === clientSubsidiaryId)?.subsidiaryContacts!! setSubsidiaryContacts(() => contacts) setValue("clientContactId", selectedCustomerId === defaultValues?.clientId && Boolean(defaultValues?.clientSubsidiaryId) ? contacts.find(contact => contact.id === defaultValues.clientContactId)?.id ?? contacts[0].id : contacts[0].id) setValue("isSubsidiaryContact", true) } else if (customerContacts?.length > 0) { setSubsidiaryContacts(() => []) setValue("clientContactId", selectedCustomerId === defaultValues?.clientId && !Boolean(defaultValues?.clientSubsidiaryId) ? customerContacts.find(contact => contact.id === defaultValues.clientContactId)?.id ?? customerContacts[0].id : customerContacts[0].id) setValue("isSubsidiaryContact", false) } }, [customerContacts, clientSubsidiaryId, selectedCustomerId]); // Automatically add the team lead to the allocated staff list const selectedTeamLeadId = watch("projectLeadId"); useEffect(() => { if (selectedTeamLeadId !== undefined) { const currentStaffIds = getValues("allocatedStaffIds"); const newList = uniq([...currentStaffIds, selectedTeamLeadId]); setValue("allocatedStaffIds", newList); } }, [getValues, selectedTeamLeadId, setValue]); // Automatically update the project & client details whene select a main project const mainProjectId = watch("mainProjectId") useEffect(() => { if (mainProjectId !== undefined && mainProjects !== undefined && !isEditMode) { const mainProject = mainProjects.find(project => project.projectId === mainProjectId); if (mainProject !== undefined) { setValue("projectName", mainProject.projectName) setValue("projectCategoryId", mainProject.projectCategoryId) setValue("projectLeadId", mainProject.projectLeadId) setValue("serviceTypeId", mainProject.serviceTypeId) setValue("fundingTypeId", mainProject.fundingTypeId) setValue("contractTypeId", mainProject.contractTypeId) setValue("locationId", mainProject.locationId) setValue("buildingTypeIds", mainProject.buildingTypeIds) setValue("workNatureIds", mainProject.workNatureIds) setValue("projectDescription", mainProject.projectDescription) setValue("expectedProjectFee", mainProject.expectedProjectFee) setValue("isClpProject", mainProject.isClpProject) setValue("clientId", mainProject.clientId) setValue("clientSubsidiaryId", mainProject.clientSubsidiaryId) setValue("clientContactId", mainProject.clientContactId) } } }, [getValues, mainProjectId, setValue, isEditMode]) // const buildingTypeIdNameMap = buildingTypes.reduce<{ [id: number]: string }>( // (acc, building) => ({ ...acc, [building.id]: building.name }), // {}, // ); // const workNatureIdNameMap = workNatures.reduce<{ [id: number]: string }>( // (acc, wn) => ({ ...acc, [wn.id]: wn.name }), // {}, // ); return ( {t("Project Details")} { isSubProject && mainProjects !== undefined && <> ({ id: mainProject.projectId, label: `${mainProject.projectCode} - ${mainProject.projectName}` }))]} name="mainProjectId" label={t("Main Project")} noOptionsText={t("No Main Project")} disabled={isEditMode} /> } ({ ...staff, label: `${staff.staffId} - ${staff.name} (${staff.team})` }))} name="projectLeadId" label={t("Team Lead")} noOptionsText={t("No Team Lead")} /> {t("CLP Project")} {t("Client Details")} ({ ...customer, label: `${customer.code} - ${customer.name}` }))} name="clientId" label={t("Client")} noOptionsText={t("No Client")} rules={{ required: "Please select a client" }} /> {customerContacts.length > 0 && ( <> subsidiaryMap[subId]) .map((subsidiaryId, index) => { const subsidiary = subsidiaryMap[subsidiaryId] return { id: subsidiary.id, label: `${subsidiary.code} - ${subsidiary.name}` } })]} name="clientSubsidiaryId" label={t("Client Subsidiary")} noOptionsText={t("No Client Subsidiary")} /> { if ( (customerContacts.length > 0 && !customerContacts.find( (contact) => contact.id === value, )) && (subsidiaryContacts?.length > 0 && !subsidiaryContacts.find( (contact) => contact.id === value, )) ) { return t("Please provide a valid contact"); } else return true; }, }} /> )} {/* */} ); }; export default ProjectClientDetails;