stepDialogHeader

mail@pastecode.io avatar
unknown
plain_text
a year ago
7.8 kB
1
Indexable
Never
import {
  Avatar,
  Box,
  Button,
  Card,
  CardContent,
  Divider,
  Grid,
  Stack,
  Typography,
} from '@mui/material';
import { calculateAge } from '../../lib/date';
import { ClientFull } from '../../types/client';
import {
  ClientProcess,
  monitorFakeProcess,
  PROCESS_AGENT_EFICA_ID,
  PROCESS_ALLOCATE_ID,
  PROCESS_SIGNED_ID,
} from '../../types/clientProcess';
import { Icon } from '@iconify/react';
import { LoadingButton } from '@mui/lab';
import { STATE_DONE_ID } from '../../types/clientState';
import { useQueryProcesses } from '../../hooks/useQueryProcesses';
import { useRef, useState } from 'react';
import { useUpdateClientProcessMutation } from '../../../ops/mutations';
import BaseDialogHeader, { DialogHeaderDivider } from '../dialog/baseDialogHeader';
import ContactsDialog from '../../../clients/components/contactsDialog';
import Content from '../context';
import NotesDialog from '../../../clients/components/notesDialog';
import PoliciesDialog from '../../../clients/components/policiesDialog';

const buttonSx = {
  color: 'primary.main',
  borderColor: 'common.borderGray',
  fontWeight: 500,
  width: 135,
};

export interface StepDialogHeaderProps {
  client: ClientFull;
  process: ClientProcess;
  onClose: () => void;
  formId?: string;
  defaultOpenDialog: OpenDialogState;
}

type OpenDialogState = 'contacts' | 'notes' | 'policies' | null;

const StepDialogHeader = ({
  defaultOpenDialog = null,
  client,
  process,
  onClose,
  formId,
}: StepDialogHeaderProps) => {
  const closeButtonRef = useRef<HTMLButtonElement>(null);
  const [openedDialog, setOpenedDialog] = useState<OpenDialogState>(defaultOpenDialog);
  const { data: clientProcesses, isLoading: clientProcessesLoading } = useQueryProcesses();
  const mutation = useUpdateClientProcessMutation();
  const isLoading = mutation.isLoading || clientProcessesLoading;
  const currentClientProcessIndex = clientProcesses
    ? clientProcesses.findIndex(({ id }) => id === client.processID)
    : -1;
  const selectedProcessIndex = clientProcesses
    ? clientProcesses.findIndex(({ id }) => id === process.id)
    : -1;
  const isSelectedProcessActive = client.processID === process.id;
  const canChangeProcessStatus =
    isSelectedProcessActive || selectedProcessIndex === currentClientProcessIndex + 1;
  const formatClientName = (string: string) => {
    return string
      .split(' ')
      .map((el) => `${el.slice(0, 1).toUpperCase()}${el.slice(1).toLowerCase()}`)
      .join(' ');
  };
  const handleChangeState = (newStateId: number) => {
    // if user change status to "Done", then close the dialog
    if (newStateId === STATE_DONE_ID) {
      closeButtonRef.current?.click();
    }

    const handleMutationSuccess = () => {
      // if adviser are marking efica step as done, then we should move client to signed step and mark it as done too
      // to move a client to the "signed" section
      if (newStateId === STATE_DONE_ID && process.id === PROCESS_AGENT_EFICA_ID) {
        mutation.mutate({ ID: client.id, stateID: STATE_DONE_ID, processID: PROCESS_SIGNED_ID });
      }
    };

    mutation.mutate(
      { ID: client.id, stateID: newStateId, processID: process.id },
      { onSuccess: handleMutationSuccess },
    );
  };

  const handleCloseSubDialog = () => setOpenedDialog(null);
  console.log(client);
  return (
    <>
      <BaseDialogHeader>
        <Button
          ref={closeButtonRef}
          startIcon={<Icon icon="mdi:chevron-left" />}
          variant="outlined"
          color="white"
          // If form id is presented then "close" button should behave as form submit button, otherwise it should just close dialog
          {...(formId ? { type: 'submit', form: formId } : { onClick: onClose })}
        >
          Back
        </Button>
        <DialogHeaderDivider />
        <Box sx={{ flexGrow: 1 }}>
          <Typography variant="h3">{process.note}</Typography>
        </Box>
        {/* Hide status control for monitoring and allocate steps */}
        {process.id !== monitorFakeProcess.id && process.id !== PROCESS_ALLOCATE_ID && (
          <>
            <LoadingButton
              loading={isLoading}
              color={canChangeProcessStatus ? 'success' : 'white'}
              variant={canChangeProcessStatus ? 'contained' : 'outlined'}
              onClick={() => canChangeProcessStatus && handleChangeState(STATE_DONE_ID)}
              sx={(theme) => ({
                '&.MuiLoadingButton-loading': {
                  backgroundColor: '#ffffff33',
                },
                '& .MuiLoadingButton-loadingIndicator': {
                  color: theme.palette.common.white,
                },
              })}
            >
              {canChangeProcessStatus ? 'Finish Step' : 'Completed'}
            </LoadingButton>
          </>
        )}
      </BaseDialogHeader>
      <Content sx={{ py: 4 }}>
        <Card
          sx={{ backgroundColor: '#FBFCFD', border: 1, borderColor: '#C7C8CA45' }}
          elevation={0}
        >
          <CardContent sx={{ p: { xs: 1, sm: 4 } }}>
            <Grid container spacing={{ xs: 2, md: 3 }} columns={{ xs: 4, sm: 8, md: 12 }}>
              <Grid item xs={6} sx={{ display: 'flex', alignItems: 'center' }}>
                <Avatar alt={client.fullname} sx={{ width: 80, height: 80 }} />
                <Box sx={{ ml: 3 }}>
                  <Typography variant="h2" color="primary.main">
                    {formatClientName(client.fullname)}
                  </Typography>
                  <Typography sx={{ mt: 1 }} variant="body2" color="text.secondary">
                    Age: {client.dateofbirth ? calculateAge(client.dateofbirth) : '-'} |{' '}
                    {client.genderNote} | {client.maritalStatus}
                  </Typography>
                </Box>
              </Grid>
              <Grid item xs={6}>
                <Stack
                  spacing={1}
                  direction={{ xs: 'column', sm: 'row' }}
                  alignItems="center"
                  justifyContent="flex-end"
                  height="100%"
                >
                  <Button
                    fullWidth
                    sx={buttonSx}
                    variant="outlined"
                    onClick={() => setOpenedDialog('policies')}
                  >
                    Policy details
                  </Button>
                  <Button
                    fullWidth
                    sx={buttonSx}
                    variant="outlined"
                    color="primary"
                    onClick={() => setOpenedDialog('contacts')}
                  >
                    Contact
                  </Button>
                  <Button
                    fullWidth
                    sx={buttonSx}
                    onClick={() => setOpenedDialog('notes')}
                    variant="outlined"
                    color="primary"
                  >
                    <Box mr={1} display="flex" justifyContent="center">
                      <Icon icon="ic:baseline-history" width={24} />
                    </Box>
                    History
                  </Button>
                </Stack>
              </Grid>
            </Grid>
          </CardContent>
        </Card>
        <NotesDialog
          client={client}
          open={openedDialog === 'notes'}
          onClose={handleCloseSubDialog}
        />
        <PoliciesDialog
          client={client}
          open={openedDialog === 'policies'}
          onClose={handleCloseSubDialog}
        />
        <ContactsDialog
          client={client}
          open={openedDialog === 'contacts'}
          onClose={handleCloseSubDialog}
        />
      </Content>
    </>
  );
};

export default StepDialogHeader;