glitchgrab 1.18.1 → 1.19.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -752,6 +752,7 @@ function ReportDialog({
|
|
|
752
752
|
position: "fixed",
|
|
753
753
|
inset: 0,
|
|
754
754
|
zIndex: 2147483647,
|
|
755
|
+
pointerEvents: "auto",
|
|
755
756
|
display: "flex",
|
|
756
757
|
alignItems: "center",
|
|
757
758
|
justifyContent: "center",
|
|
@@ -761,6 +762,8 @@ function ReportDialog({
|
|
|
761
762
|
onClick: () => {
|
|
762
763
|
if (!previewOpen) handleClose();
|
|
763
764
|
},
|
|
765
|
+
onPointerDown: (e) => e.stopPropagation(),
|
|
766
|
+
onFocus: (e) => e.stopPropagation(),
|
|
764
767
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
765
768
|
"div",
|
|
766
769
|
{
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/provider.tsx","../src/error-boundary.tsx","../src/breadcrumbs.ts","../src/utils.ts","../src/dedup.ts","../src/report-dialog.tsx","../src/report-button.tsx","../src/use-reports.ts"],"sourcesContent":["\"use client\";\n\n// ─── Core (required) ─────────────────────────────────────\nexport { GlitchgrabProvider, useGlitchgrab } from \"./provider\";\n\n// ─── Optional Components ─────────────────────────────────\nexport { ReportButton } from \"./report-button\";\nexport { GlitchgrabErrorBoundary } from \"./error-boundary\";\n\n// ─── Hooks ──────────────────────────────────────────────\nexport { useGlitchgrabReports, fetchGlitchgrabReports, useGlitchgrabActions } from \"./use-reports\";\nexport type { GlitchgrabReport } from \"./use-reports\";\n\n// ─── Breadcrumbs ─────────────────────────────────────────\nexport {\n addBreadcrumb,\n getBreadcrumbs,\n clearBreadcrumbs,\n initBreadcrumbs,\n} from \"./breadcrumbs\";\n\n// ─── Utilities ───────────────────────────────────────────\nexport { sanitizeUrl, captureContext, captureDeviceInfo, sendReport } from \"./utils\";\nexport { computeSignature, shouldSkipDuplicate, clearDedupCache } from \"./dedup\";\n\n// ─── Types ───────────────────────────────────────────────\nexport type {\n GlitchgrabConfig,\n GlitchgrabProviderProps,\n ReportPayload,\n ReportResult,\n ReportType,\n ReportSeverity,\n CapturedContext,\n DeviceInfo,\n Breadcrumb,\n BreadcrumbType,\n UseGlitchgrabReturn,\n ReportButtonProps,\n GlitchgrabSession,\n} from \"./types\";\n","\"use client\";\n\nimport {\n createContext,\n useContext,\n useRef,\n useEffect,\n useCallback,\n useState,\n} from \"react\";\nimport type {\n GlitchgrabProviderProps,\n UseGlitchgrabReturn,\n ReportPayload,\n ReportResult,\n ReportType,\n} from \"./types\";\nimport { GlitchgrabErrorBoundary } from \"./error-boundary\";\nimport { ReportDialog } from \"./report-dialog\";\nimport { sanitizeUrl, captureContext, sendReport, captureDeviceInfo } from \"./utils\";\nimport { computeSignature, shouldSkipDuplicate } from \"./dedup\";\nimport {\n initBreadcrumbs,\n addBreadcrumb as addBreadcrumbInternal,\n getBreadcrumbs,\n} from \"./breadcrumbs\";\n\nconst DEFAULT_BASE_URL = \"https://www.glitchgrab.dev\";\n\nconst GlitchgrabContext = createContext<UseGlitchgrabReturn | null>(null);\n\n/**\n * Hook to access Glitchgrab in your components.\n *\n * @example\n * ```tsx\n * const { reportBug, report, addBreadcrumb } = useGlitchgrab();\n *\n * // Report a bug\n * reportBug(\"Login button crashes on mobile\");\n *\n * // Report a feature request\n * report(\"FEATURE_REQUEST\", \"Add dark mode\");\n *\n * // Add a custom breadcrumb\n * addBreadcrumb(\"User clicked checkout\", { cartItems: \"3\" });\n * ```\n */\nexport function useGlitchgrab(): UseGlitchgrabReturn {\n const ctx = useContext(GlitchgrabContext);\n if (!ctx) {\n throw new Error(\"useGlitchgrab must be used within a GlitchgrabProvider\");\n }\n return ctx;\n}\n\nfunction GlitchgrabProviderInner({\n token,\n session,\n baseUrl,\n onError,\n onReportSent,\n breadcrumbs: enableBreadcrumbs = true,\n maxBreadcrumbs = 50,\n children,\n fallback,\n types,\n showSeverity,\n}: GlitchgrabProviderProps) {\n const visitedPagesRef = useRef<string[]>([]);\n\n // Initialize breadcrumbs\n useEffect(() => {\n if (enableBreadcrumbs) {\n initBreadcrumbs(maxBreadcrumbs);\n }\n }, [enableBreadcrumbs, maxBreadcrumbs]);\n\n // Track page visits\n useEffect(() => {\n try {\n if (typeof window === \"undefined\") return;\n\n const trackPage = () => {\n try {\n const sanitized = sanitizeUrl(window.location.href);\n const pages = visitedPagesRef.current;\n if (pages[pages.length - 1] !== sanitized) {\n pages.push(sanitized);\n if (pages.length > 20) {\n pages.splice(0, pages.length - 20);\n }\n }\n } catch {\n // Silently fail\n }\n };\n\n trackPage();\n const handlePopState = () => trackPage();\n window.addEventListener(\"popstate\", handlePopState);\n\n const origPushState = history.pushState.bind(history);\n const origReplaceState = history.replaceState.bind(history);\n\n history.pushState = function (...args) {\n origPushState(...args);\n trackPage();\n };\n history.replaceState = function (...args) {\n origReplaceState(...args);\n trackPage();\n };\n\n return () => {\n window.removeEventListener(\"popstate\", handlePopState);\n history.pushState = origPushState;\n history.replaceState = origReplaceState;\n };\n } catch {\n // Never crash\n }\n }, []);\n\n // Unhandled errors and rejections — skip in development\n useEffect(() => {\n try {\n if (typeof window === \"undefined\") return;\n if (process.env.NODE_ENV === \"development\") return;\n\n const handleError = (event: ErrorEvent) => {\n try {\n const context = captureContext(visitedPagesRef.current);\n const sig = computeSignature({\n errorMessage: event.message,\n pageUrl: context.url,\n errorStack: event.error?.stack,\n });\n if (shouldSkipDuplicate(sig)) return;\n const payload: ReportPayload = {\n token,\n source: \"SDK_AUTO\",\n type: \"BUG\",\n errorMessage: event.message,\n errorStack: event.error?.stack,\n pageUrl: context.url,\n userAgent: context.userAgent,\n breadcrumbs: context.breadcrumbs,\n deviceInfo: context.deviceInfo ?? undefined,\n metadata: {\n timestamp: context.timestamp,\n visitedPages: JSON.stringify(context.visitedPages),\n filename: event.filename ?? \"\",\n lineno: String(event.lineno ?? \"\"),\n colno: String(event.colno ?? \"\"),\n ...(session?.userId ? { sessionUserId: session.userId } : {}),\n ...(session?.name ? { sessionUserName: String(session.name) } : {}),\n ...(session?.email ? { sessionUserEmail: String(session.email) } : {}),\n ...(session?.phone ? { sessionUserPhone: String(session.phone) } : {}),\n },\n };\n sendReport(payload, baseUrl).then((result) => {\n if (result && onReportSent) onReportSent(result);\n });\n if (onError && event.error) onError(event.error);\n } catch {\n // Silently fail\n }\n };\n\n const handleRejection = (event: PromiseRejectionEvent) => {\n try {\n const context = captureContext(visitedPagesRef.current);\n const reason = event.reason;\n const errMsg = reason instanceof Error ? reason.message : String(reason);\n const errStack = reason instanceof Error ? reason.stack : undefined;\n const sig = computeSignature({\n errorMessage: errMsg,\n pageUrl: context.url,\n errorStack: errStack,\n });\n if (shouldSkipDuplicate(sig)) return;\n const payload: ReportPayload = {\n token,\n source: \"SDK_AUTO\",\n type: \"BUG\",\n errorMessage: errMsg,\n errorStack: errStack,\n pageUrl: context.url,\n userAgent: context.userAgent,\n breadcrumbs: context.breadcrumbs,\n deviceInfo: context.deviceInfo ?? undefined,\n metadata: {\n timestamp: context.timestamp,\n visitedPages: JSON.stringify(context.visitedPages),\n type: \"unhandledrejection\",\n ...(session?.userId ? { sessionUserId: session.userId } : {}),\n ...(session?.name ? { sessionUserName: String(session.name) } : {}),\n ...(session?.email ? { sessionUserEmail: String(session.email) } : {}),\n ...(session?.phone ? { sessionUserPhone: String(session.phone) } : {}),\n },\n };\n sendReport(payload, baseUrl).then((result) => {\n if (result && onReportSent) onReportSent(result);\n });\n if (onError && reason instanceof Error) onError(reason);\n } catch {\n // Silently fail\n }\n };\n\n window.addEventListener(\"error\", handleError);\n window.addEventListener(\"unhandledrejection\", handleRejection);\n\n return () => {\n window.removeEventListener(\"error\", handleError);\n window.removeEventListener(\"unhandledrejection\", handleRejection);\n };\n } catch {\n // Never crash\n }\n }, [token, baseUrl, onError, onReportSent, session]);\n\n const report = useCallback(\n async (\n type: ReportType,\n description: string,\n metadata?: Record<string, string>\n ): Promise<ReportResult | null> => {\n try {\n const context = captureContext(visitedPagesRef.current);\n const payload: ReportPayload = {\n token,\n source: \"SDK_USER_REPORT\",\n type,\n description,\n pageUrl: context.url,\n userAgent: context.userAgent,\n breadcrumbs: context.breadcrumbs,\n deviceInfo: context.deviceInfo ?? undefined,\n metadata: {\n timestamp: context.timestamp,\n visitedPages: JSON.stringify(context.visitedPages),\n ...(session?.userId ? { sessionUserId: session.userId } : {}),\n ...(session?.name ? { sessionUserName: String(session.name) } : {}),\n ...(session?.email ? { sessionUserEmail: String(session.email) } : {}),\n ...(session?.phone ? { sessionUserPhone: String(session.phone) } : {}),\n ...metadata,\n },\n };\n const result = await sendReport(payload, baseUrl);\n if (result && onReportSent) onReportSent(result);\n return result;\n } catch {\n return null;\n }\n },\n [token, baseUrl, onReportSent, session]\n );\n\n const reportBug = useCallback(\n (description: string, metadata?: Record<string, string>) =>\n report(\"BUG\", description, metadata),\n [report]\n );\n\n const addBreadcrumb = useCallback(\n (message: string, data?: Record<string, string>) => {\n addBreadcrumbInternal(\"custom\", message, data);\n },\n []\n );\n\n const openReportDialog = useCallback((options?: { description?: string; type?: ReportType }) => {\n if (typeof window !== \"undefined\") {\n window.dispatchEvent(new CustomEvent(\"glitchgrab:open-report\", { detail: options }));\n }\n }, []);\n\n // Global keyboard shortcut: Cmd+Shift+G (Mac) / Ctrl+Shift+G (Windows/Linux)\n useEffect(() => {\n try {\n if (typeof window === \"undefined\") return;\n const handleKeyDown = (e: KeyboardEvent) => {\n if ((e.metaKey || e.ctrlKey) && e.shiftKey && e.key.toLowerCase() === \"g\") {\n e.preventDefault();\n openReportDialog();\n }\n };\n window.addEventListener(\"keydown\", handleKeyDown);\n return () => window.removeEventListener(\"keydown\", handleKeyDown);\n } catch {\n // Never crash\n }\n }, [openReportDialog]);\n\n return (\n <GlitchgrabContext.Provider\n value={{\n token,\n baseUrl: baseUrl ?? DEFAULT_BASE_URL,\n reportBug,\n report,\n addBreadcrumb,\n openReportDialog,\n }}\n >\n <GlitchgrabErrorBoundary\n token={token}\n baseUrl={baseUrl}\n session={session}\n onError={onError}\n fallback={fallback}\n visitedPages={visitedPagesRef.current}\n >\n {children}\n </GlitchgrabErrorBoundary>\n <ReportDialog report={report} types={types} showSeverity={showSeverity} />\n </GlitchgrabContext.Provider>\n );\n}\n\nexport function GlitchgrabProvider(props: GlitchgrabProviderProps) {\n // No token = passthrough (SDK disabled)\n if (!props.token) return <>{props.children}</>;\n\n const resolvedProps = {\n ...props,\n baseUrl: props.baseUrl || DEFAULT_BASE_URL,\n };\n\n try {\n return <GlitchgrabProviderInner {...resolvedProps} />;\n } catch {\n return <>{props.children}</>;\n }\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport type { GlitchgrabSession, ReportPayload } from \"./types\";\nimport { captureContext, sendReport } from \"./utils\";\nimport { computeSignature, shouldSkipDuplicate } from \"./dedup\";\n\ninterface ErrorBoundaryProps {\n token: string;\n baseUrl?: string;\n session?: GlitchgrabSession | null;\n onError?: (error: Error) => void;\n fallback?: React.ReactNode;\n visitedPages: string[];\n children: React.ReactNode;\n}\n\ninterface ErrorBoundaryState {\n hasError: boolean;\n}\n\nexport class GlitchgrabErrorBoundary extends React.Component<\n ErrorBoundaryProps,\n ErrorBoundaryState\n> {\n constructor(props: ErrorBoundaryProps) {\n super(props);\n this.state = { hasError: false };\n }\n\n static getDerivedStateFromError(): ErrorBoundaryState {\n return { hasError: true };\n }\n\n componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void {\n try {\n const context = captureContext(this.props.visitedPages);\n\n const sig = computeSignature({\n errorMessage: error.message,\n pageUrl: context.url,\n errorStack: error.stack,\n });\n if (shouldSkipDuplicate(sig)) {\n if (this.props.onError) this.props.onError(error);\n return;\n }\n\n const session = this.props.session;\n const payload: ReportPayload = {\n token: this.props.token,\n source: \"SDK_AUTO\",\n type: \"BUG\",\n errorMessage: error.message,\n errorStack: error.stack,\n componentStack: errorInfo.componentStack ?? undefined,\n pageUrl: context.url,\n userAgent: context.userAgent,\n breadcrumbs: context.breadcrumbs,\n deviceInfo: context.deviceInfo ?? undefined,\n metadata: {\n timestamp: context.timestamp,\n visitedPages: JSON.stringify(context.visitedPages),\n ...(session?.userId ? { sessionUserId: session.userId } : {}),\n ...(session?.name ? { sessionUserName: String(session.name) } : {}),\n ...(session?.email ? { sessionUserEmail: String(session.email) } : {}),\n ...(session?.phone ? { sessionUserPhone: String(session.phone) } : {}),\n },\n };\n\n sendReport(payload, this.props.baseUrl);\n\n if (this.props.onError) {\n this.props.onError(error);\n }\n } catch {\n // Never crash the host app\n }\n }\n\n render(): React.ReactNode {\n if (this.state.hasError) {\n if (this.props.fallback) {\n return this.props.fallback;\n }\n\n // Re-render children — allows recovery from transient errors\n return this.props.children;\n }\n\n return this.props.children;\n }\n}\n","import type { Breadcrumb, BreadcrumbType } from \"./types\";\n\nconst MAX_DEFAULT = 50;\n\nlet breadcrumbs: Breadcrumb[] = [];\nlet maxBreadcrumbs = MAX_DEFAULT;\nlet initialized = false;\n\nexport function initBreadcrumbs(max?: number) {\n if (initialized) return;\n maxBreadcrumbs = max ?? MAX_DEFAULT;\n\n try {\n if (typeof window === \"undefined\") return;\n interceptConsole();\n interceptFetch();\n interceptNavigation();\n interceptClicks();\n initialized = true;\n } catch {\n // Never crash\n }\n}\n\nexport function addBreadcrumb(\n type: BreadcrumbType,\n message: string,\n data?: Record<string, string>\n) {\n try {\n breadcrumbs.push({\n type,\n message: message.slice(0, 200),\n timestamp: new Date().toISOString(),\n data,\n });\n if (breadcrumbs.length > maxBreadcrumbs) {\n breadcrumbs = breadcrumbs.slice(-maxBreadcrumbs);\n }\n } catch {\n // Never crash\n }\n}\n\nexport function getBreadcrumbs(): Breadcrumb[] {\n return [...breadcrumbs];\n}\n\nexport function clearBreadcrumbs() {\n breadcrumbs = [];\n}\n\n// ─── Console Interception ────────────────────────────────\n\nfunction interceptConsole() {\n const origLog = console.log;\n const origWarn = console.warn;\n const origError = console.error;\n\n console.log = function (...args: unknown[]) {\n addBreadcrumb(\"console\", `[log] ${argsToString(args)}`);\n origLog.apply(console, args);\n };\n\n console.warn = function (...args: unknown[]) {\n addBreadcrumb(\"console\", `[warn] ${argsToString(args)}`);\n origWarn.apply(console, args);\n };\n\n console.error = function (...args: unknown[]) {\n addBreadcrumb(\"console\", `[error] ${argsToString(args)}`);\n origError.apply(console, args);\n };\n}\n\nfunction argsToString(args: unknown[]): string {\n try {\n return args\n .map((a) => {\n if (typeof a === \"string\") return a;\n if (a instanceof Error) return a.message;\n try {\n return JSON.stringify(a);\n } catch {\n return String(a);\n }\n })\n .join(\" \")\n .slice(0, 200);\n } catch {\n return \"[unknown]\";\n }\n}\n\n// ─── Fetch Interception ──────────────────────────────────\n\nfunction interceptFetch() {\n const origFetch = window.fetch;\n\n window.fetch = async function (input, init) {\n const url =\n typeof input === \"string\"\n ? input\n : input instanceof URL\n ? input.toString()\n : input instanceof Request\n ? input.url\n : String(input);\n const method = init?.method ?? \"GET\";\n const start = Date.now();\n\n try {\n const response = await origFetch.apply(window, [input, init]);\n addBreadcrumb(\"api\", `${method} ${url.slice(0, 100)} → ${response.status}`, {\n method,\n status: String(response.status),\n duration: `${Date.now() - start}ms`,\n });\n return response;\n } catch (err) {\n addBreadcrumb(\"api\", `${method} ${url.slice(0, 100)} → FAILED`, {\n method,\n error: err instanceof Error ? err.message : \"unknown\",\n duration: `${Date.now() - start}ms`,\n });\n throw err;\n }\n };\n}\n\n// ─── Navigation Interception ─────────────────────────────\n\nfunction interceptNavigation() {\n const origPush = history.pushState.bind(history);\n const origReplace = history.replaceState.bind(history);\n\n history.pushState = function (...args) {\n origPush(...args);\n addBreadcrumb(\"navigation\", `Navigate to ${window.location.pathname}`);\n };\n\n history.replaceState = function (...args) {\n origReplace(...args);\n addBreadcrumb(\"navigation\", `Replace to ${window.location.pathname}`);\n };\n\n window.addEventListener(\"popstate\", () => {\n addBreadcrumb(\"navigation\", `Back/Forward to ${window.location.pathname}`);\n });\n}\n\n// ─── Click Interception ──────────────────────────────────\n\nfunction interceptClicks() {\n document.addEventListener(\n \"click\",\n (e) => {\n try {\n const target = e.target as HTMLElement;\n const tag = target.tagName?.toLowerCase();\n const text = target.textContent?.trim().slice(0, 50) ?? \"\";\n const id = target.id ? `#${target.id}` : \"\";\n const cls = target.className && typeof target.className === \"string\"\n ? `.${target.className.split(\" \")[0]}`\n : \"\";\n\n addBreadcrumb(\"click\", `Click ${tag}${id}${cls} \"${text}\"`);\n } catch {\n // Never crash\n }\n },\n { capture: true }\n );\n}\n","import type { ReportPayload, ReportResult, CapturedContext, DeviceInfo } from \"./types\";\nimport { getBreadcrumbs } from \"./breadcrumbs\";\n\nconst SENSITIVE_PARAMS = [\n \"token\", \"key\", \"secret\", \"password\", \"passwd\", \"auth\", \"authorization\",\n \"session\", \"sessionid\", \"session_id\", \"api_key\", \"apikey\", \"access_token\",\n \"refresh_token\", \"client_secret\", \"code\", \"state\", \"nonce\", \"credential\", \"private\",\n];\n\nexport function sanitizeUrl(url: string): string {\n try {\n const parsed = new URL(url);\n const params = new URLSearchParams(parsed.search);\n let modified = false;\n for (const key of Array.from(params.keys())) {\n if (SENSITIVE_PARAMS.some((s) => key.toLowerCase().includes(s))) {\n params.set(key, \"[REDACTED]\");\n modified = true;\n }\n }\n if (modified) parsed.search = params.toString();\n return parsed.toString();\n } catch {\n return url.split(\"?\")[0] ?? url;\n }\n}\n\nexport function captureDeviceInfo(): DeviceInfo | null {\n try {\n if (typeof window === \"undefined\") return null;\n return {\n screenWidth: screen.width,\n screenHeight: screen.height,\n viewportWidth: window.innerWidth,\n viewportHeight: window.innerHeight,\n platform: navigator.platform ?? \"unknown\",\n language: navigator.language ?? \"unknown\",\n online: navigator.onLine,\n colorScheme: window.matchMedia(\"(prefers-color-scheme: dark)\").matches ? \"dark\" : \"light\",\n devicePixelRatio: window.devicePixelRatio ?? 1,\n };\n } catch {\n return null;\n }\n}\n\nexport function captureContext(visitedPages: string[]): CapturedContext {\n try {\n return {\n url: sanitizeUrl(typeof window !== \"undefined\" ? window.location.href : \"\"),\n userAgent: typeof navigator !== \"undefined\" ? navigator.userAgent : \"\",\n timestamp: new Date().toISOString(),\n visitedPages: visitedPages.map(sanitizeUrl),\n breadcrumbs: getBreadcrumbs(),\n deviceInfo: captureDeviceInfo(),\n };\n } catch {\n return {\n url: \"\",\n userAgent: \"\",\n timestamp: new Date().toISOString(),\n visitedPages: [],\n breadcrumbs: [],\n deviceInfo: null,\n };\n }\n}\n\nconst DEFAULT_BASE_URL = \"https://www.glitchgrab.dev\";\nconst MAX_RETRIES = 3;\nconst RETRY_BASE_MS = 500;\n\n/**\n * Send a report and return the result.\n * Never throws — returns null on failure.\n */\nexport async function sendReport(\n payload: ReportPayload,\n baseUrl?: string\n): Promise<ReportResult | null> {\n try {\n const url = `${baseUrl ?? DEFAULT_BASE_URL}/api/v1/sdk/report`;\n const body = JSON.stringify(payload);\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${payload.token}`,\n };\n\n // keepalive has a 64KB body limit in browsers — skip it for large payloads (e.g., screenshots)\n const useKeepalive = body.length < 60_000;\n\n for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {\n try {\n const response = await fetch(url, {\n method: \"POST\",\n headers,\n body,\n ...(useKeepalive ? { keepalive: true } : {}),\n });\n\n if (response.ok) {\n const envelope = (await response.json()) as {\n success: boolean;\n data?: Omit<ReportResult, \"success\">;\n };\n return { success: envelope.success, ...(envelope.data ?? {}) };\n }\n\n if (response.status >= 400 && response.status < 500 && response.status !== 429) {\n return null;\n }\n } catch {\n // Will retry\n }\n\n if (attempt < MAX_RETRIES - 1) {\n await new Promise((resolve) =>\n setTimeout(resolve, RETRY_BASE_MS * Math.pow(2, attempt))\n );\n }\n }\n\n // Fallback: sendBeacon (fire-and-forget, no result)\n if (typeof navigator !== \"undefined\" && navigator.sendBeacon) {\n try {\n navigator.sendBeacon(url, new Blob([body], { type: \"application/json\" }));\n } catch {\n // Silently fail\n }\n }\n\n return null;\n } catch {\n return null;\n }\n}\n","const DEFAULT_WINDOW_MS = 5 * 60 * 1000;\nconst MAX_ENTRIES = 100;\n\nconst seen = new Map<string, number>();\n\nfunction hashString(input: string): string {\n let h1 = 0xdeadbeef ^ 0;\n let h2 = 0x41c6ce57 ^ 0;\n for (let i = 0; i < input.length; i++) {\n const ch = input.charCodeAt(i);\n h1 = Math.imul(h1 ^ ch, 2654435761);\n h2 = Math.imul(h2 ^ ch, 1597334677);\n }\n h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^ Math.imul(h2 ^ (h2 >>> 13), 3266489909);\n h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^ Math.imul(h1 ^ (h1 >>> 13), 3266489909);\n return (4294967296 * (2097151 & h2) + (h1 >>> 0)).toString(36);\n}\n\nfunction topStackFrame(stack: string | undefined): string {\n if (!stack) return \"\";\n const lines = stack.split(\"\\n\");\n for (const line of lines) {\n const t = line.trim();\n if (t.startsWith(\"at \") || t.includes(\"@\")) {\n return t;\n }\n }\n return \"\";\n}\n\nfunction stripUrlQuery(url: string | undefined): string {\n if (!url) return \"\";\n try {\n const u = new URL(url);\n return `${u.origin}${u.pathname}`;\n } catch {\n const q = url.indexOf(\"?\");\n return q === -1 ? url : url.slice(0, q);\n }\n}\n\nexport function computeSignature(params: {\n errorMessage: string | undefined;\n pageUrl: string | undefined;\n errorStack?: string | undefined;\n}): string {\n const msg = params.errorMessage?.trim() ?? \"\";\n const page = stripUrlQuery(params.pageUrl);\n const frame = topStackFrame(params.errorStack);\n return hashString(`${msg}|${page}|${frame}`);\n}\n\nexport function shouldSkipDuplicate(\n signature: string,\n windowMs: number = DEFAULT_WINDOW_MS,\n now: number = Date.now()\n): boolean {\n const last = seen.get(signature);\n if (last !== undefined && now - last < windowMs) {\n return true;\n }\n seen.set(signature, now);\n\n if (seen.size > MAX_ENTRIES) {\n const cutoff = now - windowMs;\n for (const [sig, ts] of seen) {\n if (ts < cutoff) seen.delete(sig);\n }\n if (seen.size > MAX_ENTRIES) {\n const excess = seen.size - MAX_ENTRIES;\n const keys = Array.from(seen.keys()).slice(0, excess);\n for (const k of keys) seen.delete(k);\n }\n }\n return false;\n}\n\nexport function clearDedupCache(): void {\n seen.clear();\n}\n","\"use client\";\n\nimport { useState, useRef, useEffect, type CSSProperties, type ReactNode } from \"react\";\n// @ts-expect-error react-dom types handled by host app\nimport { createPortal } from \"react-dom\";\nimport type { ReportType, ReportSeverity, UseGlitchgrabReturn } from \"./types\";\n\n/** Detect if the host page uses a dark or light theme */\nfunction useIsDark(): boolean {\n if (typeof window === \"undefined\") return true;\n try {\n // Check body then html — most sites set background on html, not body\n for (const el of [document.body, document.documentElement]) {\n const bg = getComputedStyle(el).backgroundColor;\n const match = bg.match(/rgba?\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)(?:\\s*,\\s*([\\d.]+))?\\s*\\)/);\n if (match) {\n const alpha = match[4] !== undefined ? parseFloat(match[4]) : 1;\n if (alpha < 0.05) continue; // transparent — skip to next element\n const [r, g, b] = [Number(match[1]), Number(match[2]), Number(match[3])];\n return (r * 299 + g * 587 + b * 114) / 1000 < 128;\n }\n }\n return window.matchMedia(\"(prefers-color-scheme: dark)\").matches;\n } catch {\n return true;\n }\n}\n\n/** Convert HSL values to a hex color string */\nfunction hslToHex(h: number, s: number, l: number): string {\n s /= 100;\n l /= 100;\n const a = s * Math.min(l, 1 - l);\n const f = (n: number) => {\n const k = (n + h / 30) % 12;\n const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);\n return Math.round(255 * color).toString(16).padStart(2, \"0\");\n };\n return `#${f(0)}${f(8)}${f(4)}`;\n}\n\n/** Parse a CSS color value into [r, g, b] or null */\nfunction parseColorToRgb(value: string): [number, number, number] | null {\n try {\n const trimmed = value.trim();\n\n // hex (#fff, #ffffff)\n const hexMatch = trimmed.match(/^#([0-9a-f]{3,8})$/i);\n if (hexMatch) {\n let hex = hexMatch[1];\n if (hex.length === 3) hex = hex[0]+hex[0]+hex[1]+hex[1]+hex[2]+hex[2];\n return [parseInt(hex.slice(0, 2), 16), parseInt(hex.slice(2, 4), 16), parseInt(hex.slice(4, 6), 16)];\n }\n\n // rgb(r, g, b) or rgba(r, g, b, a)\n const rgbMatch = trimmed.match(/rgba?\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)/);\n if (rgbMatch) return [Number(rgbMatch[1]), Number(rgbMatch[2]), Number(rgbMatch[3])];\n\n // hsl(h, s%, l%) or hsla(h, s%, l%, a)\n const hslMatch = trimmed.match(/hsla?\\(\\s*([\\d.]+)\\s*,\\s*([\\d.]+)%\\s*,\\s*([\\d.]+)%/);\n if (hslMatch) {\n const hex = hslToHex(Number(hslMatch[1]), Number(hslMatch[2]), Number(hslMatch[3]));\n return parseColorToRgb(hex);\n }\n\n return null;\n } catch {\n return null;\n }\n}\n\n/** Compute relative luminance and return ideal contrast text color */\nfunction getContrastText(r: number, g: number, b: number): string {\n const luminance = (r * 299 + g * 587 + b * 114) / 1000;\n return luminance > 150 ? \"#09090b\" : \"#ffffff\";\n}\n\n/**\n * Auto-detect the host app's primary/accent color from CSS custom properties.\n * Checks common variable names used by shadcn/ui, Radix, Tailwind, MUI, etc.\n * Returns { accent, accentText } or null if no theme detected.\n */\nfunction detectHostAccent(): { accent: string; accentText: string } | null {\n if (typeof window === \"undefined\") return null;\n try {\n const root = getComputedStyle(document.documentElement);\n\n // Common CSS variable names for primary/accent color\n const varNames = [\n \"--primary\",\n \"--accent\",\n \"--brand\",\n \"--color-primary\",\n \"--theme-primary\",\n \"--chakra-colors-primary-500\",\n \"--mui-palette-primary-main\",\n ];\n\n for (const name of varNames) {\n const raw = root.getPropertyValue(name).trim();\n if (!raw) continue;\n\n // shadcn/ui style: space-separated HSL values like \"243 75% 59%\"\n const hslSpaceMatch = raw.match(/^([\\d.]+)\\s+([\\d.]+)%\\s+([\\d.]+)%$/);\n if (hslSpaceMatch) {\n const hex = hslToHex(Number(hslSpaceMatch[1]), Number(hslSpaceMatch[2]), Number(hslSpaceMatch[3]));\n const rgb = parseColorToRgb(hex);\n return { accent: hex, accentText: rgb ? getContrastText(...rgb) : \"#ffffff\" };\n }\n\n // Standard color values (hex, rgb, hsl)\n const rgb = parseColorToRgb(raw);\n if (rgb) {\n const hex = `#${rgb.map((c) => c.toString(16).padStart(2, \"0\")).join(\"\")}`;\n return { accent: hex, accentText: getContrastText(...rgb) };\n }\n }\n\n return null;\n } catch {\n return null;\n }\n}\n\nfunction getTheme(dark: boolean) {\n const hostAccent = detectHostAccent();\n const defaults = dark\n ? { bg: \"#1c1c1e\", bgSecondary: \"#27272a\", border: \"#2c2c2e\", text: \"#fafafa\", textMuted: \"#a1a1aa\", accent: \"#22d3ee\", accentText: \"#09090b\", inputBg: \"#27272a\", inputBorder: \"#3f3f46\" }\n : { bg: \"#ffffff\", bgSecondary: \"#f4f4f5\", border: \"#e4e4e7\", text: \"#18181b\", textMuted: \"#71717a\", accent: \"#0891b2\", accentText: \"#ffffff\", inputBg: \"#fafafa\", inputBorder: \"#d4d4d8\" };\n\n if (hostAccent) {\n defaults.accent = hostAccent.accent;\n defaults.accentText = hostAccent.accentText;\n }\n\n return defaults;\n}\n\n/** Validate that report text is meaningful — rejects gibberish, throwaway words, random chars */\nfunction isLowQualityText(text: string): string | null {\n const trimmed = text.trim();\n if (!trimmed) return null;\n\n // Exact throwaway words\n const throwaway =\n /^(done|ok|yes|no|hi|hello|hey|test|testing|asdf|qwerty|abc|xyz|foo|bar|baz|lol|lmao|idk|bruh|nice|cool|wow|sup|yo|nah|yep|nope|thanks|thx|ty|k|kk|hmm|hm|na|mm|mhm|aight|bet|gg|wp|rip|omg|pls|plz)$/i;\n if (throwaway.test(trimmed)) {\n return \"Please describe the actual issue you're experiencing\";\n }\n\n // Repeated characters (aaaaaaa, !!!!!!!)\n if (/(.)\\1{4,}/.test(trimmed)) {\n return \"Please provide a meaningful description\";\n }\n\n const letters = trimmed.replace(/[^a-zA-Z]/g, \"\");\n if (letters.length >= 4) {\n // Very low vowel ratio (bkdfghjklmn...)\n const vowels = letters.replace(/[^aeiouAEIOU]/g, \"\").length;\n const vowelRatio = vowels / letters.length;\n if (vowelRatio < 0.08) {\n return \"That doesn't look like a valid description\";\n }\n\n // Keyboard mashing: single word with no real English pattern\n // Detects strings like \"asdfasfsdad\", \"jkljklfsdf\", \"qwertyuio\"\n // Real words have max 3-4 consecutive consonants; gibberish has long runs\n if (/[^aeiou\\s]{5,}/i.test(letters)) {\n const words = trimmed.split(/\\s+/);\n // Only flag if it's a single \"word\" — multi-word text is likely real\n if (words.length <= 2) {\n return \"That doesn't look like a valid description\";\n }\n }\n\n // Check if it looks like a random permutation of a few chars (asdfasfsdad)\n if (letters.length >= 6) {\n const uniqueChars = new Set(letters.toLowerCase()).size;\n const uniqueRatio = uniqueChars / letters.length;\n // Real English has ~0.6-0.9 unique ratio for short text; gibberish reuses few chars\n if (uniqueRatio < 0.4 && trimmed.split(/\\s+/).length <= 2) {\n return \"That doesn't look like a valid description\";\n }\n }\n }\n\n // Single short word that isn't a known tech term\n const words = trimmed.split(/\\s+/).filter((w) => w.length > 0);\n if (words.length === 1 && trimmed.length < 10) {\n const techTerms =\n /^(crash|error|bug|fail|broken|slow|freeze|lag|404|500|null|undefined|nan|timeout|overflow|leak|cors|oom)$/i;\n if (!techTerms.test(trimmed)) {\n return \"Please provide more detail about the issue\";\n }\n }\n\n return null;\n}\n\ninterface ReportDialogProps {\n report: UseGlitchgrabReturn[\"report\"];\n types?: ReportType[];\n showSeverity?: boolean;\n}\n\n/**\n * The report dialog — rendered inside GlitchgrabProvider automatically.\n * Opens via the `glitchgrab:open-report` custom event (triggered by `openReportDialog()`).\n */\nexport function ReportDialog({\n report,\n types,\n showSeverity = true,\n}: ReportDialogProps) {\n // Prevent hydration mismatch — render nothing until after hydration\n const [mounted, setMounted] = useState(false);\n useEffect(() => { setMounted(true); }, []);\n\n const [isOpen, setIsOpen] = useState(false);\n const [description, setDescription] = useState(\"\");\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [submitted, setSubmitted] = useState(false);\n const [screenshot, setScreenshot] = useState<string | null>(null);\n const [previewOpen, setPreviewOpen] = useState(false);\n const fileInputRef = useRef<HTMLInputElement>(null);\n const modalRef = useRef<HTMLDivElement>(null);\n\n // Stepper state\n const [step, setStep] = useState(1);\n const [reportType, setReportType] = useState<ReportType>(\"BUG\");\n const [severity, setSeverity] = useState<ReportSeverity>(\"medium\");\n const [validationError, setValidationError] = useState<string | null>(null);\n\n const availableTypes: ReportType[] = types ?? [\"BUG\", \"FEATURE_REQUEST\", \"QUESTION\", \"OTHER\"];\n\n const isDark = useIsDark();\n const t = getTheme(isDark);\n\n const handleFileUpload = (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (!file) return;\n const reader = new FileReader();\n reader.onload = () => {\n setScreenshot(reader.result as string);\n };\n reader.readAsDataURL(file);\n e.target.value = \"\";\n };\n\n const retakeScreenshot = async () => {\n setPreviewOpen(false);\n setIsOpen(false);\n setScreenshot(null);\n await new Promise((r) => setTimeout(r, 300));\n try {\n const { default: html2canvas } = await import(\"html2canvas-pro\");\n const canvas = await html2canvas(document.body, {\n scale: 0.5,\n logging: false,\n useCORS: true,\n allowTaint: true,\n });\n setScreenshot(canvas.toDataURL(\"image/jpeg\", 0.6));\n } catch {\n // silently fail\n }\n setIsOpen(true);\n };\n\n const handleOpen = async () => {\n setSubmitted(false);\n if (availableTypes.length === 1) {\n setReportType(availableTypes[0]);\n setStep(2);\n }\n try {\n const { default: html2canvas } = await import(\"html2canvas-pro\");\n const canvas = await html2canvas(document.body, {\n scale: 0.5,\n logging: false,\n useCORS: true,\n allowTaint: true,\n });\n setScreenshot(canvas.toDataURL(\"image/jpeg\", 0.6));\n } catch {\n // screenshot failed — open without it\n }\n setIsOpen(true);\n };\n\n // Listen for programmatic open via openReportDialog()\n useEffect(() => {\n const handler = (e: Event) => {\n if (isOpen) return;\n const detail = (e as CustomEvent).detail;\n if (detail?.description) setDescription(detail.description);\n if (detail?.type) {\n setReportType(detail.type);\n setStep(2);\n }\n handleOpen();\n };\n window.addEventListener(\"glitchgrab:open-report\", handler);\n return () => window.removeEventListener(\"glitchgrab:open-report\", handler);\n }, [isOpen, handleOpen]);\n\n // Close on Escape\n useEffect(() => {\n if (!isOpen) return;\n const handleEsc = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n if (previewOpen) setPreviewOpen(false);\n else handleClose();\n }\n };\n document.addEventListener(\"keydown\", handleEsc);\n return () => document.removeEventListener(\"keydown\", handleEsc);\n }, [isOpen, previewOpen]);\n\n // Paste image from clipboard (Cmd+V / Ctrl+V) when dialog is open\n useEffect(() => {\n if (!isOpen) return;\n const handlePaste = (e: ClipboardEvent) => {\n try {\n const items = e.clipboardData?.items;\n if (!items) return;\n for (let i = 0; i < items.length; i++) {\n if (items[i].type.startsWith(\"image/\")) {\n const file = items[i].getAsFile();\n if (!file) continue;\n const reader = new FileReader();\n reader.onload = () => setScreenshot(reader.result as string);\n reader.readAsDataURL(file);\n e.preventDefault();\n break;\n }\n }\n } catch {\n // silently fail\n }\n };\n window.addEventListener(\"paste\", handlePaste);\n return () => window.removeEventListener(\"paste\", handlePaste);\n }, [isOpen]);\n\n const handleClose = () => {\n setIsOpen(false);\n setStep(1);\n setReportType(\"BUG\");\n setSeverity(\"medium\");\n setValidationError(null);\n };\n\n const handleSubmit = async () => {\n try {\n if (!description.trim() || isSubmitting) return;\n\n const qualityError = isLowQualityText(description);\n if (qualityError) {\n setValidationError(qualityError);\n setStep(2);\n return;\n }\n\n setIsSubmitting(true);\n const metadata: Record<string, string> = {};\n if (screenshot) metadata.screenshot = screenshot;\n if (showSeverity && reportType === \"BUG\") {\n metadata.severity = severity;\n }\n\n const result = await report(reportType, description.trim(), Object.keys(metadata).length > 0 ? metadata : undefined);\n\n if (result) {\n setSubmitted(true);\n setDescription(\"\");\n setScreenshot(null);\n\n setTimeout(() => {\n setSubmitted(false);\n handleClose();\n }, 2000);\n }\n setIsSubmitting(false);\n } catch {\n setIsSubmitting(false);\n }\n };\n\n if (!mounted) return null;\n\n return (\n <>\n {/* Report modal */}\n {isOpen && createPortal(\n <div\n style={{\n position: \"fixed\",\n inset: 0,\n zIndex: 2147483647,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: \"rgba(0,0,0,0.5)\",\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n }}\n onClick={() => { if (!previewOpen) handleClose(); }}\n >\n <div\n ref={modalRef}\n onClick={(e) => e.stopPropagation()}\n style={{\n position: \"relative\",\n zIndex: 2147483647,\n width: \"340px\",\n maxWidth: \"calc(100% - 32px)\",\n backgroundColor: t.bg,\n borderRadius: \"12px\",\n boxShadow:\n \"0 20px 60px rgba(0, 0, 0, 0.2), 0 4px 16px rgba(0, 0, 0, 0.1)\",\n fontFamily:\n '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n overflow: \"hidden\",\n color: t.text,\n isolation: \"isolate\",\n }}\n >\n {/* Header */}\n <div\n style={{\n padding: \"16px 16px 12px\",\n borderBottom: `1px solid ${t.border}`,\n }}\n >\n <div\n style={{\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n }}\n >\n <div style={{ display: \"flex\", alignItems: \"center\", gap: \"8px\" }}>\n {step > 1 && (\n <button\n type=\"button\"\n onClick={() => setStep((s) => (s - 1) as 1 | 2 | 3)}\n style={{\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n padding: \"2px\",\n display: \"flex\",\n alignItems: \"center\",\n }}\n aria-label=\"Back\"\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path d=\"M10 3L5 8L10 13\" stroke={t.textMuted} strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </button>\n )}\n <span\n style={{\n fontSize: \"15px\",\n fontWeight: 600,\n color: t.text,\n }}\n >\n {step === 1 ? \"What's on your mind?\" : step === 2 ? \"Tell us more\" : \"Review & Send\"}\n </span>\n </div>\n <button\n type=\"button\"\n onClick={handleClose}\n style={{\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n padding: \"4px\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n aria-label=\"Close\"\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" style={{ display: \"block\" }}>\n <path d=\"M4 4L12 12M12 4L4 12\" stroke={t.textMuted} strokeWidth=\"2\" strokeLinecap=\"round\" />\n </svg>\n </button>\n </div>\n <div style={{ display: \"flex\", alignItems: \"center\", justifyContent: \"center\", gap: \"0\", marginTop: \"12px\" }}>\n {[1, 2, 3].map((s, i) => (\n <div key={s} style={{ display: \"flex\", alignItems: \"center\" }}>\n <div style={{\n width: \"8px\",\n height: \"8px\",\n borderRadius: \"50%\",\n backgroundColor: s <= step ? t.accent : t.inputBorder,\n transition: \"background-color 0.2s ease\",\n }} />\n {i < 2 && (\n <div style={{\n width: \"40px\",\n height: \"2px\",\n backgroundColor: s < step ? t.accent : t.inputBorder,\n transition: \"background-color 0.2s ease\",\n }} />\n )}\n </div>\n ))}\n </div>\n </div>\n\n {/* Body */}\n <div style={{ padding: \"16px\" }}>\n {submitted ? (\n <div\n style={{\n textAlign: \"center\",\n padding: \"20px 0\",\n color: t.accent,\n fontSize: \"14px\",\n fontWeight: 500,\n }}\n >\n {getTypeLabel(reportType)} sent. Thank you!\n </div>\n ) : (\n <>\n {/* Step 1: Category */}\n {step === 1 && (\n <div style={{ display: \"grid\", gridTemplateColumns: \"1fr 1fr\", gap: \"8px\" }}>\n {availableTypes.map((type) => (\n <button\n key={type}\n type=\"button\"\n onClick={() => {\n setReportType(type);\n setStep(2);\n }}\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: \"8px\",\n padding: \"16px 8px\",\n borderRadius: \"8px\",\n border: `1px solid ${t.inputBorder}`,\n background: t.inputBg,\n cursor: \"pointer\",\n color: t.text,\n fontFamily: \"inherit\",\n transition: \"border-color 0.15s ease\",\n }}\n onMouseEnter={(e) => { (e.currentTarget as HTMLElement).style.borderColor = t.accent; }}\n onMouseLeave={(e) => { (e.currentTarget as HTMLElement).style.borderColor = t.inputBorder; }}\n >\n {getTypeIcon(type, t.accent)}\n <span style={{ fontSize: \"13px\", fontWeight: 600 }}>{getTypeLabel(type)}</span>\n <span style={{ fontSize: \"11px\", color: t.textMuted, lineHeight: \"1.3\" }}>{getTypeSubtitle(type)}</span>\n </button>\n ))}\n </div>\n )}\n\n {/* Step 2: Details */}\n {step === 2 && (\n <>\n <textarea\n value={description}\n onChange={(e) => { setDescription(e.target.value); if (validationError) setValidationError(null); }}\n placeholder={getPlaceholder(reportType)}\n style={{\n width: \"100%\",\n minHeight: \"100px\",\n padding: \"10px 12px\",\n borderRadius: \"8px\",\n border: `1px solid ${t.inputBorder}`,\n fontSize: \"14px\",\n fontFamily: \"inherit\",\n resize: \"vertical\",\n outline: \"none\",\n boxSizing: \"border-box\",\n color: t.text,\n backgroundColor: t.inputBg,\n }}\n onFocus={(e) => { (e.target as HTMLTextAreaElement).style.borderColor = t.accent; }}\n onBlur={(e) => { (e.target as HTMLTextAreaElement).style.borderColor = t.inputBorder; }}\n autoFocus\n />\n {showSeverity && reportType === \"BUG\" && (\n <div style={{ marginTop: \"10px\" }}>\n <span style={{ fontSize: \"12px\", color: t.textMuted, marginBottom: \"6px\", display: \"block\" }}>Severity</span>\n <div style={{ display: \"flex\", gap: \"6px\" }}>\n {([\"low\", \"medium\", \"high\"] as ReportSeverity[]).map((s) => (\n <button\n key={s}\n type=\"button\"\n onClick={() => setSeverity(s)}\n style={{\n flex: 1,\n padding: \"6px 0\",\n borderRadius: \"6px\",\n border: `1px solid ${severity === s ? t.accent : t.inputBorder}`,\n background: severity === s ? t.accent : \"transparent\",\n color: severity === s ? t.accentText : t.text,\n fontSize: \"12px\",\n fontWeight: 600,\n cursor: \"pointer\",\n fontFamily: \"inherit\",\n textTransform: \"capitalize\",\n transition: \"all 0.15s ease\",\n }}\n >\n {s}\n </button>\n ))}\n </div>\n </div>\n )}\n {validationError && (\n <p style={{ color: \"#ef4444\", fontSize: \"12px\", marginTop: \"6px\" }}>\n {validationError}\n </p>\n )}\n <button\n type=\"button\"\n onClick={() => {\n const err = isLowQualityText(description);\n if (err) { setValidationError(err); return; }\n setValidationError(null);\n setStep(3);\n }}\n disabled={!description.trim()}\n style={{\n marginTop: \"12px\",\n width: \"100%\",\n padding: \"10px\",\n borderRadius: \"8px\",\n border: \"none\",\n backgroundColor: !description.trim() ? t.bgSecondary : t.accent,\n color: !description.trim() ? t.textMuted : t.accentText,\n fontSize: \"14px\",\n fontWeight: 600,\n cursor: !description.trim() ? \"not-allowed\" : \"pointer\",\n fontFamily: \"inherit\",\n transition: \"background-color 0.15s ease\",\n }}\n >\n Next\n </button>\n </>\n )}\n\n {/* Step 3: Review & Send */}\n {step === 3 && (\n <>\n {/* Summary chips */}\n <div style={{ display: \"flex\", gap: \"6px\", flexWrap: \"wrap\", marginBottom: \"12px\" }}>\n <span style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: \"4px\",\n padding: \"4px 10px\",\n borderRadius: \"12px\",\n fontSize: \"12px\",\n fontWeight: 600,\n backgroundColor: t.bgSecondary,\n color: t.text,\n border: `1px solid ${t.border}`,\n }}>\n {getTypeIcon(reportType, t.accent, 12)}\n {getTypeLabel(reportType)}\n </span>\n {showSeverity && reportType === \"BUG\" && (\n <span style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n padding: \"4px 10px\",\n borderRadius: \"12px\",\n fontSize: \"12px\",\n fontWeight: 600,\n backgroundColor: severity === \"high\" ? \"#fef2f2\" : severity === \"medium\" ? \"#fffbeb\" : \"#f0fdf4\",\n color: severity === \"high\" ? \"#dc2626\" : severity === \"medium\" ? \"#d97706\" : \"#16a34a\",\n border: `1px solid ${severity === \"high\" ? \"#fecaca\" : severity === \"medium\" ? \"#fde68a\" : \"#bbf7d0\"}`,\n textTransform: \"capitalize\",\n }}>\n {severity}\n </span>\n )}\n </div>\n\n {/* Description preview */}\n <div style={{\n padding: \"10px 12px\",\n borderRadius: \"8px\",\n border: `1px solid ${t.inputBorder}`,\n backgroundColor: t.inputBg,\n fontSize: \"13px\",\n color: t.text,\n marginBottom: \"10px\",\n maxHeight: \"80px\",\n overflow: \"hidden\",\n lineHeight: \"1.4\",\n }}>\n {description.length > 200 ? description.slice(0, 200) + \"...\" : description}\n </div>\n\n {/* Screenshot */}\n {screenshot && (\n <div style={{ marginBottom: \"10px\", position: \"relative\" }}>\n <img\n src={screenshot}\n alt=\"Page screenshot\"\n onClick={() => setPreviewOpen(true)}\n style={{\n width: \"100%\",\n borderRadius: \"6px\",\n border: `1px solid ${t.border}`,\n maxHeight: \"80px\",\n objectFit: \"cover\",\n objectPosition: \"top\",\n cursor: \"pointer\",\n }}\n />\n <button\n type=\"button\"\n onClick={() => setScreenshot(null)}\n style={{\n position: \"absolute\",\n top: \"4px\",\n right: \"4px\",\n background: \"rgba(0,0,0,0.6)\",\n border: \"none\",\n borderRadius: \"50%\",\n width: \"20px\",\n height: \"20px\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n aria-label=\"Remove screenshot\"\n >\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"none\">\n <path d=\"M1 1L9 9M9 1L1 9\" stroke=\"#fff\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n </button>\n </div>\n )}\n {!screenshot && (\n <div style={{ display: \"flex\", gap: \"6px\", marginBottom: \"10px\" }}>\n <button\n type=\"button\"\n onClick={() => fileInputRef.current?.click()}\n style={{\n flex: 1,\n padding: \"8px\",\n borderRadius: \"6px\",\n border: `1px dashed ${t.inputBorder}`,\n textAlign: \"center\",\n fontSize: \"11px\",\n color: t.textMuted,\n background: \"none\",\n cursor: \"pointer\",\n }}\n >\n Upload or paste (⌘V)\n </button>\n <button\n type=\"button\"\n onClick={retakeScreenshot}\n style={{\n flex: 1,\n padding: \"8px\",\n borderRadius: \"6px\",\n border: `1px dashed ${t.inputBorder}`,\n textAlign: \"center\",\n fontSize: \"11px\",\n color: t.textMuted,\n background: \"none\",\n cursor: \"pointer\",\n }}\n >\n Retake screenshot\n </button>\n </div>\n )}\n\n <button\n type=\"button\"\n onClick={handleSubmit}\n disabled={isSubmitting}\n style={{\n width: \"100%\",\n padding: \"10px\",\n borderRadius: \"8px\",\n border: \"none\",\n backgroundColor: isSubmitting ? t.bgSecondary : t.accent,\n color: isSubmitting ? t.textMuted : t.accentText,\n fontSize: \"14px\",\n fontWeight: 600,\n cursor: isSubmitting ? \"not-allowed\" : \"pointer\",\n fontFamily: \"inherit\",\n transition: \"background-color 0.15s ease\",\n }}\n >\n {isSubmitting ? \"Sending...\" : \"Send Report\"}\n </button>\n </>\n )}\n </>\n )}\n </div>\n\n {/* Footer */}\n <div\n style={{\n padding: \"8px 16px 10px\",\n borderTop: `1px solid ${t.border}`,\n textAlign: \"center\",\n }}\n >\n <span style={{ fontSize: \"11px\", color: t.textMuted }}>\n Powered by Glitchgrab\n </span>\n </div>\n </div>\n </div>,\n document.body\n )}\n\n {/* Hidden file input */}\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\"image/*\"\n onChange={handleFileUpload}\n style={{ display: \"none\" }}\n />\n\n {/* Full-screen screenshot preview */}\n {previewOpen && screenshot && createPortal(\n <div\n style={{\n position: \"fixed\",\n inset: 0,\n zIndex: 2147483647,\n backgroundColor: \"rgba(0,0,0,0.85)\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: \"16px\",\n cursor: \"pointer\",\n }}\n onClick={(e) => { e.stopPropagation(); setPreviewOpen(false); }}\n onMouseDown={(e) => e.stopPropagation()}\n >\n <img\n src={screenshot}\n alt=\"Screenshot preview\"\n onClick={(e) => e.stopPropagation()}\n style={{\n maxWidth: \"100%\",\n maxHeight: \"calc(100vh - 80px)\",\n borderRadius: \"8px\",\n objectFit: \"contain\",\n cursor: \"default\",\n }}\n />\n <span\n style={{\n marginTop: \"12px\",\n color: t.textMuted,\n fontSize: \"12px\",\n }}\n >\n Click outside to close\n </span>\n </div>,\n document.body\n )}\n </>\n );\n}\n\n/* ─── Helpers ─── */\n\nfunction getTypeLabel(type: ReportType): string {\n switch (type) {\n case \"BUG\": return \"Bug Report\";\n case \"FEATURE_REQUEST\": return \"Feature Request\";\n case \"QUESTION\": return \"Question\";\n case \"OTHER\": return \"Other\";\n }\n}\n\nfunction getTypeSubtitle(type: ReportType): string {\n switch (type) {\n case \"BUG\": return \"Something isn't working\";\n case \"FEATURE_REQUEST\": return \"Suggest an improvement\";\n case \"QUESTION\": return \"Ask a question\";\n case \"OTHER\": return \"General feedback\";\n }\n}\n\nfunction getPlaceholder(type: ReportType): string {\n switch (type) {\n case \"BUG\": return \"What went wrong?\";\n case \"FEATURE_REQUEST\": return \"Describe the feature you'd like...\";\n case \"QUESTION\": return \"What would you like to know?\";\n case \"OTHER\": return \"Tell us what's on your mind...\";\n }\n}\n\nfunction getTypeIcon(type: ReportType, color: string, size = 24): ReactNode {\n const props = { width: size, height: size, viewBox: \"0 0 24 24\", fill: \"none\", style: { flexShrink: 0 } as CSSProperties };\n switch (type) {\n case \"BUG\":\n return <svg {...props}><path d=\"M8 2L6.5 3.5M16 2L17.5 3.5M3 9H7M17 9H21M12 2a5 5 0 015 5v4a5 5 0 01-10 0V7a5 5 0 015-5zM7 16l-2 3M17 16l2 3\" stroke={color} strokeWidth=\"1.5\" strokeLinecap=\"round\" /></svg>;\n case \"FEATURE_REQUEST\":\n return <svg {...props}><path d=\"M12 2L15.09 8.26L22 9.27L17 14.14L18.18 21.02L12 17.77L5.82 21.02L7 14.14L2 9.27L8.91 8.26L12 2z\" stroke={color} strokeWidth=\"1.5\" strokeLinejoin=\"round\" /></svg>;\n case \"QUESTION\":\n return <svg {...props}><circle cx=\"12\" cy=\"12\" r=\"10\" stroke={color} strokeWidth=\"1.5\" /><path d=\"M9.09 9a3 3 0 015.83 1c0 2-3 3-3 3M12 17h.01\" stroke={color} strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" /></svg>;\n case \"OTHER\":\n return <svg {...props}><path d=\"M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2v10z\" stroke={color} strokeWidth=\"1.5\" strokeLinejoin=\"round\" /></svg>;\n }\n}\n","\"use client\";\n\nimport { useState, type CSSProperties, type ReactNode } from \"react\";\nimport type { ReportButtonProps } from \"./types\";\nimport { useGlitchgrab } from \"./provider\";\n\n/** Safe version of useGlitchgrab that returns null when outside provider */\nfunction useGlitchgrabSafe() {\n try {\n return useGlitchgrab();\n } catch {\n return null;\n }\n}\n\n/**\n * Optional trigger button for opening the report dialog.\n *\n * The dialog itself lives inside `GlitchgrabProvider` — you don't need this component\n * unless you want a visible trigger button. You can also open the dialog programmatically\n * via `useGlitchgrab().openReportDialog()`.\n *\n * @example\n * ```tsx\n * // Use the default floating button\n * <ReportButton />\n *\n * // Use your own trigger\n * <ReportButton>\n * {({ onClick }) => <button onClick={onClick}>Report</button>}\n * </ReportButton>\n *\n * // Or skip ReportButton entirely and use the hook\n * const { openReportDialog } = useGlitchgrab();\n * <button onClick={() => openReportDialog()}>Report</button>\n * ```\n */\nexport function ReportButton({\n position = \"bottom-right\",\n label = \"Report Bug\",\n className,\n children,\n}: ReportButtonProps & {\n children?: (props: { onClick: () => void; capturing: boolean }) => ReactNode;\n}) {\n const [capturing, setCapturing] = useState(false);\n const glitchgrab = useGlitchgrabSafe();\n\n if (!glitchgrab) return null;\n\n const handleClick = async () => {\n setCapturing(true);\n glitchgrab.openReportDialog();\n setCapturing(false);\n };\n\n // Custom trigger via render prop\n if (children) {\n return <>{children({ onClick: handleClick, capturing })}</>;\n }\n\n // Default floating button\n const isTop = position?.startsWith(\"top\") ?? false;\n const isLeft = position?.endsWith(\"left\") ?? false;\n\n const positionStyles: CSSProperties = {\n ...(isLeft ? { left: \"16px\" } : { right: \"16px\" }),\n ...(isTop ? { top: \"16px\" } : { bottom: \"16px\" }),\n };\n\n return (\n <button\n type=\"button\"\n onClick={handleClick}\n disabled={capturing}\n className={className}\n style={{\n position: \"fixed\",\n ...positionStyles,\n zIndex: 99999,\n padding: \"10px 18px\",\n borderRadius: \"24px\",\n border: \"none\",\n backgroundColor: \"#18181b\",\n color: \"#fafafa\",\n fontSize: \"14px\",\n fontWeight: 500,\n fontFamily:\n '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n cursor: capturing ? \"wait\" : \"pointer\",\n boxShadow:\n \"0 4px 12px rgba(0, 0, 0, 0.15), 0 1px 3px rgba(0, 0, 0, 0.1)\",\n transition: \"transform 0.15s ease, box-shadow 0.15s ease\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"6px\",\n opacity: capturing ? 0.7 : 1,\n }}\n onMouseEnter={(e) => {\n (e.target as HTMLElement).style.transform = \"scale(1.05)\";\n }}\n onMouseLeave={(e) => {\n (e.target as HTMLElement).style.transform = \"scale(1)\";\n }}\n aria-label={label}\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n style={{ flexShrink: 0 }}\n >\n <path\n d=\"M8 1C4.134 1 1 4.134 1 8s3.134 7 7 7 7-3.134 7-7-3.134-7-7-7zm0 12.5a.75.75 0 110-1.5.75.75 0 010 1.5zm.75-3.5a.75.75 0 01-1.5 0V5a.75.75 0 011.5 0v5z\"\n fill=\"currentColor\"\n />\n </svg>\n {capturing ? \"Capturing...\" : label}\n </button>\n );\n}\n","\"use client\";\n\nimport { useState, useEffect, useCallback } from \"react\";\n\nexport interface GlitchgrabReport {\n id: string;\n source: string;\n status: string;\n rawInput: string | null;\n reporterPrimaryKey: string;\n reporterName: string;\n reporterEmail: string | null;\n reporterPhone: string | null;\n pageUrl: string | null;\n createdAt: string;\n /** Number of comments on the linked GitHub issue (0 if no issue) */\n commentCount: number;\n issue: {\n githubNumber: number;\n githubUrl: string;\n title: string;\n labels: string[];\n severity: string | null;\n githubState: string | null;\n } | null;\n}\n\nconst BASE_URL = \"https://www.glitchgrab.dev\";\n\n/**\n * Hook to fetch bug reports for a specific user.\n *\n * ```tsx\n * const { reports, isLoading, error, refetch } = useGlitchgrabReports({\n * token: process.env.NEXT_PUBLIC_GLITCHGRAB_TOKEN!,\n * userId: session.user.id,\n * });\n * ```\n */\nexport function useGlitchgrabReports({\n token,\n userId,\n limit = 100,\n}: {\n token: string;\n userId: string;\n /** Max results (default 100, max 100) */\n limit?: number;\n}): {\n reports: GlitchgrabReport[];\n isLoading: boolean;\n isFetching: boolean;\n error: string | null;\n refetch: () => Promise<void>;\n} {\n const [reports, setReports] = useState<GlitchgrabReport[]>([]);\n const [isLoading, setIsLoading] = useState(true);\n const [isFetching, setIsFetching] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const fetchReports = useCallback(async () => {\n if (!token || !userId) {\n setIsLoading(false);\n return;\n }\n\n setIsFetching(true);\n setError(null);\n\n try {\n const res = await fetch(\n `${BASE_URL}/api/v1/sdk/reports?reporterPrimaryKey=${encodeURIComponent(userId)}&limit=${limit}`,\n { headers: { Authorization: `Bearer ${token}` } }\n );\n const data = await res.json();\n\n if (data.success) {\n setReports(data.data ?? []);\n } else {\n setError(data.error ?? \"Failed to fetch reports\");\n }\n } catch {\n setError(\"Network error\");\n } finally {\n setIsLoading(false);\n setIsFetching(false);\n }\n }, [token, userId, limit]);\n\n useEffect(() => {\n fetchReports();\n }, [fetchReports]);\n\n return { reports, isLoading, isFetching, error, refetch: fetchReports };\n}\n\n/**\n * Standalone fetcher — use with TanStack Query or any data fetching library.\n *\n * ```tsx\n * const { data } = useQuery({\n * queryKey: [\"glitchgrab-reports\", userId],\n * queryFn: () => fetchGlitchgrabReports({\n * token: process.env.NEXT_PUBLIC_GLITCHGRAB_TOKEN!,\n * userId: session.user.id,\n * }),\n * });\n * ```\n */\nexport async function fetchGlitchgrabReports({\n token,\n userId,\n limit = 100,\n}: {\n token: string;\n userId: string;\n limit?: number;\n}): Promise<GlitchgrabReport[]> {\n const res = await fetch(\n `${BASE_URL}/api/v1/sdk/reports?reporterPrimaryKey=${encodeURIComponent(userId)}&limit=${limit}`,\n { headers: { Authorization: `Bearer ${token}` } }\n );\n const data = await res.json();\n if (!data.success) throw new Error(data.error ?? \"Failed to fetch reports\");\n return data.data ?? [];\n}\n\n// ─── Report Actions ─────────────────────────────────────\n\nasync function reportAction(\n token: string,\n reportId: string,\n body: Record<string, string>\n): Promise<void> {\n const res = await fetch(`${BASE_URL}/api/v1/reports/${reportId}/actions`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(body),\n });\n const data = await res.json().catch(() => ({}));\n if (!res.ok || !data.success) throw new Error(data.error ?? \"Action failed\");\n}\n\n/**\n * Hook to manage report actions with loading/error states.\n *\n * ```tsx\n * const { approve, reject, close, isPending, error } = useGlitchgrabActions({\n * token: process.env.NEXT_PUBLIC_GLITCHGRAB_TOKEN!,\n * onSuccess: () => refetch(),\n * onError: (err) => toast.error(err.message),\n * });\n *\n * <button onClick={() => approve(reportId)} disabled={isPending}>\n * {isPending ? \"...\" : \"Approve\"}\n * </button>\n * ```\n */\nexport function useGlitchgrabActions({\n token,\n onSuccess,\n onError,\n}: {\n token: string;\n onSuccess?: () => void;\n onError?: (error: Error) => void;\n}) {\n const [isPending, setIsPending] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const run = useCallback(\n async (reportId: string, body: Record<string, string>) => {\n setIsPending(true);\n setError(null);\n try {\n await reportAction(token, reportId, body);\n onSuccess?.();\n } catch (e) {\n const err = e instanceof Error ? e : new Error(\"Action failed\");\n setError(err.message);\n onError?.(err);\n } finally {\n setIsPending(false);\n }\n },\n [token, onSuccess, onError]\n );\n\n return {\n approve: (reportId: string) => run(reportId, { action: \"label\", label: \"approved\" }),\n reject: (reportId: string) => run(reportId, { action: \"label\", label: \"rejected\" }),\n close: (reportId: string) => run(reportId, { action: \"close\" }),\n reopen: (reportId: string) => run(reportId, { action: \"reopen\" }),\n label: (reportId: string, label: string) => run(reportId, { action: \"label\", label }),\n unlabel: (reportId: string, label: string) => run(reportId, { action: \"unlabel\", label }),\n isPending,\n error,\n };\n}\n"],"mappings":"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","names":["import_react","e","rgb","words","e","import_jsx_runtime","DEFAULT_BASE_URL","maxBreadcrumbs","addBreadcrumb","import_react","import_jsx_runtime","import_react"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/provider.tsx","../src/error-boundary.tsx","../src/breadcrumbs.ts","../src/utils.ts","../src/dedup.ts","../src/report-dialog.tsx","../src/report-button.tsx","../src/use-reports.ts"],"sourcesContent":["\"use client\";\n\n// ─── Core (required) ─────────────────────────────────────\nexport { GlitchgrabProvider, useGlitchgrab } from \"./provider\";\n\n// ─── Optional Components ─────────────────────────────────\nexport { ReportButton } from \"./report-button\";\nexport { GlitchgrabErrorBoundary } from \"./error-boundary\";\n\n// ─── Hooks ──────────────────────────────────────────────\nexport { useGlitchgrabReports, fetchGlitchgrabReports, useGlitchgrabActions } from \"./use-reports\";\nexport type { GlitchgrabReport } from \"./use-reports\";\n\n// ─── Breadcrumbs ─────────────────────────────────────────\nexport {\n addBreadcrumb,\n getBreadcrumbs,\n clearBreadcrumbs,\n initBreadcrumbs,\n} from \"./breadcrumbs\";\n\n// ─── Utilities ───────────────────────────────────────────\nexport { sanitizeUrl, captureContext, captureDeviceInfo, sendReport } from \"./utils\";\nexport { computeSignature, shouldSkipDuplicate, clearDedupCache } from \"./dedup\";\n\n// ─── Types ───────────────────────────────────────────────\nexport type {\n GlitchgrabConfig,\n GlitchgrabProviderProps,\n ReportPayload,\n ReportResult,\n ReportType,\n ReportSeverity,\n CapturedContext,\n DeviceInfo,\n Breadcrumb,\n BreadcrumbType,\n UseGlitchgrabReturn,\n ReportButtonProps,\n GlitchgrabSession,\n} from \"./types\";\n","\"use client\";\n\nimport {\n createContext,\n useContext,\n useRef,\n useEffect,\n useCallback,\n useState,\n} from \"react\";\nimport type {\n GlitchgrabProviderProps,\n UseGlitchgrabReturn,\n ReportPayload,\n ReportResult,\n ReportType,\n} from \"./types\";\nimport { GlitchgrabErrorBoundary } from \"./error-boundary\";\nimport { ReportDialog } from \"./report-dialog\";\nimport { sanitizeUrl, captureContext, sendReport, captureDeviceInfo } from \"./utils\";\nimport { computeSignature, shouldSkipDuplicate } from \"./dedup\";\nimport {\n initBreadcrumbs,\n addBreadcrumb as addBreadcrumbInternal,\n getBreadcrumbs,\n} from \"./breadcrumbs\";\n\nconst DEFAULT_BASE_URL = \"https://www.glitchgrab.dev\";\n\nconst GlitchgrabContext = createContext<UseGlitchgrabReturn | null>(null);\n\n/**\n * Hook to access Glitchgrab in your components.\n *\n * @example\n * ```tsx\n * const { reportBug, report, addBreadcrumb } = useGlitchgrab();\n *\n * // Report a bug\n * reportBug(\"Login button crashes on mobile\");\n *\n * // Report a feature request\n * report(\"FEATURE_REQUEST\", \"Add dark mode\");\n *\n * // Add a custom breadcrumb\n * addBreadcrumb(\"User clicked checkout\", { cartItems: \"3\" });\n * ```\n */\nexport function useGlitchgrab(): UseGlitchgrabReturn {\n const ctx = useContext(GlitchgrabContext);\n if (!ctx) {\n throw new Error(\"useGlitchgrab must be used within a GlitchgrabProvider\");\n }\n return ctx;\n}\n\nfunction GlitchgrabProviderInner({\n token,\n session,\n baseUrl,\n onError,\n onReportSent,\n breadcrumbs: enableBreadcrumbs = true,\n maxBreadcrumbs = 50,\n children,\n fallback,\n types,\n showSeverity,\n}: GlitchgrabProviderProps) {\n const visitedPagesRef = useRef<string[]>([]);\n\n // Initialize breadcrumbs\n useEffect(() => {\n if (enableBreadcrumbs) {\n initBreadcrumbs(maxBreadcrumbs);\n }\n }, [enableBreadcrumbs, maxBreadcrumbs]);\n\n // Track page visits\n useEffect(() => {\n try {\n if (typeof window === \"undefined\") return;\n\n const trackPage = () => {\n try {\n const sanitized = sanitizeUrl(window.location.href);\n const pages = visitedPagesRef.current;\n if (pages[pages.length - 1] !== sanitized) {\n pages.push(sanitized);\n if (pages.length > 20) {\n pages.splice(0, pages.length - 20);\n }\n }\n } catch {\n // Silently fail\n }\n };\n\n trackPage();\n const handlePopState = () => trackPage();\n window.addEventListener(\"popstate\", handlePopState);\n\n const origPushState = history.pushState.bind(history);\n const origReplaceState = history.replaceState.bind(history);\n\n history.pushState = function (...args) {\n origPushState(...args);\n trackPage();\n };\n history.replaceState = function (...args) {\n origReplaceState(...args);\n trackPage();\n };\n\n return () => {\n window.removeEventListener(\"popstate\", handlePopState);\n history.pushState = origPushState;\n history.replaceState = origReplaceState;\n };\n } catch {\n // Never crash\n }\n }, []);\n\n // Unhandled errors and rejections — skip in development\n useEffect(() => {\n try {\n if (typeof window === \"undefined\") return;\n if (process.env.NODE_ENV === \"development\") return;\n\n const handleError = (event: ErrorEvent) => {\n try {\n const context = captureContext(visitedPagesRef.current);\n const sig = computeSignature({\n errorMessage: event.message,\n pageUrl: context.url,\n errorStack: event.error?.stack,\n });\n if (shouldSkipDuplicate(sig)) return;\n const payload: ReportPayload = {\n token,\n source: \"SDK_AUTO\",\n type: \"BUG\",\n errorMessage: event.message,\n errorStack: event.error?.stack,\n pageUrl: context.url,\n userAgent: context.userAgent,\n breadcrumbs: context.breadcrumbs,\n deviceInfo: context.deviceInfo ?? undefined,\n metadata: {\n timestamp: context.timestamp,\n visitedPages: JSON.stringify(context.visitedPages),\n filename: event.filename ?? \"\",\n lineno: String(event.lineno ?? \"\"),\n colno: String(event.colno ?? \"\"),\n ...(session?.userId ? { sessionUserId: session.userId } : {}),\n ...(session?.name ? { sessionUserName: String(session.name) } : {}),\n ...(session?.email ? { sessionUserEmail: String(session.email) } : {}),\n ...(session?.phone ? { sessionUserPhone: String(session.phone) } : {}),\n },\n };\n sendReport(payload, baseUrl).then((result) => {\n if (result && onReportSent) onReportSent(result);\n });\n if (onError && event.error) onError(event.error);\n } catch {\n // Silently fail\n }\n };\n\n const handleRejection = (event: PromiseRejectionEvent) => {\n try {\n const context = captureContext(visitedPagesRef.current);\n const reason = event.reason;\n const errMsg = reason instanceof Error ? reason.message : String(reason);\n const errStack = reason instanceof Error ? reason.stack : undefined;\n const sig = computeSignature({\n errorMessage: errMsg,\n pageUrl: context.url,\n errorStack: errStack,\n });\n if (shouldSkipDuplicate(sig)) return;\n const payload: ReportPayload = {\n token,\n source: \"SDK_AUTO\",\n type: \"BUG\",\n errorMessage: errMsg,\n errorStack: errStack,\n pageUrl: context.url,\n userAgent: context.userAgent,\n breadcrumbs: context.breadcrumbs,\n deviceInfo: context.deviceInfo ?? undefined,\n metadata: {\n timestamp: context.timestamp,\n visitedPages: JSON.stringify(context.visitedPages),\n type: \"unhandledrejection\",\n ...(session?.userId ? { sessionUserId: session.userId } : {}),\n ...(session?.name ? { sessionUserName: String(session.name) } : {}),\n ...(session?.email ? { sessionUserEmail: String(session.email) } : {}),\n ...(session?.phone ? { sessionUserPhone: String(session.phone) } : {}),\n },\n };\n sendReport(payload, baseUrl).then((result) => {\n if (result && onReportSent) onReportSent(result);\n });\n if (onError && reason instanceof Error) onError(reason);\n } catch {\n // Silently fail\n }\n };\n\n window.addEventListener(\"error\", handleError);\n window.addEventListener(\"unhandledrejection\", handleRejection);\n\n return () => {\n window.removeEventListener(\"error\", handleError);\n window.removeEventListener(\"unhandledrejection\", handleRejection);\n };\n } catch {\n // Never crash\n }\n }, [token, baseUrl, onError, onReportSent, session]);\n\n const report = useCallback(\n async (\n type: ReportType,\n description: string,\n metadata?: Record<string, string>\n ): Promise<ReportResult | null> => {\n try {\n const context = captureContext(visitedPagesRef.current);\n const payload: ReportPayload = {\n token,\n source: \"SDK_USER_REPORT\",\n type,\n description,\n pageUrl: context.url,\n userAgent: context.userAgent,\n breadcrumbs: context.breadcrumbs,\n deviceInfo: context.deviceInfo ?? undefined,\n metadata: {\n timestamp: context.timestamp,\n visitedPages: JSON.stringify(context.visitedPages),\n ...(session?.userId ? { sessionUserId: session.userId } : {}),\n ...(session?.name ? { sessionUserName: String(session.name) } : {}),\n ...(session?.email ? { sessionUserEmail: String(session.email) } : {}),\n ...(session?.phone ? { sessionUserPhone: String(session.phone) } : {}),\n ...metadata,\n },\n };\n const result = await sendReport(payload, baseUrl);\n if (result && onReportSent) onReportSent(result);\n return result;\n } catch {\n return null;\n }\n },\n [token, baseUrl, onReportSent, session]\n );\n\n const reportBug = useCallback(\n (description: string, metadata?: Record<string, string>) =>\n report(\"BUG\", description, metadata),\n [report]\n );\n\n const addBreadcrumb = useCallback(\n (message: string, data?: Record<string, string>) => {\n addBreadcrumbInternal(\"custom\", message, data);\n },\n []\n );\n\n const openReportDialog = useCallback((options?: { description?: string; type?: ReportType }) => {\n if (typeof window !== \"undefined\") {\n window.dispatchEvent(new CustomEvent(\"glitchgrab:open-report\", { detail: options }));\n }\n }, []);\n\n // Global keyboard shortcut: Cmd+Shift+G (Mac) / Ctrl+Shift+G (Windows/Linux)\n useEffect(() => {\n try {\n if (typeof window === \"undefined\") return;\n const handleKeyDown = (e: KeyboardEvent) => {\n if ((e.metaKey || e.ctrlKey) && e.shiftKey && e.key.toLowerCase() === \"g\") {\n e.preventDefault();\n openReportDialog();\n }\n };\n window.addEventListener(\"keydown\", handleKeyDown);\n return () => window.removeEventListener(\"keydown\", handleKeyDown);\n } catch {\n // Never crash\n }\n }, [openReportDialog]);\n\n return (\n <GlitchgrabContext.Provider\n value={{\n token,\n baseUrl: baseUrl ?? DEFAULT_BASE_URL,\n reportBug,\n report,\n addBreadcrumb,\n openReportDialog,\n }}\n >\n <GlitchgrabErrorBoundary\n token={token}\n baseUrl={baseUrl}\n session={session}\n onError={onError}\n fallback={fallback}\n visitedPages={visitedPagesRef.current}\n >\n {children}\n </GlitchgrabErrorBoundary>\n <ReportDialog report={report} types={types} showSeverity={showSeverity} />\n </GlitchgrabContext.Provider>\n );\n}\n\nexport function GlitchgrabProvider(props: GlitchgrabProviderProps) {\n // No token = passthrough (SDK disabled)\n if (!props.token) return <>{props.children}</>;\n\n const resolvedProps = {\n ...props,\n baseUrl: props.baseUrl || DEFAULT_BASE_URL,\n };\n\n try {\n return <GlitchgrabProviderInner {...resolvedProps} />;\n } catch {\n return <>{props.children}</>;\n }\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport type { GlitchgrabSession, ReportPayload } from \"./types\";\nimport { captureContext, sendReport } from \"./utils\";\nimport { computeSignature, shouldSkipDuplicate } from \"./dedup\";\n\ninterface ErrorBoundaryProps {\n token: string;\n baseUrl?: string;\n session?: GlitchgrabSession | null;\n onError?: (error: Error) => void;\n fallback?: React.ReactNode;\n visitedPages: string[];\n children: React.ReactNode;\n}\n\ninterface ErrorBoundaryState {\n hasError: boolean;\n}\n\nexport class GlitchgrabErrorBoundary extends React.Component<\n ErrorBoundaryProps,\n ErrorBoundaryState\n> {\n constructor(props: ErrorBoundaryProps) {\n super(props);\n this.state = { hasError: false };\n }\n\n static getDerivedStateFromError(): ErrorBoundaryState {\n return { hasError: true };\n }\n\n componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void {\n try {\n const context = captureContext(this.props.visitedPages);\n\n const sig = computeSignature({\n errorMessage: error.message,\n pageUrl: context.url,\n errorStack: error.stack,\n });\n if (shouldSkipDuplicate(sig)) {\n if (this.props.onError) this.props.onError(error);\n return;\n }\n\n const session = this.props.session;\n const payload: ReportPayload = {\n token: this.props.token,\n source: \"SDK_AUTO\",\n type: \"BUG\",\n errorMessage: error.message,\n errorStack: error.stack,\n componentStack: errorInfo.componentStack ?? undefined,\n pageUrl: context.url,\n userAgent: context.userAgent,\n breadcrumbs: context.breadcrumbs,\n deviceInfo: context.deviceInfo ?? undefined,\n metadata: {\n timestamp: context.timestamp,\n visitedPages: JSON.stringify(context.visitedPages),\n ...(session?.userId ? { sessionUserId: session.userId } : {}),\n ...(session?.name ? { sessionUserName: String(session.name) } : {}),\n ...(session?.email ? { sessionUserEmail: String(session.email) } : {}),\n ...(session?.phone ? { sessionUserPhone: String(session.phone) } : {}),\n },\n };\n\n sendReport(payload, this.props.baseUrl);\n\n if (this.props.onError) {\n this.props.onError(error);\n }\n } catch {\n // Never crash the host app\n }\n }\n\n render(): React.ReactNode {\n if (this.state.hasError) {\n if (this.props.fallback) {\n return this.props.fallback;\n }\n\n // Re-render children — allows recovery from transient errors\n return this.props.children;\n }\n\n return this.props.children;\n }\n}\n","import type { Breadcrumb, BreadcrumbType } from \"./types\";\n\nconst MAX_DEFAULT = 50;\n\nlet breadcrumbs: Breadcrumb[] = [];\nlet maxBreadcrumbs = MAX_DEFAULT;\nlet initialized = false;\n\nexport function initBreadcrumbs(max?: number) {\n if (initialized) return;\n maxBreadcrumbs = max ?? MAX_DEFAULT;\n\n try {\n if (typeof window === \"undefined\") return;\n interceptConsole();\n interceptFetch();\n interceptNavigation();\n interceptClicks();\n initialized = true;\n } catch {\n // Never crash\n }\n}\n\nexport function addBreadcrumb(\n type: BreadcrumbType,\n message: string,\n data?: Record<string, string>\n) {\n try {\n breadcrumbs.push({\n type,\n message: message.slice(0, 200),\n timestamp: new Date().toISOString(),\n data,\n });\n if (breadcrumbs.length > maxBreadcrumbs) {\n breadcrumbs = breadcrumbs.slice(-maxBreadcrumbs);\n }\n } catch {\n // Never crash\n }\n}\n\nexport function getBreadcrumbs(): Breadcrumb[] {\n return [...breadcrumbs];\n}\n\nexport function clearBreadcrumbs() {\n breadcrumbs = [];\n}\n\n// ─── Console Interception ────────────────────────────────\n\nfunction interceptConsole() {\n const origLog = console.log;\n const origWarn = console.warn;\n const origError = console.error;\n\n console.log = function (...args: unknown[]) {\n addBreadcrumb(\"console\", `[log] ${argsToString(args)}`);\n origLog.apply(console, args);\n };\n\n console.warn = function (...args: unknown[]) {\n addBreadcrumb(\"console\", `[warn] ${argsToString(args)}`);\n origWarn.apply(console, args);\n };\n\n console.error = function (...args: unknown[]) {\n addBreadcrumb(\"console\", `[error] ${argsToString(args)}`);\n origError.apply(console, args);\n };\n}\n\nfunction argsToString(args: unknown[]): string {\n try {\n return args\n .map((a) => {\n if (typeof a === \"string\") return a;\n if (a instanceof Error) return a.message;\n try {\n return JSON.stringify(a);\n } catch {\n return String(a);\n }\n })\n .join(\" \")\n .slice(0, 200);\n } catch {\n return \"[unknown]\";\n }\n}\n\n// ─── Fetch Interception ──────────────────────────────────\n\nfunction interceptFetch() {\n const origFetch = window.fetch;\n\n window.fetch = async function (input, init) {\n const url =\n typeof input === \"string\"\n ? input\n : input instanceof URL\n ? input.toString()\n : input instanceof Request\n ? input.url\n : String(input);\n const method = init?.method ?? \"GET\";\n const start = Date.now();\n\n try {\n const response = await origFetch.apply(window, [input, init]);\n addBreadcrumb(\"api\", `${method} ${url.slice(0, 100)} → ${response.status}`, {\n method,\n status: String(response.status),\n duration: `${Date.now() - start}ms`,\n });\n return response;\n } catch (err) {\n addBreadcrumb(\"api\", `${method} ${url.slice(0, 100)} → FAILED`, {\n method,\n error: err instanceof Error ? err.message : \"unknown\",\n duration: `${Date.now() - start}ms`,\n });\n throw err;\n }\n };\n}\n\n// ─── Navigation Interception ─────────────────────────────\n\nfunction interceptNavigation() {\n const origPush = history.pushState.bind(history);\n const origReplace = history.replaceState.bind(history);\n\n history.pushState = function (...args) {\n origPush(...args);\n addBreadcrumb(\"navigation\", `Navigate to ${window.location.pathname}`);\n };\n\n history.replaceState = function (...args) {\n origReplace(...args);\n addBreadcrumb(\"navigation\", `Replace to ${window.location.pathname}`);\n };\n\n window.addEventListener(\"popstate\", () => {\n addBreadcrumb(\"navigation\", `Back/Forward to ${window.location.pathname}`);\n });\n}\n\n// ─── Click Interception ──────────────────────────────────\n\nfunction interceptClicks() {\n document.addEventListener(\n \"click\",\n (e) => {\n try {\n const target = e.target as HTMLElement;\n const tag = target.tagName?.toLowerCase();\n const text = target.textContent?.trim().slice(0, 50) ?? \"\";\n const id = target.id ? `#${target.id}` : \"\";\n const cls = target.className && typeof target.className === \"string\"\n ? `.${target.className.split(\" \")[0]}`\n : \"\";\n\n addBreadcrumb(\"click\", `Click ${tag}${id}${cls} \"${text}\"`);\n } catch {\n // Never crash\n }\n },\n { capture: true }\n );\n}\n","import type { ReportPayload, ReportResult, CapturedContext, DeviceInfo } from \"./types\";\nimport { getBreadcrumbs } from \"./breadcrumbs\";\n\nconst SENSITIVE_PARAMS = [\n \"token\", \"key\", \"secret\", \"password\", \"passwd\", \"auth\", \"authorization\",\n \"session\", \"sessionid\", \"session_id\", \"api_key\", \"apikey\", \"access_token\",\n \"refresh_token\", \"client_secret\", \"code\", \"state\", \"nonce\", \"credential\", \"private\",\n];\n\nexport function sanitizeUrl(url: string): string {\n try {\n const parsed = new URL(url);\n const params = new URLSearchParams(parsed.search);\n let modified = false;\n for (const key of Array.from(params.keys())) {\n if (SENSITIVE_PARAMS.some((s) => key.toLowerCase().includes(s))) {\n params.set(key, \"[REDACTED]\");\n modified = true;\n }\n }\n if (modified) parsed.search = params.toString();\n return parsed.toString();\n } catch {\n return url.split(\"?\")[0] ?? url;\n }\n}\n\nexport function captureDeviceInfo(): DeviceInfo | null {\n try {\n if (typeof window === \"undefined\") return null;\n return {\n screenWidth: screen.width,\n screenHeight: screen.height,\n viewportWidth: window.innerWidth,\n viewportHeight: window.innerHeight,\n platform: navigator.platform ?? \"unknown\",\n language: navigator.language ?? \"unknown\",\n online: navigator.onLine,\n colorScheme: window.matchMedia(\"(prefers-color-scheme: dark)\").matches ? \"dark\" : \"light\",\n devicePixelRatio: window.devicePixelRatio ?? 1,\n };\n } catch {\n return null;\n }\n}\n\nexport function captureContext(visitedPages: string[]): CapturedContext {\n try {\n return {\n url: sanitizeUrl(typeof window !== \"undefined\" ? window.location.href : \"\"),\n userAgent: typeof navigator !== \"undefined\" ? navigator.userAgent : \"\",\n timestamp: new Date().toISOString(),\n visitedPages: visitedPages.map(sanitizeUrl),\n breadcrumbs: getBreadcrumbs(),\n deviceInfo: captureDeviceInfo(),\n };\n } catch {\n return {\n url: \"\",\n userAgent: \"\",\n timestamp: new Date().toISOString(),\n visitedPages: [],\n breadcrumbs: [],\n deviceInfo: null,\n };\n }\n}\n\nconst DEFAULT_BASE_URL = \"https://www.glitchgrab.dev\";\nconst MAX_RETRIES = 3;\nconst RETRY_BASE_MS = 500;\n\n/**\n * Send a report and return the result.\n * Never throws — returns null on failure.\n */\nexport async function sendReport(\n payload: ReportPayload,\n baseUrl?: string\n): Promise<ReportResult | null> {\n try {\n const url = `${baseUrl ?? DEFAULT_BASE_URL}/api/v1/sdk/report`;\n const body = JSON.stringify(payload);\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${payload.token}`,\n };\n\n // keepalive has a 64KB body limit in browsers — skip it for large payloads (e.g., screenshots)\n const useKeepalive = body.length < 60_000;\n\n for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {\n try {\n const response = await fetch(url, {\n method: \"POST\",\n headers,\n body,\n ...(useKeepalive ? { keepalive: true } : {}),\n });\n\n if (response.ok) {\n const envelope = (await response.json()) as {\n success: boolean;\n data?: Omit<ReportResult, \"success\">;\n };\n return { success: envelope.success, ...(envelope.data ?? {}) };\n }\n\n if (response.status >= 400 && response.status < 500 && response.status !== 429) {\n return null;\n }\n } catch {\n // Will retry\n }\n\n if (attempt < MAX_RETRIES - 1) {\n await new Promise((resolve) =>\n setTimeout(resolve, RETRY_BASE_MS * Math.pow(2, attempt))\n );\n }\n }\n\n // Fallback: sendBeacon (fire-and-forget, no result)\n if (typeof navigator !== \"undefined\" && navigator.sendBeacon) {\n try {\n navigator.sendBeacon(url, new Blob([body], { type: \"application/json\" }));\n } catch {\n // Silently fail\n }\n }\n\n return null;\n } catch {\n return null;\n }\n}\n","const DEFAULT_WINDOW_MS = 5 * 60 * 1000;\nconst MAX_ENTRIES = 100;\n\nconst seen = new Map<string, number>();\n\nfunction hashString(input: string): string {\n let h1 = 0xdeadbeef ^ 0;\n let h2 = 0x41c6ce57 ^ 0;\n for (let i = 0; i < input.length; i++) {\n const ch = input.charCodeAt(i);\n h1 = Math.imul(h1 ^ ch, 2654435761);\n h2 = Math.imul(h2 ^ ch, 1597334677);\n }\n h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^ Math.imul(h2 ^ (h2 >>> 13), 3266489909);\n h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^ Math.imul(h1 ^ (h1 >>> 13), 3266489909);\n return (4294967296 * (2097151 & h2) + (h1 >>> 0)).toString(36);\n}\n\nfunction topStackFrame(stack: string | undefined): string {\n if (!stack) return \"\";\n const lines = stack.split(\"\\n\");\n for (const line of lines) {\n const t = line.trim();\n if (t.startsWith(\"at \") || t.includes(\"@\")) {\n return t;\n }\n }\n return \"\";\n}\n\nfunction stripUrlQuery(url: string | undefined): string {\n if (!url) return \"\";\n try {\n const u = new URL(url);\n return `${u.origin}${u.pathname}`;\n } catch {\n const q = url.indexOf(\"?\");\n return q === -1 ? url : url.slice(0, q);\n }\n}\n\nexport function computeSignature(params: {\n errorMessage: string | undefined;\n pageUrl: string | undefined;\n errorStack?: string | undefined;\n}): string {\n const msg = params.errorMessage?.trim() ?? \"\";\n const page = stripUrlQuery(params.pageUrl);\n const frame = topStackFrame(params.errorStack);\n return hashString(`${msg}|${page}|${frame}`);\n}\n\nexport function shouldSkipDuplicate(\n signature: string,\n windowMs: number = DEFAULT_WINDOW_MS,\n now: number = Date.now()\n): boolean {\n const last = seen.get(signature);\n if (last !== undefined && now - last < windowMs) {\n return true;\n }\n seen.set(signature, now);\n\n if (seen.size > MAX_ENTRIES) {\n const cutoff = now - windowMs;\n for (const [sig, ts] of seen) {\n if (ts < cutoff) seen.delete(sig);\n }\n if (seen.size > MAX_ENTRIES) {\n const excess = seen.size - MAX_ENTRIES;\n const keys = Array.from(seen.keys()).slice(0, excess);\n for (const k of keys) seen.delete(k);\n }\n }\n return false;\n}\n\nexport function clearDedupCache(): void {\n seen.clear();\n}\n","\"use client\";\n\nimport { useState, useRef, useEffect, type CSSProperties, type ReactNode } from \"react\";\n// @ts-expect-error react-dom types handled by host app\nimport { createPortal } from \"react-dom\";\nimport type { ReportType, ReportSeverity, UseGlitchgrabReturn } from \"./types\";\n\n/** Detect if the host page uses a dark or light theme */\nfunction useIsDark(): boolean {\n if (typeof window === \"undefined\") return true;\n try {\n // Check body then html — most sites set background on html, not body\n for (const el of [document.body, document.documentElement]) {\n const bg = getComputedStyle(el).backgroundColor;\n const match = bg.match(/rgba?\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)(?:\\s*,\\s*([\\d.]+))?\\s*\\)/);\n if (match) {\n const alpha = match[4] !== undefined ? parseFloat(match[4]) : 1;\n if (alpha < 0.05) continue; // transparent — skip to next element\n const [r, g, b] = [Number(match[1]), Number(match[2]), Number(match[3])];\n return (r * 299 + g * 587 + b * 114) / 1000 < 128;\n }\n }\n return window.matchMedia(\"(prefers-color-scheme: dark)\").matches;\n } catch {\n return true;\n }\n}\n\n/** Convert HSL values to a hex color string */\nfunction hslToHex(h: number, s: number, l: number): string {\n s /= 100;\n l /= 100;\n const a = s * Math.min(l, 1 - l);\n const f = (n: number) => {\n const k = (n + h / 30) % 12;\n const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);\n return Math.round(255 * color).toString(16).padStart(2, \"0\");\n };\n return `#${f(0)}${f(8)}${f(4)}`;\n}\n\n/** Parse a CSS color value into [r, g, b] or null */\nfunction parseColorToRgb(value: string): [number, number, number] | null {\n try {\n const trimmed = value.trim();\n\n // hex (#fff, #ffffff)\n const hexMatch = trimmed.match(/^#([0-9a-f]{3,8})$/i);\n if (hexMatch) {\n let hex = hexMatch[1];\n if (hex.length === 3) hex = hex[0]+hex[0]+hex[1]+hex[1]+hex[2]+hex[2];\n return [parseInt(hex.slice(0, 2), 16), parseInt(hex.slice(2, 4), 16), parseInt(hex.slice(4, 6), 16)];\n }\n\n // rgb(r, g, b) or rgba(r, g, b, a)\n const rgbMatch = trimmed.match(/rgba?\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)/);\n if (rgbMatch) return [Number(rgbMatch[1]), Number(rgbMatch[2]), Number(rgbMatch[3])];\n\n // hsl(h, s%, l%) or hsla(h, s%, l%, a)\n const hslMatch = trimmed.match(/hsla?\\(\\s*([\\d.]+)\\s*,\\s*([\\d.]+)%\\s*,\\s*([\\d.]+)%/);\n if (hslMatch) {\n const hex = hslToHex(Number(hslMatch[1]), Number(hslMatch[2]), Number(hslMatch[3]));\n return parseColorToRgb(hex);\n }\n\n return null;\n } catch {\n return null;\n }\n}\n\n/** Compute relative luminance and return ideal contrast text color */\nfunction getContrastText(r: number, g: number, b: number): string {\n const luminance = (r * 299 + g * 587 + b * 114) / 1000;\n return luminance > 150 ? \"#09090b\" : \"#ffffff\";\n}\n\n/**\n * Auto-detect the host app's primary/accent color from CSS custom properties.\n * Checks common variable names used by shadcn/ui, Radix, Tailwind, MUI, etc.\n * Returns { accent, accentText } or null if no theme detected.\n */\nfunction detectHostAccent(): { accent: string; accentText: string } | null {\n if (typeof window === \"undefined\") return null;\n try {\n const root = getComputedStyle(document.documentElement);\n\n // Common CSS variable names for primary/accent color\n const varNames = [\n \"--primary\",\n \"--accent\",\n \"--brand\",\n \"--color-primary\",\n \"--theme-primary\",\n \"--chakra-colors-primary-500\",\n \"--mui-palette-primary-main\",\n ];\n\n for (const name of varNames) {\n const raw = root.getPropertyValue(name).trim();\n if (!raw) continue;\n\n // shadcn/ui style: space-separated HSL values like \"243 75% 59%\"\n const hslSpaceMatch = raw.match(/^([\\d.]+)\\s+([\\d.]+)%\\s+([\\d.]+)%$/);\n if (hslSpaceMatch) {\n const hex = hslToHex(Number(hslSpaceMatch[1]), Number(hslSpaceMatch[2]), Number(hslSpaceMatch[3]));\n const rgb = parseColorToRgb(hex);\n return { accent: hex, accentText: rgb ? getContrastText(...rgb) : \"#ffffff\" };\n }\n\n // Standard color values (hex, rgb, hsl)\n const rgb = parseColorToRgb(raw);\n if (rgb) {\n const hex = `#${rgb.map((c) => c.toString(16).padStart(2, \"0\")).join(\"\")}`;\n return { accent: hex, accentText: getContrastText(...rgb) };\n }\n }\n\n return null;\n } catch {\n return null;\n }\n}\n\nfunction getTheme(dark: boolean) {\n const hostAccent = detectHostAccent();\n const defaults = dark\n ? { bg: \"#1c1c1e\", bgSecondary: \"#27272a\", border: \"#2c2c2e\", text: \"#fafafa\", textMuted: \"#a1a1aa\", accent: \"#22d3ee\", accentText: \"#09090b\", inputBg: \"#27272a\", inputBorder: \"#3f3f46\" }\n : { bg: \"#ffffff\", bgSecondary: \"#f4f4f5\", border: \"#e4e4e7\", text: \"#18181b\", textMuted: \"#71717a\", accent: \"#0891b2\", accentText: \"#ffffff\", inputBg: \"#fafafa\", inputBorder: \"#d4d4d8\" };\n\n if (hostAccent) {\n defaults.accent = hostAccent.accent;\n defaults.accentText = hostAccent.accentText;\n }\n\n return defaults;\n}\n\n/** Validate that report text is meaningful — rejects gibberish, throwaway words, random chars */\nfunction isLowQualityText(text: string): string | null {\n const trimmed = text.trim();\n if (!trimmed) return null;\n\n // Exact throwaway words\n const throwaway =\n /^(done|ok|yes|no|hi|hello|hey|test|testing|asdf|qwerty|abc|xyz|foo|bar|baz|lol|lmao|idk|bruh|nice|cool|wow|sup|yo|nah|yep|nope|thanks|thx|ty|k|kk|hmm|hm|na|mm|mhm|aight|bet|gg|wp|rip|omg|pls|plz)$/i;\n if (throwaway.test(trimmed)) {\n return \"Please describe the actual issue you're experiencing\";\n }\n\n // Repeated characters (aaaaaaa, !!!!!!!)\n if (/(.)\\1{4,}/.test(trimmed)) {\n return \"Please provide a meaningful description\";\n }\n\n const letters = trimmed.replace(/[^a-zA-Z]/g, \"\");\n if (letters.length >= 4) {\n // Very low vowel ratio (bkdfghjklmn...)\n const vowels = letters.replace(/[^aeiouAEIOU]/g, \"\").length;\n const vowelRatio = vowels / letters.length;\n if (vowelRatio < 0.08) {\n return \"That doesn't look like a valid description\";\n }\n\n // Keyboard mashing: single word with no real English pattern\n // Detects strings like \"asdfasfsdad\", \"jkljklfsdf\", \"qwertyuio\"\n // Real words have max 3-4 consecutive consonants; gibberish has long runs\n if (/[^aeiou\\s]{5,}/i.test(letters)) {\n const words = trimmed.split(/\\s+/);\n // Only flag if it's a single \"word\" — multi-word text is likely real\n if (words.length <= 2) {\n return \"That doesn't look like a valid description\";\n }\n }\n\n // Check if it looks like a random permutation of a few chars (asdfasfsdad)\n if (letters.length >= 6) {\n const uniqueChars = new Set(letters.toLowerCase()).size;\n const uniqueRatio = uniqueChars / letters.length;\n // Real English has ~0.6-0.9 unique ratio for short text; gibberish reuses few chars\n if (uniqueRatio < 0.4 && trimmed.split(/\\s+/).length <= 2) {\n return \"That doesn't look like a valid description\";\n }\n }\n }\n\n // Single short word that isn't a known tech term\n const words = trimmed.split(/\\s+/).filter((w) => w.length > 0);\n if (words.length === 1 && trimmed.length < 10) {\n const techTerms =\n /^(crash|error|bug|fail|broken|slow|freeze|lag|404|500|null|undefined|nan|timeout|overflow|leak|cors|oom)$/i;\n if (!techTerms.test(trimmed)) {\n return \"Please provide more detail about the issue\";\n }\n }\n\n return null;\n}\n\ninterface ReportDialogProps {\n report: UseGlitchgrabReturn[\"report\"];\n types?: ReportType[];\n showSeverity?: boolean;\n}\n\n/**\n * The report dialog — rendered inside GlitchgrabProvider automatically.\n * Opens via the `glitchgrab:open-report` custom event (triggered by `openReportDialog()`).\n */\nexport function ReportDialog({\n report,\n types,\n showSeverity = true,\n}: ReportDialogProps) {\n // Prevent hydration mismatch — render nothing until after hydration\n const [mounted, setMounted] = useState(false);\n useEffect(() => { setMounted(true); }, []);\n\n const [isOpen, setIsOpen] = useState(false);\n const [description, setDescription] = useState(\"\");\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [submitted, setSubmitted] = useState(false);\n const [screenshot, setScreenshot] = useState<string | null>(null);\n const [previewOpen, setPreviewOpen] = useState(false);\n const fileInputRef = useRef<HTMLInputElement>(null);\n const modalRef = useRef<HTMLDivElement>(null);\n\n // Stepper state\n const [step, setStep] = useState(1);\n const [reportType, setReportType] = useState<ReportType>(\"BUG\");\n const [severity, setSeverity] = useState<ReportSeverity>(\"medium\");\n const [validationError, setValidationError] = useState<string | null>(null);\n\n const availableTypes: ReportType[] = types ?? [\"BUG\", \"FEATURE_REQUEST\", \"QUESTION\", \"OTHER\"];\n\n const isDark = useIsDark();\n const t = getTheme(isDark);\n\n const handleFileUpload = (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (!file) return;\n const reader = new FileReader();\n reader.onload = () => {\n setScreenshot(reader.result as string);\n };\n reader.readAsDataURL(file);\n e.target.value = \"\";\n };\n\n const retakeScreenshot = async () => {\n setPreviewOpen(false);\n setIsOpen(false);\n setScreenshot(null);\n await new Promise((r) => setTimeout(r, 300));\n try {\n const { default: html2canvas } = await import(\"html2canvas-pro\");\n const canvas = await html2canvas(document.body, {\n scale: 0.5,\n logging: false,\n useCORS: true,\n allowTaint: true,\n });\n setScreenshot(canvas.toDataURL(\"image/jpeg\", 0.6));\n } catch {\n // silently fail\n }\n setIsOpen(true);\n };\n\n const handleOpen = async () => {\n setSubmitted(false);\n if (availableTypes.length === 1) {\n setReportType(availableTypes[0]);\n setStep(2);\n }\n try {\n const { default: html2canvas } = await import(\"html2canvas-pro\");\n const canvas = await html2canvas(document.body, {\n scale: 0.5,\n logging: false,\n useCORS: true,\n allowTaint: true,\n });\n setScreenshot(canvas.toDataURL(\"image/jpeg\", 0.6));\n } catch {\n // screenshot failed — open without it\n }\n setIsOpen(true);\n };\n\n // Listen for programmatic open via openReportDialog()\n useEffect(() => {\n const handler = (e: Event) => {\n if (isOpen) return;\n const detail = (e as CustomEvent).detail;\n if (detail?.description) setDescription(detail.description);\n if (detail?.type) {\n setReportType(detail.type);\n setStep(2);\n }\n handleOpen();\n };\n window.addEventListener(\"glitchgrab:open-report\", handler);\n return () => window.removeEventListener(\"glitchgrab:open-report\", handler);\n }, [isOpen, handleOpen]);\n\n // Close on Escape\n useEffect(() => {\n if (!isOpen) return;\n const handleEsc = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n if (previewOpen) setPreviewOpen(false);\n else handleClose();\n }\n };\n document.addEventListener(\"keydown\", handleEsc);\n return () => document.removeEventListener(\"keydown\", handleEsc);\n }, [isOpen, previewOpen]);\n\n // Paste image from clipboard (Cmd+V / Ctrl+V) when dialog is open\n useEffect(() => {\n if (!isOpen) return;\n const handlePaste = (e: ClipboardEvent) => {\n try {\n const items = e.clipboardData?.items;\n if (!items) return;\n for (let i = 0; i < items.length; i++) {\n if (items[i].type.startsWith(\"image/\")) {\n const file = items[i].getAsFile();\n if (!file) continue;\n const reader = new FileReader();\n reader.onload = () => setScreenshot(reader.result as string);\n reader.readAsDataURL(file);\n e.preventDefault();\n break;\n }\n }\n } catch {\n // silently fail\n }\n };\n window.addEventListener(\"paste\", handlePaste);\n return () => window.removeEventListener(\"paste\", handlePaste);\n }, [isOpen]);\n\n const handleClose = () => {\n setIsOpen(false);\n setStep(1);\n setReportType(\"BUG\");\n setSeverity(\"medium\");\n setValidationError(null);\n };\n\n const handleSubmit = async () => {\n try {\n if (!description.trim() || isSubmitting) return;\n\n const qualityError = isLowQualityText(description);\n if (qualityError) {\n setValidationError(qualityError);\n setStep(2);\n return;\n }\n\n setIsSubmitting(true);\n const metadata: Record<string, string> = {};\n if (screenshot) metadata.screenshot = screenshot;\n if (showSeverity && reportType === \"BUG\") {\n metadata.severity = severity;\n }\n\n const result = await report(reportType, description.trim(), Object.keys(metadata).length > 0 ? metadata : undefined);\n\n if (result) {\n setSubmitted(true);\n setDescription(\"\");\n setScreenshot(null);\n\n setTimeout(() => {\n setSubmitted(false);\n handleClose();\n }, 2000);\n }\n setIsSubmitting(false);\n } catch {\n setIsSubmitting(false);\n }\n };\n\n if (!mounted) return null;\n\n return (\n <>\n {/* Report modal */}\n {isOpen && createPortal(\n <div\n style={{\n position: \"fixed\",\n inset: 0,\n zIndex: 2147483647,\n pointerEvents: \"auto\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: \"rgba(0,0,0,0.5)\",\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n }}\n onClick={() => { if (!previewOpen) handleClose(); }}\n onPointerDown={(e) => e.stopPropagation()}\n onFocus={(e) => e.stopPropagation()}\n >\n <div\n ref={modalRef}\n onClick={(e) => e.stopPropagation()}\n style={{\n position: \"relative\",\n zIndex: 2147483647,\n width: \"340px\",\n maxWidth: \"calc(100% - 32px)\",\n backgroundColor: t.bg,\n borderRadius: \"12px\",\n boxShadow:\n \"0 20px 60px rgba(0, 0, 0, 0.2), 0 4px 16px rgba(0, 0, 0, 0.1)\",\n fontFamily:\n '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n overflow: \"hidden\",\n color: t.text,\n isolation: \"isolate\",\n }}\n >\n {/* Header */}\n <div\n style={{\n padding: \"16px 16px 12px\",\n borderBottom: `1px solid ${t.border}`,\n }}\n >\n <div\n style={{\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n }}\n >\n <div style={{ display: \"flex\", alignItems: \"center\", gap: \"8px\" }}>\n {step > 1 && (\n <button\n type=\"button\"\n onClick={() => setStep((s) => (s - 1) as 1 | 2 | 3)}\n style={{\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n padding: \"2px\",\n display: \"flex\",\n alignItems: \"center\",\n }}\n aria-label=\"Back\"\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path d=\"M10 3L5 8L10 13\" stroke={t.textMuted} strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </button>\n )}\n <span\n style={{\n fontSize: \"15px\",\n fontWeight: 600,\n color: t.text,\n }}\n >\n {step === 1 ? \"What's on your mind?\" : step === 2 ? \"Tell us more\" : \"Review & Send\"}\n </span>\n </div>\n <button\n type=\"button\"\n onClick={handleClose}\n style={{\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n padding: \"4px\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n aria-label=\"Close\"\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" style={{ display: \"block\" }}>\n <path d=\"M4 4L12 12M12 4L4 12\" stroke={t.textMuted} strokeWidth=\"2\" strokeLinecap=\"round\" />\n </svg>\n </button>\n </div>\n <div style={{ display: \"flex\", alignItems: \"center\", justifyContent: \"center\", gap: \"0\", marginTop: \"12px\" }}>\n {[1, 2, 3].map((s, i) => (\n <div key={s} style={{ display: \"flex\", alignItems: \"center\" }}>\n <div style={{\n width: \"8px\",\n height: \"8px\",\n borderRadius: \"50%\",\n backgroundColor: s <= step ? t.accent : t.inputBorder,\n transition: \"background-color 0.2s ease\",\n }} />\n {i < 2 && (\n <div style={{\n width: \"40px\",\n height: \"2px\",\n backgroundColor: s < step ? t.accent : t.inputBorder,\n transition: \"background-color 0.2s ease\",\n }} />\n )}\n </div>\n ))}\n </div>\n </div>\n\n {/* Body */}\n <div style={{ padding: \"16px\" }}>\n {submitted ? (\n <div\n style={{\n textAlign: \"center\",\n padding: \"20px 0\",\n color: t.accent,\n fontSize: \"14px\",\n fontWeight: 500,\n }}\n >\n {getTypeLabel(reportType)} sent. Thank you!\n </div>\n ) : (\n <>\n {/* Step 1: Category */}\n {step === 1 && (\n <div style={{ display: \"grid\", gridTemplateColumns: \"1fr 1fr\", gap: \"8px\" }}>\n {availableTypes.map((type) => (\n <button\n key={type}\n type=\"button\"\n onClick={() => {\n setReportType(type);\n setStep(2);\n }}\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: \"8px\",\n padding: \"16px 8px\",\n borderRadius: \"8px\",\n border: `1px solid ${t.inputBorder}`,\n background: t.inputBg,\n cursor: \"pointer\",\n color: t.text,\n fontFamily: \"inherit\",\n transition: \"border-color 0.15s ease\",\n }}\n onMouseEnter={(e) => { (e.currentTarget as HTMLElement).style.borderColor = t.accent; }}\n onMouseLeave={(e) => { (e.currentTarget as HTMLElement).style.borderColor = t.inputBorder; }}\n >\n {getTypeIcon(type, t.accent)}\n <span style={{ fontSize: \"13px\", fontWeight: 600 }}>{getTypeLabel(type)}</span>\n <span style={{ fontSize: \"11px\", color: t.textMuted, lineHeight: \"1.3\" }}>{getTypeSubtitle(type)}</span>\n </button>\n ))}\n </div>\n )}\n\n {/* Step 2: Details */}\n {step === 2 && (\n <>\n <textarea\n value={description}\n onChange={(e) => { setDescription(e.target.value); if (validationError) setValidationError(null); }}\n placeholder={getPlaceholder(reportType)}\n style={{\n width: \"100%\",\n minHeight: \"100px\",\n padding: \"10px 12px\",\n borderRadius: \"8px\",\n border: `1px solid ${t.inputBorder}`,\n fontSize: \"14px\",\n fontFamily: \"inherit\",\n resize: \"vertical\",\n outline: \"none\",\n boxSizing: \"border-box\",\n color: t.text,\n backgroundColor: t.inputBg,\n }}\n onFocus={(e) => { (e.target as HTMLTextAreaElement).style.borderColor = t.accent; }}\n onBlur={(e) => { (e.target as HTMLTextAreaElement).style.borderColor = t.inputBorder; }}\n autoFocus\n />\n {showSeverity && reportType === \"BUG\" && (\n <div style={{ marginTop: \"10px\" }}>\n <span style={{ fontSize: \"12px\", color: t.textMuted, marginBottom: \"6px\", display: \"block\" }}>Severity</span>\n <div style={{ display: \"flex\", gap: \"6px\" }}>\n {([\"low\", \"medium\", \"high\"] as ReportSeverity[]).map((s) => (\n <button\n key={s}\n type=\"button\"\n onClick={() => setSeverity(s)}\n style={{\n flex: 1,\n padding: \"6px 0\",\n borderRadius: \"6px\",\n border: `1px solid ${severity === s ? t.accent : t.inputBorder}`,\n background: severity === s ? t.accent : \"transparent\",\n color: severity === s ? t.accentText : t.text,\n fontSize: \"12px\",\n fontWeight: 600,\n cursor: \"pointer\",\n fontFamily: \"inherit\",\n textTransform: \"capitalize\",\n transition: \"all 0.15s ease\",\n }}\n >\n {s}\n </button>\n ))}\n </div>\n </div>\n )}\n {validationError && (\n <p style={{ color: \"#ef4444\", fontSize: \"12px\", marginTop: \"6px\" }}>\n {validationError}\n </p>\n )}\n <button\n type=\"button\"\n onClick={() => {\n const err = isLowQualityText(description);\n if (err) { setValidationError(err); return; }\n setValidationError(null);\n setStep(3);\n }}\n disabled={!description.trim()}\n style={{\n marginTop: \"12px\",\n width: \"100%\",\n padding: \"10px\",\n borderRadius: \"8px\",\n border: \"none\",\n backgroundColor: !description.trim() ? t.bgSecondary : t.accent,\n color: !description.trim() ? t.textMuted : t.accentText,\n fontSize: \"14px\",\n fontWeight: 600,\n cursor: !description.trim() ? \"not-allowed\" : \"pointer\",\n fontFamily: \"inherit\",\n transition: \"background-color 0.15s ease\",\n }}\n >\n Next\n </button>\n </>\n )}\n\n {/* Step 3: Review & Send */}\n {step === 3 && (\n <>\n {/* Summary chips */}\n <div style={{ display: \"flex\", gap: \"6px\", flexWrap: \"wrap\", marginBottom: \"12px\" }}>\n <span style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: \"4px\",\n padding: \"4px 10px\",\n borderRadius: \"12px\",\n fontSize: \"12px\",\n fontWeight: 600,\n backgroundColor: t.bgSecondary,\n color: t.text,\n border: `1px solid ${t.border}`,\n }}>\n {getTypeIcon(reportType, t.accent, 12)}\n {getTypeLabel(reportType)}\n </span>\n {showSeverity && reportType === \"BUG\" && (\n <span style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n padding: \"4px 10px\",\n borderRadius: \"12px\",\n fontSize: \"12px\",\n fontWeight: 600,\n backgroundColor: severity === \"high\" ? \"#fef2f2\" : severity === \"medium\" ? \"#fffbeb\" : \"#f0fdf4\",\n color: severity === \"high\" ? \"#dc2626\" : severity === \"medium\" ? \"#d97706\" : \"#16a34a\",\n border: `1px solid ${severity === \"high\" ? \"#fecaca\" : severity === \"medium\" ? \"#fde68a\" : \"#bbf7d0\"}`,\n textTransform: \"capitalize\",\n }}>\n {severity}\n </span>\n )}\n </div>\n\n {/* Description preview */}\n <div style={{\n padding: \"10px 12px\",\n borderRadius: \"8px\",\n border: `1px solid ${t.inputBorder}`,\n backgroundColor: t.inputBg,\n fontSize: \"13px\",\n color: t.text,\n marginBottom: \"10px\",\n maxHeight: \"80px\",\n overflow: \"hidden\",\n lineHeight: \"1.4\",\n }}>\n {description.length > 200 ? description.slice(0, 200) + \"...\" : description}\n </div>\n\n {/* Screenshot */}\n {screenshot && (\n <div style={{ marginBottom: \"10px\", position: \"relative\" }}>\n <img\n src={screenshot}\n alt=\"Page screenshot\"\n onClick={() => setPreviewOpen(true)}\n style={{\n width: \"100%\",\n borderRadius: \"6px\",\n border: `1px solid ${t.border}`,\n maxHeight: \"80px\",\n objectFit: \"cover\",\n objectPosition: \"top\",\n cursor: \"pointer\",\n }}\n />\n <button\n type=\"button\"\n onClick={() => setScreenshot(null)}\n style={{\n position: \"absolute\",\n top: \"4px\",\n right: \"4px\",\n background: \"rgba(0,0,0,0.6)\",\n border: \"none\",\n borderRadius: \"50%\",\n width: \"20px\",\n height: \"20px\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n aria-label=\"Remove screenshot\"\n >\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"none\">\n <path d=\"M1 1L9 9M9 1L1 9\" stroke=\"#fff\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n </button>\n </div>\n )}\n {!screenshot && (\n <div style={{ display: \"flex\", gap: \"6px\", marginBottom: \"10px\" }}>\n <button\n type=\"button\"\n onClick={() => fileInputRef.current?.click()}\n style={{\n flex: 1,\n padding: \"8px\",\n borderRadius: \"6px\",\n border: `1px dashed ${t.inputBorder}`,\n textAlign: \"center\",\n fontSize: \"11px\",\n color: t.textMuted,\n background: \"none\",\n cursor: \"pointer\",\n }}\n >\n Upload or paste (⌘V)\n </button>\n <button\n type=\"button\"\n onClick={retakeScreenshot}\n style={{\n flex: 1,\n padding: \"8px\",\n borderRadius: \"6px\",\n border: `1px dashed ${t.inputBorder}`,\n textAlign: \"center\",\n fontSize: \"11px\",\n color: t.textMuted,\n background: \"none\",\n cursor: \"pointer\",\n }}\n >\n Retake screenshot\n </button>\n </div>\n )}\n\n <button\n type=\"button\"\n onClick={handleSubmit}\n disabled={isSubmitting}\n style={{\n width: \"100%\",\n padding: \"10px\",\n borderRadius: \"8px\",\n border: \"none\",\n backgroundColor: isSubmitting ? t.bgSecondary : t.accent,\n color: isSubmitting ? t.textMuted : t.accentText,\n fontSize: \"14px\",\n fontWeight: 600,\n cursor: isSubmitting ? \"not-allowed\" : \"pointer\",\n fontFamily: \"inherit\",\n transition: \"background-color 0.15s ease\",\n }}\n >\n {isSubmitting ? \"Sending...\" : \"Send Report\"}\n </button>\n </>\n )}\n </>\n )}\n </div>\n\n {/* Footer */}\n <div\n style={{\n padding: \"8px 16px 10px\",\n borderTop: `1px solid ${t.border}`,\n textAlign: \"center\",\n }}\n >\n <span style={{ fontSize: \"11px\", color: t.textMuted }}>\n Powered by Glitchgrab\n </span>\n </div>\n </div>\n </div>,\n document.body\n )}\n\n {/* Hidden file input */}\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\"image/*\"\n onChange={handleFileUpload}\n style={{ display: \"none\" }}\n />\n\n {/* Full-screen screenshot preview */}\n {previewOpen && screenshot && createPortal(\n <div\n style={{\n position: \"fixed\",\n inset: 0,\n zIndex: 2147483647,\n backgroundColor: \"rgba(0,0,0,0.85)\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: \"16px\",\n cursor: \"pointer\",\n }}\n onClick={(e) => { e.stopPropagation(); setPreviewOpen(false); }}\n onMouseDown={(e) => e.stopPropagation()}\n >\n <img\n src={screenshot}\n alt=\"Screenshot preview\"\n onClick={(e) => e.stopPropagation()}\n style={{\n maxWidth: \"100%\",\n maxHeight: \"calc(100vh - 80px)\",\n borderRadius: \"8px\",\n objectFit: \"contain\",\n cursor: \"default\",\n }}\n />\n <span\n style={{\n marginTop: \"12px\",\n color: t.textMuted,\n fontSize: \"12px\",\n }}\n >\n Click outside to close\n </span>\n </div>,\n document.body\n )}\n </>\n );\n}\n\n/* ─── Helpers ─── */\n\nfunction getTypeLabel(type: ReportType): string {\n switch (type) {\n case \"BUG\": return \"Bug Report\";\n case \"FEATURE_REQUEST\": return \"Feature Request\";\n case \"QUESTION\": return \"Question\";\n case \"OTHER\": return \"Other\";\n }\n}\n\nfunction getTypeSubtitle(type: ReportType): string {\n switch (type) {\n case \"BUG\": return \"Something isn't working\";\n case \"FEATURE_REQUEST\": return \"Suggest an improvement\";\n case \"QUESTION\": return \"Ask a question\";\n case \"OTHER\": return \"General feedback\";\n }\n}\n\nfunction getPlaceholder(type: ReportType): string {\n switch (type) {\n case \"BUG\": return \"What went wrong?\";\n case \"FEATURE_REQUEST\": return \"Describe the feature you'd like...\";\n case \"QUESTION\": return \"What would you like to know?\";\n case \"OTHER\": return \"Tell us what's on your mind...\";\n }\n}\n\nfunction getTypeIcon(type: ReportType, color: string, size = 24): ReactNode {\n const props = { width: size, height: size, viewBox: \"0 0 24 24\", fill: \"none\", style: { flexShrink: 0 } as CSSProperties };\n switch (type) {\n case \"BUG\":\n return <svg {...props}><path d=\"M8 2L6.5 3.5M16 2L17.5 3.5M3 9H7M17 9H21M12 2a5 5 0 015 5v4a5 5 0 01-10 0V7a5 5 0 015-5zM7 16l-2 3M17 16l2 3\" stroke={color} strokeWidth=\"1.5\" strokeLinecap=\"round\" /></svg>;\n case \"FEATURE_REQUEST\":\n return <svg {...props}><path d=\"M12 2L15.09 8.26L22 9.27L17 14.14L18.18 21.02L12 17.77L5.82 21.02L7 14.14L2 9.27L8.91 8.26L12 2z\" stroke={color} strokeWidth=\"1.5\" strokeLinejoin=\"round\" /></svg>;\n case \"QUESTION\":\n return <svg {...props}><circle cx=\"12\" cy=\"12\" r=\"10\" stroke={color} strokeWidth=\"1.5\" /><path d=\"M9.09 9a3 3 0 015.83 1c0 2-3 3-3 3M12 17h.01\" stroke={color} strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" /></svg>;\n case \"OTHER\":\n return <svg {...props}><path d=\"M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2v10z\" stroke={color} strokeWidth=\"1.5\" strokeLinejoin=\"round\" /></svg>;\n }\n}\n","\"use client\";\n\nimport { useState, type CSSProperties, type ReactNode } from \"react\";\nimport type { ReportButtonProps } from \"./types\";\nimport { useGlitchgrab } from \"./provider\";\n\n/** Safe version of useGlitchgrab that returns null when outside provider */\nfunction useGlitchgrabSafe() {\n try {\n return useGlitchgrab();\n } catch {\n return null;\n }\n}\n\n/**\n * Optional trigger button for opening the report dialog.\n *\n * The dialog itself lives inside `GlitchgrabProvider` — you don't need this component\n * unless you want a visible trigger button. You can also open the dialog programmatically\n * via `useGlitchgrab().openReportDialog()`.\n *\n * @example\n * ```tsx\n * // Use the default floating button\n * <ReportButton />\n *\n * // Use your own trigger\n * <ReportButton>\n * {({ onClick }) => <button onClick={onClick}>Report</button>}\n * </ReportButton>\n *\n * // Or skip ReportButton entirely and use the hook\n * const { openReportDialog } = useGlitchgrab();\n * <button onClick={() => openReportDialog()}>Report</button>\n * ```\n */\nexport function ReportButton({\n position = \"bottom-right\",\n label = \"Report Bug\",\n className,\n children,\n}: ReportButtonProps & {\n children?: (props: { onClick: () => void; capturing: boolean }) => ReactNode;\n}) {\n const [capturing, setCapturing] = useState(false);\n const glitchgrab = useGlitchgrabSafe();\n\n if (!glitchgrab) return null;\n\n const handleClick = async () => {\n setCapturing(true);\n glitchgrab.openReportDialog();\n setCapturing(false);\n };\n\n // Custom trigger via render prop\n if (children) {\n return <>{children({ onClick: handleClick, capturing })}</>;\n }\n\n // Default floating button\n const isTop = position?.startsWith(\"top\") ?? false;\n const isLeft = position?.endsWith(\"left\") ?? false;\n\n const positionStyles: CSSProperties = {\n ...(isLeft ? { left: \"16px\" } : { right: \"16px\" }),\n ...(isTop ? { top: \"16px\" } : { bottom: \"16px\" }),\n };\n\n return (\n <button\n type=\"button\"\n onClick={handleClick}\n disabled={capturing}\n className={className}\n style={{\n position: \"fixed\",\n ...positionStyles,\n zIndex: 99999,\n padding: \"10px 18px\",\n borderRadius: \"24px\",\n border: \"none\",\n backgroundColor: \"#18181b\",\n color: \"#fafafa\",\n fontSize: \"14px\",\n fontWeight: 500,\n fontFamily:\n '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n cursor: capturing ? \"wait\" : \"pointer\",\n boxShadow:\n \"0 4px 12px rgba(0, 0, 0, 0.15), 0 1px 3px rgba(0, 0, 0, 0.1)\",\n transition: \"transform 0.15s ease, box-shadow 0.15s ease\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"6px\",\n opacity: capturing ? 0.7 : 1,\n }}\n onMouseEnter={(e) => {\n (e.target as HTMLElement).style.transform = \"scale(1.05)\";\n }}\n onMouseLeave={(e) => {\n (e.target as HTMLElement).style.transform = \"scale(1)\";\n }}\n aria-label={label}\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n style={{ flexShrink: 0 }}\n >\n <path\n d=\"M8 1C4.134 1 1 4.134 1 8s3.134 7 7 7 7-3.134 7-7-3.134-7-7-7zm0 12.5a.75.75 0 110-1.5.75.75 0 010 1.5zm.75-3.5a.75.75 0 01-1.5 0V5a.75.75 0 011.5 0v5z\"\n fill=\"currentColor\"\n />\n </svg>\n {capturing ? \"Capturing...\" : label}\n </button>\n );\n}\n","\"use client\";\n\nimport { useState, useEffect, useCallback } from \"react\";\n\nexport interface GlitchgrabReport {\n id: string;\n source: string;\n status: string;\n rawInput: string | null;\n reporterPrimaryKey: string;\n reporterName: string;\n reporterEmail: string | null;\n reporterPhone: string | null;\n pageUrl: string | null;\n createdAt: string;\n /** Number of comments on the linked GitHub issue (0 if no issue) */\n commentCount: number;\n issue: {\n githubNumber: number;\n githubUrl: string;\n title: string;\n labels: string[];\n severity: string | null;\n githubState: string | null;\n } | null;\n}\n\nconst BASE_URL = \"https://www.glitchgrab.dev\";\n\n/**\n * Hook to fetch bug reports for a specific user.\n *\n * ```tsx\n * const { reports, isLoading, error, refetch } = useGlitchgrabReports({\n * token: process.env.NEXT_PUBLIC_GLITCHGRAB_TOKEN!,\n * userId: session.user.id,\n * });\n * ```\n */\nexport function useGlitchgrabReports({\n token,\n userId,\n limit = 100,\n}: {\n token: string;\n userId: string;\n /** Max results (default 100, max 100) */\n limit?: number;\n}): {\n reports: GlitchgrabReport[];\n isLoading: boolean;\n isFetching: boolean;\n error: string | null;\n refetch: () => Promise<void>;\n} {\n const [reports, setReports] = useState<GlitchgrabReport[]>([]);\n const [isLoading, setIsLoading] = useState(true);\n const [isFetching, setIsFetching] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const fetchReports = useCallback(async () => {\n if (!token || !userId) {\n setIsLoading(false);\n return;\n }\n\n setIsFetching(true);\n setError(null);\n\n try {\n const res = await fetch(\n `${BASE_URL}/api/v1/sdk/reports?reporterPrimaryKey=${encodeURIComponent(userId)}&limit=${limit}`,\n { headers: { Authorization: `Bearer ${token}` } }\n );\n const data = await res.json();\n\n if (data.success) {\n setReports(data.data ?? []);\n } else {\n setError(data.error ?? \"Failed to fetch reports\");\n }\n } catch {\n setError(\"Network error\");\n } finally {\n setIsLoading(false);\n setIsFetching(false);\n }\n }, [token, userId, limit]);\n\n useEffect(() => {\n fetchReports();\n }, [fetchReports]);\n\n return { reports, isLoading, isFetching, error, refetch: fetchReports };\n}\n\n/**\n * Standalone fetcher — use with TanStack Query or any data fetching library.\n *\n * ```tsx\n * const { data } = useQuery({\n * queryKey: [\"glitchgrab-reports\", userId],\n * queryFn: () => fetchGlitchgrabReports({\n * token: process.env.NEXT_PUBLIC_GLITCHGRAB_TOKEN!,\n * userId: session.user.id,\n * }),\n * });\n * ```\n */\nexport async function fetchGlitchgrabReports({\n token,\n userId,\n limit = 100,\n}: {\n token: string;\n userId: string;\n limit?: number;\n}): Promise<GlitchgrabReport[]> {\n const res = await fetch(\n `${BASE_URL}/api/v1/sdk/reports?reporterPrimaryKey=${encodeURIComponent(userId)}&limit=${limit}`,\n { headers: { Authorization: `Bearer ${token}` } }\n );\n const data = await res.json();\n if (!data.success) throw new Error(data.error ?? \"Failed to fetch reports\");\n return data.data ?? [];\n}\n\n// ─── Report Actions ─────────────────────────────────────\n\nasync function reportAction(\n token: string,\n reportId: string,\n body: Record<string, string>\n): Promise<void> {\n const res = await fetch(`${BASE_URL}/api/v1/reports/${reportId}/actions`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(body),\n });\n const data = await res.json().catch(() => ({}));\n if (!res.ok || !data.success) throw new Error(data.error ?? \"Action failed\");\n}\n\n/**\n * Hook to manage report actions with loading/error states.\n *\n * ```tsx\n * const { approve, reject, close, isPending, error } = useGlitchgrabActions({\n * token: process.env.NEXT_PUBLIC_GLITCHGRAB_TOKEN!,\n * onSuccess: () => refetch(),\n * onError: (err) => toast.error(err.message),\n * });\n *\n * <button onClick={() => approve(reportId)} disabled={isPending}>\n * {isPending ? \"...\" : \"Approve\"}\n * </button>\n * ```\n */\nexport function useGlitchgrabActions({\n token,\n onSuccess,\n onError,\n}: {\n token: string;\n onSuccess?: () => void;\n onError?: (error: Error) => void;\n}) {\n const [isPending, setIsPending] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const run = useCallback(\n async (reportId: string, body: Record<string, string>) => {\n setIsPending(true);\n setError(null);\n try {\n await reportAction(token, reportId, body);\n onSuccess?.();\n } catch (e) {\n const err = e instanceof Error ? e : new Error(\"Action failed\");\n setError(err.message);\n onError?.(err);\n } finally {\n setIsPending(false);\n }\n },\n [token, onSuccess, onError]\n );\n\n return {\n approve: (reportId: string) => run(reportId, { action: \"label\", label: \"approved\" }),\n reject: (reportId: string) => run(reportId, { action: \"label\", label: \"rejected\" }),\n close: (reportId: string) => run(reportId, { action: \"close\" }),\n reopen: (reportId: string) => run(reportId, { action: \"reopen\" }),\n label: (reportId: string, label: string) => run(reportId, { action: \"label\", label }),\n unlabel: (reportId: string, label: string) => run(reportId, { action: \"unlabel\", label }),\n isPending,\n error,\n };\n}\n"],"mappings":"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","names":["import_react","e","rgb","words","e","import_jsx_runtime","DEFAULT_BASE_URL","maxBreadcrumbs","addBreadcrumb","import_react","import_jsx_runtime","import_react"]}
|
package/dist/index.mjs
CHANGED
|
@@ -706,6 +706,7 @@ function ReportDialog({
|
|
|
706
706
|
position: "fixed",
|
|
707
707
|
inset: 0,
|
|
708
708
|
zIndex: 2147483647,
|
|
709
|
+
pointerEvents: "auto",
|
|
709
710
|
display: "flex",
|
|
710
711
|
alignItems: "center",
|
|
711
712
|
justifyContent: "center",
|
|
@@ -715,6 +716,8 @@ function ReportDialog({
|
|
|
715
716
|
onClick: () => {
|
|
716
717
|
if (!previewOpen) handleClose();
|
|
717
718
|
},
|
|
719
|
+
onPointerDown: (e) => e.stopPropagation(),
|
|
720
|
+
onFocus: (e) => e.stopPropagation(),
|
|
718
721
|
children: /* @__PURE__ */ jsxs(
|
|
719
722
|
"div",
|
|
720
723
|
{
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/provider.tsx","../src/error-boundary.tsx","../src/breadcrumbs.ts","../src/utils.ts","../src/dedup.ts","../src/report-dialog.tsx","../src/report-button.tsx","../src/use-reports.ts"],"sourcesContent":["\"use client\";\n\nimport {\n createContext,\n useContext,\n useRef,\n useEffect,\n useCallback,\n useState,\n} from \"react\";\nimport type {\n GlitchgrabProviderProps,\n UseGlitchgrabReturn,\n ReportPayload,\n ReportResult,\n ReportType,\n} from \"./types\";\nimport { GlitchgrabErrorBoundary } from \"./error-boundary\";\nimport { ReportDialog } from \"./report-dialog\";\nimport { sanitizeUrl, captureContext, sendReport, captureDeviceInfo } from \"./utils\";\nimport { computeSignature, shouldSkipDuplicate } from \"./dedup\";\nimport {\n initBreadcrumbs,\n addBreadcrumb as addBreadcrumbInternal,\n getBreadcrumbs,\n} from \"./breadcrumbs\";\n\nconst DEFAULT_BASE_URL = \"https://www.glitchgrab.dev\";\n\nconst GlitchgrabContext = createContext<UseGlitchgrabReturn | null>(null);\n\n/**\n * Hook to access Glitchgrab in your components.\n *\n * @example\n * ```tsx\n * const { reportBug, report, addBreadcrumb } = useGlitchgrab();\n *\n * // Report a bug\n * reportBug(\"Login button crashes on mobile\");\n *\n * // Report a feature request\n * report(\"FEATURE_REQUEST\", \"Add dark mode\");\n *\n * // Add a custom breadcrumb\n * addBreadcrumb(\"User clicked checkout\", { cartItems: \"3\" });\n * ```\n */\nexport function useGlitchgrab(): UseGlitchgrabReturn {\n const ctx = useContext(GlitchgrabContext);\n if (!ctx) {\n throw new Error(\"useGlitchgrab must be used within a GlitchgrabProvider\");\n }\n return ctx;\n}\n\nfunction GlitchgrabProviderInner({\n token,\n session,\n baseUrl,\n onError,\n onReportSent,\n breadcrumbs: enableBreadcrumbs = true,\n maxBreadcrumbs = 50,\n children,\n fallback,\n types,\n showSeverity,\n}: GlitchgrabProviderProps) {\n const visitedPagesRef = useRef<string[]>([]);\n\n // Initialize breadcrumbs\n useEffect(() => {\n if (enableBreadcrumbs) {\n initBreadcrumbs(maxBreadcrumbs);\n }\n }, [enableBreadcrumbs, maxBreadcrumbs]);\n\n // Track page visits\n useEffect(() => {\n try {\n if (typeof window === \"undefined\") return;\n\n const trackPage = () => {\n try {\n const sanitized = sanitizeUrl(window.location.href);\n const pages = visitedPagesRef.current;\n if (pages[pages.length - 1] !== sanitized) {\n pages.push(sanitized);\n if (pages.length > 20) {\n pages.splice(0, pages.length - 20);\n }\n }\n } catch {\n // Silently fail\n }\n };\n\n trackPage();\n const handlePopState = () => trackPage();\n window.addEventListener(\"popstate\", handlePopState);\n\n const origPushState = history.pushState.bind(history);\n const origReplaceState = history.replaceState.bind(history);\n\n history.pushState = function (...args) {\n origPushState(...args);\n trackPage();\n };\n history.replaceState = function (...args) {\n origReplaceState(...args);\n trackPage();\n };\n\n return () => {\n window.removeEventListener(\"popstate\", handlePopState);\n history.pushState = origPushState;\n history.replaceState = origReplaceState;\n };\n } catch {\n // Never crash\n }\n }, []);\n\n // Unhandled errors and rejections — skip in development\n useEffect(() => {\n try {\n if (typeof window === \"undefined\") return;\n if (process.env.NODE_ENV === \"development\") return;\n\n const handleError = (event: ErrorEvent) => {\n try {\n const context = captureContext(visitedPagesRef.current);\n const sig = computeSignature({\n errorMessage: event.message,\n pageUrl: context.url,\n errorStack: event.error?.stack,\n });\n if (shouldSkipDuplicate(sig)) return;\n const payload: ReportPayload = {\n token,\n source: \"SDK_AUTO\",\n type: \"BUG\",\n errorMessage: event.message,\n errorStack: event.error?.stack,\n pageUrl: context.url,\n userAgent: context.userAgent,\n breadcrumbs: context.breadcrumbs,\n deviceInfo: context.deviceInfo ?? undefined,\n metadata: {\n timestamp: context.timestamp,\n visitedPages: JSON.stringify(context.visitedPages),\n filename: event.filename ?? \"\",\n lineno: String(event.lineno ?? \"\"),\n colno: String(event.colno ?? \"\"),\n ...(session?.userId ? { sessionUserId: session.userId } : {}),\n ...(session?.name ? { sessionUserName: String(session.name) } : {}),\n ...(session?.email ? { sessionUserEmail: String(session.email) } : {}),\n ...(session?.phone ? { sessionUserPhone: String(session.phone) } : {}),\n },\n };\n sendReport(payload, baseUrl).then((result) => {\n if (result && onReportSent) onReportSent(result);\n });\n if (onError && event.error) onError(event.error);\n } catch {\n // Silently fail\n }\n };\n\n const handleRejection = (event: PromiseRejectionEvent) => {\n try {\n const context = captureContext(visitedPagesRef.current);\n const reason = event.reason;\n const errMsg = reason instanceof Error ? reason.message : String(reason);\n const errStack = reason instanceof Error ? reason.stack : undefined;\n const sig = computeSignature({\n errorMessage: errMsg,\n pageUrl: context.url,\n errorStack: errStack,\n });\n if (shouldSkipDuplicate(sig)) return;\n const payload: ReportPayload = {\n token,\n source: \"SDK_AUTO\",\n type: \"BUG\",\n errorMessage: errMsg,\n errorStack: errStack,\n pageUrl: context.url,\n userAgent: context.userAgent,\n breadcrumbs: context.breadcrumbs,\n deviceInfo: context.deviceInfo ?? undefined,\n metadata: {\n timestamp: context.timestamp,\n visitedPages: JSON.stringify(context.visitedPages),\n type: \"unhandledrejection\",\n ...(session?.userId ? { sessionUserId: session.userId } : {}),\n ...(session?.name ? { sessionUserName: String(session.name) } : {}),\n ...(session?.email ? { sessionUserEmail: String(session.email) } : {}),\n ...(session?.phone ? { sessionUserPhone: String(session.phone) } : {}),\n },\n };\n sendReport(payload, baseUrl).then((result) => {\n if (result && onReportSent) onReportSent(result);\n });\n if (onError && reason instanceof Error) onError(reason);\n } catch {\n // Silently fail\n }\n };\n\n window.addEventListener(\"error\", handleError);\n window.addEventListener(\"unhandledrejection\", handleRejection);\n\n return () => {\n window.removeEventListener(\"error\", handleError);\n window.removeEventListener(\"unhandledrejection\", handleRejection);\n };\n } catch {\n // Never crash\n }\n }, [token, baseUrl, onError, onReportSent, session]);\n\n const report = useCallback(\n async (\n type: ReportType,\n description: string,\n metadata?: Record<string, string>\n ): Promise<ReportResult | null> => {\n try {\n const context = captureContext(visitedPagesRef.current);\n const payload: ReportPayload = {\n token,\n source: \"SDK_USER_REPORT\",\n type,\n description,\n pageUrl: context.url,\n userAgent: context.userAgent,\n breadcrumbs: context.breadcrumbs,\n deviceInfo: context.deviceInfo ?? undefined,\n metadata: {\n timestamp: context.timestamp,\n visitedPages: JSON.stringify(context.visitedPages),\n ...(session?.userId ? { sessionUserId: session.userId } : {}),\n ...(session?.name ? { sessionUserName: String(session.name) } : {}),\n ...(session?.email ? { sessionUserEmail: String(session.email) } : {}),\n ...(session?.phone ? { sessionUserPhone: String(session.phone) } : {}),\n ...metadata,\n },\n };\n const result = await sendReport(payload, baseUrl);\n if (result && onReportSent) onReportSent(result);\n return result;\n } catch {\n return null;\n }\n },\n [token, baseUrl, onReportSent, session]\n );\n\n const reportBug = useCallback(\n (description: string, metadata?: Record<string, string>) =>\n report(\"BUG\", description, metadata),\n [report]\n );\n\n const addBreadcrumb = useCallback(\n (message: string, data?: Record<string, string>) => {\n addBreadcrumbInternal(\"custom\", message, data);\n },\n []\n );\n\n const openReportDialog = useCallback((options?: { description?: string; type?: ReportType }) => {\n if (typeof window !== \"undefined\") {\n window.dispatchEvent(new CustomEvent(\"glitchgrab:open-report\", { detail: options }));\n }\n }, []);\n\n // Global keyboard shortcut: Cmd+Shift+G (Mac) / Ctrl+Shift+G (Windows/Linux)\n useEffect(() => {\n try {\n if (typeof window === \"undefined\") return;\n const handleKeyDown = (e: KeyboardEvent) => {\n if ((e.metaKey || e.ctrlKey) && e.shiftKey && e.key.toLowerCase() === \"g\") {\n e.preventDefault();\n openReportDialog();\n }\n };\n window.addEventListener(\"keydown\", handleKeyDown);\n return () => window.removeEventListener(\"keydown\", handleKeyDown);\n } catch {\n // Never crash\n }\n }, [openReportDialog]);\n\n return (\n <GlitchgrabContext.Provider\n value={{\n token,\n baseUrl: baseUrl ?? DEFAULT_BASE_URL,\n reportBug,\n report,\n addBreadcrumb,\n openReportDialog,\n }}\n >\n <GlitchgrabErrorBoundary\n token={token}\n baseUrl={baseUrl}\n session={session}\n onError={onError}\n fallback={fallback}\n visitedPages={visitedPagesRef.current}\n >\n {children}\n </GlitchgrabErrorBoundary>\n <ReportDialog report={report} types={types} showSeverity={showSeverity} />\n </GlitchgrabContext.Provider>\n );\n}\n\nexport function GlitchgrabProvider(props: GlitchgrabProviderProps) {\n // No token = passthrough (SDK disabled)\n if (!props.token) return <>{props.children}</>;\n\n const resolvedProps = {\n ...props,\n baseUrl: props.baseUrl || DEFAULT_BASE_URL,\n };\n\n try {\n return <GlitchgrabProviderInner {...resolvedProps} />;\n } catch {\n return <>{props.children}</>;\n }\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport type { GlitchgrabSession, ReportPayload } from \"./types\";\nimport { captureContext, sendReport } from \"./utils\";\nimport { computeSignature, shouldSkipDuplicate } from \"./dedup\";\n\ninterface ErrorBoundaryProps {\n token: string;\n baseUrl?: string;\n session?: GlitchgrabSession | null;\n onError?: (error: Error) => void;\n fallback?: React.ReactNode;\n visitedPages: string[];\n children: React.ReactNode;\n}\n\ninterface ErrorBoundaryState {\n hasError: boolean;\n}\n\nexport class GlitchgrabErrorBoundary extends React.Component<\n ErrorBoundaryProps,\n ErrorBoundaryState\n> {\n constructor(props: ErrorBoundaryProps) {\n super(props);\n this.state = { hasError: false };\n }\n\n static getDerivedStateFromError(): ErrorBoundaryState {\n return { hasError: true };\n }\n\n componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void {\n try {\n const context = captureContext(this.props.visitedPages);\n\n const sig = computeSignature({\n errorMessage: error.message,\n pageUrl: context.url,\n errorStack: error.stack,\n });\n if (shouldSkipDuplicate(sig)) {\n if (this.props.onError) this.props.onError(error);\n return;\n }\n\n const session = this.props.session;\n const payload: ReportPayload = {\n token: this.props.token,\n source: \"SDK_AUTO\",\n type: \"BUG\",\n errorMessage: error.message,\n errorStack: error.stack,\n componentStack: errorInfo.componentStack ?? undefined,\n pageUrl: context.url,\n userAgent: context.userAgent,\n breadcrumbs: context.breadcrumbs,\n deviceInfo: context.deviceInfo ?? undefined,\n metadata: {\n timestamp: context.timestamp,\n visitedPages: JSON.stringify(context.visitedPages),\n ...(session?.userId ? { sessionUserId: session.userId } : {}),\n ...(session?.name ? { sessionUserName: String(session.name) } : {}),\n ...(session?.email ? { sessionUserEmail: String(session.email) } : {}),\n ...(session?.phone ? { sessionUserPhone: String(session.phone) } : {}),\n },\n };\n\n sendReport(payload, this.props.baseUrl);\n\n if (this.props.onError) {\n this.props.onError(error);\n }\n } catch {\n // Never crash the host app\n }\n }\n\n render(): React.ReactNode {\n if (this.state.hasError) {\n if (this.props.fallback) {\n return this.props.fallback;\n }\n\n // Re-render children — allows recovery from transient errors\n return this.props.children;\n }\n\n return this.props.children;\n }\n}\n","import type { Breadcrumb, BreadcrumbType } from \"./types\";\n\nconst MAX_DEFAULT = 50;\n\nlet breadcrumbs: Breadcrumb[] = [];\nlet maxBreadcrumbs = MAX_DEFAULT;\nlet initialized = false;\n\nexport function initBreadcrumbs(max?: number) {\n if (initialized) return;\n maxBreadcrumbs = max ?? MAX_DEFAULT;\n\n try {\n if (typeof window === \"undefined\") return;\n interceptConsole();\n interceptFetch();\n interceptNavigation();\n interceptClicks();\n initialized = true;\n } catch {\n // Never crash\n }\n}\n\nexport function addBreadcrumb(\n type: BreadcrumbType,\n message: string,\n data?: Record<string, string>\n) {\n try {\n breadcrumbs.push({\n type,\n message: message.slice(0, 200),\n timestamp: new Date().toISOString(),\n data,\n });\n if (breadcrumbs.length > maxBreadcrumbs) {\n breadcrumbs = breadcrumbs.slice(-maxBreadcrumbs);\n }\n } catch {\n // Never crash\n }\n}\n\nexport function getBreadcrumbs(): Breadcrumb[] {\n return [...breadcrumbs];\n}\n\nexport function clearBreadcrumbs() {\n breadcrumbs = [];\n}\n\n// ─── Console Interception ────────────────────────────────\n\nfunction interceptConsole() {\n const origLog = console.log;\n const origWarn = console.warn;\n const origError = console.error;\n\n console.log = function (...args: unknown[]) {\n addBreadcrumb(\"console\", `[log] ${argsToString(args)}`);\n origLog.apply(console, args);\n };\n\n console.warn = function (...args: unknown[]) {\n addBreadcrumb(\"console\", `[warn] ${argsToString(args)}`);\n origWarn.apply(console, args);\n };\n\n console.error = function (...args: unknown[]) {\n addBreadcrumb(\"console\", `[error] ${argsToString(args)}`);\n origError.apply(console, args);\n };\n}\n\nfunction argsToString(args: unknown[]): string {\n try {\n return args\n .map((a) => {\n if (typeof a === \"string\") return a;\n if (a instanceof Error) return a.message;\n try {\n return JSON.stringify(a);\n } catch {\n return String(a);\n }\n })\n .join(\" \")\n .slice(0, 200);\n } catch {\n return \"[unknown]\";\n }\n}\n\n// ─── Fetch Interception ──────────────────────────────────\n\nfunction interceptFetch() {\n const origFetch = window.fetch;\n\n window.fetch = async function (input, init) {\n const url =\n typeof input === \"string\"\n ? input\n : input instanceof URL\n ? input.toString()\n : input instanceof Request\n ? input.url\n : String(input);\n const method = init?.method ?? \"GET\";\n const start = Date.now();\n\n try {\n const response = await origFetch.apply(window, [input, init]);\n addBreadcrumb(\"api\", `${method} ${url.slice(0, 100)} → ${response.status}`, {\n method,\n status: String(response.status),\n duration: `${Date.now() - start}ms`,\n });\n return response;\n } catch (err) {\n addBreadcrumb(\"api\", `${method} ${url.slice(0, 100)} → FAILED`, {\n method,\n error: err instanceof Error ? err.message : \"unknown\",\n duration: `${Date.now() - start}ms`,\n });\n throw err;\n }\n };\n}\n\n// ─── Navigation Interception ─────────────────────────────\n\nfunction interceptNavigation() {\n const origPush = history.pushState.bind(history);\n const origReplace = history.replaceState.bind(history);\n\n history.pushState = function (...args) {\n origPush(...args);\n addBreadcrumb(\"navigation\", `Navigate to ${window.location.pathname}`);\n };\n\n history.replaceState = function (...args) {\n origReplace(...args);\n addBreadcrumb(\"navigation\", `Replace to ${window.location.pathname}`);\n };\n\n window.addEventListener(\"popstate\", () => {\n addBreadcrumb(\"navigation\", `Back/Forward to ${window.location.pathname}`);\n });\n}\n\n// ─── Click Interception ──────────────────────────────────\n\nfunction interceptClicks() {\n document.addEventListener(\n \"click\",\n (e) => {\n try {\n const target = e.target as HTMLElement;\n const tag = target.tagName?.toLowerCase();\n const text = target.textContent?.trim().slice(0, 50) ?? \"\";\n const id = target.id ? `#${target.id}` : \"\";\n const cls = target.className && typeof target.className === \"string\"\n ? `.${target.className.split(\" \")[0]}`\n : \"\";\n\n addBreadcrumb(\"click\", `Click ${tag}${id}${cls} \"${text}\"`);\n } catch {\n // Never crash\n }\n },\n { capture: true }\n );\n}\n","import type { ReportPayload, ReportResult, CapturedContext, DeviceInfo } from \"./types\";\nimport { getBreadcrumbs } from \"./breadcrumbs\";\n\nconst SENSITIVE_PARAMS = [\n \"token\", \"key\", \"secret\", \"password\", \"passwd\", \"auth\", \"authorization\",\n \"session\", \"sessionid\", \"session_id\", \"api_key\", \"apikey\", \"access_token\",\n \"refresh_token\", \"client_secret\", \"code\", \"state\", \"nonce\", \"credential\", \"private\",\n];\n\nexport function sanitizeUrl(url: string): string {\n try {\n const parsed = new URL(url);\n const params = new URLSearchParams(parsed.search);\n let modified = false;\n for (const key of Array.from(params.keys())) {\n if (SENSITIVE_PARAMS.some((s) => key.toLowerCase().includes(s))) {\n params.set(key, \"[REDACTED]\");\n modified = true;\n }\n }\n if (modified) parsed.search = params.toString();\n return parsed.toString();\n } catch {\n return url.split(\"?\")[0] ?? url;\n }\n}\n\nexport function captureDeviceInfo(): DeviceInfo | null {\n try {\n if (typeof window === \"undefined\") return null;\n return {\n screenWidth: screen.width,\n screenHeight: screen.height,\n viewportWidth: window.innerWidth,\n viewportHeight: window.innerHeight,\n platform: navigator.platform ?? \"unknown\",\n language: navigator.language ?? \"unknown\",\n online: navigator.onLine,\n colorScheme: window.matchMedia(\"(prefers-color-scheme: dark)\").matches ? \"dark\" : \"light\",\n devicePixelRatio: window.devicePixelRatio ?? 1,\n };\n } catch {\n return null;\n }\n}\n\nexport function captureContext(visitedPages: string[]): CapturedContext {\n try {\n return {\n url: sanitizeUrl(typeof window !== \"undefined\" ? window.location.href : \"\"),\n userAgent: typeof navigator !== \"undefined\" ? navigator.userAgent : \"\",\n timestamp: new Date().toISOString(),\n visitedPages: visitedPages.map(sanitizeUrl),\n breadcrumbs: getBreadcrumbs(),\n deviceInfo: captureDeviceInfo(),\n };\n } catch {\n return {\n url: \"\",\n userAgent: \"\",\n timestamp: new Date().toISOString(),\n visitedPages: [],\n breadcrumbs: [],\n deviceInfo: null,\n };\n }\n}\n\nconst DEFAULT_BASE_URL = \"https://www.glitchgrab.dev\";\nconst MAX_RETRIES = 3;\nconst RETRY_BASE_MS = 500;\n\n/**\n * Send a report and return the result.\n * Never throws — returns null on failure.\n */\nexport async function sendReport(\n payload: ReportPayload,\n baseUrl?: string\n): Promise<ReportResult | null> {\n try {\n const url = `${baseUrl ?? DEFAULT_BASE_URL}/api/v1/sdk/report`;\n const body = JSON.stringify(payload);\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${payload.token}`,\n };\n\n // keepalive has a 64KB body limit in browsers — skip it for large payloads (e.g., screenshots)\n const useKeepalive = body.length < 60_000;\n\n for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {\n try {\n const response = await fetch(url, {\n method: \"POST\",\n headers,\n body,\n ...(useKeepalive ? { keepalive: true } : {}),\n });\n\n if (response.ok) {\n const envelope = (await response.json()) as {\n success: boolean;\n data?: Omit<ReportResult, \"success\">;\n };\n return { success: envelope.success, ...(envelope.data ?? {}) };\n }\n\n if (response.status >= 400 && response.status < 500 && response.status !== 429) {\n return null;\n }\n } catch {\n // Will retry\n }\n\n if (attempt < MAX_RETRIES - 1) {\n await new Promise((resolve) =>\n setTimeout(resolve, RETRY_BASE_MS * Math.pow(2, attempt))\n );\n }\n }\n\n // Fallback: sendBeacon (fire-and-forget, no result)\n if (typeof navigator !== \"undefined\" && navigator.sendBeacon) {\n try {\n navigator.sendBeacon(url, new Blob([body], { type: \"application/json\" }));\n } catch {\n // Silently fail\n }\n }\n\n return null;\n } catch {\n return null;\n }\n}\n","const DEFAULT_WINDOW_MS = 5 * 60 * 1000;\nconst MAX_ENTRIES = 100;\n\nconst seen = new Map<string, number>();\n\nfunction hashString(input: string): string {\n let h1 = 0xdeadbeef ^ 0;\n let h2 = 0x41c6ce57 ^ 0;\n for (let i = 0; i < input.length; i++) {\n const ch = input.charCodeAt(i);\n h1 = Math.imul(h1 ^ ch, 2654435761);\n h2 = Math.imul(h2 ^ ch, 1597334677);\n }\n h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^ Math.imul(h2 ^ (h2 >>> 13), 3266489909);\n h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^ Math.imul(h1 ^ (h1 >>> 13), 3266489909);\n return (4294967296 * (2097151 & h2) + (h1 >>> 0)).toString(36);\n}\n\nfunction topStackFrame(stack: string | undefined): string {\n if (!stack) return \"\";\n const lines = stack.split(\"\\n\");\n for (const line of lines) {\n const t = line.trim();\n if (t.startsWith(\"at \") || t.includes(\"@\")) {\n return t;\n }\n }\n return \"\";\n}\n\nfunction stripUrlQuery(url: string | undefined): string {\n if (!url) return \"\";\n try {\n const u = new URL(url);\n return `${u.origin}${u.pathname}`;\n } catch {\n const q = url.indexOf(\"?\");\n return q === -1 ? url : url.slice(0, q);\n }\n}\n\nexport function computeSignature(params: {\n errorMessage: string | undefined;\n pageUrl: string | undefined;\n errorStack?: string | undefined;\n}): string {\n const msg = params.errorMessage?.trim() ?? \"\";\n const page = stripUrlQuery(params.pageUrl);\n const frame = topStackFrame(params.errorStack);\n return hashString(`${msg}|${page}|${frame}`);\n}\n\nexport function shouldSkipDuplicate(\n signature: string,\n windowMs: number = DEFAULT_WINDOW_MS,\n now: number = Date.now()\n): boolean {\n const last = seen.get(signature);\n if (last !== undefined && now - last < windowMs) {\n return true;\n }\n seen.set(signature, now);\n\n if (seen.size > MAX_ENTRIES) {\n const cutoff = now - windowMs;\n for (const [sig, ts] of seen) {\n if (ts < cutoff) seen.delete(sig);\n }\n if (seen.size > MAX_ENTRIES) {\n const excess = seen.size - MAX_ENTRIES;\n const keys = Array.from(seen.keys()).slice(0, excess);\n for (const k of keys) seen.delete(k);\n }\n }\n return false;\n}\n\nexport function clearDedupCache(): void {\n seen.clear();\n}\n","\"use client\";\n\nimport { useState, useRef, useEffect, type CSSProperties, type ReactNode } from \"react\";\n// @ts-expect-error react-dom types handled by host app\nimport { createPortal } from \"react-dom\";\nimport type { ReportType, ReportSeverity, UseGlitchgrabReturn } from \"./types\";\n\n/** Detect if the host page uses a dark or light theme */\nfunction useIsDark(): boolean {\n if (typeof window === \"undefined\") return true;\n try {\n // Check body then html — most sites set background on html, not body\n for (const el of [document.body, document.documentElement]) {\n const bg = getComputedStyle(el).backgroundColor;\n const match = bg.match(/rgba?\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)(?:\\s*,\\s*([\\d.]+))?\\s*\\)/);\n if (match) {\n const alpha = match[4] !== undefined ? parseFloat(match[4]) : 1;\n if (alpha < 0.05) continue; // transparent — skip to next element\n const [r, g, b] = [Number(match[1]), Number(match[2]), Number(match[3])];\n return (r * 299 + g * 587 + b * 114) / 1000 < 128;\n }\n }\n return window.matchMedia(\"(prefers-color-scheme: dark)\").matches;\n } catch {\n return true;\n }\n}\n\n/** Convert HSL values to a hex color string */\nfunction hslToHex(h: number, s: number, l: number): string {\n s /= 100;\n l /= 100;\n const a = s * Math.min(l, 1 - l);\n const f = (n: number) => {\n const k = (n + h / 30) % 12;\n const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);\n return Math.round(255 * color).toString(16).padStart(2, \"0\");\n };\n return `#${f(0)}${f(8)}${f(4)}`;\n}\n\n/** Parse a CSS color value into [r, g, b] or null */\nfunction parseColorToRgb(value: string): [number, number, number] | null {\n try {\n const trimmed = value.trim();\n\n // hex (#fff, #ffffff)\n const hexMatch = trimmed.match(/^#([0-9a-f]{3,8})$/i);\n if (hexMatch) {\n let hex = hexMatch[1];\n if (hex.length === 3) hex = hex[0]+hex[0]+hex[1]+hex[1]+hex[2]+hex[2];\n return [parseInt(hex.slice(0, 2), 16), parseInt(hex.slice(2, 4), 16), parseInt(hex.slice(4, 6), 16)];\n }\n\n // rgb(r, g, b) or rgba(r, g, b, a)\n const rgbMatch = trimmed.match(/rgba?\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)/);\n if (rgbMatch) return [Number(rgbMatch[1]), Number(rgbMatch[2]), Number(rgbMatch[3])];\n\n // hsl(h, s%, l%) or hsla(h, s%, l%, a)\n const hslMatch = trimmed.match(/hsla?\\(\\s*([\\d.]+)\\s*,\\s*([\\d.]+)%\\s*,\\s*([\\d.]+)%/);\n if (hslMatch) {\n const hex = hslToHex(Number(hslMatch[1]), Number(hslMatch[2]), Number(hslMatch[3]));\n return parseColorToRgb(hex);\n }\n\n return null;\n } catch {\n return null;\n }\n}\n\n/** Compute relative luminance and return ideal contrast text color */\nfunction getContrastText(r: number, g: number, b: number): string {\n const luminance = (r * 299 + g * 587 + b * 114) / 1000;\n return luminance > 150 ? \"#09090b\" : \"#ffffff\";\n}\n\n/**\n * Auto-detect the host app's primary/accent color from CSS custom properties.\n * Checks common variable names used by shadcn/ui, Radix, Tailwind, MUI, etc.\n * Returns { accent, accentText } or null if no theme detected.\n */\nfunction detectHostAccent(): { accent: string; accentText: string } | null {\n if (typeof window === \"undefined\") return null;\n try {\n const root = getComputedStyle(document.documentElement);\n\n // Common CSS variable names for primary/accent color\n const varNames = [\n \"--primary\",\n \"--accent\",\n \"--brand\",\n \"--color-primary\",\n \"--theme-primary\",\n \"--chakra-colors-primary-500\",\n \"--mui-palette-primary-main\",\n ];\n\n for (const name of varNames) {\n const raw = root.getPropertyValue(name).trim();\n if (!raw) continue;\n\n // shadcn/ui style: space-separated HSL values like \"243 75% 59%\"\n const hslSpaceMatch = raw.match(/^([\\d.]+)\\s+([\\d.]+)%\\s+([\\d.]+)%$/);\n if (hslSpaceMatch) {\n const hex = hslToHex(Number(hslSpaceMatch[1]), Number(hslSpaceMatch[2]), Number(hslSpaceMatch[3]));\n const rgb = parseColorToRgb(hex);\n return { accent: hex, accentText: rgb ? getContrastText(...rgb) : \"#ffffff\" };\n }\n\n // Standard color values (hex, rgb, hsl)\n const rgb = parseColorToRgb(raw);\n if (rgb) {\n const hex = `#${rgb.map((c) => c.toString(16).padStart(2, \"0\")).join(\"\")}`;\n return { accent: hex, accentText: getContrastText(...rgb) };\n }\n }\n\n return null;\n } catch {\n return null;\n }\n}\n\nfunction getTheme(dark: boolean) {\n const hostAccent = detectHostAccent();\n const defaults = dark\n ? { bg: \"#1c1c1e\", bgSecondary: \"#27272a\", border: \"#2c2c2e\", text: \"#fafafa\", textMuted: \"#a1a1aa\", accent: \"#22d3ee\", accentText: \"#09090b\", inputBg: \"#27272a\", inputBorder: \"#3f3f46\" }\n : { bg: \"#ffffff\", bgSecondary: \"#f4f4f5\", border: \"#e4e4e7\", text: \"#18181b\", textMuted: \"#71717a\", accent: \"#0891b2\", accentText: \"#ffffff\", inputBg: \"#fafafa\", inputBorder: \"#d4d4d8\" };\n\n if (hostAccent) {\n defaults.accent = hostAccent.accent;\n defaults.accentText = hostAccent.accentText;\n }\n\n return defaults;\n}\n\n/** Validate that report text is meaningful — rejects gibberish, throwaway words, random chars */\nfunction isLowQualityText(text: string): string | null {\n const trimmed = text.trim();\n if (!trimmed) return null;\n\n // Exact throwaway words\n const throwaway =\n /^(done|ok|yes|no|hi|hello|hey|test|testing|asdf|qwerty|abc|xyz|foo|bar|baz|lol|lmao|idk|bruh|nice|cool|wow|sup|yo|nah|yep|nope|thanks|thx|ty|k|kk|hmm|hm|na|mm|mhm|aight|bet|gg|wp|rip|omg|pls|plz)$/i;\n if (throwaway.test(trimmed)) {\n return \"Please describe the actual issue you're experiencing\";\n }\n\n // Repeated characters (aaaaaaa, !!!!!!!)\n if (/(.)\\1{4,}/.test(trimmed)) {\n return \"Please provide a meaningful description\";\n }\n\n const letters = trimmed.replace(/[^a-zA-Z]/g, \"\");\n if (letters.length >= 4) {\n // Very low vowel ratio (bkdfghjklmn...)\n const vowels = letters.replace(/[^aeiouAEIOU]/g, \"\").length;\n const vowelRatio = vowels / letters.length;\n if (vowelRatio < 0.08) {\n return \"That doesn't look like a valid description\";\n }\n\n // Keyboard mashing: single word with no real English pattern\n // Detects strings like \"asdfasfsdad\", \"jkljklfsdf\", \"qwertyuio\"\n // Real words have max 3-4 consecutive consonants; gibberish has long runs\n if (/[^aeiou\\s]{5,}/i.test(letters)) {\n const words = trimmed.split(/\\s+/);\n // Only flag if it's a single \"word\" — multi-word text is likely real\n if (words.length <= 2) {\n return \"That doesn't look like a valid description\";\n }\n }\n\n // Check if it looks like a random permutation of a few chars (asdfasfsdad)\n if (letters.length >= 6) {\n const uniqueChars = new Set(letters.toLowerCase()).size;\n const uniqueRatio = uniqueChars / letters.length;\n // Real English has ~0.6-0.9 unique ratio for short text; gibberish reuses few chars\n if (uniqueRatio < 0.4 && trimmed.split(/\\s+/).length <= 2) {\n return \"That doesn't look like a valid description\";\n }\n }\n }\n\n // Single short word that isn't a known tech term\n const words = trimmed.split(/\\s+/).filter((w) => w.length > 0);\n if (words.length === 1 && trimmed.length < 10) {\n const techTerms =\n /^(crash|error|bug|fail|broken|slow|freeze|lag|404|500|null|undefined|nan|timeout|overflow|leak|cors|oom)$/i;\n if (!techTerms.test(trimmed)) {\n return \"Please provide more detail about the issue\";\n }\n }\n\n return null;\n}\n\ninterface ReportDialogProps {\n report: UseGlitchgrabReturn[\"report\"];\n types?: ReportType[];\n showSeverity?: boolean;\n}\n\n/**\n * The report dialog — rendered inside GlitchgrabProvider automatically.\n * Opens via the `glitchgrab:open-report` custom event (triggered by `openReportDialog()`).\n */\nexport function ReportDialog({\n report,\n types,\n showSeverity = true,\n}: ReportDialogProps) {\n // Prevent hydration mismatch — render nothing until after hydration\n const [mounted, setMounted] = useState(false);\n useEffect(() => { setMounted(true); }, []);\n\n const [isOpen, setIsOpen] = useState(false);\n const [description, setDescription] = useState(\"\");\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [submitted, setSubmitted] = useState(false);\n const [screenshot, setScreenshot] = useState<string | null>(null);\n const [previewOpen, setPreviewOpen] = useState(false);\n const fileInputRef = useRef<HTMLInputElement>(null);\n const modalRef = useRef<HTMLDivElement>(null);\n\n // Stepper state\n const [step, setStep] = useState(1);\n const [reportType, setReportType] = useState<ReportType>(\"BUG\");\n const [severity, setSeverity] = useState<ReportSeverity>(\"medium\");\n const [validationError, setValidationError] = useState<string | null>(null);\n\n const availableTypes: ReportType[] = types ?? [\"BUG\", \"FEATURE_REQUEST\", \"QUESTION\", \"OTHER\"];\n\n const isDark = useIsDark();\n const t = getTheme(isDark);\n\n const handleFileUpload = (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (!file) return;\n const reader = new FileReader();\n reader.onload = () => {\n setScreenshot(reader.result as string);\n };\n reader.readAsDataURL(file);\n e.target.value = \"\";\n };\n\n const retakeScreenshot = async () => {\n setPreviewOpen(false);\n setIsOpen(false);\n setScreenshot(null);\n await new Promise((r) => setTimeout(r, 300));\n try {\n const { default: html2canvas } = await import(\"html2canvas-pro\");\n const canvas = await html2canvas(document.body, {\n scale: 0.5,\n logging: false,\n useCORS: true,\n allowTaint: true,\n });\n setScreenshot(canvas.toDataURL(\"image/jpeg\", 0.6));\n } catch {\n // silently fail\n }\n setIsOpen(true);\n };\n\n const handleOpen = async () => {\n setSubmitted(false);\n if (availableTypes.length === 1) {\n setReportType(availableTypes[0]);\n setStep(2);\n }\n try {\n const { default: html2canvas } = await import(\"html2canvas-pro\");\n const canvas = await html2canvas(document.body, {\n scale: 0.5,\n logging: false,\n useCORS: true,\n allowTaint: true,\n });\n setScreenshot(canvas.toDataURL(\"image/jpeg\", 0.6));\n } catch {\n // screenshot failed — open without it\n }\n setIsOpen(true);\n };\n\n // Listen for programmatic open via openReportDialog()\n useEffect(() => {\n const handler = (e: Event) => {\n if (isOpen) return;\n const detail = (e as CustomEvent).detail;\n if (detail?.description) setDescription(detail.description);\n if (detail?.type) {\n setReportType(detail.type);\n setStep(2);\n }\n handleOpen();\n };\n window.addEventListener(\"glitchgrab:open-report\", handler);\n return () => window.removeEventListener(\"glitchgrab:open-report\", handler);\n }, [isOpen, handleOpen]);\n\n // Close on Escape\n useEffect(() => {\n if (!isOpen) return;\n const handleEsc = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n if (previewOpen) setPreviewOpen(false);\n else handleClose();\n }\n };\n document.addEventListener(\"keydown\", handleEsc);\n return () => document.removeEventListener(\"keydown\", handleEsc);\n }, [isOpen, previewOpen]);\n\n // Paste image from clipboard (Cmd+V / Ctrl+V) when dialog is open\n useEffect(() => {\n if (!isOpen) return;\n const handlePaste = (e: ClipboardEvent) => {\n try {\n const items = e.clipboardData?.items;\n if (!items) return;\n for (let i = 0; i < items.length; i++) {\n if (items[i].type.startsWith(\"image/\")) {\n const file = items[i].getAsFile();\n if (!file) continue;\n const reader = new FileReader();\n reader.onload = () => setScreenshot(reader.result as string);\n reader.readAsDataURL(file);\n e.preventDefault();\n break;\n }\n }\n } catch {\n // silently fail\n }\n };\n window.addEventListener(\"paste\", handlePaste);\n return () => window.removeEventListener(\"paste\", handlePaste);\n }, [isOpen]);\n\n const handleClose = () => {\n setIsOpen(false);\n setStep(1);\n setReportType(\"BUG\");\n setSeverity(\"medium\");\n setValidationError(null);\n };\n\n const handleSubmit = async () => {\n try {\n if (!description.trim() || isSubmitting) return;\n\n const qualityError = isLowQualityText(description);\n if (qualityError) {\n setValidationError(qualityError);\n setStep(2);\n return;\n }\n\n setIsSubmitting(true);\n const metadata: Record<string, string> = {};\n if (screenshot) metadata.screenshot = screenshot;\n if (showSeverity && reportType === \"BUG\") {\n metadata.severity = severity;\n }\n\n const result = await report(reportType, description.trim(), Object.keys(metadata).length > 0 ? metadata : undefined);\n\n if (result) {\n setSubmitted(true);\n setDescription(\"\");\n setScreenshot(null);\n\n setTimeout(() => {\n setSubmitted(false);\n handleClose();\n }, 2000);\n }\n setIsSubmitting(false);\n } catch {\n setIsSubmitting(false);\n }\n };\n\n if (!mounted) return null;\n\n return (\n <>\n {/* Report modal */}\n {isOpen && createPortal(\n <div\n style={{\n position: \"fixed\",\n inset: 0,\n zIndex: 2147483647,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: \"rgba(0,0,0,0.5)\",\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n }}\n onClick={() => { if (!previewOpen) handleClose(); }}\n >\n <div\n ref={modalRef}\n onClick={(e) => e.stopPropagation()}\n style={{\n position: \"relative\",\n zIndex: 2147483647,\n width: \"340px\",\n maxWidth: \"calc(100% - 32px)\",\n backgroundColor: t.bg,\n borderRadius: \"12px\",\n boxShadow:\n \"0 20px 60px rgba(0, 0, 0, 0.2), 0 4px 16px rgba(0, 0, 0, 0.1)\",\n fontFamily:\n '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n overflow: \"hidden\",\n color: t.text,\n isolation: \"isolate\",\n }}\n >\n {/* Header */}\n <div\n style={{\n padding: \"16px 16px 12px\",\n borderBottom: `1px solid ${t.border}`,\n }}\n >\n <div\n style={{\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n }}\n >\n <div style={{ display: \"flex\", alignItems: \"center\", gap: \"8px\" }}>\n {step > 1 && (\n <button\n type=\"button\"\n onClick={() => setStep((s) => (s - 1) as 1 | 2 | 3)}\n style={{\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n padding: \"2px\",\n display: \"flex\",\n alignItems: \"center\",\n }}\n aria-label=\"Back\"\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path d=\"M10 3L5 8L10 13\" stroke={t.textMuted} strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </button>\n )}\n <span\n style={{\n fontSize: \"15px\",\n fontWeight: 600,\n color: t.text,\n }}\n >\n {step === 1 ? \"What's on your mind?\" : step === 2 ? \"Tell us more\" : \"Review & Send\"}\n </span>\n </div>\n <button\n type=\"button\"\n onClick={handleClose}\n style={{\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n padding: \"4px\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n aria-label=\"Close\"\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" style={{ display: \"block\" }}>\n <path d=\"M4 4L12 12M12 4L4 12\" stroke={t.textMuted} strokeWidth=\"2\" strokeLinecap=\"round\" />\n </svg>\n </button>\n </div>\n <div style={{ display: \"flex\", alignItems: \"center\", justifyContent: \"center\", gap: \"0\", marginTop: \"12px\" }}>\n {[1, 2, 3].map((s, i) => (\n <div key={s} style={{ display: \"flex\", alignItems: \"center\" }}>\n <div style={{\n width: \"8px\",\n height: \"8px\",\n borderRadius: \"50%\",\n backgroundColor: s <= step ? t.accent : t.inputBorder,\n transition: \"background-color 0.2s ease\",\n }} />\n {i < 2 && (\n <div style={{\n width: \"40px\",\n height: \"2px\",\n backgroundColor: s < step ? t.accent : t.inputBorder,\n transition: \"background-color 0.2s ease\",\n }} />\n )}\n </div>\n ))}\n </div>\n </div>\n\n {/* Body */}\n <div style={{ padding: \"16px\" }}>\n {submitted ? (\n <div\n style={{\n textAlign: \"center\",\n padding: \"20px 0\",\n color: t.accent,\n fontSize: \"14px\",\n fontWeight: 500,\n }}\n >\n {getTypeLabel(reportType)} sent. Thank you!\n </div>\n ) : (\n <>\n {/* Step 1: Category */}\n {step === 1 && (\n <div style={{ display: \"grid\", gridTemplateColumns: \"1fr 1fr\", gap: \"8px\" }}>\n {availableTypes.map((type) => (\n <button\n key={type}\n type=\"button\"\n onClick={() => {\n setReportType(type);\n setStep(2);\n }}\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: \"8px\",\n padding: \"16px 8px\",\n borderRadius: \"8px\",\n border: `1px solid ${t.inputBorder}`,\n background: t.inputBg,\n cursor: \"pointer\",\n color: t.text,\n fontFamily: \"inherit\",\n transition: \"border-color 0.15s ease\",\n }}\n onMouseEnter={(e) => { (e.currentTarget as HTMLElement).style.borderColor = t.accent; }}\n onMouseLeave={(e) => { (e.currentTarget as HTMLElement).style.borderColor = t.inputBorder; }}\n >\n {getTypeIcon(type, t.accent)}\n <span style={{ fontSize: \"13px\", fontWeight: 600 }}>{getTypeLabel(type)}</span>\n <span style={{ fontSize: \"11px\", color: t.textMuted, lineHeight: \"1.3\" }}>{getTypeSubtitle(type)}</span>\n </button>\n ))}\n </div>\n )}\n\n {/* Step 2: Details */}\n {step === 2 && (\n <>\n <textarea\n value={description}\n onChange={(e) => { setDescription(e.target.value); if (validationError) setValidationError(null); }}\n placeholder={getPlaceholder(reportType)}\n style={{\n width: \"100%\",\n minHeight: \"100px\",\n padding: \"10px 12px\",\n borderRadius: \"8px\",\n border: `1px solid ${t.inputBorder}`,\n fontSize: \"14px\",\n fontFamily: \"inherit\",\n resize: \"vertical\",\n outline: \"none\",\n boxSizing: \"border-box\",\n color: t.text,\n backgroundColor: t.inputBg,\n }}\n onFocus={(e) => { (e.target as HTMLTextAreaElement).style.borderColor = t.accent; }}\n onBlur={(e) => { (e.target as HTMLTextAreaElement).style.borderColor = t.inputBorder; }}\n autoFocus\n />\n {showSeverity && reportType === \"BUG\" && (\n <div style={{ marginTop: \"10px\" }}>\n <span style={{ fontSize: \"12px\", color: t.textMuted, marginBottom: \"6px\", display: \"block\" }}>Severity</span>\n <div style={{ display: \"flex\", gap: \"6px\" }}>\n {([\"low\", \"medium\", \"high\"] as ReportSeverity[]).map((s) => (\n <button\n key={s}\n type=\"button\"\n onClick={() => setSeverity(s)}\n style={{\n flex: 1,\n padding: \"6px 0\",\n borderRadius: \"6px\",\n border: `1px solid ${severity === s ? t.accent : t.inputBorder}`,\n background: severity === s ? t.accent : \"transparent\",\n color: severity === s ? t.accentText : t.text,\n fontSize: \"12px\",\n fontWeight: 600,\n cursor: \"pointer\",\n fontFamily: \"inherit\",\n textTransform: \"capitalize\",\n transition: \"all 0.15s ease\",\n }}\n >\n {s}\n </button>\n ))}\n </div>\n </div>\n )}\n {validationError && (\n <p style={{ color: \"#ef4444\", fontSize: \"12px\", marginTop: \"6px\" }}>\n {validationError}\n </p>\n )}\n <button\n type=\"button\"\n onClick={() => {\n const err = isLowQualityText(description);\n if (err) { setValidationError(err); return; }\n setValidationError(null);\n setStep(3);\n }}\n disabled={!description.trim()}\n style={{\n marginTop: \"12px\",\n width: \"100%\",\n padding: \"10px\",\n borderRadius: \"8px\",\n border: \"none\",\n backgroundColor: !description.trim() ? t.bgSecondary : t.accent,\n color: !description.trim() ? t.textMuted : t.accentText,\n fontSize: \"14px\",\n fontWeight: 600,\n cursor: !description.trim() ? \"not-allowed\" : \"pointer\",\n fontFamily: \"inherit\",\n transition: \"background-color 0.15s ease\",\n }}\n >\n Next\n </button>\n </>\n )}\n\n {/* Step 3: Review & Send */}\n {step === 3 && (\n <>\n {/* Summary chips */}\n <div style={{ display: \"flex\", gap: \"6px\", flexWrap: \"wrap\", marginBottom: \"12px\" }}>\n <span style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: \"4px\",\n padding: \"4px 10px\",\n borderRadius: \"12px\",\n fontSize: \"12px\",\n fontWeight: 600,\n backgroundColor: t.bgSecondary,\n color: t.text,\n border: `1px solid ${t.border}`,\n }}>\n {getTypeIcon(reportType, t.accent, 12)}\n {getTypeLabel(reportType)}\n </span>\n {showSeverity && reportType === \"BUG\" && (\n <span style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n padding: \"4px 10px\",\n borderRadius: \"12px\",\n fontSize: \"12px\",\n fontWeight: 600,\n backgroundColor: severity === \"high\" ? \"#fef2f2\" : severity === \"medium\" ? \"#fffbeb\" : \"#f0fdf4\",\n color: severity === \"high\" ? \"#dc2626\" : severity === \"medium\" ? \"#d97706\" : \"#16a34a\",\n border: `1px solid ${severity === \"high\" ? \"#fecaca\" : severity === \"medium\" ? \"#fde68a\" : \"#bbf7d0\"}`,\n textTransform: \"capitalize\",\n }}>\n {severity}\n </span>\n )}\n </div>\n\n {/* Description preview */}\n <div style={{\n padding: \"10px 12px\",\n borderRadius: \"8px\",\n border: `1px solid ${t.inputBorder}`,\n backgroundColor: t.inputBg,\n fontSize: \"13px\",\n color: t.text,\n marginBottom: \"10px\",\n maxHeight: \"80px\",\n overflow: \"hidden\",\n lineHeight: \"1.4\",\n }}>\n {description.length > 200 ? description.slice(0, 200) + \"...\" : description}\n </div>\n\n {/* Screenshot */}\n {screenshot && (\n <div style={{ marginBottom: \"10px\", position: \"relative\" }}>\n <img\n src={screenshot}\n alt=\"Page screenshot\"\n onClick={() => setPreviewOpen(true)}\n style={{\n width: \"100%\",\n borderRadius: \"6px\",\n border: `1px solid ${t.border}`,\n maxHeight: \"80px\",\n objectFit: \"cover\",\n objectPosition: \"top\",\n cursor: \"pointer\",\n }}\n />\n <button\n type=\"button\"\n onClick={() => setScreenshot(null)}\n style={{\n position: \"absolute\",\n top: \"4px\",\n right: \"4px\",\n background: \"rgba(0,0,0,0.6)\",\n border: \"none\",\n borderRadius: \"50%\",\n width: \"20px\",\n height: \"20px\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n aria-label=\"Remove screenshot\"\n >\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"none\">\n <path d=\"M1 1L9 9M9 1L1 9\" stroke=\"#fff\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n </button>\n </div>\n )}\n {!screenshot && (\n <div style={{ display: \"flex\", gap: \"6px\", marginBottom: \"10px\" }}>\n <button\n type=\"button\"\n onClick={() => fileInputRef.current?.click()}\n style={{\n flex: 1,\n padding: \"8px\",\n borderRadius: \"6px\",\n border: `1px dashed ${t.inputBorder}`,\n textAlign: \"center\",\n fontSize: \"11px\",\n color: t.textMuted,\n background: \"none\",\n cursor: \"pointer\",\n }}\n >\n Upload or paste (⌘V)\n </button>\n <button\n type=\"button\"\n onClick={retakeScreenshot}\n style={{\n flex: 1,\n padding: \"8px\",\n borderRadius: \"6px\",\n border: `1px dashed ${t.inputBorder}`,\n textAlign: \"center\",\n fontSize: \"11px\",\n color: t.textMuted,\n background: \"none\",\n cursor: \"pointer\",\n }}\n >\n Retake screenshot\n </button>\n </div>\n )}\n\n <button\n type=\"button\"\n onClick={handleSubmit}\n disabled={isSubmitting}\n style={{\n width: \"100%\",\n padding: \"10px\",\n borderRadius: \"8px\",\n border: \"none\",\n backgroundColor: isSubmitting ? t.bgSecondary : t.accent,\n color: isSubmitting ? t.textMuted : t.accentText,\n fontSize: \"14px\",\n fontWeight: 600,\n cursor: isSubmitting ? \"not-allowed\" : \"pointer\",\n fontFamily: \"inherit\",\n transition: \"background-color 0.15s ease\",\n }}\n >\n {isSubmitting ? \"Sending...\" : \"Send Report\"}\n </button>\n </>\n )}\n </>\n )}\n </div>\n\n {/* Footer */}\n <div\n style={{\n padding: \"8px 16px 10px\",\n borderTop: `1px solid ${t.border}`,\n textAlign: \"center\",\n }}\n >\n <span style={{ fontSize: \"11px\", color: t.textMuted }}>\n Powered by Glitchgrab\n </span>\n </div>\n </div>\n </div>,\n document.body\n )}\n\n {/* Hidden file input */}\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\"image/*\"\n onChange={handleFileUpload}\n style={{ display: \"none\" }}\n />\n\n {/* Full-screen screenshot preview */}\n {previewOpen && screenshot && createPortal(\n <div\n style={{\n position: \"fixed\",\n inset: 0,\n zIndex: 2147483647,\n backgroundColor: \"rgba(0,0,0,0.85)\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: \"16px\",\n cursor: \"pointer\",\n }}\n onClick={(e) => { e.stopPropagation(); setPreviewOpen(false); }}\n onMouseDown={(e) => e.stopPropagation()}\n >\n <img\n src={screenshot}\n alt=\"Screenshot preview\"\n onClick={(e) => e.stopPropagation()}\n style={{\n maxWidth: \"100%\",\n maxHeight: \"calc(100vh - 80px)\",\n borderRadius: \"8px\",\n objectFit: \"contain\",\n cursor: \"default\",\n }}\n />\n <span\n style={{\n marginTop: \"12px\",\n color: t.textMuted,\n fontSize: \"12px\",\n }}\n >\n Click outside to close\n </span>\n </div>,\n document.body\n )}\n </>\n );\n}\n\n/* ─── Helpers ─── */\n\nfunction getTypeLabel(type: ReportType): string {\n switch (type) {\n case \"BUG\": return \"Bug Report\";\n case \"FEATURE_REQUEST\": return \"Feature Request\";\n case \"QUESTION\": return \"Question\";\n case \"OTHER\": return \"Other\";\n }\n}\n\nfunction getTypeSubtitle(type: ReportType): string {\n switch (type) {\n case \"BUG\": return \"Something isn't working\";\n case \"FEATURE_REQUEST\": return \"Suggest an improvement\";\n case \"QUESTION\": return \"Ask a question\";\n case \"OTHER\": return \"General feedback\";\n }\n}\n\nfunction getPlaceholder(type: ReportType): string {\n switch (type) {\n case \"BUG\": return \"What went wrong?\";\n case \"FEATURE_REQUEST\": return \"Describe the feature you'd like...\";\n case \"QUESTION\": return \"What would you like to know?\";\n case \"OTHER\": return \"Tell us what's on your mind...\";\n }\n}\n\nfunction getTypeIcon(type: ReportType, color: string, size = 24): ReactNode {\n const props = { width: size, height: size, viewBox: \"0 0 24 24\", fill: \"none\", style: { flexShrink: 0 } as CSSProperties };\n switch (type) {\n case \"BUG\":\n return <svg {...props}><path d=\"M8 2L6.5 3.5M16 2L17.5 3.5M3 9H7M17 9H21M12 2a5 5 0 015 5v4a5 5 0 01-10 0V7a5 5 0 015-5zM7 16l-2 3M17 16l2 3\" stroke={color} strokeWidth=\"1.5\" strokeLinecap=\"round\" /></svg>;\n case \"FEATURE_REQUEST\":\n return <svg {...props}><path d=\"M12 2L15.09 8.26L22 9.27L17 14.14L18.18 21.02L12 17.77L5.82 21.02L7 14.14L2 9.27L8.91 8.26L12 2z\" stroke={color} strokeWidth=\"1.5\" strokeLinejoin=\"round\" /></svg>;\n case \"QUESTION\":\n return <svg {...props}><circle cx=\"12\" cy=\"12\" r=\"10\" stroke={color} strokeWidth=\"1.5\" /><path d=\"M9.09 9a3 3 0 015.83 1c0 2-3 3-3 3M12 17h.01\" stroke={color} strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" /></svg>;\n case \"OTHER\":\n return <svg {...props}><path d=\"M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2v10z\" stroke={color} strokeWidth=\"1.5\" strokeLinejoin=\"round\" /></svg>;\n }\n}\n","\"use client\";\n\nimport { useState, type CSSProperties, type ReactNode } from \"react\";\nimport type { ReportButtonProps } from \"./types\";\nimport { useGlitchgrab } from \"./provider\";\n\n/** Safe version of useGlitchgrab that returns null when outside provider */\nfunction useGlitchgrabSafe() {\n try {\n return useGlitchgrab();\n } catch {\n return null;\n }\n}\n\n/**\n * Optional trigger button for opening the report dialog.\n *\n * The dialog itself lives inside `GlitchgrabProvider` — you don't need this component\n * unless you want a visible trigger button. You can also open the dialog programmatically\n * via `useGlitchgrab().openReportDialog()`.\n *\n * @example\n * ```tsx\n * // Use the default floating button\n * <ReportButton />\n *\n * // Use your own trigger\n * <ReportButton>\n * {({ onClick }) => <button onClick={onClick}>Report</button>}\n * </ReportButton>\n *\n * // Or skip ReportButton entirely and use the hook\n * const { openReportDialog } = useGlitchgrab();\n * <button onClick={() => openReportDialog()}>Report</button>\n * ```\n */\nexport function ReportButton({\n position = \"bottom-right\",\n label = \"Report Bug\",\n className,\n children,\n}: ReportButtonProps & {\n children?: (props: { onClick: () => void; capturing: boolean }) => ReactNode;\n}) {\n const [capturing, setCapturing] = useState(false);\n const glitchgrab = useGlitchgrabSafe();\n\n if (!glitchgrab) return null;\n\n const handleClick = async () => {\n setCapturing(true);\n glitchgrab.openReportDialog();\n setCapturing(false);\n };\n\n // Custom trigger via render prop\n if (children) {\n return <>{children({ onClick: handleClick, capturing })}</>;\n }\n\n // Default floating button\n const isTop = position?.startsWith(\"top\") ?? false;\n const isLeft = position?.endsWith(\"left\") ?? false;\n\n const positionStyles: CSSProperties = {\n ...(isLeft ? { left: \"16px\" } : { right: \"16px\" }),\n ...(isTop ? { top: \"16px\" } : { bottom: \"16px\" }),\n };\n\n return (\n <button\n type=\"button\"\n onClick={handleClick}\n disabled={capturing}\n className={className}\n style={{\n position: \"fixed\",\n ...positionStyles,\n zIndex: 99999,\n padding: \"10px 18px\",\n borderRadius: \"24px\",\n border: \"none\",\n backgroundColor: \"#18181b\",\n color: \"#fafafa\",\n fontSize: \"14px\",\n fontWeight: 500,\n fontFamily:\n '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n cursor: capturing ? \"wait\" : \"pointer\",\n boxShadow:\n \"0 4px 12px rgba(0, 0, 0, 0.15), 0 1px 3px rgba(0, 0, 0, 0.1)\",\n transition: \"transform 0.15s ease, box-shadow 0.15s ease\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"6px\",\n opacity: capturing ? 0.7 : 1,\n }}\n onMouseEnter={(e) => {\n (e.target as HTMLElement).style.transform = \"scale(1.05)\";\n }}\n onMouseLeave={(e) => {\n (e.target as HTMLElement).style.transform = \"scale(1)\";\n }}\n aria-label={label}\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n style={{ flexShrink: 0 }}\n >\n <path\n d=\"M8 1C4.134 1 1 4.134 1 8s3.134 7 7 7 7-3.134 7-7-3.134-7-7-7zm0 12.5a.75.75 0 110-1.5.75.75 0 010 1.5zm.75-3.5a.75.75 0 01-1.5 0V5a.75.75 0 011.5 0v5z\"\n fill=\"currentColor\"\n />\n </svg>\n {capturing ? \"Capturing...\" : label}\n </button>\n );\n}\n","\"use client\";\n\nimport { useState, useEffect, useCallback } from \"react\";\n\nexport interface GlitchgrabReport {\n id: string;\n source: string;\n status: string;\n rawInput: string | null;\n reporterPrimaryKey: string;\n reporterName: string;\n reporterEmail: string | null;\n reporterPhone: string | null;\n pageUrl: string | null;\n createdAt: string;\n /** Number of comments on the linked GitHub issue (0 if no issue) */\n commentCount: number;\n issue: {\n githubNumber: number;\n githubUrl: string;\n title: string;\n labels: string[];\n severity: string | null;\n githubState: string | null;\n } | null;\n}\n\nconst BASE_URL = \"https://www.glitchgrab.dev\";\n\n/**\n * Hook to fetch bug reports for a specific user.\n *\n * ```tsx\n * const { reports, isLoading, error, refetch } = useGlitchgrabReports({\n * token: process.env.NEXT_PUBLIC_GLITCHGRAB_TOKEN!,\n * userId: session.user.id,\n * });\n * ```\n */\nexport function useGlitchgrabReports({\n token,\n userId,\n limit = 100,\n}: {\n token: string;\n userId: string;\n /** Max results (default 100, max 100) */\n limit?: number;\n}): {\n reports: GlitchgrabReport[];\n isLoading: boolean;\n isFetching: boolean;\n error: string | null;\n refetch: () => Promise<void>;\n} {\n const [reports, setReports] = useState<GlitchgrabReport[]>([]);\n const [isLoading, setIsLoading] = useState(true);\n const [isFetching, setIsFetching] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const fetchReports = useCallback(async () => {\n if (!token || !userId) {\n setIsLoading(false);\n return;\n }\n\n setIsFetching(true);\n setError(null);\n\n try {\n const res = await fetch(\n `${BASE_URL}/api/v1/sdk/reports?reporterPrimaryKey=${encodeURIComponent(userId)}&limit=${limit}`,\n { headers: { Authorization: `Bearer ${token}` } }\n );\n const data = await res.json();\n\n if (data.success) {\n setReports(data.data ?? []);\n } else {\n setError(data.error ?? \"Failed to fetch reports\");\n }\n } catch {\n setError(\"Network error\");\n } finally {\n setIsLoading(false);\n setIsFetching(false);\n }\n }, [token, userId, limit]);\n\n useEffect(() => {\n fetchReports();\n }, [fetchReports]);\n\n return { reports, isLoading, isFetching, error, refetch: fetchReports };\n}\n\n/**\n * Standalone fetcher — use with TanStack Query or any data fetching library.\n *\n * ```tsx\n * const { data } = useQuery({\n * queryKey: [\"glitchgrab-reports\", userId],\n * queryFn: () => fetchGlitchgrabReports({\n * token: process.env.NEXT_PUBLIC_GLITCHGRAB_TOKEN!,\n * userId: session.user.id,\n * }),\n * });\n * ```\n */\nexport async function fetchGlitchgrabReports({\n token,\n userId,\n limit = 100,\n}: {\n token: string;\n userId: string;\n limit?: number;\n}): Promise<GlitchgrabReport[]> {\n const res = await fetch(\n `${BASE_URL}/api/v1/sdk/reports?reporterPrimaryKey=${encodeURIComponent(userId)}&limit=${limit}`,\n { headers: { Authorization: `Bearer ${token}` } }\n );\n const data = await res.json();\n if (!data.success) throw new Error(data.error ?? \"Failed to fetch reports\");\n return data.data ?? [];\n}\n\n// ─── Report Actions ─────────────────────────────────────\n\nasync function reportAction(\n token: string,\n reportId: string,\n body: Record<string, string>\n): Promise<void> {\n const res = await fetch(`${BASE_URL}/api/v1/reports/${reportId}/actions`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(body),\n });\n const data = await res.json().catch(() => ({}));\n if (!res.ok || !data.success) throw new Error(data.error ?? \"Action failed\");\n}\n\n/**\n * Hook to manage report actions with loading/error states.\n *\n * ```tsx\n * const { approve, reject, close, isPending, error } = useGlitchgrabActions({\n * token: process.env.NEXT_PUBLIC_GLITCHGRAB_TOKEN!,\n * onSuccess: () => refetch(),\n * onError: (err) => toast.error(err.message),\n * });\n *\n * <button onClick={() => approve(reportId)} disabled={isPending}>\n * {isPending ? \"...\" : \"Approve\"}\n * </button>\n * ```\n */\nexport function useGlitchgrabActions({\n token,\n onSuccess,\n onError,\n}: {\n token: string;\n onSuccess?: () => void;\n onError?: (error: Error) => void;\n}) {\n const [isPending, setIsPending] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const run = useCallback(\n async (reportId: string, body: Record<string, string>) => {\n setIsPending(true);\n setError(null);\n try {\n await reportAction(token, reportId, body);\n onSuccess?.();\n } catch (e) {\n const err = e instanceof Error ? e : new Error(\"Action failed\");\n setError(err.message);\n onError?.(err);\n } finally {\n setIsPending(false);\n }\n },\n [token, onSuccess, onError]\n );\n\n return {\n approve: (reportId: string) => run(reportId, { action: \"label\", label: \"approved\" }),\n reject: (reportId: string) => run(reportId, { action: \"label\", label: \"rejected\" }),\n close: (reportId: string) => run(reportId, { action: \"close\" }),\n reopen: (reportId: string) => run(reportId, { action: \"reopen\" }),\n label: (reportId: string, label: string) => run(reportId, { action: \"label\", label }),\n unlabel: (reportId: string, label: string) => run(reportId, { action: \"unlabel\", label }),\n isPending,\n error,\n };\n}\n"],"mappings":"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","names":["useRef","useEffect","e","rgb","words","e","Fragment","jsx","jsxs","DEFAULT_BASE_URL","maxBreadcrumbs","useRef","useEffect","addBreadcrumb","useState","Fragment","jsx","jsxs","useState","useState","useEffect","useCallback"]}
|
|
1
|
+
{"version":3,"sources":["../src/provider.tsx","../src/error-boundary.tsx","../src/breadcrumbs.ts","../src/utils.ts","../src/dedup.ts","../src/report-dialog.tsx","../src/report-button.tsx","../src/use-reports.ts"],"sourcesContent":["\"use client\";\n\nimport {\n createContext,\n useContext,\n useRef,\n useEffect,\n useCallback,\n useState,\n} from \"react\";\nimport type {\n GlitchgrabProviderProps,\n UseGlitchgrabReturn,\n ReportPayload,\n ReportResult,\n ReportType,\n} from \"./types\";\nimport { GlitchgrabErrorBoundary } from \"./error-boundary\";\nimport { ReportDialog } from \"./report-dialog\";\nimport { sanitizeUrl, captureContext, sendReport, captureDeviceInfo } from \"./utils\";\nimport { computeSignature, shouldSkipDuplicate } from \"./dedup\";\nimport {\n initBreadcrumbs,\n addBreadcrumb as addBreadcrumbInternal,\n getBreadcrumbs,\n} from \"./breadcrumbs\";\n\nconst DEFAULT_BASE_URL = \"https://www.glitchgrab.dev\";\n\nconst GlitchgrabContext = createContext<UseGlitchgrabReturn | null>(null);\n\n/**\n * Hook to access Glitchgrab in your components.\n *\n * @example\n * ```tsx\n * const { reportBug, report, addBreadcrumb } = useGlitchgrab();\n *\n * // Report a bug\n * reportBug(\"Login button crashes on mobile\");\n *\n * // Report a feature request\n * report(\"FEATURE_REQUEST\", \"Add dark mode\");\n *\n * // Add a custom breadcrumb\n * addBreadcrumb(\"User clicked checkout\", { cartItems: \"3\" });\n * ```\n */\nexport function useGlitchgrab(): UseGlitchgrabReturn {\n const ctx = useContext(GlitchgrabContext);\n if (!ctx) {\n throw new Error(\"useGlitchgrab must be used within a GlitchgrabProvider\");\n }\n return ctx;\n}\n\nfunction GlitchgrabProviderInner({\n token,\n session,\n baseUrl,\n onError,\n onReportSent,\n breadcrumbs: enableBreadcrumbs = true,\n maxBreadcrumbs = 50,\n children,\n fallback,\n types,\n showSeverity,\n}: GlitchgrabProviderProps) {\n const visitedPagesRef = useRef<string[]>([]);\n\n // Initialize breadcrumbs\n useEffect(() => {\n if (enableBreadcrumbs) {\n initBreadcrumbs(maxBreadcrumbs);\n }\n }, [enableBreadcrumbs, maxBreadcrumbs]);\n\n // Track page visits\n useEffect(() => {\n try {\n if (typeof window === \"undefined\") return;\n\n const trackPage = () => {\n try {\n const sanitized = sanitizeUrl(window.location.href);\n const pages = visitedPagesRef.current;\n if (pages[pages.length - 1] !== sanitized) {\n pages.push(sanitized);\n if (pages.length > 20) {\n pages.splice(0, pages.length - 20);\n }\n }\n } catch {\n // Silently fail\n }\n };\n\n trackPage();\n const handlePopState = () => trackPage();\n window.addEventListener(\"popstate\", handlePopState);\n\n const origPushState = history.pushState.bind(history);\n const origReplaceState = history.replaceState.bind(history);\n\n history.pushState = function (...args) {\n origPushState(...args);\n trackPage();\n };\n history.replaceState = function (...args) {\n origReplaceState(...args);\n trackPage();\n };\n\n return () => {\n window.removeEventListener(\"popstate\", handlePopState);\n history.pushState = origPushState;\n history.replaceState = origReplaceState;\n };\n } catch {\n // Never crash\n }\n }, []);\n\n // Unhandled errors and rejections — skip in development\n useEffect(() => {\n try {\n if (typeof window === \"undefined\") return;\n if (process.env.NODE_ENV === \"development\") return;\n\n const handleError = (event: ErrorEvent) => {\n try {\n const context = captureContext(visitedPagesRef.current);\n const sig = computeSignature({\n errorMessage: event.message,\n pageUrl: context.url,\n errorStack: event.error?.stack,\n });\n if (shouldSkipDuplicate(sig)) return;\n const payload: ReportPayload = {\n token,\n source: \"SDK_AUTO\",\n type: \"BUG\",\n errorMessage: event.message,\n errorStack: event.error?.stack,\n pageUrl: context.url,\n userAgent: context.userAgent,\n breadcrumbs: context.breadcrumbs,\n deviceInfo: context.deviceInfo ?? undefined,\n metadata: {\n timestamp: context.timestamp,\n visitedPages: JSON.stringify(context.visitedPages),\n filename: event.filename ?? \"\",\n lineno: String(event.lineno ?? \"\"),\n colno: String(event.colno ?? \"\"),\n ...(session?.userId ? { sessionUserId: session.userId } : {}),\n ...(session?.name ? { sessionUserName: String(session.name) } : {}),\n ...(session?.email ? { sessionUserEmail: String(session.email) } : {}),\n ...(session?.phone ? { sessionUserPhone: String(session.phone) } : {}),\n },\n };\n sendReport(payload, baseUrl).then((result) => {\n if (result && onReportSent) onReportSent(result);\n });\n if (onError && event.error) onError(event.error);\n } catch {\n // Silently fail\n }\n };\n\n const handleRejection = (event: PromiseRejectionEvent) => {\n try {\n const context = captureContext(visitedPagesRef.current);\n const reason = event.reason;\n const errMsg = reason instanceof Error ? reason.message : String(reason);\n const errStack = reason instanceof Error ? reason.stack : undefined;\n const sig = computeSignature({\n errorMessage: errMsg,\n pageUrl: context.url,\n errorStack: errStack,\n });\n if (shouldSkipDuplicate(sig)) return;\n const payload: ReportPayload = {\n token,\n source: \"SDK_AUTO\",\n type: \"BUG\",\n errorMessage: errMsg,\n errorStack: errStack,\n pageUrl: context.url,\n userAgent: context.userAgent,\n breadcrumbs: context.breadcrumbs,\n deviceInfo: context.deviceInfo ?? undefined,\n metadata: {\n timestamp: context.timestamp,\n visitedPages: JSON.stringify(context.visitedPages),\n type: \"unhandledrejection\",\n ...(session?.userId ? { sessionUserId: session.userId } : {}),\n ...(session?.name ? { sessionUserName: String(session.name) } : {}),\n ...(session?.email ? { sessionUserEmail: String(session.email) } : {}),\n ...(session?.phone ? { sessionUserPhone: String(session.phone) } : {}),\n },\n };\n sendReport(payload, baseUrl).then((result) => {\n if (result && onReportSent) onReportSent(result);\n });\n if (onError && reason instanceof Error) onError(reason);\n } catch {\n // Silently fail\n }\n };\n\n window.addEventListener(\"error\", handleError);\n window.addEventListener(\"unhandledrejection\", handleRejection);\n\n return () => {\n window.removeEventListener(\"error\", handleError);\n window.removeEventListener(\"unhandledrejection\", handleRejection);\n };\n } catch {\n // Never crash\n }\n }, [token, baseUrl, onError, onReportSent, session]);\n\n const report = useCallback(\n async (\n type: ReportType,\n description: string,\n metadata?: Record<string, string>\n ): Promise<ReportResult | null> => {\n try {\n const context = captureContext(visitedPagesRef.current);\n const payload: ReportPayload = {\n token,\n source: \"SDK_USER_REPORT\",\n type,\n description,\n pageUrl: context.url,\n userAgent: context.userAgent,\n breadcrumbs: context.breadcrumbs,\n deviceInfo: context.deviceInfo ?? undefined,\n metadata: {\n timestamp: context.timestamp,\n visitedPages: JSON.stringify(context.visitedPages),\n ...(session?.userId ? { sessionUserId: session.userId } : {}),\n ...(session?.name ? { sessionUserName: String(session.name) } : {}),\n ...(session?.email ? { sessionUserEmail: String(session.email) } : {}),\n ...(session?.phone ? { sessionUserPhone: String(session.phone) } : {}),\n ...metadata,\n },\n };\n const result = await sendReport(payload, baseUrl);\n if (result && onReportSent) onReportSent(result);\n return result;\n } catch {\n return null;\n }\n },\n [token, baseUrl, onReportSent, session]\n );\n\n const reportBug = useCallback(\n (description: string, metadata?: Record<string, string>) =>\n report(\"BUG\", description, metadata),\n [report]\n );\n\n const addBreadcrumb = useCallback(\n (message: string, data?: Record<string, string>) => {\n addBreadcrumbInternal(\"custom\", message, data);\n },\n []\n );\n\n const openReportDialog = useCallback((options?: { description?: string; type?: ReportType }) => {\n if (typeof window !== \"undefined\") {\n window.dispatchEvent(new CustomEvent(\"glitchgrab:open-report\", { detail: options }));\n }\n }, []);\n\n // Global keyboard shortcut: Cmd+Shift+G (Mac) / Ctrl+Shift+G (Windows/Linux)\n useEffect(() => {\n try {\n if (typeof window === \"undefined\") return;\n const handleKeyDown = (e: KeyboardEvent) => {\n if ((e.metaKey || e.ctrlKey) && e.shiftKey && e.key.toLowerCase() === \"g\") {\n e.preventDefault();\n openReportDialog();\n }\n };\n window.addEventListener(\"keydown\", handleKeyDown);\n return () => window.removeEventListener(\"keydown\", handleKeyDown);\n } catch {\n // Never crash\n }\n }, [openReportDialog]);\n\n return (\n <GlitchgrabContext.Provider\n value={{\n token,\n baseUrl: baseUrl ?? DEFAULT_BASE_URL,\n reportBug,\n report,\n addBreadcrumb,\n openReportDialog,\n }}\n >\n <GlitchgrabErrorBoundary\n token={token}\n baseUrl={baseUrl}\n session={session}\n onError={onError}\n fallback={fallback}\n visitedPages={visitedPagesRef.current}\n >\n {children}\n </GlitchgrabErrorBoundary>\n <ReportDialog report={report} types={types} showSeverity={showSeverity} />\n </GlitchgrabContext.Provider>\n );\n}\n\nexport function GlitchgrabProvider(props: GlitchgrabProviderProps) {\n // No token = passthrough (SDK disabled)\n if (!props.token) return <>{props.children}</>;\n\n const resolvedProps = {\n ...props,\n baseUrl: props.baseUrl || DEFAULT_BASE_URL,\n };\n\n try {\n return <GlitchgrabProviderInner {...resolvedProps} />;\n } catch {\n return <>{props.children}</>;\n }\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport type { GlitchgrabSession, ReportPayload } from \"./types\";\nimport { captureContext, sendReport } from \"./utils\";\nimport { computeSignature, shouldSkipDuplicate } from \"./dedup\";\n\ninterface ErrorBoundaryProps {\n token: string;\n baseUrl?: string;\n session?: GlitchgrabSession | null;\n onError?: (error: Error) => void;\n fallback?: React.ReactNode;\n visitedPages: string[];\n children: React.ReactNode;\n}\n\ninterface ErrorBoundaryState {\n hasError: boolean;\n}\n\nexport class GlitchgrabErrorBoundary extends React.Component<\n ErrorBoundaryProps,\n ErrorBoundaryState\n> {\n constructor(props: ErrorBoundaryProps) {\n super(props);\n this.state = { hasError: false };\n }\n\n static getDerivedStateFromError(): ErrorBoundaryState {\n return { hasError: true };\n }\n\n componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void {\n try {\n const context = captureContext(this.props.visitedPages);\n\n const sig = computeSignature({\n errorMessage: error.message,\n pageUrl: context.url,\n errorStack: error.stack,\n });\n if (shouldSkipDuplicate(sig)) {\n if (this.props.onError) this.props.onError(error);\n return;\n }\n\n const session = this.props.session;\n const payload: ReportPayload = {\n token: this.props.token,\n source: \"SDK_AUTO\",\n type: \"BUG\",\n errorMessage: error.message,\n errorStack: error.stack,\n componentStack: errorInfo.componentStack ?? undefined,\n pageUrl: context.url,\n userAgent: context.userAgent,\n breadcrumbs: context.breadcrumbs,\n deviceInfo: context.deviceInfo ?? undefined,\n metadata: {\n timestamp: context.timestamp,\n visitedPages: JSON.stringify(context.visitedPages),\n ...(session?.userId ? { sessionUserId: session.userId } : {}),\n ...(session?.name ? { sessionUserName: String(session.name) } : {}),\n ...(session?.email ? { sessionUserEmail: String(session.email) } : {}),\n ...(session?.phone ? { sessionUserPhone: String(session.phone) } : {}),\n },\n };\n\n sendReport(payload, this.props.baseUrl);\n\n if (this.props.onError) {\n this.props.onError(error);\n }\n } catch {\n // Never crash the host app\n }\n }\n\n render(): React.ReactNode {\n if (this.state.hasError) {\n if (this.props.fallback) {\n return this.props.fallback;\n }\n\n // Re-render children — allows recovery from transient errors\n return this.props.children;\n }\n\n return this.props.children;\n }\n}\n","import type { Breadcrumb, BreadcrumbType } from \"./types\";\n\nconst MAX_DEFAULT = 50;\n\nlet breadcrumbs: Breadcrumb[] = [];\nlet maxBreadcrumbs = MAX_DEFAULT;\nlet initialized = false;\n\nexport function initBreadcrumbs(max?: number) {\n if (initialized) return;\n maxBreadcrumbs = max ?? MAX_DEFAULT;\n\n try {\n if (typeof window === \"undefined\") return;\n interceptConsole();\n interceptFetch();\n interceptNavigation();\n interceptClicks();\n initialized = true;\n } catch {\n // Never crash\n }\n}\n\nexport function addBreadcrumb(\n type: BreadcrumbType,\n message: string,\n data?: Record<string, string>\n) {\n try {\n breadcrumbs.push({\n type,\n message: message.slice(0, 200),\n timestamp: new Date().toISOString(),\n data,\n });\n if (breadcrumbs.length > maxBreadcrumbs) {\n breadcrumbs = breadcrumbs.slice(-maxBreadcrumbs);\n }\n } catch {\n // Never crash\n }\n}\n\nexport function getBreadcrumbs(): Breadcrumb[] {\n return [...breadcrumbs];\n}\n\nexport function clearBreadcrumbs() {\n breadcrumbs = [];\n}\n\n// ─── Console Interception ────────────────────────────────\n\nfunction interceptConsole() {\n const origLog = console.log;\n const origWarn = console.warn;\n const origError = console.error;\n\n console.log = function (...args: unknown[]) {\n addBreadcrumb(\"console\", `[log] ${argsToString(args)}`);\n origLog.apply(console, args);\n };\n\n console.warn = function (...args: unknown[]) {\n addBreadcrumb(\"console\", `[warn] ${argsToString(args)}`);\n origWarn.apply(console, args);\n };\n\n console.error = function (...args: unknown[]) {\n addBreadcrumb(\"console\", `[error] ${argsToString(args)}`);\n origError.apply(console, args);\n };\n}\n\nfunction argsToString(args: unknown[]): string {\n try {\n return args\n .map((a) => {\n if (typeof a === \"string\") return a;\n if (a instanceof Error) return a.message;\n try {\n return JSON.stringify(a);\n } catch {\n return String(a);\n }\n })\n .join(\" \")\n .slice(0, 200);\n } catch {\n return \"[unknown]\";\n }\n}\n\n// ─── Fetch Interception ──────────────────────────────────\n\nfunction interceptFetch() {\n const origFetch = window.fetch;\n\n window.fetch = async function (input, init) {\n const url =\n typeof input === \"string\"\n ? input\n : input instanceof URL\n ? input.toString()\n : input instanceof Request\n ? input.url\n : String(input);\n const method = init?.method ?? \"GET\";\n const start = Date.now();\n\n try {\n const response = await origFetch.apply(window, [input, init]);\n addBreadcrumb(\"api\", `${method} ${url.slice(0, 100)} → ${response.status}`, {\n method,\n status: String(response.status),\n duration: `${Date.now() - start}ms`,\n });\n return response;\n } catch (err) {\n addBreadcrumb(\"api\", `${method} ${url.slice(0, 100)} → FAILED`, {\n method,\n error: err instanceof Error ? err.message : \"unknown\",\n duration: `${Date.now() - start}ms`,\n });\n throw err;\n }\n };\n}\n\n// ─── Navigation Interception ─────────────────────────────\n\nfunction interceptNavigation() {\n const origPush = history.pushState.bind(history);\n const origReplace = history.replaceState.bind(history);\n\n history.pushState = function (...args) {\n origPush(...args);\n addBreadcrumb(\"navigation\", `Navigate to ${window.location.pathname}`);\n };\n\n history.replaceState = function (...args) {\n origReplace(...args);\n addBreadcrumb(\"navigation\", `Replace to ${window.location.pathname}`);\n };\n\n window.addEventListener(\"popstate\", () => {\n addBreadcrumb(\"navigation\", `Back/Forward to ${window.location.pathname}`);\n });\n}\n\n// ─── Click Interception ──────────────────────────────────\n\nfunction interceptClicks() {\n document.addEventListener(\n \"click\",\n (e) => {\n try {\n const target = e.target as HTMLElement;\n const tag = target.tagName?.toLowerCase();\n const text = target.textContent?.trim().slice(0, 50) ?? \"\";\n const id = target.id ? `#${target.id}` : \"\";\n const cls = target.className && typeof target.className === \"string\"\n ? `.${target.className.split(\" \")[0]}`\n : \"\";\n\n addBreadcrumb(\"click\", `Click ${tag}${id}${cls} \"${text}\"`);\n } catch {\n // Never crash\n }\n },\n { capture: true }\n );\n}\n","import type { ReportPayload, ReportResult, CapturedContext, DeviceInfo } from \"./types\";\nimport { getBreadcrumbs } from \"./breadcrumbs\";\n\nconst SENSITIVE_PARAMS = [\n \"token\", \"key\", \"secret\", \"password\", \"passwd\", \"auth\", \"authorization\",\n \"session\", \"sessionid\", \"session_id\", \"api_key\", \"apikey\", \"access_token\",\n \"refresh_token\", \"client_secret\", \"code\", \"state\", \"nonce\", \"credential\", \"private\",\n];\n\nexport function sanitizeUrl(url: string): string {\n try {\n const parsed = new URL(url);\n const params = new URLSearchParams(parsed.search);\n let modified = false;\n for (const key of Array.from(params.keys())) {\n if (SENSITIVE_PARAMS.some((s) => key.toLowerCase().includes(s))) {\n params.set(key, \"[REDACTED]\");\n modified = true;\n }\n }\n if (modified) parsed.search = params.toString();\n return parsed.toString();\n } catch {\n return url.split(\"?\")[0] ?? url;\n }\n}\n\nexport function captureDeviceInfo(): DeviceInfo | null {\n try {\n if (typeof window === \"undefined\") return null;\n return {\n screenWidth: screen.width,\n screenHeight: screen.height,\n viewportWidth: window.innerWidth,\n viewportHeight: window.innerHeight,\n platform: navigator.platform ?? \"unknown\",\n language: navigator.language ?? \"unknown\",\n online: navigator.onLine,\n colorScheme: window.matchMedia(\"(prefers-color-scheme: dark)\").matches ? \"dark\" : \"light\",\n devicePixelRatio: window.devicePixelRatio ?? 1,\n };\n } catch {\n return null;\n }\n}\n\nexport function captureContext(visitedPages: string[]): CapturedContext {\n try {\n return {\n url: sanitizeUrl(typeof window !== \"undefined\" ? window.location.href : \"\"),\n userAgent: typeof navigator !== \"undefined\" ? navigator.userAgent : \"\",\n timestamp: new Date().toISOString(),\n visitedPages: visitedPages.map(sanitizeUrl),\n breadcrumbs: getBreadcrumbs(),\n deviceInfo: captureDeviceInfo(),\n };\n } catch {\n return {\n url: \"\",\n userAgent: \"\",\n timestamp: new Date().toISOString(),\n visitedPages: [],\n breadcrumbs: [],\n deviceInfo: null,\n };\n }\n}\n\nconst DEFAULT_BASE_URL = \"https://www.glitchgrab.dev\";\nconst MAX_RETRIES = 3;\nconst RETRY_BASE_MS = 500;\n\n/**\n * Send a report and return the result.\n * Never throws — returns null on failure.\n */\nexport async function sendReport(\n payload: ReportPayload,\n baseUrl?: string\n): Promise<ReportResult | null> {\n try {\n const url = `${baseUrl ?? DEFAULT_BASE_URL}/api/v1/sdk/report`;\n const body = JSON.stringify(payload);\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${payload.token}`,\n };\n\n // keepalive has a 64KB body limit in browsers — skip it for large payloads (e.g., screenshots)\n const useKeepalive = body.length < 60_000;\n\n for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {\n try {\n const response = await fetch(url, {\n method: \"POST\",\n headers,\n body,\n ...(useKeepalive ? { keepalive: true } : {}),\n });\n\n if (response.ok) {\n const envelope = (await response.json()) as {\n success: boolean;\n data?: Omit<ReportResult, \"success\">;\n };\n return { success: envelope.success, ...(envelope.data ?? {}) };\n }\n\n if (response.status >= 400 && response.status < 500 && response.status !== 429) {\n return null;\n }\n } catch {\n // Will retry\n }\n\n if (attempt < MAX_RETRIES - 1) {\n await new Promise((resolve) =>\n setTimeout(resolve, RETRY_BASE_MS * Math.pow(2, attempt))\n );\n }\n }\n\n // Fallback: sendBeacon (fire-and-forget, no result)\n if (typeof navigator !== \"undefined\" && navigator.sendBeacon) {\n try {\n navigator.sendBeacon(url, new Blob([body], { type: \"application/json\" }));\n } catch {\n // Silently fail\n }\n }\n\n return null;\n } catch {\n return null;\n }\n}\n","const DEFAULT_WINDOW_MS = 5 * 60 * 1000;\nconst MAX_ENTRIES = 100;\n\nconst seen = new Map<string, number>();\n\nfunction hashString(input: string): string {\n let h1 = 0xdeadbeef ^ 0;\n let h2 = 0x41c6ce57 ^ 0;\n for (let i = 0; i < input.length; i++) {\n const ch = input.charCodeAt(i);\n h1 = Math.imul(h1 ^ ch, 2654435761);\n h2 = Math.imul(h2 ^ ch, 1597334677);\n }\n h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^ Math.imul(h2 ^ (h2 >>> 13), 3266489909);\n h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^ Math.imul(h1 ^ (h1 >>> 13), 3266489909);\n return (4294967296 * (2097151 & h2) + (h1 >>> 0)).toString(36);\n}\n\nfunction topStackFrame(stack: string | undefined): string {\n if (!stack) return \"\";\n const lines = stack.split(\"\\n\");\n for (const line of lines) {\n const t = line.trim();\n if (t.startsWith(\"at \") || t.includes(\"@\")) {\n return t;\n }\n }\n return \"\";\n}\n\nfunction stripUrlQuery(url: string | undefined): string {\n if (!url) return \"\";\n try {\n const u = new URL(url);\n return `${u.origin}${u.pathname}`;\n } catch {\n const q = url.indexOf(\"?\");\n return q === -1 ? url : url.slice(0, q);\n }\n}\n\nexport function computeSignature(params: {\n errorMessage: string | undefined;\n pageUrl: string | undefined;\n errorStack?: string | undefined;\n}): string {\n const msg = params.errorMessage?.trim() ?? \"\";\n const page = stripUrlQuery(params.pageUrl);\n const frame = topStackFrame(params.errorStack);\n return hashString(`${msg}|${page}|${frame}`);\n}\n\nexport function shouldSkipDuplicate(\n signature: string,\n windowMs: number = DEFAULT_WINDOW_MS,\n now: number = Date.now()\n): boolean {\n const last = seen.get(signature);\n if (last !== undefined && now - last < windowMs) {\n return true;\n }\n seen.set(signature, now);\n\n if (seen.size > MAX_ENTRIES) {\n const cutoff = now - windowMs;\n for (const [sig, ts] of seen) {\n if (ts < cutoff) seen.delete(sig);\n }\n if (seen.size > MAX_ENTRIES) {\n const excess = seen.size - MAX_ENTRIES;\n const keys = Array.from(seen.keys()).slice(0, excess);\n for (const k of keys) seen.delete(k);\n }\n }\n return false;\n}\n\nexport function clearDedupCache(): void {\n seen.clear();\n}\n","\"use client\";\n\nimport { useState, useRef, useEffect, type CSSProperties, type ReactNode } from \"react\";\n// @ts-expect-error react-dom types handled by host app\nimport { createPortal } from \"react-dom\";\nimport type { ReportType, ReportSeverity, UseGlitchgrabReturn } from \"./types\";\n\n/** Detect if the host page uses a dark or light theme */\nfunction useIsDark(): boolean {\n if (typeof window === \"undefined\") return true;\n try {\n // Check body then html — most sites set background on html, not body\n for (const el of [document.body, document.documentElement]) {\n const bg = getComputedStyle(el).backgroundColor;\n const match = bg.match(/rgba?\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)(?:\\s*,\\s*([\\d.]+))?\\s*\\)/);\n if (match) {\n const alpha = match[4] !== undefined ? parseFloat(match[4]) : 1;\n if (alpha < 0.05) continue; // transparent — skip to next element\n const [r, g, b] = [Number(match[1]), Number(match[2]), Number(match[3])];\n return (r * 299 + g * 587 + b * 114) / 1000 < 128;\n }\n }\n return window.matchMedia(\"(prefers-color-scheme: dark)\").matches;\n } catch {\n return true;\n }\n}\n\n/** Convert HSL values to a hex color string */\nfunction hslToHex(h: number, s: number, l: number): string {\n s /= 100;\n l /= 100;\n const a = s * Math.min(l, 1 - l);\n const f = (n: number) => {\n const k = (n + h / 30) % 12;\n const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);\n return Math.round(255 * color).toString(16).padStart(2, \"0\");\n };\n return `#${f(0)}${f(8)}${f(4)}`;\n}\n\n/** Parse a CSS color value into [r, g, b] or null */\nfunction parseColorToRgb(value: string): [number, number, number] | null {\n try {\n const trimmed = value.trim();\n\n // hex (#fff, #ffffff)\n const hexMatch = trimmed.match(/^#([0-9a-f]{3,8})$/i);\n if (hexMatch) {\n let hex = hexMatch[1];\n if (hex.length === 3) hex = hex[0]+hex[0]+hex[1]+hex[1]+hex[2]+hex[2];\n return [parseInt(hex.slice(0, 2), 16), parseInt(hex.slice(2, 4), 16), parseInt(hex.slice(4, 6), 16)];\n }\n\n // rgb(r, g, b) or rgba(r, g, b, a)\n const rgbMatch = trimmed.match(/rgba?\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)/);\n if (rgbMatch) return [Number(rgbMatch[1]), Number(rgbMatch[2]), Number(rgbMatch[3])];\n\n // hsl(h, s%, l%) or hsla(h, s%, l%, a)\n const hslMatch = trimmed.match(/hsla?\\(\\s*([\\d.]+)\\s*,\\s*([\\d.]+)%\\s*,\\s*([\\d.]+)%/);\n if (hslMatch) {\n const hex = hslToHex(Number(hslMatch[1]), Number(hslMatch[2]), Number(hslMatch[3]));\n return parseColorToRgb(hex);\n }\n\n return null;\n } catch {\n return null;\n }\n}\n\n/** Compute relative luminance and return ideal contrast text color */\nfunction getContrastText(r: number, g: number, b: number): string {\n const luminance = (r * 299 + g * 587 + b * 114) / 1000;\n return luminance > 150 ? \"#09090b\" : \"#ffffff\";\n}\n\n/**\n * Auto-detect the host app's primary/accent color from CSS custom properties.\n * Checks common variable names used by shadcn/ui, Radix, Tailwind, MUI, etc.\n * Returns { accent, accentText } or null if no theme detected.\n */\nfunction detectHostAccent(): { accent: string; accentText: string } | null {\n if (typeof window === \"undefined\") return null;\n try {\n const root = getComputedStyle(document.documentElement);\n\n // Common CSS variable names for primary/accent color\n const varNames = [\n \"--primary\",\n \"--accent\",\n \"--brand\",\n \"--color-primary\",\n \"--theme-primary\",\n \"--chakra-colors-primary-500\",\n \"--mui-palette-primary-main\",\n ];\n\n for (const name of varNames) {\n const raw = root.getPropertyValue(name).trim();\n if (!raw) continue;\n\n // shadcn/ui style: space-separated HSL values like \"243 75% 59%\"\n const hslSpaceMatch = raw.match(/^([\\d.]+)\\s+([\\d.]+)%\\s+([\\d.]+)%$/);\n if (hslSpaceMatch) {\n const hex = hslToHex(Number(hslSpaceMatch[1]), Number(hslSpaceMatch[2]), Number(hslSpaceMatch[3]));\n const rgb = parseColorToRgb(hex);\n return { accent: hex, accentText: rgb ? getContrastText(...rgb) : \"#ffffff\" };\n }\n\n // Standard color values (hex, rgb, hsl)\n const rgb = parseColorToRgb(raw);\n if (rgb) {\n const hex = `#${rgb.map((c) => c.toString(16).padStart(2, \"0\")).join(\"\")}`;\n return { accent: hex, accentText: getContrastText(...rgb) };\n }\n }\n\n return null;\n } catch {\n return null;\n }\n}\n\nfunction getTheme(dark: boolean) {\n const hostAccent = detectHostAccent();\n const defaults = dark\n ? { bg: \"#1c1c1e\", bgSecondary: \"#27272a\", border: \"#2c2c2e\", text: \"#fafafa\", textMuted: \"#a1a1aa\", accent: \"#22d3ee\", accentText: \"#09090b\", inputBg: \"#27272a\", inputBorder: \"#3f3f46\" }\n : { bg: \"#ffffff\", bgSecondary: \"#f4f4f5\", border: \"#e4e4e7\", text: \"#18181b\", textMuted: \"#71717a\", accent: \"#0891b2\", accentText: \"#ffffff\", inputBg: \"#fafafa\", inputBorder: \"#d4d4d8\" };\n\n if (hostAccent) {\n defaults.accent = hostAccent.accent;\n defaults.accentText = hostAccent.accentText;\n }\n\n return defaults;\n}\n\n/** Validate that report text is meaningful — rejects gibberish, throwaway words, random chars */\nfunction isLowQualityText(text: string): string | null {\n const trimmed = text.trim();\n if (!trimmed) return null;\n\n // Exact throwaway words\n const throwaway =\n /^(done|ok|yes|no|hi|hello|hey|test|testing|asdf|qwerty|abc|xyz|foo|bar|baz|lol|lmao|idk|bruh|nice|cool|wow|sup|yo|nah|yep|nope|thanks|thx|ty|k|kk|hmm|hm|na|mm|mhm|aight|bet|gg|wp|rip|omg|pls|plz)$/i;\n if (throwaway.test(trimmed)) {\n return \"Please describe the actual issue you're experiencing\";\n }\n\n // Repeated characters (aaaaaaa, !!!!!!!)\n if (/(.)\\1{4,}/.test(trimmed)) {\n return \"Please provide a meaningful description\";\n }\n\n const letters = trimmed.replace(/[^a-zA-Z]/g, \"\");\n if (letters.length >= 4) {\n // Very low vowel ratio (bkdfghjklmn...)\n const vowels = letters.replace(/[^aeiouAEIOU]/g, \"\").length;\n const vowelRatio = vowels / letters.length;\n if (vowelRatio < 0.08) {\n return \"That doesn't look like a valid description\";\n }\n\n // Keyboard mashing: single word with no real English pattern\n // Detects strings like \"asdfasfsdad\", \"jkljklfsdf\", \"qwertyuio\"\n // Real words have max 3-4 consecutive consonants; gibberish has long runs\n if (/[^aeiou\\s]{5,}/i.test(letters)) {\n const words = trimmed.split(/\\s+/);\n // Only flag if it's a single \"word\" — multi-word text is likely real\n if (words.length <= 2) {\n return \"That doesn't look like a valid description\";\n }\n }\n\n // Check if it looks like a random permutation of a few chars (asdfasfsdad)\n if (letters.length >= 6) {\n const uniqueChars = new Set(letters.toLowerCase()).size;\n const uniqueRatio = uniqueChars / letters.length;\n // Real English has ~0.6-0.9 unique ratio for short text; gibberish reuses few chars\n if (uniqueRatio < 0.4 && trimmed.split(/\\s+/).length <= 2) {\n return \"That doesn't look like a valid description\";\n }\n }\n }\n\n // Single short word that isn't a known tech term\n const words = trimmed.split(/\\s+/).filter((w) => w.length > 0);\n if (words.length === 1 && trimmed.length < 10) {\n const techTerms =\n /^(crash|error|bug|fail|broken|slow|freeze|lag|404|500|null|undefined|nan|timeout|overflow|leak|cors|oom)$/i;\n if (!techTerms.test(trimmed)) {\n return \"Please provide more detail about the issue\";\n }\n }\n\n return null;\n}\n\ninterface ReportDialogProps {\n report: UseGlitchgrabReturn[\"report\"];\n types?: ReportType[];\n showSeverity?: boolean;\n}\n\n/**\n * The report dialog — rendered inside GlitchgrabProvider automatically.\n * Opens via the `glitchgrab:open-report` custom event (triggered by `openReportDialog()`).\n */\nexport function ReportDialog({\n report,\n types,\n showSeverity = true,\n}: ReportDialogProps) {\n // Prevent hydration mismatch — render nothing until after hydration\n const [mounted, setMounted] = useState(false);\n useEffect(() => { setMounted(true); }, []);\n\n const [isOpen, setIsOpen] = useState(false);\n const [description, setDescription] = useState(\"\");\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [submitted, setSubmitted] = useState(false);\n const [screenshot, setScreenshot] = useState<string | null>(null);\n const [previewOpen, setPreviewOpen] = useState(false);\n const fileInputRef = useRef<HTMLInputElement>(null);\n const modalRef = useRef<HTMLDivElement>(null);\n\n // Stepper state\n const [step, setStep] = useState(1);\n const [reportType, setReportType] = useState<ReportType>(\"BUG\");\n const [severity, setSeverity] = useState<ReportSeverity>(\"medium\");\n const [validationError, setValidationError] = useState<string | null>(null);\n\n const availableTypes: ReportType[] = types ?? [\"BUG\", \"FEATURE_REQUEST\", \"QUESTION\", \"OTHER\"];\n\n const isDark = useIsDark();\n const t = getTheme(isDark);\n\n const handleFileUpload = (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (!file) return;\n const reader = new FileReader();\n reader.onload = () => {\n setScreenshot(reader.result as string);\n };\n reader.readAsDataURL(file);\n e.target.value = \"\";\n };\n\n const retakeScreenshot = async () => {\n setPreviewOpen(false);\n setIsOpen(false);\n setScreenshot(null);\n await new Promise((r) => setTimeout(r, 300));\n try {\n const { default: html2canvas } = await import(\"html2canvas-pro\");\n const canvas = await html2canvas(document.body, {\n scale: 0.5,\n logging: false,\n useCORS: true,\n allowTaint: true,\n });\n setScreenshot(canvas.toDataURL(\"image/jpeg\", 0.6));\n } catch {\n // silently fail\n }\n setIsOpen(true);\n };\n\n const handleOpen = async () => {\n setSubmitted(false);\n if (availableTypes.length === 1) {\n setReportType(availableTypes[0]);\n setStep(2);\n }\n try {\n const { default: html2canvas } = await import(\"html2canvas-pro\");\n const canvas = await html2canvas(document.body, {\n scale: 0.5,\n logging: false,\n useCORS: true,\n allowTaint: true,\n });\n setScreenshot(canvas.toDataURL(\"image/jpeg\", 0.6));\n } catch {\n // screenshot failed — open without it\n }\n setIsOpen(true);\n };\n\n // Listen for programmatic open via openReportDialog()\n useEffect(() => {\n const handler = (e: Event) => {\n if (isOpen) return;\n const detail = (e as CustomEvent).detail;\n if (detail?.description) setDescription(detail.description);\n if (detail?.type) {\n setReportType(detail.type);\n setStep(2);\n }\n handleOpen();\n };\n window.addEventListener(\"glitchgrab:open-report\", handler);\n return () => window.removeEventListener(\"glitchgrab:open-report\", handler);\n }, [isOpen, handleOpen]);\n\n // Close on Escape\n useEffect(() => {\n if (!isOpen) return;\n const handleEsc = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n if (previewOpen) setPreviewOpen(false);\n else handleClose();\n }\n };\n document.addEventListener(\"keydown\", handleEsc);\n return () => document.removeEventListener(\"keydown\", handleEsc);\n }, [isOpen, previewOpen]);\n\n // Paste image from clipboard (Cmd+V / Ctrl+V) when dialog is open\n useEffect(() => {\n if (!isOpen) return;\n const handlePaste = (e: ClipboardEvent) => {\n try {\n const items = e.clipboardData?.items;\n if (!items) return;\n for (let i = 0; i < items.length; i++) {\n if (items[i].type.startsWith(\"image/\")) {\n const file = items[i].getAsFile();\n if (!file) continue;\n const reader = new FileReader();\n reader.onload = () => setScreenshot(reader.result as string);\n reader.readAsDataURL(file);\n e.preventDefault();\n break;\n }\n }\n } catch {\n // silently fail\n }\n };\n window.addEventListener(\"paste\", handlePaste);\n return () => window.removeEventListener(\"paste\", handlePaste);\n }, [isOpen]);\n\n const handleClose = () => {\n setIsOpen(false);\n setStep(1);\n setReportType(\"BUG\");\n setSeverity(\"medium\");\n setValidationError(null);\n };\n\n const handleSubmit = async () => {\n try {\n if (!description.trim() || isSubmitting) return;\n\n const qualityError = isLowQualityText(description);\n if (qualityError) {\n setValidationError(qualityError);\n setStep(2);\n return;\n }\n\n setIsSubmitting(true);\n const metadata: Record<string, string> = {};\n if (screenshot) metadata.screenshot = screenshot;\n if (showSeverity && reportType === \"BUG\") {\n metadata.severity = severity;\n }\n\n const result = await report(reportType, description.trim(), Object.keys(metadata).length > 0 ? metadata : undefined);\n\n if (result) {\n setSubmitted(true);\n setDescription(\"\");\n setScreenshot(null);\n\n setTimeout(() => {\n setSubmitted(false);\n handleClose();\n }, 2000);\n }\n setIsSubmitting(false);\n } catch {\n setIsSubmitting(false);\n }\n };\n\n if (!mounted) return null;\n\n return (\n <>\n {/* Report modal */}\n {isOpen && createPortal(\n <div\n style={{\n position: \"fixed\",\n inset: 0,\n zIndex: 2147483647,\n pointerEvents: \"auto\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: \"rgba(0,0,0,0.5)\",\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n }}\n onClick={() => { if (!previewOpen) handleClose(); }}\n onPointerDown={(e) => e.stopPropagation()}\n onFocus={(e) => e.stopPropagation()}\n >\n <div\n ref={modalRef}\n onClick={(e) => e.stopPropagation()}\n style={{\n position: \"relative\",\n zIndex: 2147483647,\n width: \"340px\",\n maxWidth: \"calc(100% - 32px)\",\n backgroundColor: t.bg,\n borderRadius: \"12px\",\n boxShadow:\n \"0 20px 60px rgba(0, 0, 0, 0.2), 0 4px 16px rgba(0, 0, 0, 0.1)\",\n fontFamily:\n '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n overflow: \"hidden\",\n color: t.text,\n isolation: \"isolate\",\n }}\n >\n {/* Header */}\n <div\n style={{\n padding: \"16px 16px 12px\",\n borderBottom: `1px solid ${t.border}`,\n }}\n >\n <div\n style={{\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n }}\n >\n <div style={{ display: \"flex\", alignItems: \"center\", gap: \"8px\" }}>\n {step > 1 && (\n <button\n type=\"button\"\n onClick={() => setStep((s) => (s - 1) as 1 | 2 | 3)}\n style={{\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n padding: \"2px\",\n display: \"flex\",\n alignItems: \"center\",\n }}\n aria-label=\"Back\"\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path d=\"M10 3L5 8L10 13\" stroke={t.textMuted} strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </button>\n )}\n <span\n style={{\n fontSize: \"15px\",\n fontWeight: 600,\n color: t.text,\n }}\n >\n {step === 1 ? \"What's on your mind?\" : step === 2 ? \"Tell us more\" : \"Review & Send\"}\n </span>\n </div>\n <button\n type=\"button\"\n onClick={handleClose}\n style={{\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n padding: \"4px\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n aria-label=\"Close\"\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" style={{ display: \"block\" }}>\n <path d=\"M4 4L12 12M12 4L4 12\" stroke={t.textMuted} strokeWidth=\"2\" strokeLinecap=\"round\" />\n </svg>\n </button>\n </div>\n <div style={{ display: \"flex\", alignItems: \"center\", justifyContent: \"center\", gap: \"0\", marginTop: \"12px\" }}>\n {[1, 2, 3].map((s, i) => (\n <div key={s} style={{ display: \"flex\", alignItems: \"center\" }}>\n <div style={{\n width: \"8px\",\n height: \"8px\",\n borderRadius: \"50%\",\n backgroundColor: s <= step ? t.accent : t.inputBorder,\n transition: \"background-color 0.2s ease\",\n }} />\n {i < 2 && (\n <div style={{\n width: \"40px\",\n height: \"2px\",\n backgroundColor: s < step ? t.accent : t.inputBorder,\n transition: \"background-color 0.2s ease\",\n }} />\n )}\n </div>\n ))}\n </div>\n </div>\n\n {/* Body */}\n <div style={{ padding: \"16px\" }}>\n {submitted ? (\n <div\n style={{\n textAlign: \"center\",\n padding: \"20px 0\",\n color: t.accent,\n fontSize: \"14px\",\n fontWeight: 500,\n }}\n >\n {getTypeLabel(reportType)} sent. Thank you!\n </div>\n ) : (\n <>\n {/* Step 1: Category */}\n {step === 1 && (\n <div style={{ display: \"grid\", gridTemplateColumns: \"1fr 1fr\", gap: \"8px\" }}>\n {availableTypes.map((type) => (\n <button\n key={type}\n type=\"button\"\n onClick={() => {\n setReportType(type);\n setStep(2);\n }}\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: \"8px\",\n padding: \"16px 8px\",\n borderRadius: \"8px\",\n border: `1px solid ${t.inputBorder}`,\n background: t.inputBg,\n cursor: \"pointer\",\n color: t.text,\n fontFamily: \"inherit\",\n transition: \"border-color 0.15s ease\",\n }}\n onMouseEnter={(e) => { (e.currentTarget as HTMLElement).style.borderColor = t.accent; }}\n onMouseLeave={(e) => { (e.currentTarget as HTMLElement).style.borderColor = t.inputBorder; }}\n >\n {getTypeIcon(type, t.accent)}\n <span style={{ fontSize: \"13px\", fontWeight: 600 }}>{getTypeLabel(type)}</span>\n <span style={{ fontSize: \"11px\", color: t.textMuted, lineHeight: \"1.3\" }}>{getTypeSubtitle(type)}</span>\n </button>\n ))}\n </div>\n )}\n\n {/* Step 2: Details */}\n {step === 2 && (\n <>\n <textarea\n value={description}\n onChange={(e) => { setDescription(e.target.value); if (validationError) setValidationError(null); }}\n placeholder={getPlaceholder(reportType)}\n style={{\n width: \"100%\",\n minHeight: \"100px\",\n padding: \"10px 12px\",\n borderRadius: \"8px\",\n border: `1px solid ${t.inputBorder}`,\n fontSize: \"14px\",\n fontFamily: \"inherit\",\n resize: \"vertical\",\n outline: \"none\",\n boxSizing: \"border-box\",\n color: t.text,\n backgroundColor: t.inputBg,\n }}\n onFocus={(e) => { (e.target as HTMLTextAreaElement).style.borderColor = t.accent; }}\n onBlur={(e) => { (e.target as HTMLTextAreaElement).style.borderColor = t.inputBorder; }}\n autoFocus\n />\n {showSeverity && reportType === \"BUG\" && (\n <div style={{ marginTop: \"10px\" }}>\n <span style={{ fontSize: \"12px\", color: t.textMuted, marginBottom: \"6px\", display: \"block\" }}>Severity</span>\n <div style={{ display: \"flex\", gap: \"6px\" }}>\n {([\"low\", \"medium\", \"high\"] as ReportSeverity[]).map((s) => (\n <button\n key={s}\n type=\"button\"\n onClick={() => setSeverity(s)}\n style={{\n flex: 1,\n padding: \"6px 0\",\n borderRadius: \"6px\",\n border: `1px solid ${severity === s ? t.accent : t.inputBorder}`,\n background: severity === s ? t.accent : \"transparent\",\n color: severity === s ? t.accentText : t.text,\n fontSize: \"12px\",\n fontWeight: 600,\n cursor: \"pointer\",\n fontFamily: \"inherit\",\n textTransform: \"capitalize\",\n transition: \"all 0.15s ease\",\n }}\n >\n {s}\n </button>\n ))}\n </div>\n </div>\n )}\n {validationError && (\n <p style={{ color: \"#ef4444\", fontSize: \"12px\", marginTop: \"6px\" }}>\n {validationError}\n </p>\n )}\n <button\n type=\"button\"\n onClick={() => {\n const err = isLowQualityText(description);\n if (err) { setValidationError(err); return; }\n setValidationError(null);\n setStep(3);\n }}\n disabled={!description.trim()}\n style={{\n marginTop: \"12px\",\n width: \"100%\",\n padding: \"10px\",\n borderRadius: \"8px\",\n border: \"none\",\n backgroundColor: !description.trim() ? t.bgSecondary : t.accent,\n color: !description.trim() ? t.textMuted : t.accentText,\n fontSize: \"14px\",\n fontWeight: 600,\n cursor: !description.trim() ? \"not-allowed\" : \"pointer\",\n fontFamily: \"inherit\",\n transition: \"background-color 0.15s ease\",\n }}\n >\n Next\n </button>\n </>\n )}\n\n {/* Step 3: Review & Send */}\n {step === 3 && (\n <>\n {/* Summary chips */}\n <div style={{ display: \"flex\", gap: \"6px\", flexWrap: \"wrap\", marginBottom: \"12px\" }}>\n <span style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: \"4px\",\n padding: \"4px 10px\",\n borderRadius: \"12px\",\n fontSize: \"12px\",\n fontWeight: 600,\n backgroundColor: t.bgSecondary,\n color: t.text,\n border: `1px solid ${t.border}`,\n }}>\n {getTypeIcon(reportType, t.accent, 12)}\n {getTypeLabel(reportType)}\n </span>\n {showSeverity && reportType === \"BUG\" && (\n <span style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n padding: \"4px 10px\",\n borderRadius: \"12px\",\n fontSize: \"12px\",\n fontWeight: 600,\n backgroundColor: severity === \"high\" ? \"#fef2f2\" : severity === \"medium\" ? \"#fffbeb\" : \"#f0fdf4\",\n color: severity === \"high\" ? \"#dc2626\" : severity === \"medium\" ? \"#d97706\" : \"#16a34a\",\n border: `1px solid ${severity === \"high\" ? \"#fecaca\" : severity === \"medium\" ? \"#fde68a\" : \"#bbf7d0\"}`,\n textTransform: \"capitalize\",\n }}>\n {severity}\n </span>\n )}\n </div>\n\n {/* Description preview */}\n <div style={{\n padding: \"10px 12px\",\n borderRadius: \"8px\",\n border: `1px solid ${t.inputBorder}`,\n backgroundColor: t.inputBg,\n fontSize: \"13px\",\n color: t.text,\n marginBottom: \"10px\",\n maxHeight: \"80px\",\n overflow: \"hidden\",\n lineHeight: \"1.4\",\n }}>\n {description.length > 200 ? description.slice(0, 200) + \"...\" : description}\n </div>\n\n {/* Screenshot */}\n {screenshot && (\n <div style={{ marginBottom: \"10px\", position: \"relative\" }}>\n <img\n src={screenshot}\n alt=\"Page screenshot\"\n onClick={() => setPreviewOpen(true)}\n style={{\n width: \"100%\",\n borderRadius: \"6px\",\n border: `1px solid ${t.border}`,\n maxHeight: \"80px\",\n objectFit: \"cover\",\n objectPosition: \"top\",\n cursor: \"pointer\",\n }}\n />\n <button\n type=\"button\"\n onClick={() => setScreenshot(null)}\n style={{\n position: \"absolute\",\n top: \"4px\",\n right: \"4px\",\n background: \"rgba(0,0,0,0.6)\",\n border: \"none\",\n borderRadius: \"50%\",\n width: \"20px\",\n height: \"20px\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n aria-label=\"Remove screenshot\"\n >\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"none\">\n <path d=\"M1 1L9 9M9 1L1 9\" stroke=\"#fff\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n </button>\n </div>\n )}\n {!screenshot && (\n <div style={{ display: \"flex\", gap: \"6px\", marginBottom: \"10px\" }}>\n <button\n type=\"button\"\n onClick={() => fileInputRef.current?.click()}\n style={{\n flex: 1,\n padding: \"8px\",\n borderRadius: \"6px\",\n border: `1px dashed ${t.inputBorder}`,\n textAlign: \"center\",\n fontSize: \"11px\",\n color: t.textMuted,\n background: \"none\",\n cursor: \"pointer\",\n }}\n >\n Upload or paste (⌘V)\n </button>\n <button\n type=\"button\"\n onClick={retakeScreenshot}\n style={{\n flex: 1,\n padding: \"8px\",\n borderRadius: \"6px\",\n border: `1px dashed ${t.inputBorder}`,\n textAlign: \"center\",\n fontSize: \"11px\",\n color: t.textMuted,\n background: \"none\",\n cursor: \"pointer\",\n }}\n >\n Retake screenshot\n </button>\n </div>\n )}\n\n <button\n type=\"button\"\n onClick={handleSubmit}\n disabled={isSubmitting}\n style={{\n width: \"100%\",\n padding: \"10px\",\n borderRadius: \"8px\",\n border: \"none\",\n backgroundColor: isSubmitting ? t.bgSecondary : t.accent,\n color: isSubmitting ? t.textMuted : t.accentText,\n fontSize: \"14px\",\n fontWeight: 600,\n cursor: isSubmitting ? \"not-allowed\" : \"pointer\",\n fontFamily: \"inherit\",\n transition: \"background-color 0.15s ease\",\n }}\n >\n {isSubmitting ? \"Sending...\" : \"Send Report\"}\n </button>\n </>\n )}\n </>\n )}\n </div>\n\n {/* Footer */}\n <div\n style={{\n padding: \"8px 16px 10px\",\n borderTop: `1px solid ${t.border}`,\n textAlign: \"center\",\n }}\n >\n <span style={{ fontSize: \"11px\", color: t.textMuted }}>\n Powered by Glitchgrab\n </span>\n </div>\n </div>\n </div>,\n document.body\n )}\n\n {/* Hidden file input */}\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\"image/*\"\n onChange={handleFileUpload}\n style={{ display: \"none\" }}\n />\n\n {/* Full-screen screenshot preview */}\n {previewOpen && screenshot && createPortal(\n <div\n style={{\n position: \"fixed\",\n inset: 0,\n zIndex: 2147483647,\n backgroundColor: \"rgba(0,0,0,0.85)\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: \"16px\",\n cursor: \"pointer\",\n }}\n onClick={(e) => { e.stopPropagation(); setPreviewOpen(false); }}\n onMouseDown={(e) => e.stopPropagation()}\n >\n <img\n src={screenshot}\n alt=\"Screenshot preview\"\n onClick={(e) => e.stopPropagation()}\n style={{\n maxWidth: \"100%\",\n maxHeight: \"calc(100vh - 80px)\",\n borderRadius: \"8px\",\n objectFit: \"contain\",\n cursor: \"default\",\n }}\n />\n <span\n style={{\n marginTop: \"12px\",\n color: t.textMuted,\n fontSize: \"12px\",\n }}\n >\n Click outside to close\n </span>\n </div>,\n document.body\n )}\n </>\n );\n}\n\n/* ─── Helpers ─── */\n\nfunction getTypeLabel(type: ReportType): string {\n switch (type) {\n case \"BUG\": return \"Bug Report\";\n case \"FEATURE_REQUEST\": return \"Feature Request\";\n case \"QUESTION\": return \"Question\";\n case \"OTHER\": return \"Other\";\n }\n}\n\nfunction getTypeSubtitle(type: ReportType): string {\n switch (type) {\n case \"BUG\": return \"Something isn't working\";\n case \"FEATURE_REQUEST\": return \"Suggest an improvement\";\n case \"QUESTION\": return \"Ask a question\";\n case \"OTHER\": return \"General feedback\";\n }\n}\n\nfunction getPlaceholder(type: ReportType): string {\n switch (type) {\n case \"BUG\": return \"What went wrong?\";\n case \"FEATURE_REQUEST\": return \"Describe the feature you'd like...\";\n case \"QUESTION\": return \"What would you like to know?\";\n case \"OTHER\": return \"Tell us what's on your mind...\";\n }\n}\n\nfunction getTypeIcon(type: ReportType, color: string, size = 24): ReactNode {\n const props = { width: size, height: size, viewBox: \"0 0 24 24\", fill: \"none\", style: { flexShrink: 0 } as CSSProperties };\n switch (type) {\n case \"BUG\":\n return <svg {...props}><path d=\"M8 2L6.5 3.5M16 2L17.5 3.5M3 9H7M17 9H21M12 2a5 5 0 015 5v4a5 5 0 01-10 0V7a5 5 0 015-5zM7 16l-2 3M17 16l2 3\" stroke={color} strokeWidth=\"1.5\" strokeLinecap=\"round\" /></svg>;\n case \"FEATURE_REQUEST\":\n return <svg {...props}><path d=\"M12 2L15.09 8.26L22 9.27L17 14.14L18.18 21.02L12 17.77L5.82 21.02L7 14.14L2 9.27L8.91 8.26L12 2z\" stroke={color} strokeWidth=\"1.5\" strokeLinejoin=\"round\" /></svg>;\n case \"QUESTION\":\n return <svg {...props}><circle cx=\"12\" cy=\"12\" r=\"10\" stroke={color} strokeWidth=\"1.5\" /><path d=\"M9.09 9a3 3 0 015.83 1c0 2-3 3-3 3M12 17h.01\" stroke={color} strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" /></svg>;\n case \"OTHER\":\n return <svg {...props}><path d=\"M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2v10z\" stroke={color} strokeWidth=\"1.5\" strokeLinejoin=\"round\" /></svg>;\n }\n}\n","\"use client\";\n\nimport { useState, type CSSProperties, type ReactNode } from \"react\";\nimport type { ReportButtonProps } from \"./types\";\nimport { useGlitchgrab } from \"./provider\";\n\n/** Safe version of useGlitchgrab that returns null when outside provider */\nfunction useGlitchgrabSafe() {\n try {\n return useGlitchgrab();\n } catch {\n return null;\n }\n}\n\n/**\n * Optional trigger button for opening the report dialog.\n *\n * The dialog itself lives inside `GlitchgrabProvider` — you don't need this component\n * unless you want a visible trigger button. You can also open the dialog programmatically\n * via `useGlitchgrab().openReportDialog()`.\n *\n * @example\n * ```tsx\n * // Use the default floating button\n * <ReportButton />\n *\n * // Use your own trigger\n * <ReportButton>\n * {({ onClick }) => <button onClick={onClick}>Report</button>}\n * </ReportButton>\n *\n * // Or skip ReportButton entirely and use the hook\n * const { openReportDialog } = useGlitchgrab();\n * <button onClick={() => openReportDialog()}>Report</button>\n * ```\n */\nexport function ReportButton({\n position = \"bottom-right\",\n label = \"Report Bug\",\n className,\n children,\n}: ReportButtonProps & {\n children?: (props: { onClick: () => void; capturing: boolean }) => ReactNode;\n}) {\n const [capturing, setCapturing] = useState(false);\n const glitchgrab = useGlitchgrabSafe();\n\n if (!glitchgrab) return null;\n\n const handleClick = async () => {\n setCapturing(true);\n glitchgrab.openReportDialog();\n setCapturing(false);\n };\n\n // Custom trigger via render prop\n if (children) {\n return <>{children({ onClick: handleClick, capturing })}</>;\n }\n\n // Default floating button\n const isTop = position?.startsWith(\"top\") ?? false;\n const isLeft = position?.endsWith(\"left\") ?? false;\n\n const positionStyles: CSSProperties = {\n ...(isLeft ? { left: \"16px\" } : { right: \"16px\" }),\n ...(isTop ? { top: \"16px\" } : { bottom: \"16px\" }),\n };\n\n return (\n <button\n type=\"button\"\n onClick={handleClick}\n disabled={capturing}\n className={className}\n style={{\n position: \"fixed\",\n ...positionStyles,\n zIndex: 99999,\n padding: \"10px 18px\",\n borderRadius: \"24px\",\n border: \"none\",\n backgroundColor: \"#18181b\",\n color: \"#fafafa\",\n fontSize: \"14px\",\n fontWeight: 500,\n fontFamily:\n '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n cursor: capturing ? \"wait\" : \"pointer\",\n boxShadow:\n \"0 4px 12px rgba(0, 0, 0, 0.15), 0 1px 3px rgba(0, 0, 0, 0.1)\",\n transition: \"transform 0.15s ease, box-shadow 0.15s ease\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"6px\",\n opacity: capturing ? 0.7 : 1,\n }}\n onMouseEnter={(e) => {\n (e.target as HTMLElement).style.transform = \"scale(1.05)\";\n }}\n onMouseLeave={(e) => {\n (e.target as HTMLElement).style.transform = \"scale(1)\";\n }}\n aria-label={label}\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n style={{ flexShrink: 0 }}\n >\n <path\n d=\"M8 1C4.134 1 1 4.134 1 8s3.134 7 7 7 7-3.134 7-7-3.134-7-7-7zm0 12.5a.75.75 0 110-1.5.75.75 0 010 1.5zm.75-3.5a.75.75 0 01-1.5 0V5a.75.75 0 011.5 0v5z\"\n fill=\"currentColor\"\n />\n </svg>\n {capturing ? \"Capturing...\" : label}\n </button>\n );\n}\n","\"use client\";\n\nimport { useState, useEffect, useCallback } from \"react\";\n\nexport interface GlitchgrabReport {\n id: string;\n source: string;\n status: string;\n rawInput: string | null;\n reporterPrimaryKey: string;\n reporterName: string;\n reporterEmail: string | null;\n reporterPhone: string | null;\n pageUrl: string | null;\n createdAt: string;\n /** Number of comments on the linked GitHub issue (0 if no issue) */\n commentCount: number;\n issue: {\n githubNumber: number;\n githubUrl: string;\n title: string;\n labels: string[];\n severity: string | null;\n githubState: string | null;\n } | null;\n}\n\nconst BASE_URL = \"https://www.glitchgrab.dev\";\n\n/**\n * Hook to fetch bug reports for a specific user.\n *\n * ```tsx\n * const { reports, isLoading, error, refetch } = useGlitchgrabReports({\n * token: process.env.NEXT_PUBLIC_GLITCHGRAB_TOKEN!,\n * userId: session.user.id,\n * });\n * ```\n */\nexport function useGlitchgrabReports({\n token,\n userId,\n limit = 100,\n}: {\n token: string;\n userId: string;\n /** Max results (default 100, max 100) */\n limit?: number;\n}): {\n reports: GlitchgrabReport[];\n isLoading: boolean;\n isFetching: boolean;\n error: string | null;\n refetch: () => Promise<void>;\n} {\n const [reports, setReports] = useState<GlitchgrabReport[]>([]);\n const [isLoading, setIsLoading] = useState(true);\n const [isFetching, setIsFetching] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const fetchReports = useCallback(async () => {\n if (!token || !userId) {\n setIsLoading(false);\n return;\n }\n\n setIsFetching(true);\n setError(null);\n\n try {\n const res = await fetch(\n `${BASE_URL}/api/v1/sdk/reports?reporterPrimaryKey=${encodeURIComponent(userId)}&limit=${limit}`,\n { headers: { Authorization: `Bearer ${token}` } }\n );\n const data = await res.json();\n\n if (data.success) {\n setReports(data.data ?? []);\n } else {\n setError(data.error ?? \"Failed to fetch reports\");\n }\n } catch {\n setError(\"Network error\");\n } finally {\n setIsLoading(false);\n setIsFetching(false);\n }\n }, [token, userId, limit]);\n\n useEffect(() => {\n fetchReports();\n }, [fetchReports]);\n\n return { reports, isLoading, isFetching, error, refetch: fetchReports };\n}\n\n/**\n * Standalone fetcher — use with TanStack Query or any data fetching library.\n *\n * ```tsx\n * const { data } = useQuery({\n * queryKey: [\"glitchgrab-reports\", userId],\n * queryFn: () => fetchGlitchgrabReports({\n * token: process.env.NEXT_PUBLIC_GLITCHGRAB_TOKEN!,\n * userId: session.user.id,\n * }),\n * });\n * ```\n */\nexport async function fetchGlitchgrabReports({\n token,\n userId,\n limit = 100,\n}: {\n token: string;\n userId: string;\n limit?: number;\n}): Promise<GlitchgrabReport[]> {\n const res = await fetch(\n `${BASE_URL}/api/v1/sdk/reports?reporterPrimaryKey=${encodeURIComponent(userId)}&limit=${limit}`,\n { headers: { Authorization: `Bearer ${token}` } }\n );\n const data = await res.json();\n if (!data.success) throw new Error(data.error ?? \"Failed to fetch reports\");\n return data.data ?? [];\n}\n\n// ─── Report Actions ─────────────────────────────────────\n\nasync function reportAction(\n token: string,\n reportId: string,\n body: Record<string, string>\n): Promise<void> {\n const res = await fetch(`${BASE_URL}/api/v1/reports/${reportId}/actions`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(body),\n });\n const data = await res.json().catch(() => ({}));\n if (!res.ok || !data.success) throw new Error(data.error ?? \"Action failed\");\n}\n\n/**\n * Hook to manage report actions with loading/error states.\n *\n * ```tsx\n * const { approve, reject, close, isPending, error } = useGlitchgrabActions({\n * token: process.env.NEXT_PUBLIC_GLITCHGRAB_TOKEN!,\n * onSuccess: () => refetch(),\n * onError: (err) => toast.error(err.message),\n * });\n *\n * <button onClick={() => approve(reportId)} disabled={isPending}>\n * {isPending ? \"...\" : \"Approve\"}\n * </button>\n * ```\n */\nexport function useGlitchgrabActions({\n token,\n onSuccess,\n onError,\n}: {\n token: string;\n onSuccess?: () => void;\n onError?: (error: Error) => void;\n}) {\n const [isPending, setIsPending] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const run = useCallback(\n async (reportId: string, body: Record<string, string>) => {\n setIsPending(true);\n setError(null);\n try {\n await reportAction(token, reportId, body);\n onSuccess?.();\n } catch (e) {\n const err = e instanceof Error ? e : new Error(\"Action failed\");\n setError(err.message);\n onError?.(err);\n } finally {\n setIsPending(false);\n }\n },\n [token, onSuccess, onError]\n );\n\n return {\n approve: (reportId: string) => run(reportId, { action: \"label\", label: \"approved\" }),\n reject: (reportId: string) => run(reportId, { action: \"label\", label: \"rejected\" }),\n close: (reportId: string) => run(reportId, { action: \"close\" }),\n reopen: (reportId: string) => run(reportId, { action: \"reopen\" }),\n label: (reportId: string, label: string) => run(reportId, { action: \"label\", label }),\n unlabel: (reportId: string, label: string) => run(reportId, { action: \"unlabel\", label }),\n isPending,\n error,\n };\n}\n"],"mappings":"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","names":["useRef","useEffect","e","rgb","words","e","Fragment","jsx","jsxs","DEFAULT_BASE_URL","maxBreadcrumbs","useRef","useEffect","addBreadcrumb","useState","Fragment","jsx","jsxs","useState","useState","useEffect","useCallback"]}
|