import { createResource, createSignal, createMemo, Show, For } from 'solid-js'; import { A } from '@solidjs/router'; import AdminShell from '~/components/AdminShell'; const API = '/api/gateway'; type SupportCase = { id: string; title: string; description: string; type: 'platform_issue' | 'customer_query' | 'professional_query' | 'billing_issue' | 'lead_dispute'; priority: 'low' | 'medium' | 'high' | 'critical'; status: 'new' | 'in_progress' | 'waiting_for_user' | 'resolved' | 'closed'; requesterName?: string; requesterEmail?: string; updatedAt: string; createdAt: string; }; const STATUS_OPTIONS: SupportCase['status'][] = ['new', 'in_progress', 'waiting_for_user', 'resolved', 'closed']; const TYPE_OPTIONS: SupportCase['type'][] = ['platform_issue', 'customer_query', 'professional_query', 'billing_issue', 'lead_dispute']; const PRIORITY_OPTIONS: SupportCase['priority'][] = ['low', 'medium', 'high', 'critical']; function formatValue(input: string): string { return input.replace(/_/g, ' ').replace(/\b\w/g, (c) => c.toUpperCase()); } function typeBadgeStyle(type: string): string { const map: Record = { platform_issue: 'background:#dbeafe;color:#1d4ed8', customer_query: 'background:#dcfce7;color:#15803d', billing_issue: 'background:#ffedd5;color:#c2410c', lead_dispute: 'background:#fee2e2;color:#b91c1c', professional_query: 'background:#f3e8ff;color:#7e22ce', }; return map[type] || 'background:#f1f5f9;color:#475569'; } function priorityBadgeStyle(priority: string): string { const map: Record = { low: 'background:#f1f5f9;color:#475569', medium: 'background:#dbeafe;color:#1d4ed8', high: 'background:#ffedd5;color:#c2410c', critical: 'background:#fee2e2;color:#b91c1c', }; return map[priority] || 'background:#f1f5f9;color:#475569'; } function statusBadgeStyle(status: string): string { const map: Record = { new: 'background:#dbeafe;color:#1d4ed8', in_progress: 'background:#ffedd5;color:#c2410c', waiting_for_user: 'background:#fef9c3;color:#a16207', resolved: 'background:#dcfce7;color:#15803d', closed: 'background:#f1f5f9;color:#475569', }; return map[status] || 'background:#f1f5f9;color:#475569'; } const BADGE_STYLE = 'display:inline-block;padding:2px 8px;border-radius:999px;font-size:11px;font-weight:600'; async function loadAllCases(): Promise { try { const res = await fetch(`${API}/api/admin/support-cases`); if (!res.ok) throw new Error('Failed'); const data = await res.json(); return Array.isArray(data.cases) ? data.cases : Array.isArray(data) ? data : []; } catch { return []; } } export default function SupportPage() { const [activeTab, setActiveTab] = createSignal<'queue' | 'create'>('queue'); const [statusFilter, setStatusFilter] = createSignal<'all' | SupportCase['status']>('all'); const [refetchKey, setRefetchKey] = createSignal(0); const [cases] = createResource(refetchKey, loadAllCases); const refetch = () => setRefetchKey((k) => k + 1); const filteredCases = createMemo(() => { const all = cases() ?? []; const sf = statusFilter(); if (sf === 'all') return all; return all.filter((c) => c.status === sf); }); const stats = createMemo(() => { const all = cases() ?? []; return { newCount: all.filter((c) => c.status === 'new').length, inProgressCount: all.filter((c) => c.status === 'in_progress').length, waitingCount: all.filter((c) => c.status === 'waiting_for_user').length, total: all.length, }; }); // Create Case form state const [fTitle, setFTitle] = createSignal(''); const [fDesc, setFDesc] = createSignal(''); const [fType, setFType] = createSignal('customer_query'); const [fPriority, setFPriority] = createSignal('medium'); const [fRequesterName, setFRequesterName] = createSignal(''); const [fRequesterEmail, setFRequesterEmail] = createSignal(''); const [createLoading, setCreateLoading] = createSignal(false); const [createSuccess, setCreateSuccess] = createSignal(''); const [createError, setCreateError] = createSignal(''); const resetForm = () => { setFTitle(''); setFDesc(''); setFType('customer_query'); setFPriority('medium'); setFRequesterName(''); setFRequesterEmail(''); }; const handleCreate = async (e: Event) => { e.preventDefault(); setCreateLoading(true); setCreateSuccess(''); setCreateError(''); try { const res = await fetch(`${API}/api/admin/support-cases`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ title: fTitle(), description: fDesc(), type: fType(), priority: fPriority(), requesterName: fRequesterName(), requesterEmail: fRequesterEmail(), }), }); if (!res.ok) { const d = await res.json().catch(() => ({})); throw new Error((d as any).message || 'Failed to create case'); } setCreateSuccess('Case created!'); resetForm(); refetch(); setActiveTab('queue'); } catch (err: any) { setCreateError(err.message || 'Failed to create case'); } finally { setCreateLoading(false); } }; const statCards = [ { label: 'New', getValue: () => stats().newCount }, { label: 'In Progress', getValue: () => stats().inProgressCount }, { label: 'Waiting', getValue: () => stats().waitingCount }, { label: 'Total', getValue: () => stats().total }, ]; return (

Support Management

Handle platform issues and customer queries

{/* Stats bar */}
{(card) => (
{card.getValue()}
{card.label}
)}
{/* Tabs */}
{/* Support Queue Tab */}
0}> {(item) => ( {}}> )}
Issue Type Priority Status Requester Updated At Actions
Loading...
Failed to load cases.
No support cases found.
{item.title}
{item.description}
{formatValue(item.type)} {formatValue(item.priority)} {formatValue(item.status)}
{item.requesterName || '—'}
{item.requesterEmail || ''}
{item.updatedAt ? new Date(item.updatedAt).toLocaleString() : '—'}
{/* Create Case Tab */}

Create Support Case

Create an internal support record for platform issues, customer concerns, or compensation-related reviews.

{createSuccess()}
{createError()}
setFTitle(e.currentTarget.value)} style="width:100%;padding:8px 10px;border:1px solid #e2e8f0;border-radius:6px;font-size:14px;box-sizing:border-box" />