Rev 3697 | 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>
);
}