"use client"; import { useEffect, useState } from "react"; import { useParams } from "next/navigation"; import { useAuth } from "@/lib/auth"; import { getTicket, getComments, addComment, updateTicketStatus, assignTicket, getGroups, getTeam, type Ticket, type Comment, type Group, type TeamMember, } from "@/lib/api"; import BadgeStatus from "@/components/BadgeStatus"; import BadgePriority from "@/components/BadgePriority"; import Link from "next/link"; const STATUS_OPTIONS = [ { value: "open", label: "Abierto" }, { value: "pending", label: "Pendiente" }, { value: "in_progress", label: "En Progreso" }, { value: "resolved", label: "Resuelto" }, { value: "closed", label: "Cerrado" }, ]; export default function TicketDetailPage() { const params = useParams(); const id = Number(params.id); const { user } = useAuth(); const isTeam = user?.role === "admin" || user?.role === "agent"; const [ticket, setTicket] = useState(null); const [comments, setComments] = useState([]); const [groups, setGroups] = useState([]); const [team, setTeam] = useState([]); const [loading, setLoading] = useState(true); const [comment, setComment] = useState(""); const [isInternal, setIsInternal] = useState(false); const [submitting, setSubmitting] = useState(false); const [acting, setActing] = useState(false); const [error, setError] = useState(""); const [statusOpen, setStatusOpen] = useState(false); const [assignOpen, setAssignOpen] = useState(false); useEffect(() => { Promise.all([ getTicket(id).catch(() => null), getComments(id).catch(() => []), getGroups().catch(() => []), getTeam().catch(() => []), ]) .then(([ticketData, commentsData, groupsData, teamData]) => { setTicket(ticketData); setComments(commentsData); setGroups(groupsData); setTeam(teamData); }) .finally(() => setLoading(false)); }, [id]); const refreshTicket = async () => { const updated = await getTicket(id).catch(() => null); if (updated) setTicket(updated); }; const handleAddComment = async (e: React.FormEvent) => { e.preventDefault(); if (!comment.trim()) return; setSubmitting(true); try { await addComment(id, comment, isInternal); const updated = await getComments(id).catch(() => []); setComments(updated); setComment(""); setIsInternal(false); } catch { // ignore } finally { setSubmitting(false); } }; const handleStatusChange = async (newStatus: string) => { setStatusOpen(false); setError(""); setActing(true); try { await updateTicketStatus(id, newStatus); await refreshTicket(); } catch (err: any) { setError(err.message || "No se pudo cambiar el estado"); } finally { setActing(false); } }; const handleAssignDepartment = async (groupId: number) => { if (!ticket) return; setAssignOpen(false); setError(""); setActing(true); try { await assignTicket(id, ticket.assigneeId ?? 0, groupId); await refreshTicket(); } catch (err: any) { setError(err.message || "No se pudo asignar el departamento"); } finally { setActing(false); } }; const handleAssignAgent = async (idUsuario: string | null) => { if (!ticket) return; setAssignOpen(false); setError(""); setActing(true); try { await assignTicket( id, idUsuario === null ? 0 : Number(idUsuario), ticket.groupId ?? undefined ); await refreshTicket(); } catch (err: any) { setError(err.message || "No se pudo asignar el agente"); } finally { setActing(false); } }; if (loading) { return (
); } if (!ticket) { return (
Ticket no encontrado
Volver a tickets
); } return (
{/* Ticket Header */}
{ticket.ticketNumber}

{ticket.title}

{isTeam && (
{/* Status Change (dropdown controlado por React: sin bootstrap.js) */}
{statusOpen && ( <>
setStatusOpen(false)} />
    {STATUS_OPTIONS.map((s) => (
  • ))}
)}
{/* Assign (dropdown controlado por React: sin bootstrap.js) */}
{assignOpen && ( <>
setAssignOpen(false)} />
  • Departamento
  • {groups.length === 0 && (
  • Sin departamentos
  • )} {groups.map((g) => (
  • ))}

  • Agente
  • {team.map((m) => (
  • ))}
)}
)}
{error && (
{error}
)}
{/* Comments Timeline */}
Comentarios ({comments.length})
{comments.length > 0 ? ( comments.map((c) => (
{c.userName || "Usuario"} {c.isInternal && ( Nota Interna )}
{c.content}
{new Date(c.createdAt).toLocaleString("es-CL")}
)) ) : (
No hay comentarios aún
)}
{/* Comment Form */}
setIsInternal(e.target.checked)} />
{/* Ticket Info Sidebar */}
Información del Ticket
Solicitante {ticket.requesterName || "N/A"}
Email {ticket.requesterEmail || "N/A"}
Asignado a {ticket.assigneeName || "Sin asignar"}
Grupo {ticket.groupName || "N/A"}
Creado {new Date(ticket.createdAt).toLocaleString("es-CL")}
Actualizado {new Date(ticket.updatedAt).toLocaleString("es-CL")}
{/* Description */}
Descripción

{ticket.description || "Sin descripción"}

); }