diff --git a/frontend/src/app/(app)/settings/departments/page.tsx b/frontend/src/app/(app)/settings/departments/page.tsx index e35d8d8..f97bd98 100644 --- a/frontend/src/app/(app)/settings/departments/page.tsx +++ b/frontend/src/app/(app)/settings/departments/page.tsx @@ -8,9 +8,11 @@ import { deleteGroup, type Group, } from "@/lib/api"; +import { useAuth } from "@/lib/auth"; import Modal from "@/components/Modal"; export default function DepartmentsPage() { + const { user, isLoading: authLoading } = useAuth(); const [groups, setGroups] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(""); @@ -36,8 +38,13 @@ export default function DepartmentsPage() { }, []); useEffect(() => { + if (authLoading) return; + if (user?.role !== "admin") { + setLoading(false); + return; + } fetchGroups(); - }, [fetchGroups]); + }, [fetchGroups, authLoading, user?.role]); const openCreate = () => { setEditing(null); @@ -94,6 +101,20 @@ export default function DepartmentsPage() { } }; + if (!authLoading && user?.role !== "admin") { + return ( +
+
+

Departamentos

+
+
+ + Solo los administradores pueden gestionar departamentos. +
+
+ ); + } + return (
diff --git a/frontend/src/app/(app)/settings/sla/page.tsx b/frontend/src/app/(app)/settings/sla/page.tsx index ac35dac..859e2ff 100644 --- a/frontend/src/app/(app)/settings/sla/page.tsx +++ b/frontend/src/app/(app)/settings/sla/page.tsx @@ -7,9 +7,11 @@ import { updateSla, type SLAPolicy, } from "@/lib/api"; +import { useAuth } from "@/lib/auth"; import Modal from "@/components/Modal"; export default function SlaPage() { + const { user, isLoading: authLoading } = useAuth(); const [policies, setPolicies] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(""); @@ -37,8 +39,13 @@ export default function SlaPage() { }, []); useEffect(() => { + if (authLoading) return; + if (user?.role !== "admin") { + setLoading(false); + return; + } fetchPolicies(); - }, [fetchPolicies]); + }, [fetchPolicies, authLoading, user?.role]); const openCreate = () => { setEditing(null); @@ -101,6 +108,20 @@ export default function SlaPage() { } }; + if (!authLoading && user?.role !== "admin") { + return ( +
+
+

Políticas SLA

+
+
+ + Solo los administradores pueden gestionar las políticas SLA. +
+
+ ); + } + return (
diff --git a/frontend/src/app/(app)/settings/team/page.tsx b/frontend/src/app/(app)/settings/team/page.tsx index d6efb21..13f9a69 100644 --- a/frontend/src/app/(app)/settings/team/page.tsx +++ b/frontend/src/app/(app)/settings/team/page.tsx @@ -9,9 +9,11 @@ import { type TeamMember, type Group, } from "@/lib/api"; +import { useAuth } from "@/lib/auth"; import Modal from "@/components/Modal"; export default function TeamPage() { + const { user, isLoading: authLoading } = useAuth(); const [team, setTeam] = useState([]); const [groups, setGroups] = useState([]); const [loading, setLoading] = useState(true); @@ -41,8 +43,13 @@ export default function TeamPage() { }, []); useEffect(() => { + if (authLoading) return; + if (user?.role !== "admin") { + setLoading(false); + return; + } fetchData(); - }, [fetchData]); + }, [fetchData, authLoading, user?.role]); const openCreate = () => { setEditing(null); @@ -97,6 +104,20 @@ export default function TeamPage() { } }; + if (!authLoading && user?.role !== "admin") { + return ( +
+
+

Equipo de Soporte

+
+
+ + Solo los administradores pueden gestionar el equipo. +
+
+ ); + } + return (
diff --git a/frontend/src/app/(app)/tickets/page.tsx b/frontend/src/app/(app)/tickets/page.tsx index 1966fde..334579b 100644 --- a/frontend/src/app/(app)/tickets/page.tsx +++ b/frontend/src/app/(app)/tickets/page.tsx @@ -3,6 +3,7 @@ import { useEffect, useState, useCallback } from "react"; import { useRouter } from "next/navigation"; import { getTickets, type Ticket } from "@/lib/api"; +import { useAuth } from "@/lib/auth"; import BadgeStatus from "@/components/BadgeStatus"; import BadgePriority from "@/components/BadgePriority"; import PaginationComponent from "@/components/Pagination"; @@ -10,21 +11,33 @@ import Link from "next/link"; export default function TicketsPage() { const router = useRouter(); + const { user } = useAuth(); const [tickets, setTickets] = useState([]); const [total, setTotal] = useState(0); const [page, setPage] = useState(1); const [loading, setLoading] = useState(true); + const [view, setView] = useState<"all" | "mine" | "assigned" | "unassigned">("all"); const [statusFilter, setStatusFilter] = useState(""); const [priorityFilter, setPriorityFilter] = useState(""); const [search, setSearch] = useState(""); const pageSize = 10; + const numericId = parseInt(user?.idUsuario ?? "", 10); + const hasNumericId = !isNaN(numericId); + const fetchTickets = useCallback(async () => { setLoading(true); try { const data = await getTickets({ status: statusFilter || undefined, priority: priorityFilter || undefined, + requesterId: view === "mine" && hasNumericId ? numericId : undefined, + assigneeId: + view === "assigned" && hasNumericId + ? numericId + : view === "unassigned" + ? 0 + : undefined, search: search || undefined, page, pageSize, @@ -37,7 +50,7 @@ export default function TicketsPage() { } finally { setLoading(false); } - }, [statusFilter, priorityFilter, search, page]); + }, [statusFilter, priorityFilter, search, page, view, numericId, hasNumericId]); useEffect(() => { fetchTickets(); @@ -56,6 +69,30 @@ export default function TicketsPage() {
{/* Filters */} +
+
+ {( + [ + ["all", "Todos"], + ["mine", "Míos"], + ["assigned", "Asignados a mí"], + ["unassigned", "Sin asignar"], + ] as const + ).map(([v, label]) => ( + + ))} +
+
diff --git a/frontend/src/components/Sidebar.tsx b/frontend/src/components/Sidebar.tsx index 1bcc00f..99bb666 100644 --- a/frontend/src/components/Sidebar.tsx +++ b/frontend/src/components/Sidebar.tsx @@ -24,6 +24,9 @@ export default function Sidebar() { pathname === href || (href !== "/" && pathname.startsWith(href)); const fullName = user ? `${user.nombres} ${user.apPaterno}` : "Usuario"; + const isAdmin = user?.role === "admin"; + const roleLabel = + user?.role === "admin" ? "Administrador" : user?.role === "agent" ? "Agente" : "Usuario"; const initials = user?.nombres ?.split(" ") .map((n: string) => n[0]) @@ -54,13 +57,15 @@ export default function Sidebar() { {item.label} ))} -
- Configuración -
- {configItems.map((item) => ( + {isAdmin && ( + <> +
+ Configuración +
+ {configItems.map((item) => ( {item.label} - ))} + ))} + + )}
{initials}
{fullName}
-
{user?.tipo || "Usuario"}
+
{roleLabel}