Загрузка данных


import { ContractorAutocomplete } from '@/entities/Location/components/ContractorAutocomplete';
import { AppConsts } from '@/shared';
import {
  NUMBER_FIELD_SYMBOLS_LIMIT,
  TICKET_DESCRIPTION_SYMBOLS_LIMIT,
} from '@/shared/consts/constants';
import { useFieldValidation } from '@/shared/hooks/useFieldValidation';
import { useGetLocationUUID } from '@/shared/hooks/useGetLocationUUID';
import { isMultilineValue } from '@/utils';
import { ticketDrawerSchema } from '@/widgets/TicketDrawer/schema/ticketSchema';
import { yupResolver } from '@hookform/resolvers/yup';
import { useCreateLocationTicketMutation } from '@shared/api/location/client';
import {
  Button,
  DateTimeField,
  Drawer,
  DrawerActions,
  TextField,
} from '@shared/components';
import { useCloseDrawer } from '@shared/hooks/drawer/useCloseDrawer';
import {
  EventActionTypes,
  useSendClickStreamEvent,
} from '@shared/hooks/useSendClickStreamEvent';
import { DrawerTypes } from '@shared/model/drawer/drawer.types';
import dayjs from 'dayjs';
import { useEffect } from 'react';
import {
  Controller,
  FormProvider,
  SubmitHandler,
  useForm,
} from 'react-hook-form';
import { useTranslation } from 'react-i18next';

type Value = {
  field: 'number' | 'description';
  limitedSymbols?: number;
};

const INPUT_VALUES: Value[] = [
  { field: 'number', limitedSymbols: NUMBER_FIELD_SYMBOLS_LIMIT },
  { field: 'description', limitedSymbols: TICKET_DESCRIPTION_SYMBOLS_LIMIT },
];

export const TicketCreateDrawer = () => {
  const { id } = useGetLocationUUID();

  const { t } = useTranslation('common');
  const { sendEvent } = useSendClickStreamEvent(
    EventActionTypes.createLocationTicket,
  );

  const closeDrawer = useCloseDrawer();

  const methods = useForm({
    mode: 'onBlur',
    defaultValues: {
      number: '',
      deadline: undefined,
      registeredAt: new Date(),
      description: '',
      contractorId: null,
    },
    resolver: yupResolver(ticketDrawerSchema),
  });

  const {
    control,
    handleSubmit,
    reset,
    getValues,
    formState: { isDirty, isValid },
  } = methods;

  const { isRequiredField } = useFieldValidation(ticketDrawerSchema);

  const [createTicket, { isLoading, isSuccess, reset: resetCreateTicket }] =
    useCreateLocationTicketMutation();

  const handleSave: SubmitHandler<{
    number: string;
    deadline: Date;
    registeredAt: Date;
    description?: string;
    contractorId?: string | null;
  }> = (data) => {
    createTicket({
      locationTicketCreateRequest: {
        registeredAt: dayjs(data.registeredAt).format(
          AppConsts.Date.format.Rfc3339,
        ),
        number: data.number.trim(),
        deadline: dayjs(data.deadline).format(AppConsts.Date.format.Rfc3339),
        locationId: id,
        description: data?.description || '',
        contractorId: data?.contractorId || undefined,
      },
    });
  };

  useEffect(() => {
    if (isSuccess) {
      closeDrawer(DrawerTypes.ticketCreate);
      resetCreateTicket();
      reset();
      sendEvent();
    }
  }, [isSuccess]);

  const isSaveButtonDisabled = !isDirty || !isValid;

  const actions: DrawerActions = {
    actionPrimary: (
      <Button
        onClick={handleSubmit(handleSave)}
        loading={isLoading}
        disabled={isSaveButtonDisabled}
      >
        {t('buttons.save')}
      </Button>
    ),
  };

  const handleClose = () => {
    reset();
  };

  return (
    <FormProvider {...methods}>
      <Drawer
        type={DrawerTypes.ticketCreate}
        title={t('drawerTitle.createTicket')}
        actions={actions}
        onClose={handleClose}
      >
        {INPUT_VALUES.map((value) => (
          <Controller
            key={value.field}
            name={value.field}
            control={control}
            render={({ field, fieldState: { error } }) => (
              <TextField
                fullWidth
                label={t(value.field)}
                error={!!error?.message}
                limitedSymbols={value.limitedSymbols}
                helperText={t(error?.message as string)}
                multiline={isMultilineValue(value.field)}
                required={isRequiredField(value.field)}
                {...field}
              />
            )}
          />
        ))}

        <Controller
          control={control}
          name='registeredAt'
          render={({ field: { value, onChange } }) => (
            <DateTimeField
              label={t('createdAt')}
              value={value}
              onChange={onChange}
              required={isRequiredField('registredAt')}
              maxDate={getValues('deadline')}
              margin='none'
            />
          )}
        />
        <Controller
          control={control}
          name='deadline'
          render={({ field: { value, onChange } }) => (
            <DateTimeField
              label={t('ticket:deadline')}
              value={value}
              onChange={onChange}
              required={isRequiredField('deadline')}
              minDate={getValues('registeredAt')}
              margin='none'
            />
          )}
        />

        <ContractorAutocomplete />
      </Drawer>
    </FormProvider>
  );
};