d3e1441f87
- Implemented bulk upload for students and workers with file validation and error handling. - Added Excel template download feature for user uploads. - Created success page for form submissions with QR code display. - Established context and reducer for form state management, including user search and response handling. - Added mermaid diagrams for event registration documentation.
153 lines
4.3 KiB
TypeScript
153 lines
4.3 KiB
TypeScript
import { GetCuestionario } from '@/types/evento';
|
|
import { UsuarioDataResponse } from '@/containers/formulario/formulario-registro';
|
|
|
|
export type RespuestaFormulario = Record<string, string | number>;
|
|
|
|
// ── Estado ──────────────────────────────────────────────────────────────────
|
|
|
|
export interface FormularioState {
|
|
// Datos del cuestionario cargado desde la API
|
|
data: GetCuestionario | null;
|
|
loadingData: boolean;
|
|
errorData: string | null;
|
|
|
|
// Respuestas del usuario
|
|
respuestas: RespuestaFormulario;
|
|
|
|
// Búsqueda de cuenta/rfc
|
|
cuentaBuscada: string;
|
|
busquedaCompletada: boolean;
|
|
loadingBusqueda: boolean;
|
|
errorBusqueda: string | null;
|
|
usuarioEncontrado: UsuarioDataResponse | null;
|
|
|
|
// Envío
|
|
isSending: boolean;
|
|
}
|
|
|
|
export const initialState: FormularioState = {
|
|
data: null,
|
|
loadingData: true,
|
|
errorData: null,
|
|
|
|
respuestas: {},
|
|
|
|
cuentaBuscada: '',
|
|
busquedaCompletada: false,
|
|
loadingBusqueda: false,
|
|
errorBusqueda: null,
|
|
usuarioEncontrado: null,
|
|
|
|
isSending: false,
|
|
};
|
|
|
|
// ── Acciones ─────────────────────────────────────────────────────────────────
|
|
|
|
export type FormularioAction =
|
|
// Carga del cuestionario
|
|
| { type: 'FETCH_DATA_START' }
|
|
| { type: 'FETCH_DATA_SUCCESS'; payload: GetCuestionario }
|
|
| { type: 'FETCH_DATA_ERROR'; payload: string }
|
|
|
|
// Respuestas
|
|
| { type: 'SET_RESPUESTA'; payload: { id: string; valor: string } }
|
|
| { type: 'SET_RESPUESTAS_BULK'; payload: RespuestaFormulario }
|
|
| { type: 'LIMPIAR_CAMPOS_AUTORELLENO'; payload: number[] } // ids de pregunta
|
|
|
|
// Búsqueda de cuenta
|
|
| { type: 'BUSQUEDA_START'; payload: string } // cuenta buscada
|
|
| { type: 'BUSQUEDA_SUCCESS'; payload: UsuarioDataResponse }
|
|
| { type: 'BUSQUEDA_ERROR'; payload: string }
|
|
| { type: 'BUSQUEDA_RESET' }
|
|
|
|
// Envío
|
|
| { type: 'SEND_START' }
|
|
| { type: 'SEND_END' };
|
|
|
|
// ── Reducer ──────────────────────────────────────────────────────────────────
|
|
|
|
export function formularioReducer(
|
|
state: FormularioState,
|
|
action: FormularioAction
|
|
): FormularioState {
|
|
switch (action.type) {
|
|
// Carga del cuestionario
|
|
case 'FETCH_DATA_START':
|
|
return { ...state, loadingData: true, errorData: null };
|
|
|
|
case 'FETCH_DATA_SUCCESS':
|
|
return { ...state, loadingData: false, data: action.payload };
|
|
|
|
case 'FETCH_DATA_ERROR':
|
|
return { ...state, loadingData: false, errorData: action.payload };
|
|
|
|
// Respuestas
|
|
case 'SET_RESPUESTA':
|
|
return {
|
|
...state,
|
|
respuestas: { ...state.respuestas, [action.payload.id]: action.payload.valor },
|
|
};
|
|
|
|
case 'SET_RESPUESTAS_BULK':
|
|
return {
|
|
...state,
|
|
respuestas: { ...state.respuestas, ...action.payload },
|
|
};
|
|
|
|
case 'LIMPIAR_CAMPOS_AUTORELLENO': {
|
|
const limpio = { ...state.respuestas };
|
|
action.payload.forEach((id) => delete limpio[id]);
|
|
return { ...state, respuestas: limpio };
|
|
}
|
|
|
|
// Búsqueda
|
|
case 'BUSQUEDA_START':
|
|
return {
|
|
...state,
|
|
loadingBusqueda: true,
|
|
errorBusqueda: null,
|
|
busquedaCompletada: false,
|
|
usuarioEncontrado: null,
|
|
cuentaBuscada: action.payload,
|
|
};
|
|
|
|
case 'BUSQUEDA_SUCCESS':
|
|
return {
|
|
...state,
|
|
loadingBusqueda: false,
|
|
busquedaCompletada: true,
|
|
errorBusqueda: null,
|
|
usuarioEncontrado: action.payload,
|
|
};
|
|
|
|
case 'BUSQUEDA_ERROR':
|
|
return {
|
|
...state,
|
|
loadingBusqueda: false,
|
|
busquedaCompletada: false,
|
|
errorBusqueda: action.payload,
|
|
usuarioEncontrado: null,
|
|
};
|
|
|
|
case 'BUSQUEDA_RESET':
|
|
return {
|
|
...state,
|
|
cuentaBuscada: '',
|
|
busquedaCompletada: false,
|
|
loadingBusqueda: false,
|
|
errorBusqueda: null,
|
|
usuarioEncontrado: null,
|
|
};
|
|
|
|
// Envío
|
|
case 'SEND_START':
|
|
return { ...state, isSending: true };
|
|
|
|
case 'SEND_END':
|
|
return { ...state, isSending: false };
|
|
|
|
default:
|
|
return state;
|
|
}
|
|
}
|