"use client" /** * Bug Tracker - Main Page * Submit bugs, feature requests, and questions */ import { useState } from "react" import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import { Textarea } from "@/components/ui/textarea" import { Label } from "@/components/ui/label" import { Bug, Lightbulb, HelpCircle, MessageSquare, CheckCircle, ArrowRight, ExternalLink } from "lucide-react" import Link from "next/link" import { getApiUrl } from "@/lib/api-config" import { useAuth } from "@/contexts/auth-context" const TICKET_TYPES = [ { value: "bug", label: "Bug Report", icon: Bug, description: "Something isn't working" }, { value: "feature", label: "Feature Request", icon: Lightbulb, description: "Suggest an improvement" }, { value: "question", label: "Question", icon: HelpCircle, description: "Ask for help" }, { value: "other", label: "Other", icon: MessageSquare, description: "General feedback" }, ] const PRIORITIES = [ { value: "low", label: "Low", color: "bg-gray-500" }, { value: "medium", label: "Medium", color: "bg-yellow-500" }, { value: "high", label: "High", color: "bg-orange-500" }, { value: "critical", label: "Critical", color: "bg-red-500" }, ] export default function BugsPage() { const { user } = useAuth() const [step, setStep] = useState<"type" | "form" | "success">("type") const [selectedType, setSelectedType] = useState("bug") const [submitting, setSubmitting] = useState(false) const [ticketNumber, setTicketNumber] = useState("") const [error, setError] = useState("") const [formData, setFormData] = useState({ title: "", description: "", priority: "medium", reporter_email: "", reporter_name: "", }) const handleTypeSelect = (type: string) => { setSelectedType(type) setStep("form") } const handleSubmit = async (e: React.FormEvent) => { e.preventDefault() setSubmitting(true) setError("") try { const token = localStorage.getItem("token") const headers: Record = { "Content-Type": "application/json", } if (token) { headers["Authorization"] = `Bearer ${token}` } const res = await fetch(`${getApiUrl()}/tickets/`, { method: "POST", headers, body: JSON.stringify({ type: selectedType, priority: formData.priority, title: formData.title, description: formData.description, reporter_email: user?.email || formData.reporter_email, reporter_name: formData.reporter_name, page_url: window.location.href, browser: navigator.userAgent, }), }) if (!res.ok) { const data = await res.json() throw new Error(data.detail || "Failed to submit") } const ticket = await res.json() setTicketNumber(ticket.ticket_number) setStep("success") } catch (e: any) { setError(e.message || "Failed to submit ticket") } finally { setSubmitting(false) } } // Success screen if (step === "success") { return (

Ticket Submitted!

Your ticket number is {ticketNumber}

We'll review your submission and get back to you soon.

) } return (

How can we help?

Report bugs, request features, or ask questions

{step === "type" && ( <> {/* Type Selection */}
{TICKET_TYPES.map((type) => { const Icon = type.icon return ( ) })}
{/* Quick Links */}
{user && ( )}
)} {step === "form" && (
{TICKET_TYPES.find(t => t.value === selectedType)?.icon && ( (() => { const Icon = TICKET_TYPES.find(t => t.value === selectedType)!.icon return })() )} {TICKET_TYPES.find(t => t.value === selectedType)?.label} Fill out the details below
{/* Title */}
setFormData({ ...formData, title: e.target.value })} required maxLength={200} />
{/* Description */}