All files / src/components/rent_rental RentRentalForm.tsx

0% Statements 0/86
0% Branches 0/1
0% Functions 0/1
0% Lines 0/86

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136                                                                                                                                                                                                                                                                               
import { Controller, SubmitHandler, useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { Dispatch, FC, SetStateAction, useEffect, useState } from 'react';
import { ErrorMessage } from '@hookform/error-message';
import { ErrorResponse } from '../../models/errorResponse';
import { OkResponse } from '../../models/okResponse';
import { Pending } from '../../models/pending';
import { rentalSchema, RentalSchemaType } from '../../validations/rental';
import { DesktopDatePicker, LocalizationProvider } from '@mui/x-date-pickers';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
import dayjs from 'dayjs';
import { useFetchRentRental } from '../../hooks/useFetchRentRental';
import styled from 'styled-components';
import { StyledInput } from '../../global';
import { StyledErrorMessageWrapper } from '../../global';
 
type Props = {
  id: string;
  setResult: Dispatch<SetStateAction<OkResponse | ErrorResponse | Pending | null>>;
};
 
const StyledTitle = styled.h1`
  font-size: 2.6rem;
  font-weight: 400;
  text-align: center;
`;
 
const StyledBox = styled.div`
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
`;
 
const StyledLabel = styled.label`
  display: block;
  font-size: 1.6rem;
  margin: 20px 0 5px 0;
  padding: 0;
`;
 
const StyledSubmitWrapper = styled.div`
  display: flex;
  justify-content: center;
  width: 100%;
  margin: 50px 0 10px 0;
`;
 
const StyledSubmitInput = styled.input`
  padding: 5px 20px;
  background-color: #caad63;
  border: none;
  font-size: 1.6rem;
  cursor: pointer;
`;
 
const RentRentalForm: FC<Props> = (props) => {
  const [cleared, setCleared] = useState<boolean>(false);
  useEffect(() => {
    if (cleared) {
      const timeout = setTimeout(() => {
        setCleared(false);
      }, 10);
 
      return () => clearTimeout(timeout);
    }
    return () => {};
  }, [cleared]);
  const {
    register,
    handleSubmit,
    formState: { errors },
    control,
  } = useForm<RentalSchemaType>({
    resolver: zodResolver(rentalSchema),
  });
  const onSubmit: SubmitHandler<RentalSchemaType> = async (formData) => {
    console.table(formData);
    props.setResult('pending');
    const result: ErrorResponse | OkResponse = await useFetchRentRental(parseInt(props.id), formData);
    props.setResult(result);
  };
  return (
    <StyledBox>
      <StyledTitle>貸し出し情報の登録</StyledTitle>
      <form onSubmit={handleSubmit(onSubmit)}>
        <StyledLabel htmlFor="recipient">借用者</StyledLabel>
        <StyledInput id="recipient" type="text" {...register('recipient')} />
        <br />
        <StyledErrorMessageWrapper>
          <ErrorMessage errors={errors} name="recipient" message={errors.recipient?.message} />
        </StyledErrorMessageWrapper>
        <br />
        <StyledLabel htmlFor="rental_description">貸し出しに関する備考</StyledLabel>
        <StyledInput id="rental_description" type="text" {...register('rental_description')} />
        <br />
        <StyledErrorMessageWrapper>
          <ErrorMessage errors={errors} name="rental_description" message={errors.rental_description?.message} />
        </StyledErrorMessageWrapper>
        <br />
        <StyledLabel htmlFor="scheduled_replace_at">返却予定日</StyledLabel>
        <Controller
          name="scheduled_replace_at"
          control={control}
          render={({ field }) => (
            <LocalizationProvider {...field} dateAdapter={AdapterDayjs}>
              <DesktopDatePicker
                label="scheduled_replace_at"
                onChange={(value) =>
                  field.onChange(value === null ? '' : dayjs(value).format('YYYY-MM-DD[T]HH:mm:ss[Z]'))
                }
                format="YYYY/MM/DD"
                slotProps={{
                  calendarHeader: { format: 'YYYY年MM月' },
                  field: { clearable: true, onClear: () => setCleared(true) },
                }}
              />
            </LocalizationProvider>
          )}
        />
        <br />
        <StyledErrorMessageWrapper>
          <ErrorMessage errors={errors} name="scheduled_replace_at" message={errors.scheduled_replace_at?.message} />
        </StyledErrorMessageWrapper>
        <br />
        <StyledSubmitWrapper>
          <StyledSubmitInput type="submit" value="貸し出し" />
        </StyledSubmitWrapper>
      </form>
    </StyledBox>
  );
};
 
export default RentRentalForm;