1d22adc42e
Backend (Express + MariaDB) y frontend (React + Vite, identidad Fluent/Windows) con el nucleo funcional: seguridad, organizacion, proyectos, actividades, subtareas, dependencias, dashboard, calendario, gantt, comentarios, adjuntos, notificaciones in-app y catalogos. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
41 lines
1.1 KiB
JavaScript
41 lines
1.1 KiB
JavaScript
import { useCallback, useEffect, useState } from 'react';
|
|
import { useUi } from '../context/ui-context.jsx';
|
|
|
|
// Abstrae el patron repetido loading/try-catch/error para llamadas a la API.
|
|
export function useAsync(fn, deps = []) {
|
|
const [data, setData] = useState(null);
|
|
const [loading, setLoading] = useState(true);
|
|
const [error, setError] = useState(null);
|
|
|
|
const reload = useCallback(async () => {
|
|
setLoading(true);
|
|
setError(null);
|
|
try {
|
|
const result = await fn();
|
|
setData(result);
|
|
} catch (err) {
|
|
setError(err.message);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, deps);
|
|
|
|
useEffect(() => { reload(); }, [reload]);
|
|
|
|
return { data, loading, error, reload, setData };
|
|
}
|
|
|
|
// Ejecuta una accion mostrando error via ContentDialog si falla.
|
|
export function useAction() {
|
|
const { openDialog, t } = useUi();
|
|
return useCallback(async (fn) => {
|
|
try {
|
|
return await fn();
|
|
} catch (err) {
|
|
openDialog({ tone: 'error', title: t('common_error'), message: err.message });
|
|
throw err;
|
|
}
|
|
}, [openDialog, t]);
|
|
}
|