"use client" import { cn } from "@mdxui/primitives/lib/utils" import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@mdxui/primitives/table" import { Badge } from "@mdxui/primitives/badge" import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from "@mdxui/primitives/tooltip" import type { Sentiment } from "./feedback/types" import type { BugSeverity } from "./bug-report/types" import type { Severity } from "./error-report/types" import type { ResolutionStatus, SatisfactionRating } from "./resolution/types" // Type discriminator for support activity types export type SupportActivityType = "feedback" | "contact" | "bug-report" | "error-report" | "resolution" // Base fields shared by all support activity records interface BaseSupportActivity { id: string timestamp: string userName?: string userEmail?: string page: string device: string } // Type-specific activity records interface FeedbackActivity extends BaseSupportActivity { type: "feedback" sentiment: Sentiment message?: string } interface ContactActivity extends BaseSupportActivity { type: "contact" status: "new" | "in-progress" | "resolved" topic?: string message: string } interface BugReportActivity extends BaseSupportActivity { type: "bug-report" severity: BugSeverity title: string } interface ErrorReportActivity extends BaseSupportActivity { type: "error-report" severity: Severity description: string errorCode?: string } interface ResolutionActivity extends BaseSupportActivity { type: "resolution" resolved: ResolutionStatus satisfaction: SatisfactionRating ticketId?: string feedback?: string } // Union type for all support activity records export type SupportActivityRecord = | FeedbackActivity | ContactActivity | BugReportActivity | ErrorReportActivity | ResolutionActivity // Sample data with a mix of all support types const sampleActivityRecords: SupportActivityRecord[] = [ { id: "act_001", type: "feedback", sentiment: "very-satisfied", message: "The new dashboard design is much cleaner. Love the dark mode!", userName: "Alex Smith", userEmail: "alex.smith@company.com", page: "/dashboard", timestamp: "2026-01-29T21:42:15Z", device: "Desktop", }, { id: "act_002", type: "bug-report", severity: "critical", title: "Payment processing fails on checkout", userName: "Maria Garcia", userEmail: "maria.g@startup.io", page: "/checkout", timestamp: "2026-01-29T21:30:00Z", device: "Mobile", }, { id: "act_003", type: "contact", status: "new", topic: "Sales", message: "We're interested in the enterprise plan for our team of 50. Can we schedule a demo?", userName: "Michael Brown", userEmail: "m.brown@techstartup.io", page: "/pricing", timestamp: "2026-01-29T20:30:15Z", device: "Desktop", }, { id: "act_004", type: "error-report", severity: "high", description: "Application crashed when uploading large files", errorCode: "ERR_FILE_UPLOAD", userName: "James Wilson", userEmail: "jwilson@enterprise.com", page: "/upload", timestamp: "2026-01-29T20:15:33Z", device: "Desktop", }, { id: "act_005", type: "resolution", resolved: "yes", satisfaction: 5, ticketId: "TKT-1234", feedback: "Support team was incredibly helpful and resolved my issue quickly.", userName: "Sarah Chen", userEmail: "sarah@bigcorp.com", page: "/support/ticket/1234", timestamp: "2026-01-29T19:45:22Z", device: "Desktop", }, { id: "act_006", type: "feedback", sentiment: "dissatisfied", message: "The loading time is too slow on mobile. Please optimize.", userName: "Emily Johnson", userEmail: "emily.j@agency.co", page: "/reports", timestamp: "2026-01-29T19:12:44Z", device: "Mobile", }, { id: "act_007", type: "bug-report", severity: "minor", title: "Tooltip text cut off on hover", userName: "David Kim", userEmail: "dkim@enterprise.com", page: "/settings", timestamp: "2026-01-29T18:22:11Z", device: "Desktop", }, { id: "act_008", type: "contact", status: "in-progress", topic: "Support", message: "The webhook notifications stopped working yesterday. Our team relies on this for critical workflows.", userName: "Lisa Wang", userEmail: "lisa@startup.io", page: "/webhooks", timestamp: "2026-01-29T18:05:22Z", device: "Desktop", }, { id: "act_009", type: "error-report", severity: "medium", description: "Intermittent connection timeout during API calls", errorCode: "ERR_TIMEOUT", userName: undefined, userEmail: undefined, page: "/api-console", timestamp: "2026-01-29T17:55:02Z", device: "Tablet", }, { id: "act_010", type: "resolution", resolved: "partially", satisfaction: 3, ticketId: "TKT-1198", feedback: "Issue was partially fixed but I still see occasional glitches.", userName: "Robert Taylor", userEmail: "rtaylor@corp.net", page: "/support/ticket/1198", timestamp: "2026-01-29T16:48:09Z", device: "Desktop", }, ] // Type badge configuration - using outline for all types, simple and clean const typeLabels: Record = { "feedback": "Feedback", "contact": "Contact", "bug-report": "Bug", "error-report": "Error", "resolution": "Resolution", } // Status/Sentiment labels const sentimentLabels: Record = { "very-dissatisfied": "Very Dissatisfied", "dissatisfied": "Dissatisfied", "neutral": "Neutral", "satisfied": "Satisfied", "very-satisfied": "Very Satisfied", } const contactStatusLabels: Record<"new" | "in-progress" | "resolved", string> = { "new": "New", "in-progress": "In Progress", "resolved": "Resolved", } const bugSeverityLabels: Record = { "cosmetic": "Cosmetic", "minor": "Minor", "major": "Major", "critical": "Critical", } const errorSeverityLabels: Record = { "low": "Low", "medium": "Medium", "high": "High", "critical": "Critical", } const resolutionLabels: Record = { "yes": "Resolved", "no": "Unresolved", "partially": "Partial", } // Helper to render status/sentiment badge based on type - using secondary for all function StatusBadge({ record }: { record: SupportActivityRecord }) { switch (record.type) { case "feedback": return ( {sentimentLabels[record.sentiment]} ) case "contact": return ( {contactStatusLabels[record.status]} ) case "bug-report": return ( {bugSeverityLabels[record.severity]} ) case "error-report": return ( {errorSeverityLabels[record.severity]} ) case "resolution": return ( {resolutionLabels[record.resolved]} ) } } // Helper to get summary text based on type function getSummary(record: SupportActivityRecord): string | undefined { switch (record.type) { case "feedback": return record.message case "contact": return record.message case "bug-report": return record.title case "error-report": return record.description case "resolution": return record.feedback } } export interface SupportActivityTableProps { /** Activity records to display */ data?: SupportActivityRecord[] /** Additional class name */ className?: string } export function SupportActivityTable({ data = sampleActivityRecords, className, }: SupportActivityTableProps) { return (
User Type Status Summary Page Device Date {data.map((record) => { const summary = getSummary(record) return ( {record.userName ? (
{record.userName} {record.userEmail}
) : ( Anonymous )}
{typeLabels[record.type]} {summary ? ( {summary}

{summary}

) : ( No message )}
{record.page} {record.device} {new Date(record.timestamp).toLocaleDateString("en-US", { month: "short", day: "numeric", hour: "2-digit", minute: "2-digit", })}
) })}
) }