clientsInProgress

mail@pastecode.io avatar
unknown
plain_text
a year ago
5.9 kB
1
Indexable
Never
import { Box, TextField, Typography } from '@mui/material';
import { Client } from '../../common/types/client';
import { ClientProcess } from '../../common/types/clientProcess';
import { DataGrid, GridColumns, GridFilterModel, GridRowParams } from '@mui/x-data-grid';
import { useDebounce } from 'usehooks-ts';
import { useIsAdviser } from '../../common/hooks/auth';
import { useMemo, useState } from 'react';
import { useQuery } from '@tanstack/react-query';
import AdviserContactDialog from '../../advisers/components/dialogs/contact';
import AdviserDecisionDialog from '../../advisers/components/dialogs/decision';
import AdviserEficaDialog from '../../advisers/components/dialogs/eficaDialog';
import AllocateDialog from '../../ops/components/dialogs/allocateDialog';
import ClientProcessSelector from './clientProcessSelector';
import ContactDialog from '../../ops/components/dialogs/contactDialog';
import EficaDialog from '../../ops/components/dialogs/eficaDialog';
import MonitoringDialog from '../../ops/components/dialogs/monitoringDialog';
import PreContactDialog from '../../ops/components/dialogs/preContactDialog';
import ProcessIndicator from '../../common/components/stepIndicator';
import StepDialog, { StepContentProps } from '../../common/components/stepDialog';
import VerifyDialog from '../../ops/components/dialogs/verifyDialog';

type StepComponentType = ((props: StepContentProps) => JSX.Element) & { formId?: string };

const processNameToComponent: Record<string, StepComponentType> = {
  verify: VerifyDialog,
  efica: EficaDialog,
  precontact: PreContactDialog,
  contact: ContactDialog,
  allocate: AllocateDialog,
  monitor: MonitoringDialog,
  agent_contact: AdviserContactDialog,
  agent_decision: AdviserDecisionDialog,
  agent_efica: AdviserEficaDialog,
};

interface IClientsInProgressProps {
  apiQueryFilters?: Record<string, string | number>;
}

const ClientsInProgress = ({ apiQueryFilters }: IClientsInProgressProps) => {
  const { data: clients } = useQuery<Client[]>({
    queryKey: ['/Ops/ClientLists', apiQueryFilters],
  });
  const [filterModel, setFilterModel] = useState<GridFilterModel>();
  const debounceFilterModel = useDebounce(filterModel, 500);
  const [selectedClientPayload, setSelectedClientPayload] = useState<{
    clientId: number;
    process: ClientProcess;
    openNotes?: boolean;
  }>();
  const selectedClient = useMemo(
    () => clients?.find(({ id }) => id === selectedClientPayload?.clientId),
    [selectedClientPayload?.clientId, clients],
  );
  const isAdviser = useIsAdviser();

  const handleSelectProcess = (process: ClientProcess, client: Client, openNotes) => {
    setSelectedClientPayload({
      process,
      clientId: client.id,
      openNotes,
    });
  };

  const handleFilterClients = (query: string) => {
    setFilterModel({
      items: [],
      quickFilterValues: [query],
    });
  };

  const handleCloseStepDialog = () => setSelectedClientPayload(undefined);
  const StepComponent = selectedClientPayload?.process?.name
    ? processNameToComponent[selectedClientPayload.process.name]
    : undefined;
  const columns: GridColumns<Client> = [
    {
      field: 'fullname',
      headerName: 'Client',
      flex: 1,
      minWidth: 180,
      renderCell: ({ row }) => (
        <Typography fontWeight={600} variant="caption">
          {row.fullname}
        </Typography>
      ),
    },
    { field: 'email', headerName: 'Email', minWidth: 250, flex: 1 },
    { field: 'phone', headerName: 'Cellphone', width: 130 },
    { field: 'idNumber', headerName: 'ID number', width: 100 },
    {
      field: 'processName',
      headerName: 'Status',
      width: 270,
      valueGetter: ({ row }) => row.processID,
      renderCell: ({ row }) => <ProcessIndicator client={row} />,
    },
    {
      field: 'process',
      hide: true,
    },
    {
      field: 'actions',
      type: 'actions',
      renderHeader: () =>
        (apiQueryFilters?.isAllocated === 0 && !isAdviser) ||
        (isAdviser && !apiQueryFilters?.isSigned) ? (
          <Box width={180} justifyContent="space-between" display="flex">
            <Typography color="#B9BBBF" fontSize="14px" fontWeight={500}>
              Change step
            </Typography>
            <Typography color="#B9BBBF" fontSize="14px" ml={1} fontWeight={500}>
              History
            </Typography>
          </Box>
        ) : null,
      width: 220,
      getActions: ({ row }: GridRowParams<Client>) => [
        <ClientProcessSelector
          key="dropdown"
          client={row}
          onChange={(process, openNotes) => handleSelectProcess(process, row, openNotes)}
        />,
      ],
    },
  ];

  return (
    <Box>
      <TextField
        sx={{ mb: 2 }}
        onChange={(event) => handleFilterClients(event.target.value)}
        placeholder="Filter clients..."
      />
      <DataGrid
        autoHeight
        disableSelectionOnClick
        filterModel={debounceFilterModel}
        rows={clients || []}
        columns={columns}
        sx={{
          '& .MuiDataGrid-columnHeaderTitle': {
            color: '#B9BBBF',
          },
        }}
        hideFooter
        disableColumnMenu
        rowHeight={60}
        headerHeight={55}
      />
      {StepComponent && selectedClientPayload && selectedClient && (
        <StepDialog
          clientId={selectedClient.id}
          process={selectedClientPayload.process}
          onClose={handleCloseStepDialog}
          formId={StepComponent.formId}
          defaultOpenDialog={selectedClientPayload.openNotes ? 'notes' : null}
        >
          {(client) => (
            <StepComponent
              onClose={handleCloseStepDialog}
              client={client}
              process={selectedClientPayload.process}
            />
          )}
        </StepDialog>
      )}
    </Box>
  );
};

export default ClientsInProgress;