UX: motivo requerido, dock móvil, hamburguesa desktop, toaster Sileo, panel de estadísticas
Alumno: - Modal de solicitud: campo "Notas" renombrado a "Motivo del préstamo", ahora requerido, con hint sobre uso (para qué clase o proyecto). Admin: - Bandeja de solicitudes pendientes, activos y devoluciones ahora muestran el motivo del alumno (en tabla desktop y tarjetas móvil). - /admin/inventario se convirtió en "Estadísticas": grid de KPIs del día (solicitadas, aprobadas, rechazadas, devoluciones, en préstamo, vencidos) arriba del inventario existente. Los cambios de estado se cuentan desde audit_log, el rango del día se calcula automáticamente en timezone America/Tijuana con DST via Intl API (src/lib/date.ts). Rediseño móvil: - Sidebar desktop se puede colapsar con botón hamburguesa. Estado persiste en localStorage sin flash (script is:inline bloqueante). - Nav móvil reemplazado por dock píldora flotante con iconos SVG inline (heroicons outline). Respeta safe-area-inset-bottom. Notificaciones estilo Sileo: - Componente Toaster global (React island client:idle) que escucha CustomEvents. Toasts con backdrop-blur, animación de entrada translateY+opacity, auto-dismiss 3.8s, click para cerrar. Helper toastAfterReload deja pendiente en sessionStorage para sobrevivir location.reload() post-acción. Diagnóstico: - /api/whoami devuelve user+profile actuales para depurar sesión. - Endpoint devolver retorna un objeto `debug` en el 403 con email+rol vistos por el server (temporal, para trazar bug del 403). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -5,7 +5,12 @@ const json = (body: unknown, status = 200) =>
|
||||
|
||||
export const POST: APIRoute = async ({ params, locals }) => {
|
||||
if (!locals.user) return json({ error: 'no autenticado' }, 401);
|
||||
if (locals.profile?.rol !== 'admin') return json({ error: 'no autorizado' }, 403);
|
||||
if (locals.profile?.rol !== 'admin') {
|
||||
return json({
|
||||
error: 'no autorizado',
|
||||
debug: { email: locals.user.email, profile_rol: locals.profile?.rol ?? null },
|
||||
}, 403);
|
||||
}
|
||||
|
||||
const id = Number(params.id);
|
||||
if (!Number.isInteger(id) || id <= 0) return json({ error: 'id inválido' }, 400);
|
||||
|
||||
Reference in New Issue
Block a user