Refactor code structure for improved readability and maintainability

This commit is contained in:
miguel
2025-09-09 15:16:40 -06:00
parent 99bfb46b8b
commit b399821439
6 changed files with 153 additions and 21 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

+1 -1
View File
@@ -25,7 +25,7 @@ export default function Page() {
}))
: [
{
src: '/default-banner.jpeg',
src: '/default-banner.png',
alt: 'Banner de eventos activos',
},
]
+4 -1
View File
@@ -9,7 +9,10 @@ export interface CarouselProps {
}[];
}
export default function Carousel({ id="carousel-banners-eventos", images }: CarouselProps) {
export default function Carousel({
id = 'carousel-banners-eventos',
images,
}: CarouselProps) {
if (!images || images.length === 0) {
return <div></div>;
}
+81 -13
View File
@@ -320,14 +320,28 @@ export default function FormularioEditor({
<Select
label="Tipo de pregunta"
value={pregunta.tipo}
onChange={(e) =>
onChange={(e) => {
const nuevoTipo = e.target.value as TipoPregunta;
handleUpdatePregunta(
seccionIdx,
preguntaIdx,
'tipo',
e.target.value
)
}
nuevoTipo
);
// Si cambia a un tipo cerrado y no tiene opciones, agregar opciones por defecto
if (
(nuevoTipo === 'Cerrada' || nuevoTipo === 'Multiple') &&
(!pregunta.opciones || pregunta.opciones.length === 0)
) {
handleUpdatePregunta(
seccionIdx,
preguntaIdx,
'opciones',
[{ valor: '' }, { valor: '' }]
);
}
}}
options={tipoPreguntaOpciones.map((tipo) => ({
label: tipo,
value: tipo,
@@ -384,14 +398,16 @@ export default function FormularioEditor({
{(pregunta.tipo === 'Cerrada' ||
pregunta.tipo === 'Multiple') && (
<div className="mb-2">
<label className="form-label">Opciones</label>
{(pregunta.opciones || []).map((op, opIdx) => (
<SimpleInput
key={opIdx}
value={op.valor}
onChange={(e) => {
<div className="d-flex justify-content-between align-items-center mb-2">
<label className="form-label mb-0">Opciones</label>
<Button
variant="success"
size="sm"
icon="plus"
outline
onClick={() => {
const nuevasOpciones = [...(pregunta.opciones || [])];
nuevasOpciones[opIdx].valor = e.target.value;
nuevasOpciones.push({ valor: '' });
handleUpdatePregunta(
seccionIdx,
preguntaIdx,
@@ -399,9 +415,61 @@ export default function FormularioEditor({
nuevasOpciones
);
}}
placeholder={`Opción ${opIdx + 1}`}
/>
>
Agregar opción
</Button>
</div>
{(pregunta.opciones || []).map((op, opIdx) => (
<div key={opIdx} className="d-flex align-items-center mb-2">
<SimpleInput
value={op.valor}
onChange={(e) => {
const nuevasOpciones = [...(pregunta.opciones || [])];
nuevasOpciones[opIdx].valor = e.target.value;
handleUpdatePregunta(
seccionIdx,
preguntaIdx,
'opciones',
nuevasOpciones
);
}}
placeholder={`Opción ${opIdx + 1}`}
className={{
container: 'me-2 flex-grow-1 mb-0',
input: 'form-control',
}}
/>
<Button
variant="danger"
size="sm"
icon="trash"
outline
onClick={() => {
const nuevasOpciones = [...(pregunta.opciones || [])];
nuevasOpciones.splice(opIdx, 1);
handleUpdatePregunta(
seccionIdx,
preguntaIdx,
'opciones',
nuevasOpciones
);
}}
disabled={pregunta.opciones?.length === 1}
title={
pregunta.opciones?.length === 1
? 'Una pregunta cerrada debe tener al menos una opción'
: 'Eliminar opción'
}
/>
</div>
))}
{(!pregunta.opciones || pregunta.opciones.length === 0) && (
<div className="text-muted small">
<i className="bi bi-info-circle me-1"></i>
Esta pregunta cerrada no tiene opciones. Agrega al menos
una opción.
</div>
)}
</div>
)}
</div>
@@ -144,7 +144,11 @@ export default function FormularioRegistro({
// ------------------------
useEffect(() => {
if (!cuentaInfo) {
if (preguntas) {
if (data?.cuestionario.secciones) {
const preguntas = data.cuestionario.secciones.flatMap((seccion) =>
seccion.preguntas.map((pregunta) => pregunta.pregunta)
);
const idsPrefetch = preguntas
.filter((pregunta) =>
[
@@ -171,7 +175,11 @@ export default function FormularioRegistro({
const nuevasRespuestas: RespuestaFormulario = {};
if (preguntas) {
if (data?.cuestionario.secciones) {
const preguntas = data.cuestionario.secciones.flatMap((seccion) =>
seccion.preguntas.map((pregunta) => pregunta.pregunta)
);
for (const pregunta of preguntas) {
const id = pregunta.id_pregunta;
switch (pregunta.validacion) {
@@ -209,7 +217,7 @@ export default function FormularioRegistro({
...nuevasRespuestas,
}));
}
}, [cuentaInfo]);
}, [cuentaInfo, data?.cuestionario.secciones]);
// ------------------------
// Funciones auxiliares
@@ -329,6 +337,7 @@ export default function FormularioRegistro({
// Condición para mostrar el formulario
// ------------------------
const mostrarFormularioRestante =
!preguntaComunidad || // Si no hay pregunta de comunidad, mostrar el formulario
(isComunidad &&
confirmativeOption.some((opt) =>
isComunidad.label?.toLowerCase().includes(opt.toLowerCase())
@@ -480,11 +489,12 @@ export default function FormularioRegistro({
respuestas[`${pregunta.pregunta.id_pregunta}`];
if (
confirmativeOption.includes(isComunidad?.label) &&
cuentaInfo &&
(!preguntaComunidad ||
(confirmativeOption.includes(isComunidad?.label || '') &&
cuentaInfo)) &&
respuestaActual === undefined // solo si no ha respondido
) {
if (pregunta.pregunta.validacion === 'genero') {
if (pregunta.pregunta.validacion === 'genero' && cuentaInfo) {
const generoTexto =
cuentaInfo.genero === 'M' ? 'Masculino' : 'Femenino';
+51
View File
@@ -154,6 +154,57 @@ export const plantillasDisponibles: Plantilla[] = [
],
},
},
{
imagen: '/plantilla_general.png',
nombre: 'Registro General',
id: 'registro-general',
datos: {
nombre_form: 'Registro Para Asistencia General',
descripcion:
'Con este formulario estaras reservando tu lugar en el evento. Por favor, completa todos los campos obligatorios.',
fecha_inicio: '2025-08-01T08:00:00',
fecha_fin: '2025-08-10T23:59:59',
id_tipo_cuestionario: 1,
secciones: [
{
titulo: 'Información Personal',
descripcion:
'Proporciona tus datos personales para poder contactarte y enviarte información relevante sobre la Feria de la Sexualidad.',
preguntas: [
{
titulo: 'Numero de cuenta',
tipo: 'Abierta (Respuesta corta)',
obligatoria: false,
},
{
titulo: 'Correo electrónico',
tipo: 'Abierta (Respuesta corta)',
obligatoria: true,
validacion: 'correo',
},
{
titulo: 'Nombre(s)',
tipo: 'Abierta (Respuesta corta)',
obligatoria: true,
validacion: 'nombre',
},
{
titulo: 'Apellidos',
tipo: 'Abierta (Respuesta corta)',
obligatoria: true,
validacion: 'apellidos',
},
{
titulo: 'Tipo de Asistente',
tipo: 'Cerrada',
obligatoria: true,
opciones: [{ valor: 'Alumno' }, { valor: 'Profesor' }],
},
],
},
],
},
},
];
/*