'use client'; import { useEffect, useState } from 'react'; import { useRouter } from 'next/navigation'; import Link from 'next/link'; import { usePortalAuthStore } from '@/lib/portal-auth-store'; import portalApi from '@/lib/portal-api'; import { formatDate } from '@/lib/utils'; interface PortalTicket { id: string; subject: string; status: string; type?: string; createdAt: string; } const statusBadge: Record = { OPEN: { bg: '#DBEAFE', text: '#1D4ED8' }, IN_PROGRESS: { bg: '#FEF9C3', text: '#CA8A04' }, RESOLVED: { bg: '#DCFCE7', text: '#16A34A' }, CLOSED: { bg: '#F1F5F9', text: '#64748B' }, }; export default function PortalTicketsPage() { const router = useRouter(); const { isAuthenticated } = usePortalAuthStore(); const [mounted, setMounted] = useState(false); const [tickets, setTickets] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(''); const [showModal, setShowModal] = useState(false); const [form, setForm] = useState({ subject: '', description: '' }); const [submitting, setSubmitting] = useState(false); const [submitError, setSubmitError] = useState(''); useEffect(() => { setMounted(true); }, []); useEffect(() => { if (!mounted) return; if (!isAuthenticated) { router.replace('/portal/login'); return; } loadTickets(); }, [mounted, isAuthenticated, router]); const loadTickets = () => { setLoading(true); portalApi.get('/api/v1/portal/tickets') .then((res) => { const data = res.data; setTickets(Array.isArray(data) ? data : data.data ?? []); }) .catch(() => setError('Failed to load tickets.')) .finally(() => setLoading(false)); }; const handleSubmitTicket = async (e: React.FormEvent) => { e.preventDefault(); setSubmitError(''); setSubmitting(true); try { await portalApi.post('/api/v1/portal/tickets', form); setShowModal(false); setForm({ subject: '', description: '' }); loadTickets(); } catch (err: unknown) { setSubmitError((err as any)?.response?.data?.message ?? 'Failed to submit ticket.'); } finally { setSubmitting(false); } }; if (!mounted || !isAuthenticated) return null; return (
← Back

Support Tickets

{error && (
{error}
)}
{loading ? (
Loading…
) : tickets.length === 0 ? (
No tickets yet. Click "New Ticket" to raise a support request.
) : ( {['Subject', 'Type', 'Status', 'Date'].map((h) => ( ))} {tickets.map((t, i) => { const badge = statusBadge[t.status] ?? statusBadge.CLOSED; return ( ); })}
{h}
{t.subject} {t.type ?? '—'} {t.status.replace('_', ' ')} {formatDate(t.createdAt)}
)}
{/* New Ticket Modal */} {showModal && (

New Support Ticket

Describe your issue and our team will get back to you.

{submitError && (
{submitError}
)}
setForm({ ...form, subject: e.target.value })} placeholder="e.g. Internet not working" style={inputStyle} />