import { useState, useMemo, useCallback } from 'react'; import { MOCK_BUGS, MOCK_USERS } from '../../data/mockData'; import { useAuth } from '../../contexts/AuthContext'; import { formatDate, formatDateTime } from '../../utils/format'; import type { BugReport, BugSeverity, BugStatus, BugReportNote } from '../../types'; function StatusBadge({ status }: { status: BugStatus }) { const map: Record = { open: 'badge-open', in_progress: 'badge-progress', resolved: 'badge-resolved', closed: 'badge-closed' }; const labels: Record = { open: 'Open', in_progress: 'In Progress', resolved: 'Resolved', closed: 'Closed' }; return {labels[status]}; } function SeverityBadge({ severity }: { severity: BugSeverity }) { const map: Record = { low: 'badge-low', medium: 'badge-medium', high: 'badge-high', critical: 'badge-critical' }; return {severity}; } const STATUSES: BugStatus[] = ['open', 'in_progress', 'resolved', 'closed']; const STAFF_MEMBERS = MOCK_USERS.filter((u) => u.role === 'dev' || u.role === 'com'); export default function IntranetBugs() { const { user } = useAuth(); const [bugs, setBugs] = useState(MOCK_BUGS); const [selected, setSelected] = useState(null); const [statusFilter, setStatusFilter] = useState('all'); const [severityFilter, setSeverityFilter] = useState('all'); const [assignedFilter, setAssignedFilter] = useState('all'); const [noteText, setNoteText] = useState(''); const openCount = bugs.filter((b) => b.status === 'open').length; const criticalCount = bugs.filter((b) => b.severity === 'critical').length; const myCount = bugs.filter((b) => b.assignedToId === user?.id).length; const filtered = useMemo(() => { return bugs.filter((b) => { if (statusFilter !== 'all' && b.status !== statusFilter) return false; if (severityFilter !== 'all' && b.severity !== severityFilter) return false; if (assignedFilter !== 'all') { if (assignedFilter === 'unassigned' && b.assignedToId) return false; if (assignedFilter !== 'unassigned' && b.assignedToId !== assignedFilter) return false; } return true; }); }, [bugs, statusFilter, severityFilter, assignedFilter]); const updateBug = useCallback((id: string, changes: Partial) => { setBugs((prev) => prev.map((b) => b.id === id ? { ...b, ...changes, updatedAt: new Date().toISOString() } : b)); setSelected((prev) => prev?.id === id ? { ...prev, ...changes, updatedAt: new Date().toISOString() } : prev); }, []); const handleAssign = useCallback((bugId: string, staffId: string) => { const staff = STAFF_MEMBERS.find((s) => s.id === staffId); updateBug(bugId, { assignedToId: staffId || undefined, assignedToName: staff?.username }); }, [updateBug]); const handleStatusChange = useCallback((bugId: string, status: BugStatus) => { updateBug(bugId, { status }); }, [updateBug]); const handleAddNote = useCallback((bugId: string) => { if (!noteText.trim() || !user) return; const note: BugReportNote = { id: `n${Date.now()}`, bugReportId: bugId, authorId: user.id, authorName: user.username, content: noteText.trim(), createdAt: new Date().toISOString(), }; setBugs((prev) => prev.map((b) => b.id === bugId ? { ...b, notes: [...(b.notes ?? []), note] } : b)); setSelected((prev) => prev?.id === bugId ? { ...prev, notes: [...(prev.notes ?? []), note] } : prev); setNoteText(''); }, [noteText, user]); return (
{/* Left panel */}
INTRANET / BUG REPORTS

BUG DASHBOARD

{/* Stats */}
{[ { label: 'Open', value: openCount, color: 'var(--color-green)' }, { label: 'Critical', value: criticalCount, color: 'var(--color-red)' }, { label: 'Mine', value: myCount, color: 'var(--color-amber)' }, ].map(({ label, value, color }) => (
{value}
{label}
))}
{/* Filters */}
{/* Bug list */}
{filtered.length === 0 ? (
No reports match filters.
) : ( filtered.map((bug) => (
setSelected(bug === selected ? null : bug)} style={{ background: selected?.id === bug.id ? 'rgba(37,99,235,0.08)' : 'var(--color-surface)', border: `1px solid ${selected?.id === bug.id ? 'var(--color-yellow)' : 'var(--color-border)'}`, padding: '0.85rem 1.1rem', cursor: 'pointer', transition: 'all 0.15s', }} role="button" tabIndex={0} onKeyDown={(e) => e.key === 'Enter' && setSelected(bug === selected ? null : bug)} aria-label={`Select bug report ${bug.uniqueCode}`} >
{bug.uniqueCode}
{formatDate(bug.createdAt)}
{bug.title}
{bug.submittedByName} — Assigned: {bug.assignedToName ?? 'None'}
)) )}
{/* Right panel — detail */} {selected && (
{selected.uniqueCode}

{selected.title}

{/* Controls */}
{/* Description */}
DESCRIPTION
{selected.description}
STEPS TO REPRODUCE
{selected.stepsToReproduce}
{/* Internal notes */}
INTERNAL NOTES (staff only)
{(selected.notes ?? []).length === 0 ? (
No notes yet.
) : (
{(selected.notes ?? []).map((note) => (
{note.authorName} — {formatDateTime(note.createdAt)}
{note.content}
))}
)}