"use client" import { cn } from "@mdxui/primitives/lib/utils" import { Button } from "@mdxui/primitives/button" import { Input } from "@mdxui/primitives/input" import { Textarea } from "@mdxui/primitives/textarea" import { Label } from "@mdxui/primitives/label" import { Badge } from "@mdxui/primitives/badge" import { Checkbox } from "@mdxui/primitives/checkbox" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@mdxui/primitives/select" import { useState } from "react" import type { BugReportData, BugReportUser, BugSeverity } from "./types" const SEVERITY_OPTIONS: Array<{ value: BugSeverity; label: string; variant: 'default' | 'secondary' | 'destructive' | 'outline' }> = [ { value: 'cosmetic', label: 'Cosmetic', variant: 'secondary' }, { value: 'minor', label: 'Minor', variant: 'outline' }, { value: 'major', label: 'Major', variant: 'default' }, { value: 'critical', label: 'Critical', variant: 'destructive' }, ] interface BugReportContentProps { showStepsToReproduce?: boolean showWorkedBefore?: boolean user?: BugReportUser context?: Record captureMetadata?: boolean onSubmit?: (data: BugReportData) => Promise | void apiEndpoint?: string submitLabel?: string onSuccess: () => void onError: (error: string) => void } function captureCurrentMetadata() { return { url: window.location.href, timestamp: new Date().toISOString(), viewport: { width: window.innerWidth, height: window.innerHeight }, userAgent: navigator.userAgent, } } export function BugReportContent({ showStepsToReproduce = true, showWorkedBefore = true, user, context, captureMetadata = true, onSubmit, apiEndpoint, submitLabel = "Submit Bug Report", onSuccess, onError, }: BugReportContentProps) { const [title, setTitle] = useState("") const [expected, setExpected] = useState("") const [actual, setActual] = useState("") const [stepsToReproduce, setStepsToReproduce] = useState("") const [severity, setSeverity] = useState("minor") const [workedBefore, setWorkedBefore] = useState(false) const [isSubmitting, setIsSubmitting] = useState(false) const [errors, setErrors] = useState>({}) const validate = (): boolean => { const newErrors: Record = {} if (title.trim().length < 5) { newErrors.title = "Title must be at least 5 characters" } if (expected.trim().length < 10) { newErrors.expected = "Expected behavior must be at least 10 characters" } if (actual.trim().length < 10) { newErrors.actual = "Actual behavior must be at least 10 characters" } setErrors(newErrors) return Object.keys(newErrors).length === 0 } const handleSubmit = async () => { if (!validate()) return setIsSubmitting(true) const data: BugReportData = { title: title.trim(), expected: expected.trim(), actual: actual.trim(), stepsToReproduce: showStepsToReproduce && stepsToReproduce.trim() ? stepsToReproduce.trim() : undefined, severity, workedBefore: showWorkedBefore ? workedBefore : undefined, user, context, metadata: captureMetadata ? captureCurrentMetadata() : undefined, } try { if (onSubmit) { await onSubmit(data) } else if (apiEndpoint) { const response = await fetch(apiEndpoint, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(data), }) if (!response.ok) { throw new Error(`Failed to submit: ${response.statusText}`) } } onSuccess() } catch (err) { onError(err instanceof Error ? err.message : "Failed to submit bug report") } finally { setIsSubmitting(false) } } const isValid = title.trim().length >= 5 && expected.trim().length >= 10 && actual.trim().length >= 10 const selectedSeverityOption = SEVERITY_OPTIONS.find(opt => opt.value === severity) return (
{/* Title */}
setTitle(e.target.value)} placeholder="Brief summary of the issue" className={cn(errors.title && "border-destructive")} /> {errors.title && (

{errors.title}

)}
{/* Expected Behavior */}