'use client'; import { useEffect, useState, useRef } from 'react'; import { useParams, useRouter } from 'next/navigation'; const ADMIN_API_URL = process.env.NEXT_PUBLIC_ADMIN_API_URL || 'http://localhost:3004/api'; interface Attachment { id: string; fileName: string; originalName: string; mimeType: string; sizeBytes: number; createdAt: string; } interface Comment { id: string; authorName: string; authorType: string; content: string; createdAt: string; attachments: Attachment[]; } interface Ticket { id: string; subject: string; description: string; category: string; priority: string; status: string; createdByName: string; assignee: { firstName: string; lastName: string } | null; comments: Comment[]; attachments: Attachment[]; createdAt: string; } const statusColors: Record = { open: 'bg-yellow-50 text-yellow-700', in_progress: 'bg-blue-50 text-blue-700', waiting_tenant: 'bg-orange-50 text-orange-700', resolved: 'bg-green-50 text-green-700', closed: 'bg-surface-100 text-surface-500', }; function formatBytes(bytes: number) { if (bytes < 1024) return bytes + ' B'; if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB'; return (bytes / (1024 * 1024)).toFixed(1) + ' MB'; } export default function TicketDetailPage() { const params = useParams(); const router = useRouter(); const ticketId = params.id as string; const [ticket, setTicket] = useState(null); const [loading, setLoading] = useState(true); const [comment, setComment] = useState(''); const [submitting, setSubmitting] = useState(false); const [uploading, setUploading] = useState(false); const fileInputRef = useRef(null); const [selectedFiles, setSelectedFiles] = useState([]); useEffect(() => { loadTicket(); }, [ticketId]); function authHeaders() { const token = localStorage.getItem('accessToken'); return { Authorization: `Bearer ${token}` }; } async function loadTicket() { try { const res = await fetch(`${ADMIN_API_URL}/public/support/tickets/${ticketId}`, { headers: authHeaders(), }); const data = await res.json(); setTicket(data.data || data); } catch { // not found } finally { setLoading(false); } } async function handleAddComment() { if (!comment.trim() && selectedFiles.length === 0) return; setSubmitting(true); try { // Add comment first if (comment.trim()) { await fetch(`${ADMIN_API_URL}/public/support/tickets/${ticketId}/comments`, { method: 'POST', headers: { 'Content-Type': 'application/json', ...authHeaders() }, body: JSON.stringify({ content: comment }), }); } // Upload files if any if (selectedFiles.length > 0) { const formData = new FormData(); selectedFiles.forEach((f) => formData.append('files', f)); await fetch(`${ADMIN_API_URL}/public/support/tickets/${ticketId}/attachments`, { method: 'POST', headers: authHeaders(), body: formData, }); } setComment(''); setSelectedFiles([]); loadTicket(); } catch (err) { console.error('Failed to submit:', err); } finally { setSubmitting(false); } } async function handleFileUpload(files: FileList) { setUploading(true); try { const formData = new FormData(); Array.from(files).forEach((f) => formData.append('files', f)); await fetch(`${ADMIN_API_URL}/public/support/tickets/${ticketId}/attachments`, { method: 'POST', headers: authHeaders(), body: formData, }); loadTicket(); } catch (err) { console.error('Failed to upload:', err); } finally { setUploading(false); } } function handleDownload(fileName: string, originalName: string) { const token = localStorage.getItem('accessToken'); window.open(`${ADMIN_API_URL}/public/support/uploads/${fileName}?token=${token}`, '_blank'); } if (loading) return
Loading...
; if (!ticket) return
Ticket not found
; return (
{/* Main content */}
{/* Ticket header */}

{ticket.subject}

{ticket.status.replace(/_/g, ' ')}

{ticket.description}

Created {new Date(ticket.createdAt).toLocaleString()} by {ticket.createdByName}
{/* Ticket-level attachments */} {ticket.attachments.length > 0 && (

Attachments

{ticket.attachments.map((a) => ( ))}
)} {/* Comments thread */}

Conversation ({ticket.comments.length})

{ticket.comments.map((c) => (
{c.authorName} {c.authorType === 'super_admin' ? 'FiberOps Team' : 'You'}
{new Date(c.createdAt).toLocaleString()}

{c.content}

{/* Comment attachments */} {c.attachments.length > 0 && (
{c.attachments.map((a) => ( ))}
)}
))} {/* Add comment form */}