Proyectos de Subversion LeadersLinked - SPA

Rev

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

Rev Autor Línea Nro. Línea
3697 stevensc 1
import React, { useState } from 'react';
2
import { useForm } from 'react-hook-form';
3
import { useDispatch } from 'react-redux';
4
import { Button, styled, Tab, Tabs } from '@mui/material';
3230 stevensc 5
 
3697 stevensc 6
import { useFetch } from '@hooks';
7
import { getTemplate } from '@services/habits/habits';
8
import { INTELLIGENCES, WEEK_DAYS } from '@constants/habits';
9
import { addNotification } from '@store/notification/notification.actions';
3230 stevensc 10
 
3697 stevensc 11
import Row from '@components/common/Row';
12
import Form from '@components/common/form';
13
import Input from '@components/UI/inputs/Input';
14
import Widget from '@components/UI/Widget';
15
import TabPanel from '@components/common/tab-panel';
16
import Ckeditor from '@components/common/ckeditor/Ckeditor';
17
import Select from '@components/UI/inputs/Select';
18
import CheckboxInput from '@components/UI/inputs/Checkbox';
19
import LoadingWrapper from '@components/common/loading-wrapper';
3230 stevensc 20
 
3239 stevensc 21
const FormTabPanel = styled(TabPanel)(({ theme }) => ({
22
  display: 'flex',
23
  flexDirection: 'column',
24
  width: '100%',
25
  gap: theme.spacing(0.5)
3697 stevensc 26
}));
3239 stevensc 27
 
3230 stevensc 28
export default function HabitForm({
29
  onSubmit = () => {},
30
  defaultValues = {
31
    name: '',
32
    description: '',
3239 stevensc 33
    monday_active: false,
34
    tuesday_active: false,
35
    wednesday_active: false,
36
    thursday_active: false,
37
    friday_active: false,
38
    saturday_active: false,
39
    sunday_active: false,
3292 stevensc 40
    monday_time: undefined,
41
    tuesday_time: undefined,
42
    wednesday_time: undefined,
43
    thursday_time: undefined,
44
    friday_time: undefined,
45
    saturday_time: undefined,
46
    sunday_time: undefined,
3239 stevensc 47
    quantitative_value: false,
48
    qualitative_description: '',
49
    notification_10min_before: false,
50
    notification_30min_before: false,
51
    intelligence: ''
3230 stevensc 52
  },
53
  values = {}
54
}) {
3697 stevensc 55
  const { data: templates } = useFetch('/helpers/habits-and-skills', []);
56
  const [currentTemplate, setCurrentTemplate] = useState(null);
57
  const [currentTab, setCurrentTab] = useState(0);
58
  const dispatch = useDispatch();
3230 stevensc 59
 
60
  const {
3239 stevensc 61
    handleSubmit,
3230 stevensc 62
    control,
63
    formState: { errors, isSubmitting },
3239 stevensc 64
    trigger
3230 stevensc 65
  } = useForm({
66
    defaultValues,
3303 stevensc 67
    values: currentTemplate ?? values
3697 stevensc 68
  });
3303 stevensc 69
 
70
  const getHabitTemplate = async (url) => {
71
    try {
3697 stevensc 72
      const response = await getTemplate(url);
73
      setCurrentTemplate(response);
3303 stevensc 74
    } catch (error) {
3697 stevensc 75
      dispatch(addNotification({ style: 'danger', msg: error.message }));
3303 stevensc 76
    }
3697 stevensc 77
  };
3303 stevensc 78
 
3239 stevensc 79
  const handleChange = async (event, newValue) => {
3697 stevensc 80
    const valid = await trigger();
81
    if (valid) setCurrentTab(newValue);
82
  };
3230 stevensc 83
 
3239 stevensc 84
  const nextStep = async () => {
3697 stevensc 85
    const valid = await trigger();
86
    if (valid) setCurrentTab(currentTab + 1);
87
  };
3239 stevensc 88
 
3373 stevensc 89
  const formatHabit = (habit) => {
3697 stevensc 90
    const dataArray = Object.entries(habit);
3373 stevensc 91
    const formatedData = dataArray.map(([key, value]) => {
3697 stevensc 92
      if (key.includes('active')) return [key, value ? 1 : 0];
93
      if (key.includes('time')) return [key, value.padEnd(8, ':00')];
94
      return [key, value];
95
    });
96
    return Object.fromEntries(formatedData);
97
  };
3239 stevensc 98
 
3373 stevensc 99
  const dataAdapter = (habit) => {
3697 stevensc 100
    const formatedHabit = formatHabit(habit);
101
    onSubmit(formatedHabit);
102
  };
3373 stevensc 103
 
3230 stevensc 104
  return (
3239 stevensc 105
    <Widget>
3230 stevensc 106
      <Tabs value={currentTab} onChange={handleChange}>
3239 stevensc 107
        <Tab label='Detalles' />
108
        <Tab label='Frecuencia' />
109
        <Tab label='Valor' />
110
        <Tab label='Notificaciones' />
3230 stevensc 111
      </Tabs>
112
      <Widget.Body>
3239 stevensc 113
        <Form onSubmit={handleSubmit(dataAdapter)}>
3230 stevensc 114
          <LoadingWrapper loading={isSubmitting} displayChildren>
3239 stevensc 115
            {/* Detalles */}
116
            <FormTabPanel value={0} index={currentTab}>
3303 stevensc 117
              <Select
3306 stevensc 118
                label='Plantilla:'
3303 stevensc 119
                options={templates.map((template) => ({
3697 stevensc 120
                  label: template.name,
3303 stevensc 121
                  value: template.link
122
                }))}
3306 stevensc 123
                onChange={(e) => getHabitTemplate(e.target.value)}
3303 stevensc 124
              />
125
 
3239 stevensc 126
              <Input
3262 stevensc 127
                label='Nombre del hábito o competencia:'
3239 stevensc 128
                name='name'
3262 stevensc 129
                placeholder='Escribe el nombre del hábito o competencia'
3239 stevensc 130
                control={control}
131
                rules={{ required: 'El nombre es requerido' }}
132
                error={errors.name?.message}
133
              />
134
 
3230 stevensc 135
              <Select
3262 stevensc 136
                label='Inteligencias:'
3230 stevensc 137
                name='intelligence'
138
                options={INTELLIGENCES}
139
                control={control}
140
                rules={{ required: 'Este campo es requerido' }}
141
                error={errors.intelligence?.message}
142
              />
143
 
3239 stevensc 144
              <Ckeditor
3230 stevensc 145
                control={control}
146
                name='description'
147
                error={errors.description?.message}
3239 stevensc 148
                rules={{ required: 'La descripción es requerida' }}
149
                label='Descripción:'
3230 stevensc 150
              />
151
 
3239 stevensc 152
              <Button color='primary' onClick={nextStep}>
153
                Continuar
154
              </Button>
155
            </FormTabPanel>
156
 
157
            {/* Frecuencia */}
158
            <FormTabPanel value={1} index={currentTab}>
159
              {WEEK_DAYS.map(({ label, value, time }) => {
160
                return (
161
                  <Row
162
                    key={value}
163
                    styles={{
164
                      flexFlow: 'nowrap',
165
                      justifyContent: 'space-between'
166
                    }}
167
                  >
168
                    {/* Campos de días activos */}
3697 stevensc 169
                    <CheckboxInput label={label} control={control} name={value} />
3239 stevensc 170
                    {/* Puedes repetir los campos de días activos y sus horas para cada día de la semana */}
171
                    <Input
172
                      type='time'
173
                      control={control}
174
                      name={time}
175
                      rules={{
176
                        validate: (time, formValues) => {
3697 stevensc 177
                          if (!formValues[value]) return true;
178
                          if (formValues[value] && time) return true;
179
                          return 'La hora es requerida si el día está activo';
3239 stevensc 180
                        }
181
                      }}
182
                      style={{ width: 'auto' }}
183
                      error={errors[time]?.message}
184
                    />
185
                  </Row>
3697 stevensc 186
                );
3239 stevensc 187
              })}
188
 
189
              <Button color='primary' onClick={nextStep}>
190
                Continuar
191
              </Button>
192
            </FormTabPanel>
193
 
194
            {/* Valor */}
195
            <FormTabPanel value={2} index={currentTab}>
3230 stevensc 196
              <Input
3239 stevensc 197
                control={control}
198
                label='Valor cuantitativo:'
199
                name='quantitative_value'
3230 stevensc 200
                type='number'
3239 stevensc 201
                rules={{ required: 'El valor es requerido' }}
202
                error={errors.quantitative_value?.message}
3230 stevensc 203
              />
204
 
3239 stevensc 205
              <Ckeditor
3230 stevensc 206
                control={control}
3239 stevensc 207
                name='qualitative_description'
208
                error={errors.qualitative_description?.message}
209
                rules={{ required: 'La descripción es requerida' }}
210
                label='Descripción cualitativa:'
3230 stevensc 211
              />
212
 
3239 stevensc 213
              <Button color='primary' onClick={nextStep}>
214
                Continuar
215
              </Button>
216
            </FormTabPanel>
3230 stevensc 217
 
3239 stevensc 218
            {/* Notificaciones */}
219
            <FormTabPanel value={3} index={currentTab}>
220
              <CheckboxInput
221
                label='Notificación 10 min antes'
222
                name='notification_10min_before'
3230 stevensc 223
                control={control}
224
              />
3239 stevensc 225
              <CheckboxInput
226
                label='Notificación 30 min antes'
227
                name='notification_30min_before'
228
                control={control}
229
                rules={{
230
                  validate: (value, formValues) => {
231
                    if (!value && !formValues.notification_10min_before) {
3697 stevensc 232
                      return 'Debe seleccionar al menos una opción';
3239 stevensc 233
                    }
234
                    if (value && formValues.notification_10min_before) {
3697 stevensc 235
                      return 'No se puede seleccionar ambas opciones simultáneamente';
3239 stevensc 236
                    }
3697 stevensc 237
                    return true;
3239 stevensc 238
                  }
239
                }}
240
              />
3371 stevensc 241
              <Button color='primary' type='submit' disabled={isSubmitting}>
242
                Crear
3239 stevensc 243
              </Button>
244
            </FormTabPanel>
3230 stevensc 245
          </LoadingWrapper>
246
        </Form>
247
      </Widget.Body>
248
    </Widget>
3697 stevensc 249
  );
3230 stevensc 250
}