From baef1cc5d6f0b979bfe77f5d0439a60da00daa21 Mon Sep 17 00:00:00 2001 From: Nurfog Date: Tue, 6 Oct 2026 12:33:38 -0300 Subject: [PATCH] feat: dashboard visible para usuarios normales con solo sus tickets --- frontend/src/app/(app)/page.tsx | 142 ++++++++++++++++++++++------ frontend/src/components/Sidebar.tsx | 8 +- 2 files changed, 118 insertions(+), 32 deletions(-) diff --git a/frontend/src/app/(app)/page.tsx b/frontend/src/app/(app)/page.tsx index c453af4..5d963e5 100644 --- a/frontend/src/app/(app)/page.tsx +++ b/frontend/src/app/(app)/page.tsx @@ -2,40 +2,58 @@ import { useEffect, useState } from "react"; import StatsCard from "@/components/StatsCard"; -import { getTicketStats, type DashboardStats } from "@/lib/api"; +import BadgeStatus from "@/components/BadgeStatus"; +import BadgePriority from "@/components/BadgePriority"; +import { getTicketStats, getTickets, type DashboardStats, type Ticket } from "@/lib/api"; import { useAuth } from "@/lib/auth"; +import { formatDate } from "@/lib/format"; import Link from "next/link"; +import { useRouter } from "next/navigation"; + +const emptyStats: DashboardStats = { + totalTickets: 0, + openTickets: 0, + inProgressTickets: 0, + resolvedTickets: 0, + closedTickets: 0, + unassignedTickets: 0, + criticalTickets: 0, + dailyCounts: [], +}; export default function DashboardPage() { const { user, isLoading: authLoading } = useAuth(); + const router = useRouter(); const [stats, setStats] = useState(null); const [loading, setLoading] = useState(true); + const [myTickets, setMyTickets] = useState([]); + const [myTotal, setMyTotal] = useState(0); - const canView = user?.role === "admin" || user?.role === "supervisor"; + // Equipo (ve todo o su área) vs usuario normal (solo sus tickets). + // El backend ya filtra stats y tickets por solicitante cuando no es equipo. + const isTeam = + user?.role === "admin" || user?.role === "agent" || user?.role === "supervisor"; useEffect(() => { if (authLoading) return; - if (!canView) { - // Diferido para no disparar cascading renders (igual que AuthProvider). - queueMicrotask(() => setLoading(false)); - return; - } getTicketStats() .then(setStats) .catch(() => { - setStats({ - totalTickets: 0, - openTickets: 0, - inProgressTickets: 0, - resolvedTickets: 0, - closedTickets: 0, - unassignedTickets: 0, - criticalTickets: 0, - dailyCounts: [], - }); + setStats(emptyStats); }) .finally(() => setLoading(false)); - }, [authLoading, canView]); + if (!isTeam) { + getTickets({ page: 1, pageSize: 10 }) + .then((data) => { + setMyTickets(data.items || []); + setMyTotal(data.total || 0); + }) + .catch(() => { + setMyTickets([]); + setMyTotal(0); + }); + } + }, [authLoading, isTeam]); if (authLoading || loading) { return ( @@ -45,20 +63,90 @@ export default function DashboardPage() { ); } - // Solo administradores (todas las áreas) y supervisores (solo su área). - if (!canView) { + // Usuario normal: sin mensaje de permisos, solo sus tickets. + if (!isTeam) { return (
-

Dashboard

- - - Ir a Tickets +

Mis Tickets

+ + + Nuevo Ticket
-
- - El Dashboard está disponible solo para administradores y supervisores. + +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ + + Últimos tickets ({myTotal}) + + + Ver todos + +
+
+ + + + + + + + + + + + {myTickets.length === 0 ? ( + + + + ) : ( + myTickets.map((ticket) => ( + router.push(`/tickets/${ticket.id}`)} + style={{ cursor: "pointer" }} + > + + + + + + + )) + )} + +
#AsuntoEstadoPrioridadActualizado
+ +
Sin tickets
+

Aún no has creado ningún ticket

+
+ {ticket.ticketNumber || `#${ticket.id}`} + +
{ticket.title}
+
+ {formatDate(ticket.updatedAt)} +
+
); diff --git a/frontend/src/components/Sidebar.tsx b/frontend/src/components/Sidebar.tsx index f9173b2..abb17cf 100644 --- a/frontend/src/components/Sidebar.tsx +++ b/frontend/src/components/Sidebar.tsx @@ -9,11 +9,9 @@ export default function Sidebar() { const { user, logout } = useAuth(); const navItems = [ - // Dashboard solo para administradores (todas las áreas) y - // supervisores (solo su área). - ...((user?.role === "admin" || user?.role === "supervisor") - ? [{ href: "/", icon: "bi-speedometer2", label: "Dashboard" }] - : []), + // Dashboard para todos: el equipo ve el global (o su área) y los + // usuarios normales ven solo sus tickets (sin mensaje de permisos). + { href: "/", icon: "bi-speedometer2", label: "Dashboard" }, { href: "/tickets", icon: "bi-ticket-detailed", label: "Tickets" }, { href: "/knowledge-base", icon: "bi-journal-bookmark", label: "Knowledge Base" }, ];