Untitled

mail@pastecode.io avatar
unknown
plain_text
a month ago
5.2 kB
2
Indexable
Never
import { zodResolver } from '@hookform/resolvers/zod';
import { isEqual } from 'lodash';
import { useForm, useWatch } from 'react-hook-form';
import { useRouter } from 'next/navigation';
import Button from '@/components/ui/Button';
import DatePicker from '@/components/ui/DatePicker';
import { Form } from '@/components/ui/Form';
import Input from '@/components/ui/Input';
import TextArea from '@/components/ui/TextArea';
import { NewEntry } from '@/lib/api/entries/types';
import { BasicFormField } from '../components';
import { defaultFormValues } from './constants';
import { createEntrySchema, editEntrySchema } from './formSchema';

interface EntryFormProps {
  onSubmit(data: NewEntry): void;
  initialData?: Partial<NewEntry>;
  isSavingEntry?: boolean;
  isReadonly?: boolean;
}

const EntryForm = ({ onSubmit, initialData, isSavingEntry, isReadonly }: EntryFormProps) => {
  const isEditMode = !!initialData;
  const router = useRouter();
  const form = useForm<NewEntry>({
    resolver: zodResolver(isEditMode ? editEntrySchema : createEntrySchema),
    defaultValues: initialData || defaultFormValues,
  });
  const { control, handleSubmit } = form;
  const watchedValues = useWatch({ control });

  const isDataUnchanged = isEqual(watchedValues, initialData);

  return (
    <div className='m-auto p-5'>
      <Form {...form}>
        <form onSubmit={handleSubmit(onSubmit)} className='space-y-2 max-w-2xl mx-auto bg-white rounded-lg p-8'>
          <BasicFormField
            name='title'
            label='Tytuł'
            control={control}
            className='pb-4'
            render={(field) => (
              <Input
                placeholder='Tytuł'
                className='w-full h-12 p-3 border rounded-md text-sm'
                disabled={isReadonly}
                {...field}
              />
            )}
          />
          <BasicFormField
            name='description'
            label='Opis'
            control={control}
            className='pb-4'
            render={(field) => (
              <TextArea placeholder='Opis' className=' min-h-28 max-h-52' disabled={isReadonly} {...field} />
            )}
          />
          <div className='grid grid-cols-1 md:grid-cols-2 gap-3'>
            <BasicFormField
              name='startDate'
              label='Data utworzenia'
              control={control}
              render={({ onChange, value }) => (
                <DatePicker mode='single' onChange={(value) => onChange(value)} value={value} className='w-full h-12' />
              )}
            />
            <BasicFormField
              name='dedicated_time'
              label='Poświęcony czas (w godzinach)'
              control={control}
              className='pb-4'
              render={({ value, onChange }) => (
                <Input
                  placeholder='Poświęcony czas (w godzinach)'
                  className='w-full h-12'
                  disabled={isReadonly}
                  type='number'
                  min='1'
                  value={value ?? ''}
                  onChange={(value) => onChange(Number(value))}
                />
              )}
            />
          </div>
          <div className='grid gap-3'>
            <BasicFormField
              name='achievements'
              label='Osiągnięcia'
              control={control}
              className='pb-4'
              render={({ value, onChange }) => (
                <TextArea
                  placeholder='Osiągnięcia'
                  className='w-full min-h-14 max-h-28'
                  disabled={isReadonly}
                  value={value || ''}
                  onChange={onChange}
                />
              )}
            />
            <BasicFormField
              name='problems'
              label='Problemy'
              control={control}
              className='pb-4'
              render={({ value, onChange }) => (
                <TextArea
                  placeholder='Problemy'
                  className='w-full min-h-14 max-h-28'
                  disabled={isReadonly}
                  value={value || ''}
                  onChange={onChange}
                />
              )}
            />
          </div>
          <div className='flex flex-col md:flex-row justify-end space-y-2 md:space-y-0 md:space-x-2'>
            {!isReadonly && (
              <>
                <Button
                  disabled={isSavingEntry}
                  className='w-32 h-12 '
                  variant='secondary'
                  onClick={() => router.back()}
                  type='button'
                >
                  Anuluj
                </Button>
                <Button type='submit' isLoading={isSavingEntry} className='w-32 h-12 ' disabled={isDataUnchanged}>
                  {initialData ? 'Edytuj' : 'Dodaj'}
                </Button>
              </>
            )}
          </div>
        </form>
      </Form>
    </div>
  );
};

export default EntryForm;
Leave a Comment