Proyectos de Subversion LeadersLinked - SPA

Rev

Rev 3373 | Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |

import React, { useState } from 'react';
import { useForm } from 'react-hook-form';
import { useDispatch } from 'react-redux';
import { Button, styled, Tab, Tabs } from '@mui/material';

import { useFetch } from '@hooks';
import { getTemplate } from '@services/habits/habits';
import { INTELLIGENCES, WEEK_DAYS } from '@constants/habits';
import { addNotification } from '@store/notification/notification.actions';

import Row from '@components/common/Row';
import Form from '@components/common/form';
import Input from '@components/UI/inputs/Input';
import Widget from '@components/UI/Widget';
import TabPanel from '@components/common/tab-panel';
import Ckeditor from '@components/common/ckeditor/Ckeditor';
import Select from '@components/UI/inputs/Select';
import CheckboxInput from '@components/UI/inputs/Checkbox';
import LoadingWrapper from '@components/common/loading-wrapper';

const FormTabPanel = styled(TabPanel)(({ theme }) => ({
  display: 'flex',
  flexDirection: 'column',
  width: '100%',
  gap: theme.spacing(0.5)
}));

export default function HabitForm({
  onSubmit = () => {},
  defaultValues = {
    name: '',
    description: '',
    monday_active: false,
    tuesday_active: false,
    wednesday_active: false,
    thursday_active: false,
    friday_active: false,
    saturday_active: false,
    sunday_active: false,
    monday_time: undefined,
    tuesday_time: undefined,
    wednesday_time: undefined,
    thursday_time: undefined,
    friday_time: undefined,
    saturday_time: undefined,
    sunday_time: undefined,
    quantitative_value: false,
    qualitative_description: '',
    notification_10min_before: false,
    notification_30min_before: false,
    intelligence: ''
  },
  values = {}
}) {
  const { data: templates } = useFetch('/helpers/habits-and-skills', []);
  const [currentTemplate, setCurrentTemplate] = useState(null);
  const [currentTab, setCurrentTab] = useState(0);
  const dispatch = useDispatch();

  const {
    handleSubmit,
    control,
    formState: { errors, isSubmitting },
    trigger
  } = useForm({
    defaultValues,
    values: currentTemplate ?? values
  });

  const getHabitTemplate = async (url) => {
    try {
      const response = await getTemplate(url);
      setCurrentTemplate(response);
    } catch (error) {
      dispatch(addNotification({ style: 'danger', msg: error.message }));
    }
  };

  const handleChange = async (event, newValue) => {
    const valid = await trigger();
    if (valid) setCurrentTab(newValue);
  };

  const nextStep = async () => {
    const valid = await trigger();
    if (valid) setCurrentTab(currentTab + 1);
  };

  const formatHabit = (habit) => {
    const dataArray = Object.entries(habit);
    const formatedData = dataArray.map(([key, value]) => {
      if (key.includes('active')) return [key, value ? 1 : 0];
      if (key.includes('time')) return [key, value.padEnd(8, ':00')];
      return [key, value];
    });
    return Object.fromEntries(formatedData);
  };

  const dataAdapter = (habit) => {
    const formatedHabit = formatHabit(habit);
    onSubmit(formatedHabit);
  };

  return (
    <Widget>
      <Tabs value={currentTab} onChange={handleChange}>
        <Tab label='Detalles' />
        <Tab label='Frecuencia' />
        <Tab label='Valor' />
        <Tab label='Notificaciones' />
      </Tabs>
      <Widget.Body>
        <Form onSubmit={handleSubmit(dataAdapter)}>
          <LoadingWrapper loading={isSubmitting} displayChildren>
            {/* Detalles */}
            <FormTabPanel value={0} index={currentTab}>
              <Select
                label='Plantilla:'
                options={templates.map((template) => ({
                  label: template.name,
                  value: template.link
                }))}
                onChange={(e) => getHabitTemplate(e.target.value)}
              />

              <Input
                label='Nombre del hábito o competencia:'
                name='name'
                placeholder='Escribe el nombre del hábito o competencia'
                control={control}
                rules={{ required: 'El nombre es requerido' }}
                error={errors.name?.message}
              />

              <Select
                label='Inteligencias:'
                name='intelligence'
                options={INTELLIGENCES}
                control={control}
                rules={{ required: 'Este campo es requerido' }}
                error={errors.intelligence?.message}
              />

              <Ckeditor
                control={control}
                name='description'
                error={errors.description?.message}
                rules={{ required: 'La descripción es requerida' }}
                label='Descripción:'
              />

              <Button color='primary' onClick={nextStep}>
                Continuar
              </Button>
            </FormTabPanel>

            {/* Frecuencia */}
            <FormTabPanel value={1} index={currentTab}>
              {WEEK_DAYS.map(({ label, value, time }) => {
                return (
                  <Row
                    key={value}
                    styles={{
                      flexFlow: 'nowrap',
                      justifyContent: 'space-between'
                    }}
                  >
                    {/* Campos de días activos */}
                    <CheckboxInput label={label} control={control} name={value} />
                    {/* Puedes repetir los campos de días activos y sus horas para cada día de la semana */}
                    <Input
                      type='time'
                      control={control}
                      name={time}
                      rules={{
                        validate: (time, formValues) => {
                          if (!formValues[value]) return true;
                          if (formValues[value] && time) return true;
                          return 'La hora es requerida si el día está activo';
                        }
                      }}
                      style={{ width: 'auto' }}
                      error={errors[time]?.message}
                    />
                  </Row>
                );
              })}

              <Button color='primary' onClick={nextStep}>
                Continuar
              </Button>
            </FormTabPanel>

            {/* Valor */}
            <FormTabPanel value={2} index={currentTab}>
              <Input
                control={control}
                label='Valor cuantitativo:'
                name='quantitative_value'
                type='number'
                rules={{ required: 'El valor es requerido' }}
                error={errors.quantitative_value?.message}
              />

              <Ckeditor
                control={control}
                name='qualitative_description'
                error={errors.qualitative_description?.message}
                rules={{ required: 'La descripción es requerida' }}
                label='Descripción cualitativa:'
              />

              <Button color='primary' onClick={nextStep}>
                Continuar
              </Button>
            </FormTabPanel>

            {/* Notificaciones */}
            <FormTabPanel value={3} index={currentTab}>
              <CheckboxInput
                label='Notificación 10 min antes'
                name='notification_10min_before'
                control={control}
              />
              <CheckboxInput
                label='Notificación 30 min antes'
                name='notification_30min_before'
                control={control}
                rules={{
                  validate: (value, formValues) => {
                    if (!value && !formValues.notification_10min_before) {
                      return 'Debe seleccionar al menos una opción';
                    }
                    if (value && formValues.notification_10min_before) {
                      return 'No se puede seleccionar ambas opciones simultáneamente';
                    }
                    return true;
                  }
                }}
              />
              <Button color='primary' type='submit' disabled={isSubmitting}>
                Crear
              </Button>
            </FormTabPanel>
          </LoadingWrapper>
        </Form>
      </Widget.Body>
    </Widget>
  );
}