'use client'; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { Header } from '@/components/layouts/header'; import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@horux/shared-ui'; import { apiClient } from '@/lib/api/client'; import { Bell, Loader2 } from 'lucide-react'; const ROLE_LABELS: Record = { owner: 'Owner', supervisor: 'Supervisor', auxiliar: 'Auxiliar', cliente: 'Cliente', }; const EMAIL_LABELS: Record = { documento_subido: { label: 'Documento subido', description: 'Cuando se sube una declaración o documento extra del contribuyente.', status: 'active', }, weekly_update: { label: 'Reporte semanal', description: 'Resumen de KPIs, alertas y discrepancias enviado los lunes 8:00 AM.', status: 'active', }, subscription_expiring: { label: 'Vencimiento de suscripción', description: 'Aviso cuando la suscripción del despacho está por vencer.', status: 'active', }, recordatorio_fiscal: { label: 'Recordatorios fiscales', description: 'Avisos de obligaciones próximas a vencer (declaraciones, pagos provisionales).', status: 'pending', }, alertas_nuevas: { label: 'Alertas nuevas', description: 'Notificación diaria cuando aparecen alertas fiscales nuevas para un contribuyente.', status: 'active', }, recordatorio_proximo: { label: 'Recordatorios próximos', description: 'Avisos de recordatorios del calendario a 3, 1 y 0 días de su fecha límite.', status: 'active', }, }; interface ListResponse { emailTypes: string[]; roles: string[]; preferences: Record>; } export default function NotificacionesPage() { const queryClient = useQueryClient(); const { data, isLoading } = useQuery({ queryKey: ['notification-preferences'], queryFn: async () => { const res = await apiClient.get('/notificaciones'); return res.data; }, }); const mutation = useMutation({ mutationFn: async ({ emailType, role, enabled }: { emailType: string; role: string; enabled: boolean }) => { await apiClient.put('/notificaciones', { emailType, role, enabled }); }, onMutate: async ({ emailType, role, enabled }) => { await queryClient.cancelQueries({ queryKey: ['notification-preferences'] }); const previous = queryClient.getQueryData(['notification-preferences']); if (previous) { queryClient.setQueryData(['notification-preferences'], { ...previous, preferences: { ...previous.preferences, [emailType]: { ...previous.preferences[emailType], [role]: enabled, }, }, }); } return { previous }; }, onError: (_err, _vars, context) => { if (context?.previous) queryClient.setQueryData(['notification-preferences'], context.previous); }, onSettled: () => { queryClient.invalidateQueries({ queryKey: ['notification-preferences'] }); }, }); const roles = data?.roles ?? []; const emailTypes = data?.emailTypes ?? []; return ( <>
Correos informativos por rol Activa o desactiva cada notificación según el rol del usuario en el despacho. Por default todos están activados. Los correos críticos (welcome, recuperación de contraseña, confirmación de pago) siempre se envían. {isLoading ? (
Cargando...
) : ( {roles.map(role => ( ))} {emailTypes.map(type => { const meta = EMAIL_LABELS[type]; if (!meta) return null; const isPending = meta.status === 'pending'; return ( {roles.map(role => { const checked = data?.preferences?.[type]?.[role] !== false; return ( ); })} ); })}
Notificación {ROLE_LABELS[role] ?? role}
{meta.label} {isPending && ( Próximamente )}

{meta.description}

)}
); }