Proyectos de Subversion LeadersLinked - SPA

Rev

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

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