Proyectos de Subversion LeadersLinked - SPA

Rev

Rev 3371 | Rev 3697 | 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) => ({
                  name: 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>
  )
}