glitchgrab 1.12.0 → 1.13.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 CHANGED
@@ -50,7 +50,7 @@ __export(index_exports, {
50
50
  module.exports = __toCommonJS(index_exports);
51
51
 
52
52
  // src/provider.tsx
53
- var import_react = require("react");
53
+ var import_react2 = require("react");
54
54
 
55
55
  // src/error-boundary.tsx
56
56
  var React = __toESM(require("react"));
@@ -359,244 +359,10 @@ var GlitchgrabErrorBoundary = class extends React.Component {
359
359
  }
360
360
  };
361
361
 
362
- // src/provider.tsx
363
- var import_jsx_runtime = require("react/jsx-runtime");
364
- var DEFAULT_BASE_URL2 = "https://www.glitchgrab.dev";
365
- var GlitchgrabContext = (0, import_react.createContext)(null);
366
- function useGlitchgrab() {
367
- const ctx = (0, import_react.useContext)(GlitchgrabContext);
368
- if (!ctx) {
369
- throw new Error("useGlitchgrab must be used within a GlitchgrabProvider");
370
- }
371
- return ctx;
372
- }
373
- function GlitchgrabProviderInner({
374
- token,
375
- session,
376
- baseUrl,
377
- onError,
378
- onReportSent,
379
- breadcrumbs: enableBreadcrumbs = true,
380
- maxBreadcrumbs: maxBreadcrumbs2 = 50,
381
- children,
382
- fallback
383
- }) {
384
- const visitedPagesRef = (0, import_react.useRef)([]);
385
- (0, import_react.useEffect)(() => {
386
- if (enableBreadcrumbs) {
387
- initBreadcrumbs(maxBreadcrumbs2);
388
- }
389
- }, [enableBreadcrumbs, maxBreadcrumbs2]);
390
- (0, import_react.useEffect)(() => {
391
- try {
392
- if (typeof window === "undefined") return;
393
- const trackPage = () => {
394
- try {
395
- const sanitized = sanitizeUrl(window.location.href);
396
- const pages = visitedPagesRef.current;
397
- if (pages[pages.length - 1] !== sanitized) {
398
- pages.push(sanitized);
399
- if (pages.length > 20) {
400
- pages.splice(0, pages.length - 20);
401
- }
402
- }
403
- } catch (e) {
404
- }
405
- };
406
- trackPage();
407
- const handlePopState = () => trackPage();
408
- window.addEventListener("popstate", handlePopState);
409
- const origPushState = history.pushState.bind(history);
410
- const origReplaceState = history.replaceState.bind(history);
411
- history.pushState = function(...args) {
412
- origPushState(...args);
413
- trackPage();
414
- };
415
- history.replaceState = function(...args) {
416
- origReplaceState(...args);
417
- trackPage();
418
- };
419
- return () => {
420
- window.removeEventListener("popstate", handlePopState);
421
- history.pushState = origPushState;
422
- history.replaceState = origReplaceState;
423
- };
424
- } catch (e) {
425
- }
426
- }, []);
427
- (0, import_react.useEffect)(() => {
428
- try {
429
- if (typeof window === "undefined") return;
430
- if (process.env.NODE_ENV === "development") return;
431
- const handleError = (event) => {
432
- var _a, _b, _c, _d, _e;
433
- try {
434
- const context = captureContext(visitedPagesRef.current);
435
- const payload = {
436
- token,
437
- source: "SDK_AUTO",
438
- type: "BUG",
439
- errorMessage: event.message,
440
- errorStack: (_a = event.error) == null ? void 0 : _a.stack,
441
- pageUrl: context.url,
442
- userAgent: context.userAgent,
443
- breadcrumbs: context.breadcrumbs,
444
- deviceInfo: (_b = context.deviceInfo) != null ? _b : void 0,
445
- metadata: {
446
- timestamp: context.timestamp,
447
- visitedPages: JSON.stringify(context.visitedPages),
448
- filename: (_c = event.filename) != null ? _c : "",
449
- lineno: String((_d = event.lineno) != null ? _d : ""),
450
- colno: String((_e = event.colno) != null ? _e : ""),
451
- ...(session == null ? void 0 : session.userId) ? { sessionUserId: session.userId } : {},
452
- ...(session == null ? void 0 : session.name) ? { sessionUserName: String(session.name) } : {},
453
- ...(session == null ? void 0 : session.email) ? { sessionUserEmail: String(session.email) } : {}
454
- }
455
- };
456
- sendReport(payload, baseUrl).then((result) => {
457
- if (result && onReportSent) onReportSent(result);
458
- });
459
- if (onError && event.error) onError(event.error);
460
- } catch (e) {
461
- }
462
- };
463
- const handleRejection = (event) => {
464
- var _a;
465
- try {
466
- const context = captureContext(visitedPagesRef.current);
467
- const reason = event.reason;
468
- const payload = {
469
- token,
470
- source: "SDK_AUTO",
471
- type: "BUG",
472
- errorMessage: reason instanceof Error ? reason.message : String(reason),
473
- errorStack: reason instanceof Error ? reason.stack : void 0,
474
- pageUrl: context.url,
475
- userAgent: context.userAgent,
476
- breadcrumbs: context.breadcrumbs,
477
- deviceInfo: (_a = context.deviceInfo) != null ? _a : void 0,
478
- metadata: {
479
- timestamp: context.timestamp,
480
- visitedPages: JSON.stringify(context.visitedPages),
481
- type: "unhandledrejection",
482
- ...(session == null ? void 0 : session.userId) ? { sessionUserId: session.userId } : {},
483
- ...(session == null ? void 0 : session.name) ? { sessionUserName: String(session.name) } : {},
484
- ...(session == null ? void 0 : session.email) ? { sessionUserEmail: String(session.email) } : {}
485
- }
486
- };
487
- sendReport(payload, baseUrl).then((result) => {
488
- if (result && onReportSent) onReportSent(result);
489
- });
490
- if (onError && reason instanceof Error) onError(reason);
491
- } catch (e) {
492
- }
493
- };
494
- window.addEventListener("error", handleError);
495
- window.addEventListener("unhandledrejection", handleRejection);
496
- return () => {
497
- window.removeEventListener("error", handleError);
498
- window.removeEventListener("unhandledrejection", handleRejection);
499
- };
500
- } catch (e) {
501
- }
502
- }, [token, baseUrl, onError, onReportSent]);
503
- const report = (0, import_react.useCallback)(
504
- async (type, description, metadata) => {
505
- var _a;
506
- try {
507
- const context = captureContext(visitedPagesRef.current);
508
- const payload = {
509
- token,
510
- source: "SDK_USER_REPORT",
511
- type,
512
- description,
513
- pageUrl: context.url,
514
- userAgent: context.userAgent,
515
- breadcrumbs: context.breadcrumbs,
516
- deviceInfo: (_a = context.deviceInfo) != null ? _a : void 0,
517
- metadata: {
518
- timestamp: context.timestamp,
519
- visitedPages: JSON.stringify(context.visitedPages),
520
- ...(session == null ? void 0 : session.userId) ? { sessionUserId: session.userId } : {},
521
- ...(session == null ? void 0 : session.name) ? { sessionUserName: String(session.name) } : {},
522
- ...(session == null ? void 0 : session.email) ? { sessionUserEmail: String(session.email) } : {},
523
- ...(session == null ? void 0 : session.phone) ? { sessionUserPhone: String(session.phone) } : {},
524
- ...metadata
525
- }
526
- };
527
- const result = await sendReport(payload, baseUrl);
528
- if (result && onReportSent) onReportSent(result);
529
- return result;
530
- } catch (e) {
531
- return null;
532
- }
533
- },
534
- [token, baseUrl, onReportSent, session]
535
- );
536
- const reportBug = (0, import_react.useCallback)(
537
- (description, metadata) => report("BUG", description, metadata),
538
- [report]
539
- );
540
- const addBreadcrumb2 = (0, import_react.useCallback)(
541
- (message, data) => {
542
- addBreadcrumb("custom", message, data);
543
- },
544
- []
545
- );
546
- const openReportDialog = (0, import_react.useCallback)((options) => {
547
- if (typeof window !== "undefined") {
548
- window.dispatchEvent(new CustomEvent("glitchgrab:open-report", { detail: options }));
549
- }
550
- }, []);
551
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
552
- GlitchgrabContext.Provider,
553
- {
554
- value: {
555
- token,
556
- baseUrl: baseUrl != null ? baseUrl : DEFAULT_BASE_URL2,
557
- reportBug,
558
- report,
559
- addBreadcrumb: addBreadcrumb2,
560
- openReportDialog
561
- },
562
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
563
- GlitchgrabErrorBoundary,
564
- {
565
- token,
566
- baseUrl,
567
- onError,
568
- fallback,
569
- visitedPages: visitedPagesRef.current,
570
- children
571
- }
572
- )
573
- }
574
- );
575
- }
576
- function GlitchgrabProvider(props) {
577
- if (!props.token) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: props.children });
578
- const resolvedProps = {
579
- ...props,
580
- baseUrl: props.baseUrl || DEFAULT_BASE_URL2
581
- };
582
- try {
583
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(GlitchgrabProviderInner, { ...resolvedProps });
584
- } catch (e) {
585
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: props.children });
586
- }
587
- }
588
-
589
- // src/report-button.tsx
590
- var import_react2 = require("react");
362
+ // src/report-dialog.tsx
363
+ var import_react = require("react");
591
364
  var import_react_dom = require("react-dom");
592
- var import_jsx_runtime2 = require("react/jsx-runtime");
593
- function useGlitchgrabSafe() {
594
- try {
595
- return useGlitchgrab();
596
- } catch (e) {
597
- return null;
598
- }
599
- }
365
+ var import_jsx_runtime = require("react/jsx-runtime");
600
366
  function useIsDark() {
601
367
  if (typeof window === "undefined") return true;
602
368
  try {
@@ -614,37 +380,32 @@ function useIsDark() {
614
380
  function getTheme(dark) {
615
381
  return dark ? { bg: "#1c1c1e", bgSecondary: "#27272a", border: "#2c2c2e", text: "#fafafa", textMuted: "#a1a1aa", accent: "#22d3ee", accentText: "#09090b", inputBg: "#27272a", inputBorder: "#3f3f46" } : { bg: "#ffffff", bgSecondary: "#f4f4f5", border: "#e4e4e7", text: "#18181b", textMuted: "#71717a", accent: "#0891b2", accentText: "#ffffff", inputBg: "#fafafa", inputBorder: "#d4d4d8" };
616
382
  }
617
- function ReportButton({
618
- position = "bottom-right",
619
- label = "Report Bug",
620
- className,
621
- variant = "classic",
622
- showSeverity = true,
383
+ function ReportDialog({
384
+ report,
623
385
  types,
624
- children
386
+ showSeverity = true
625
387
  }) {
626
- var _a, _b;
627
- const [capturing, setCapturing] = (0, import_react2.useState)(false);
628
- const [isOpen, setIsOpen] = (0, import_react2.useState)(false);
629
- const [description, setDescription] = (0, import_react2.useState)("");
630
- const [isSubmitting, setIsSubmitting] = (0, import_react2.useState)(false);
631
- const [submitted, setSubmitted] = (0, import_react2.useState)(false);
632
- const [screenshot, setScreenshot] = (0, import_react2.useState)(null);
633
- const [previewOpen, setPreviewOpen] = (0, import_react2.useState)(false);
634
- const fileInputRef = (0, import_react2.useRef)(null);
635
- const modalRef = (0, import_react2.useRef)(null);
636
- const glitchgrab = useGlitchgrabSafe();
637
- const [step, setStep] = (0, import_react2.useState)(1);
638
- const [reportType, setReportType] = (0, import_react2.useState)("BUG");
639
- const [severity, setSeverity] = (0, import_react2.useState)("medium");
388
+ const [mounted, setMounted] = (0, import_react.useState)(false);
389
+ (0, import_react.useEffect)(() => {
390
+ setMounted(true);
391
+ }, []);
392
+ const [isOpen, setIsOpen] = (0, import_react.useState)(false);
393
+ const [description, setDescription] = (0, import_react.useState)("");
394
+ const [isSubmitting, setIsSubmitting] = (0, import_react.useState)(false);
395
+ const [submitted, setSubmitted] = (0, import_react.useState)(false);
396
+ const [screenshot, setScreenshot] = (0, import_react.useState)(null);
397
+ const [previewOpen, setPreviewOpen] = (0, import_react.useState)(false);
398
+ const fileInputRef = (0, import_react.useRef)(null);
399
+ const modalRef = (0, import_react.useRef)(null);
400
+ const [step, setStep] = (0, import_react.useState)(1);
401
+ const [reportType, setReportType] = (0, import_react.useState)("BUG");
402
+ const [severity, setSeverity] = (0, import_react.useState)("medium");
640
403
  const availableTypes = types != null ? types : ["BUG", "FEATURE_REQUEST", "QUESTION", "OTHER"];
641
- if (!glitchgrab) return null;
642
- const { reportBug, report } = glitchgrab;
643
404
  const isDark = useIsDark();
644
405
  const t = getTheme(isDark);
645
406
  const handleFileUpload = (e) => {
646
- var _a2;
647
- const file = (_a2 = e.target.files) == null ? void 0 : _a2[0];
407
+ var _a;
408
+ const file = (_a = e.target.files) == null ? void 0 : _a[0];
648
409
  if (!file) return;
649
410
  const reader = new FileReader();
650
411
  reader.onload = () => {
@@ -672,9 +433,8 @@ function ReportButton({
672
433
  setIsOpen(true);
673
434
  };
674
435
  const handleOpen = async () => {
675
- setCapturing(true);
676
436
  setSubmitted(false);
677
- if (variant === "stepper" && availableTypes.length === 1) {
437
+ if (availableTypes.length === 1) {
678
438
  setReportType(availableTypes[0]);
679
439
  setStep(2);
680
440
  }
@@ -689,24 +449,23 @@ function ReportButton({
689
449
  setScreenshot(canvas.toDataURL("image/jpeg", 0.6));
690
450
  } catch (e) {
691
451
  }
692
- setCapturing(false);
693
452
  setIsOpen(true);
694
453
  };
695
- (0, import_react2.useEffect)(() => {
454
+ (0, import_react.useEffect)(() => {
696
455
  const handler = (e) => {
697
456
  if (isOpen) return;
698
457
  const detail = e.detail;
699
458
  if (detail == null ? void 0 : detail.description) setDescription(detail.description);
700
459
  if (detail == null ? void 0 : detail.type) {
701
460
  setReportType(detail.type);
702
- if (variant === "stepper") setStep(2);
461
+ setStep(2);
703
462
  }
704
463
  handleOpen();
705
464
  };
706
465
  window.addEventListener("glitchgrab:open-report", handler);
707
466
  return () => window.removeEventListener("glitchgrab:open-report", handler);
708
- }, [isOpen, handleOpen, variant]);
709
- (0, import_react2.useEffect)(() => {
467
+ }, [isOpen, handleOpen]);
468
+ (0, import_react.useEffect)(() => {
710
469
  if (!isOpen) return;
711
470
  const handleEsc = (e) => {
712
471
  if (e.key === "Escape") {
@@ -729,10 +488,10 @@ function ReportButton({
729
488
  setIsSubmitting(true);
730
489
  const metadata = {};
731
490
  if (screenshot) metadata.screenshot = screenshot;
732
- if (variant === "stepper" && showSeverity && reportType === "BUG") {
491
+ if (showSeverity && reportType === "BUG") {
733
492
  metadata.severity = severity;
734
493
  }
735
- const result = variant === "stepper" ? await report(reportType, description.trim(), Object.keys(metadata).length > 0 ? metadata : void 0) : await reportBug(description.trim(), Object.keys(metadata).length > 0 ? metadata : void 0);
494
+ const result = await report(reportType, description.trim(), Object.keys(metadata).length > 0 ? metadata : void 0);
736
495
  if (result) {
737
496
  setSubmitted(true);
738
497
  setDescription("");
@@ -747,27 +506,10 @@ function ReportButton({
747
506
  setIsSubmitting(false);
748
507
  }
749
508
  };
750
- const isTop = (_a = position == null ? void 0 : position.startsWith("top")) != null ? _a : false;
751
- const isLeft = (_b = position == null ? void 0 : position.endsWith("left")) != null ? _b : false;
752
- const modalPositionStyles = children ? {} : {
753
- ...isLeft ? { left: "16px" } : { right: "16px" },
754
- ...isTop ? { top: "64px" } : { bottom: "64px" }
755
- };
756
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
757
- children ? children({ onClick: handleOpen, capturing }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
758
- DefaultTrigger,
759
- {
760
- onClick: handleOpen,
761
- capturing,
762
- label,
763
- className,
764
- position,
765
- isLeft,
766
- isTop
767
- }
768
- ),
769
- isOpen && typeof document !== "undefined" && (0, import_react_dom.createPortal)(
770
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
509
+ if (!mounted) return null;
510
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
511
+ isOpen && (0, import_react_dom.createPortal)(
512
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
771
513
  "div",
772
514
  {
773
515
  style: {
@@ -783,14 +525,13 @@ function ReportButton({
783
525
  onClick: () => {
784
526
  if (!previewOpen) handleClose();
785
527
  },
786
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
528
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
787
529
  "div",
788
530
  {
789
531
  ref: modalRef,
790
532
  onClick: (e) => e.stopPropagation(),
791
533
  style: {
792
- position: children ? "relative" : "fixed",
793
- ...modalPositionStyles,
534
+ position: "relative",
794
535
  zIndex: 2147483647,
795
536
  width: "340px",
796
537
  maxWidth: "calc(100% - 32px)",
@@ -803,7 +544,7 @@ function ReportButton({
803
544
  isolation: "isolate"
804
545
  },
805
546
  children: [
806
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
547
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
807
548
  "div",
808
549
  {
809
550
  style: {
@@ -811,7 +552,7 @@ function ReportButton({
811
552
  borderBottom: `1px solid ${t.border}`
812
553
  },
813
554
  children: [
814
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
555
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
815
556
  "div",
816
557
  {
817
558
  style: {
@@ -820,8 +561,8 @@ function ReportButton({
820
561
  alignItems: "center"
821
562
  },
822
563
  children: [
823
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
824
- variant === "stepper" && step > 1 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
564
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
565
+ step > 1 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
825
566
  "button",
826
567
  {
827
568
  type: "button",
@@ -835,10 +576,10 @@ function ReportButton({
835
576
  alignItems: "center"
836
577
  },
837
578
  "aria-label": "Back",
838
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M10 3L5 8L10 13", stroke: t.textMuted, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) })
579
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M10 3L5 8L10 13", stroke: t.textMuted, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) })
839
580
  }
840
581
  ),
841
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
582
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
842
583
  "span",
843
584
  {
844
585
  style: {
@@ -846,11 +587,11 @@ function ReportButton({
846
587
  fontWeight: 600,
847
588
  color: t.text
848
589
  },
849
- children: variant === "stepper" ? step === 1 ? "What's on your mind?" : step === 2 ? "Tell us more" : "Review & Send" : "Report a Bug"
590
+ children: step === 1 ? "What's on your mind?" : step === 2 ? "Tell us more" : "Review & Send"
850
591
  }
851
592
  )
852
593
  ] }),
853
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
594
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
854
595
  "button",
855
596
  {
856
597
  type: "button",
@@ -865,21 +606,21 @@ function ReportButton({
865
606
  justifyContent: "center"
866
607
  },
867
608
  "aria-label": "Close",
868
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", style: { display: "block" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M4 4L12 12M12 4L4 12", stroke: t.textMuted, strokeWidth: "2", strokeLinecap: "round" }) })
609
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", style: { display: "block" }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M4 4L12 12M12 4L4 12", stroke: t.textMuted, strokeWidth: "2", strokeLinecap: "round" }) })
869
610
  }
870
611
  )
871
612
  ]
872
613
  }
873
614
  ),
874
- variant === "stepper" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", gap: "0", marginTop: "12px" }, children: [1, 2, 3].map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", alignItems: "center" }, children: [
875
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: {
615
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", gap: "0", marginTop: "12px" }, children: [1, 2, 3].map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", alignItems: "center" }, children: [
616
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: {
876
617
  width: "8px",
877
618
  height: "8px",
878
619
  borderRadius: "50%",
879
620
  backgroundColor: s <= step ? t.accent : t.inputBorder,
880
621
  transition: "background-color 0.2s ease"
881
622
  } }),
882
- i < 2 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: {
623
+ i < 2 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: {
883
624
  width: "40px",
884
625
  height: "2px",
885
626
  backgroundColor: s < step ? t.accent : t.inputBorder,
@@ -889,7 +630,7 @@ function ReportButton({
889
630
  ]
890
631
  }
891
632
  ),
892
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { padding: "16px" }, children: submitted ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
633
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { padding: "16px" }, children: submitted ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
893
634
  "div",
894
635
  {
895
636
  style: {
@@ -899,283 +640,172 @@ function ReportButton({
899
640
  fontSize: "14px",
900
641
  fontWeight: 500
901
642
  },
902
- children: variant === "stepper" ? `${getTypeLabel(reportType)} sent. Thank you!` : "Bug report sent. Thank you!"
643
+ children: [
644
+ getTypeLabel(reportType),
645
+ " sent. Thank you!"
646
+ ]
903
647
  }
904
- ) : variant === "stepper" ? (
905
- /* ─── Stepper Flow ─── */
906
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
907
- step === 1 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: "8px" }, children: availableTypes.map((type) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
908
- "button",
909
- {
910
- type: "button",
911
- onClick: () => {
912
- setReportType(type);
913
- setStep(2);
914
- },
915
- style: {
916
- display: "flex",
917
- flexDirection: "column",
918
- alignItems: "center",
919
- gap: "8px",
920
- padding: "16px 8px",
921
- borderRadius: "8px",
922
- border: `1px solid ${t.inputBorder}`,
923
- background: t.inputBg,
924
- cursor: "pointer",
925
- color: t.text,
926
- fontFamily: "inherit",
927
- transition: "border-color 0.15s ease"
648
+ ) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
649
+ step === 1 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: "8px" }, children: availableTypes.map((type) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
650
+ "button",
651
+ {
652
+ type: "button",
653
+ onClick: () => {
654
+ setReportType(type);
655
+ setStep(2);
656
+ },
657
+ style: {
658
+ display: "flex",
659
+ flexDirection: "column",
660
+ alignItems: "center",
661
+ gap: "8px",
662
+ padding: "16px 8px",
663
+ borderRadius: "8px",
664
+ border: `1px solid ${t.inputBorder}`,
665
+ background: t.inputBg,
666
+ cursor: "pointer",
667
+ color: t.text,
668
+ fontFamily: "inherit",
669
+ transition: "border-color 0.15s ease"
670
+ },
671
+ onMouseEnter: (e) => {
672
+ e.currentTarget.style.borderColor = t.accent;
673
+ },
674
+ onMouseLeave: (e) => {
675
+ e.currentTarget.style.borderColor = t.inputBorder;
676
+ },
677
+ children: [
678
+ getTypeIcon(type, t.accent),
679
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontSize: "13px", fontWeight: 600 }, children: getTypeLabel(type) }),
680
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontSize: "11px", color: t.textMuted, lineHeight: "1.3" }, children: getTypeSubtitle(type) })
681
+ ]
682
+ },
683
+ type
684
+ )) }),
685
+ step === 2 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
686
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
687
+ "textarea",
688
+ {
689
+ value: description,
690
+ onChange: (e) => setDescription(e.target.value),
691
+ placeholder: getPlaceholder(reportType),
692
+ style: {
693
+ width: "100%",
694
+ minHeight: "100px",
695
+ padding: "10px 12px",
696
+ borderRadius: "8px",
697
+ border: `1px solid ${t.inputBorder}`,
698
+ fontSize: "14px",
699
+ fontFamily: "inherit",
700
+ resize: "vertical",
701
+ outline: "none",
702
+ boxSizing: "border-box",
703
+ color: t.text,
704
+ backgroundColor: t.inputBg
928
705
  },
929
- onMouseEnter: (e) => {
930
- e.currentTarget.style.borderColor = t.accent;
706
+ onFocus: (e) => {
707
+ e.target.style.borderColor = t.accent;
931
708
  },
932
- onMouseLeave: (e) => {
933
- e.currentTarget.style.borderColor = t.inputBorder;
709
+ onBlur: (e) => {
710
+ e.target.style.borderColor = t.inputBorder;
934
711
  },
935
- children: [
936
- getTypeIcon(type, t.accent),
937
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { fontSize: "13px", fontWeight: 600 }, children: getTypeLabel(type) }),
938
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { fontSize: "11px", color: t.textMuted, lineHeight: "1.3" }, children: getTypeSubtitle(type) })
939
- ]
940
- },
941
- type
942
- )) }),
943
- step === 2 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
944
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
945
- "textarea",
946
- {
947
- value: description,
948
- onChange: (e) => setDescription(e.target.value),
949
- placeholder: getPlaceholder(reportType),
950
- style: {
951
- width: "100%",
952
- minHeight: "100px",
953
- padding: "10px 12px",
954
- borderRadius: "8px",
955
- border: `1px solid ${t.inputBorder}`,
956
- fontSize: "14px",
957
- fontFamily: "inherit",
958
- resize: "vertical",
959
- outline: "none",
960
- boxSizing: "border-box",
961
- color: t.text,
962
- backgroundColor: t.inputBg
963
- },
964
- onFocus: (e) => {
965
- e.target.style.borderColor = t.accent;
966
- },
967
- onBlur: (e) => {
968
- e.target.style.borderColor = t.inputBorder;
969
- },
970
- autoFocus: true
971
- }
972
- ),
973
- showSeverity && reportType === "BUG" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { marginTop: "10px" }, children: [
974
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { fontSize: "12px", color: t.textMuted, marginBottom: "6px", display: "block" }, children: "Severity" }),
975
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { display: "flex", gap: "6px" }, children: ["low", "medium", "high"].map((s) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
976
- "button",
977
- {
978
- type: "button",
979
- onClick: () => setSeverity(s),
980
- style: {
981
- flex: 1,
982
- padding: "6px 0",
983
- borderRadius: "6px",
984
- border: `1px solid ${severity === s ? t.accent : t.inputBorder}`,
985
- background: severity === s ? t.accent : "transparent",
986
- color: severity === s ? t.accentText : t.text,
987
- fontSize: "12px",
988
- fontWeight: 600,
989
- cursor: "pointer",
990
- fontFamily: "inherit",
991
- textTransform: "capitalize",
992
- transition: "all 0.15s ease"
993
- },
994
- children: s
995
- },
996
- s
997
- )) })
998
- ] }),
999
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
712
+ autoFocus: true
713
+ }
714
+ ),
715
+ showSeverity && reportType === "BUG" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { marginTop: "10px" }, children: [
716
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontSize: "12px", color: t.textMuted, marginBottom: "6px", display: "block" }, children: "Severity" }),
717
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { display: "flex", gap: "6px" }, children: ["low", "medium", "high"].map((s) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1000
718
  "button",
1001
719
  {
1002
720
  type: "button",
1003
- onClick: () => setStep(3),
1004
- disabled: !description.trim(),
721
+ onClick: () => setSeverity(s),
1005
722
  style: {
1006
- marginTop: "12px",
1007
- width: "100%",
1008
- padding: "10px",
1009
- borderRadius: "8px",
1010
- border: "none",
1011
- backgroundColor: !description.trim() ? t.bgSecondary : t.accent,
1012
- color: !description.trim() ? t.textMuted : t.accentText,
1013
- fontSize: "14px",
723
+ flex: 1,
724
+ padding: "6px 0",
725
+ borderRadius: "6px",
726
+ border: `1px solid ${severity === s ? t.accent : t.inputBorder}`,
727
+ background: severity === s ? t.accent : "transparent",
728
+ color: severity === s ? t.accentText : t.text,
729
+ fontSize: "12px",
1014
730
  fontWeight: 600,
1015
- cursor: !description.trim() ? "not-allowed" : "pointer",
731
+ cursor: "pointer",
1016
732
  fontFamily: "inherit",
1017
- transition: "background-color 0.15s ease"
733
+ textTransform: "capitalize",
734
+ transition: "all 0.15s ease"
1018
735
  },
1019
- children: "Next"
1020
- }
1021
- )
736
+ children: s
737
+ },
738
+ s
739
+ )) })
1022
740
  ] }),
1023
- step === 3 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
1024
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", gap: "6px", flexWrap: "wrap", marginBottom: "12px" }, children: [
1025
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: {
1026
- display: "inline-flex",
1027
- alignItems: "center",
1028
- gap: "4px",
1029
- padding: "4px 10px",
1030
- borderRadius: "12px",
1031
- fontSize: "12px",
1032
- fontWeight: 600,
1033
- backgroundColor: t.bgSecondary,
1034
- color: t.text,
1035
- border: `1px solid ${t.border}`
1036
- }, children: [
1037
- getTypeIcon(reportType, t.accent, 12),
1038
- getTypeLabel(reportType)
1039
- ] }),
1040
- showSeverity && reportType === "BUG" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: {
1041
- display: "inline-flex",
1042
- alignItems: "center",
1043
- padding: "4px 10px",
1044
- borderRadius: "12px",
1045
- fontSize: "12px",
741
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
742
+ "button",
743
+ {
744
+ type: "button",
745
+ onClick: () => setStep(3),
746
+ disabled: !description.trim(),
747
+ style: {
748
+ marginTop: "12px",
749
+ width: "100%",
750
+ padding: "10px",
751
+ borderRadius: "8px",
752
+ border: "none",
753
+ backgroundColor: !description.trim() ? t.bgSecondary : t.accent,
754
+ color: !description.trim() ? t.textMuted : t.accentText,
755
+ fontSize: "14px",
1046
756
  fontWeight: 600,
1047
- backgroundColor: severity === "high" ? "#fef2f2" : severity === "medium" ? "#fffbeb" : "#f0fdf4",
1048
- color: severity === "high" ? "#dc2626" : severity === "medium" ? "#d97706" : "#16a34a",
1049
- border: `1px solid ${severity === "high" ? "#fecaca" : severity === "medium" ? "#fde68a" : "#bbf7d0"}`,
1050
- textTransform: "capitalize"
1051
- }, children: severity })
1052
- ] }),
1053
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: {
1054
- padding: "10px 12px",
1055
- borderRadius: "8px",
1056
- border: `1px solid ${t.inputBorder}`,
1057
- backgroundColor: t.inputBg,
1058
- fontSize: "13px",
757
+ cursor: !description.trim() ? "not-allowed" : "pointer",
758
+ fontFamily: "inherit",
759
+ transition: "background-color 0.15s ease"
760
+ },
761
+ children: "Next"
762
+ }
763
+ )
764
+ ] }),
765
+ step === 3 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
766
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", gap: "6px", flexWrap: "wrap", marginBottom: "12px" }, children: [
767
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { style: {
768
+ display: "inline-flex",
769
+ alignItems: "center",
770
+ gap: "4px",
771
+ padding: "4px 10px",
772
+ borderRadius: "12px",
773
+ fontSize: "12px",
774
+ fontWeight: 600,
775
+ backgroundColor: t.bgSecondary,
1059
776
  color: t.text,
1060
- marginBottom: "10px",
1061
- maxHeight: "80px",
1062
- overflow: "hidden",
1063
- lineHeight: "1.4"
1064
- }, children: description.length > 200 ? description.slice(0, 200) + "..." : description }),
1065
- screenshot && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { marginBottom: "10px", position: "relative" }, children: [
1066
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1067
- "img",
1068
- {
1069
- src: screenshot,
1070
- alt: "Page screenshot",
1071
- onClick: () => setPreviewOpen(true),
1072
- style: {
1073
- width: "100%",
1074
- borderRadius: "6px",
1075
- border: `1px solid ${t.border}`,
1076
- maxHeight: "80px",
1077
- objectFit: "cover",
1078
- objectPosition: "top",
1079
- cursor: "pointer"
1080
- }
1081
- }
1082
- ),
1083
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1084
- "button",
1085
- {
1086
- type: "button",
1087
- onClick: () => setScreenshot(null),
1088
- style: {
1089
- position: "absolute",
1090
- top: "4px",
1091
- right: "4px",
1092
- background: "rgba(0,0,0,0.6)",
1093
- border: "none",
1094
- borderRadius: "50%",
1095
- width: "20px",
1096
- height: "20px",
1097
- cursor: "pointer",
1098
- display: "flex",
1099
- alignItems: "center",
1100
- justifyContent: "center"
1101
- },
1102
- "aria-label": "Remove screenshot",
1103
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { width: "10", height: "10", viewBox: "0 0 10 10", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M1 1L9 9M9 1L1 9", stroke: "#fff", strokeWidth: "1.5", strokeLinecap: "round" }) })
1104
- }
1105
- )
1106
- ] }),
1107
- !screenshot && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", gap: "6px", marginBottom: "10px" }, children: [
1108
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1109
- "button",
1110
- {
1111
- type: "button",
1112
- onClick: () => {
1113
- var _a2;
1114
- return (_a2 = fileInputRef.current) == null ? void 0 : _a2.click();
1115
- },
1116
- style: {
1117
- flex: 1,
1118
- padding: "8px",
1119
- borderRadius: "6px",
1120
- border: `1px dashed ${t.inputBorder}`,
1121
- textAlign: "center",
1122
- fontSize: "11px",
1123
- color: t.textMuted,
1124
- background: "none",
1125
- cursor: "pointer"
1126
- },
1127
- children: "Upload screenshot"
1128
- }
1129
- ),
1130
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1131
- "button",
1132
- {
1133
- type: "button",
1134
- onClick: retakeScreenshot,
1135
- style: {
1136
- flex: 1,
1137
- padding: "8px",
1138
- borderRadius: "6px",
1139
- border: `1px dashed ${t.inputBorder}`,
1140
- textAlign: "center",
1141
- fontSize: "11px",
1142
- color: t.textMuted,
1143
- background: "none",
1144
- cursor: "pointer"
1145
- },
1146
- children: "Retake screenshot"
1147
- }
1148
- )
777
+ border: `1px solid ${t.border}`
778
+ }, children: [
779
+ getTypeIcon(reportType, t.accent, 12),
780
+ getTypeLabel(reportType)
1149
781
  ] }),
1150
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1151
- "button",
1152
- {
1153
- type: "button",
1154
- onClick: handleSubmit,
1155
- disabled: isSubmitting,
1156
- style: {
1157
- width: "100%",
1158
- padding: "10px",
1159
- borderRadius: "8px",
1160
- border: "none",
1161
- backgroundColor: isSubmitting ? t.bgSecondary : t.accent,
1162
- color: isSubmitting ? t.textMuted : t.accentText,
1163
- fontSize: "14px",
1164
- fontWeight: 600,
1165
- cursor: isSubmitting ? "not-allowed" : "pointer",
1166
- fontFamily: "inherit",
1167
- transition: "background-color 0.15s ease"
1168
- },
1169
- children: isSubmitting ? "Sending..." : "Send Report"
1170
- }
1171
- )
1172
- ] })
1173
- ] })
1174
- ) : (
1175
- /* ─── Classic Flow ─── */
1176
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
1177
- screenshot && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { marginBottom: "10px", position: "relative" }, children: [
1178
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
782
+ showSeverity && reportType === "BUG" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: {
783
+ display: "inline-flex",
784
+ alignItems: "center",
785
+ padding: "4px 10px",
786
+ borderRadius: "12px",
787
+ fontSize: "12px",
788
+ fontWeight: 600,
789
+ backgroundColor: severity === "high" ? "#fef2f2" : severity === "medium" ? "#fffbeb" : "#f0fdf4",
790
+ color: severity === "high" ? "#dc2626" : severity === "medium" ? "#d97706" : "#16a34a",
791
+ border: `1px solid ${severity === "high" ? "#fecaca" : severity === "medium" ? "#fde68a" : "#bbf7d0"}`,
792
+ textTransform: "capitalize"
793
+ }, children: severity })
794
+ ] }),
795
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: {
796
+ padding: "10px 12px",
797
+ borderRadius: "8px",
798
+ border: `1px solid ${t.inputBorder}`,
799
+ backgroundColor: t.inputBg,
800
+ fontSize: "13px",
801
+ color: t.text,
802
+ marginBottom: "10px",
803
+ maxHeight: "80px",
804
+ overflow: "hidden",
805
+ lineHeight: "1.4"
806
+ }, children: description.length > 200 ? description.slice(0, 200) + "..." : description }),
807
+ screenshot && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { marginBottom: "10px", position: "relative" }, children: [
808
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1179
809
  "img",
1180
810
  {
1181
811
  src: screenshot,
@@ -1185,14 +815,14 @@ function ReportButton({
1185
815
  width: "100%",
1186
816
  borderRadius: "6px",
1187
817
  border: `1px solid ${t.border}`,
1188
- maxHeight: "120px",
818
+ maxHeight: "80px",
1189
819
  objectFit: "cover",
1190
820
  objectPosition: "top",
1191
821
  cursor: "pointer"
1192
822
  }
1193
823
  }
1194
824
  ),
1195
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
825
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1196
826
  "button",
1197
827
  {
1198
828
  type: "button",
@@ -1212,153 +842,69 @@ function ReportButton({
1212
842
  justifyContent: "center"
1213
843
  },
1214
844
  "aria-label": "Remove screenshot",
1215
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { width: "10", height: "10", viewBox: "0 0 10 10", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M1 1L9 9M9 1L1 9", stroke: "#fff", strokeWidth: "1.5", strokeLinecap: "round" }) })
845
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { width: "10", height: "10", viewBox: "0 0 10 10", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M1 1L9 9M9 1L1 9", stroke: "#fff", strokeWidth: "1.5", strokeLinecap: "round" }) })
846
+ }
847
+ )
848
+ ] }),
849
+ !screenshot && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", gap: "6px", marginBottom: "10px" }, children: [
850
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
851
+ "button",
852
+ {
853
+ type: "button",
854
+ onClick: () => {
855
+ var _a;
856
+ return (_a = fileInputRef.current) == null ? void 0 : _a.click();
857
+ },
858
+ style: {
859
+ flex: 1,
860
+ padding: "8px",
861
+ borderRadius: "6px",
862
+ border: `1px dashed ${t.inputBorder}`,
863
+ textAlign: "center",
864
+ fontSize: "11px",
865
+ color: t.textMuted,
866
+ background: "none",
867
+ cursor: "pointer"
868
+ },
869
+ children: "Upload screenshot"
1216
870
  }
1217
871
  ),
1218
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1219
- "div",
872
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
873
+ "button",
1220
874
  {
875
+ type: "button",
876
+ onClick: retakeScreenshot,
1221
877
  style: {
1222
- position: "absolute",
1223
- bottom: "4px",
1224
- left: "6px",
1225
- right: "6px",
1226
- display: "flex",
1227
- justifyContent: "space-between",
1228
- alignItems: "center"
878
+ flex: 1,
879
+ padding: "8px",
880
+ borderRadius: "6px",
881
+ border: `1px dashed ${t.inputBorder}`,
882
+ textAlign: "center",
883
+ fontSize: "11px",
884
+ color: t.textMuted,
885
+ background: "none",
886
+ cursor: "pointer"
1229
887
  },
1230
- children: [
1231
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1232
- "span",
1233
- {
1234
- style: {
1235
- background: "rgba(0,0,0,0.6)",
1236
- color: "#fff",
1237
- fontSize: "10px",
1238
- padding: "2px 6px",
1239
- borderRadius: "4px"
1240
- },
1241
- children: [
1242
- "Screenshot (",
1243
- Math.round(screenshot.length * 0.75 / 1024),
1244
- "KB) \u2014 click to preview"
1245
- ]
1246
- }
1247
- ),
1248
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", gap: "4px" }, children: [
1249
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1250
- "button",
1251
- {
1252
- type: "button",
1253
- onClick: () => {
1254
- var _a2;
1255
- return (_a2 = fileInputRef.current) == null ? void 0 : _a2.click();
1256
- },
1257
- style: {
1258
- background: t.accent,
1259
- color: t.accentText,
1260
- fontSize: "10px",
1261
- padding: "3px 8px",
1262
- borderRadius: "4px",
1263
- border: "none",
1264
- cursor: "pointer",
1265
- fontWeight: 600
1266
- },
1267
- children: "Upload"
1268
- }
1269
- ),
1270
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1271
- "button",
1272
- {
1273
- type: "button",
1274
- onClick: retakeScreenshot,
1275
- style: {
1276
- background: t.accent,
1277
- color: t.accentText,
1278
- fontSize: "10px",
1279
- padding: "3px 8px",
1280
- borderRadius: "4px",
1281
- border: "none",
1282
- cursor: "pointer",
1283
- fontWeight: 600
1284
- },
1285
- children: "Retake"
1286
- }
1287
- )
1288
- ] })
1289
- ]
888
+ children: "Retake screenshot"
1290
889
  }
1291
890
  )
1292
891
  ] }),
1293
- !screenshot && !submitted && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1294
- "button",
1295
- {
1296
- type: "button",
1297
- onClick: () => {
1298
- var _a2;
1299
- return (_a2 = fileInputRef.current) == null ? void 0 : _a2.click();
1300
- },
1301
- style: {
1302
- marginBottom: "10px",
1303
- padding: "10px",
1304
- borderRadius: "6px",
1305
- border: `1px dashed ${t.inputBorder}`,
1306
- textAlign: "center",
1307
- fontSize: "11px",
1308
- color: t.textMuted,
1309
- width: "100%",
1310
- background: "none",
1311
- cursor: "pointer"
1312
- },
1313
- children: "Click to upload a screenshot"
1314
- }
1315
- ),
1316
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1317
- "textarea",
1318
- {
1319
- value: description,
1320
- onChange: (e) => setDescription(e.target.value),
1321
- placeholder: "Describe what went wrong...",
1322
- style: {
1323
- width: "100%",
1324
- minHeight: "100px",
1325
- padding: "10px 12px",
1326
- borderRadius: "8px",
1327
- border: `1px solid ${t.inputBorder}`,
1328
- fontSize: "14px",
1329
- fontFamily: "inherit",
1330
- resize: "vertical",
1331
- outline: "none",
1332
- boxSizing: "border-box",
1333
- color: t.text,
1334
- backgroundColor: t.inputBg
1335
- },
1336
- onFocus: (e) => {
1337
- e.target.style.borderColor = t.accent;
1338
- },
1339
- onBlur: (e) => {
1340
- e.target.style.borderColor = t.inputBorder;
1341
- },
1342
- autoFocus: true
1343
- }
1344
- ),
1345
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
892
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1346
893
  "button",
1347
894
  {
1348
895
  type: "button",
1349
896
  onClick: handleSubmit,
1350
- disabled: !description.trim() || isSubmitting,
897
+ disabled: isSubmitting,
1351
898
  style: {
1352
- marginTop: "12px",
1353
899
  width: "100%",
1354
900
  padding: "10px",
1355
901
  borderRadius: "8px",
1356
902
  border: "none",
1357
- backgroundColor: !description.trim() || isSubmitting ? t.bgSecondary : t.accent,
1358
- color: !description.trim() || isSubmitting ? t.textMuted : t.accentText,
903
+ backgroundColor: isSubmitting ? t.bgSecondary : t.accent,
904
+ color: isSubmitting ? t.textMuted : t.accentText,
1359
905
  fontSize: "14px",
1360
906
  fontWeight: 600,
1361
- cursor: !description.trim() || isSubmitting ? "not-allowed" : "pointer",
907
+ cursor: isSubmitting ? "not-allowed" : "pointer",
1362
908
  fontFamily: "inherit",
1363
909
  transition: "background-color 0.15s ease"
1364
910
  },
@@ -1366,8 +912,8 @@ function ReportButton({
1366
912
  }
1367
913
  )
1368
914
  ] })
1369
- ) }),
1370
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
915
+ ] }) }),
916
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1371
917
  "div",
1372
918
  {
1373
919
  style: {
@@ -1375,7 +921,7 @@ function ReportButton({
1375
921
  borderTop: `1px solid ${t.border}`,
1376
922
  textAlign: "center"
1377
923
  },
1378
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { fontSize: "11px", color: t.textMuted }, children: "Powered by Glitchgrab" })
924
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontSize: "11px", color: t.textMuted }, children: "Powered by Glitchgrab" })
1379
925
  }
1380
926
  )
1381
927
  ]
@@ -1385,7 +931,7 @@ function ReportButton({
1385
931
  ),
1386
932
  document.body
1387
933
  ),
1388
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
934
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1389
935
  "input",
1390
936
  {
1391
937
  ref: fileInputRef,
@@ -1395,8 +941,8 @@ function ReportButton({
1395
941
  style: { display: "none" }
1396
942
  }
1397
943
  ),
1398
- previewOpen && screenshot && typeof document !== "undefined" && (0, import_react_dom.createPortal)(
1399
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
944
+ previewOpen && screenshot && (0, import_react_dom.createPortal)(
945
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
1400
946
  "div",
1401
947
  {
1402
948
  style: {
@@ -1417,7 +963,7 @@ function ReportButton({
1417
963
  },
1418
964
  onMouseDown: (e) => e.stopPropagation(),
1419
965
  children: [
1420
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
966
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1421
967
  "img",
1422
968
  {
1423
969
  src: screenshot,
@@ -1432,7 +978,7 @@ function ReportButton({
1432
978
  }
1433
979
  }
1434
980
  ),
1435
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
981
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1436
982
  "span",
1437
983
  {
1438
984
  style: {
@@ -1490,36 +1036,290 @@ function getTypeIcon(type, color, size = 24) {
1490
1036
  const props = { width: size, height: size, viewBox: "0 0 24 24", fill: "none", style: { flexShrink: 0 } };
1491
1037
  switch (type) {
1492
1038
  case "BUG":
1493
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("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" }) });
1039
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("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" }) });
1494
1040
  case "FEATURE_REQUEST":
1495
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("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" }) });
1041
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("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" }) });
1496
1042
  case "QUESTION":
1497
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { ...props, children: [
1498
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: "12", cy: "12", r: "10", stroke: color, strokeWidth: "1.5" }),
1499
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("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" })
1043
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { ...props, children: [
1044
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "12", cy: "12", r: "10", stroke: color, strokeWidth: "1.5" }),
1045
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("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" })
1500
1046
  ] });
1501
1047
  case "OTHER":
1502
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("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" }) });
1048
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("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" }) });
1503
1049
  }
1504
1050
  }
1505
- function DefaultTrigger({
1506
- onClick,
1507
- capturing,
1508
- label,
1051
+
1052
+ // src/provider.tsx
1053
+ var import_jsx_runtime2 = require("react/jsx-runtime");
1054
+ var DEFAULT_BASE_URL2 = "https://www.glitchgrab.dev";
1055
+ var GlitchgrabContext = (0, import_react2.createContext)(null);
1056
+ function useGlitchgrab() {
1057
+ const ctx = (0, import_react2.useContext)(GlitchgrabContext);
1058
+ if (!ctx) {
1059
+ throw new Error("useGlitchgrab must be used within a GlitchgrabProvider");
1060
+ }
1061
+ return ctx;
1062
+ }
1063
+ function GlitchgrabProviderInner({
1064
+ token,
1065
+ session,
1066
+ baseUrl,
1067
+ onError,
1068
+ onReportSent,
1069
+ breadcrumbs: enableBreadcrumbs = true,
1070
+ maxBreadcrumbs: maxBreadcrumbs2 = 50,
1071
+ children,
1072
+ fallback,
1073
+ types,
1074
+ showSeverity
1075
+ }) {
1076
+ const visitedPagesRef = (0, import_react2.useRef)([]);
1077
+ (0, import_react2.useEffect)(() => {
1078
+ if (enableBreadcrumbs) {
1079
+ initBreadcrumbs(maxBreadcrumbs2);
1080
+ }
1081
+ }, [enableBreadcrumbs, maxBreadcrumbs2]);
1082
+ (0, import_react2.useEffect)(() => {
1083
+ try {
1084
+ if (typeof window === "undefined") return;
1085
+ const trackPage = () => {
1086
+ try {
1087
+ const sanitized = sanitizeUrl(window.location.href);
1088
+ const pages = visitedPagesRef.current;
1089
+ if (pages[pages.length - 1] !== sanitized) {
1090
+ pages.push(sanitized);
1091
+ if (pages.length > 20) {
1092
+ pages.splice(0, pages.length - 20);
1093
+ }
1094
+ }
1095
+ } catch (e) {
1096
+ }
1097
+ };
1098
+ trackPage();
1099
+ const handlePopState = () => trackPage();
1100
+ window.addEventListener("popstate", handlePopState);
1101
+ const origPushState = history.pushState.bind(history);
1102
+ const origReplaceState = history.replaceState.bind(history);
1103
+ history.pushState = function(...args) {
1104
+ origPushState(...args);
1105
+ trackPage();
1106
+ };
1107
+ history.replaceState = function(...args) {
1108
+ origReplaceState(...args);
1109
+ trackPage();
1110
+ };
1111
+ return () => {
1112
+ window.removeEventListener("popstate", handlePopState);
1113
+ history.pushState = origPushState;
1114
+ history.replaceState = origReplaceState;
1115
+ };
1116
+ } catch (e) {
1117
+ }
1118
+ }, []);
1119
+ (0, import_react2.useEffect)(() => {
1120
+ try {
1121
+ if (typeof window === "undefined") return;
1122
+ if (process.env.NODE_ENV === "development") return;
1123
+ const handleError = (event) => {
1124
+ var _a, _b, _c, _d, _e;
1125
+ try {
1126
+ const context = captureContext(visitedPagesRef.current);
1127
+ const payload = {
1128
+ token,
1129
+ source: "SDK_AUTO",
1130
+ type: "BUG",
1131
+ errorMessage: event.message,
1132
+ errorStack: (_a = event.error) == null ? void 0 : _a.stack,
1133
+ pageUrl: context.url,
1134
+ userAgent: context.userAgent,
1135
+ breadcrumbs: context.breadcrumbs,
1136
+ deviceInfo: (_b = context.deviceInfo) != null ? _b : void 0,
1137
+ metadata: {
1138
+ timestamp: context.timestamp,
1139
+ visitedPages: JSON.stringify(context.visitedPages),
1140
+ filename: (_c = event.filename) != null ? _c : "",
1141
+ lineno: String((_d = event.lineno) != null ? _d : ""),
1142
+ colno: String((_e = event.colno) != null ? _e : ""),
1143
+ ...(session == null ? void 0 : session.userId) ? { sessionUserId: session.userId } : {},
1144
+ ...(session == null ? void 0 : session.name) ? { sessionUserName: String(session.name) } : {},
1145
+ ...(session == null ? void 0 : session.email) ? { sessionUserEmail: String(session.email) } : {}
1146
+ }
1147
+ };
1148
+ sendReport(payload, baseUrl).then((result) => {
1149
+ if (result && onReportSent) onReportSent(result);
1150
+ });
1151
+ if (onError && event.error) onError(event.error);
1152
+ } catch (e) {
1153
+ }
1154
+ };
1155
+ const handleRejection = (event) => {
1156
+ var _a;
1157
+ try {
1158
+ const context = captureContext(visitedPagesRef.current);
1159
+ const reason = event.reason;
1160
+ const payload = {
1161
+ token,
1162
+ source: "SDK_AUTO",
1163
+ type: "BUG",
1164
+ errorMessage: reason instanceof Error ? reason.message : String(reason),
1165
+ errorStack: reason instanceof Error ? reason.stack : void 0,
1166
+ pageUrl: context.url,
1167
+ userAgent: context.userAgent,
1168
+ breadcrumbs: context.breadcrumbs,
1169
+ deviceInfo: (_a = context.deviceInfo) != null ? _a : void 0,
1170
+ metadata: {
1171
+ timestamp: context.timestamp,
1172
+ visitedPages: JSON.stringify(context.visitedPages),
1173
+ type: "unhandledrejection",
1174
+ ...(session == null ? void 0 : session.userId) ? { sessionUserId: session.userId } : {},
1175
+ ...(session == null ? void 0 : session.name) ? { sessionUserName: String(session.name) } : {},
1176
+ ...(session == null ? void 0 : session.email) ? { sessionUserEmail: String(session.email) } : {}
1177
+ }
1178
+ };
1179
+ sendReport(payload, baseUrl).then((result) => {
1180
+ if (result && onReportSent) onReportSent(result);
1181
+ });
1182
+ if (onError && reason instanceof Error) onError(reason);
1183
+ } catch (e) {
1184
+ }
1185
+ };
1186
+ window.addEventListener("error", handleError);
1187
+ window.addEventListener("unhandledrejection", handleRejection);
1188
+ return () => {
1189
+ window.removeEventListener("error", handleError);
1190
+ window.removeEventListener("unhandledrejection", handleRejection);
1191
+ };
1192
+ } catch (e) {
1193
+ }
1194
+ }, [token, baseUrl, onError, onReportSent]);
1195
+ const report = (0, import_react2.useCallback)(
1196
+ async (type, description, metadata) => {
1197
+ var _a;
1198
+ try {
1199
+ const context = captureContext(visitedPagesRef.current);
1200
+ const payload = {
1201
+ token,
1202
+ source: "SDK_USER_REPORT",
1203
+ type,
1204
+ description,
1205
+ pageUrl: context.url,
1206
+ userAgent: context.userAgent,
1207
+ breadcrumbs: context.breadcrumbs,
1208
+ deviceInfo: (_a = context.deviceInfo) != null ? _a : void 0,
1209
+ metadata: {
1210
+ timestamp: context.timestamp,
1211
+ visitedPages: JSON.stringify(context.visitedPages),
1212
+ ...(session == null ? void 0 : session.userId) ? { sessionUserId: session.userId } : {},
1213
+ ...(session == null ? void 0 : session.name) ? { sessionUserName: String(session.name) } : {},
1214
+ ...(session == null ? void 0 : session.email) ? { sessionUserEmail: String(session.email) } : {},
1215
+ ...(session == null ? void 0 : session.phone) ? { sessionUserPhone: String(session.phone) } : {},
1216
+ ...metadata
1217
+ }
1218
+ };
1219
+ const result = await sendReport(payload, baseUrl);
1220
+ if (result && onReportSent) onReportSent(result);
1221
+ return result;
1222
+ } catch (e) {
1223
+ return null;
1224
+ }
1225
+ },
1226
+ [token, baseUrl, onReportSent, session]
1227
+ );
1228
+ const reportBug = (0, import_react2.useCallback)(
1229
+ (description, metadata) => report("BUG", description, metadata),
1230
+ [report]
1231
+ );
1232
+ const addBreadcrumb2 = (0, import_react2.useCallback)(
1233
+ (message, data) => {
1234
+ addBreadcrumb("custom", message, data);
1235
+ },
1236
+ []
1237
+ );
1238
+ const openReportDialog = (0, import_react2.useCallback)((options) => {
1239
+ if (typeof window !== "undefined") {
1240
+ window.dispatchEvent(new CustomEvent("glitchgrab:open-report", { detail: options }));
1241
+ }
1242
+ }, []);
1243
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1244
+ GlitchgrabContext.Provider,
1245
+ {
1246
+ value: {
1247
+ token,
1248
+ baseUrl: baseUrl != null ? baseUrl : DEFAULT_BASE_URL2,
1249
+ reportBug,
1250
+ report,
1251
+ addBreadcrumb: addBreadcrumb2,
1252
+ openReportDialog
1253
+ },
1254
+ children: [
1255
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1256
+ GlitchgrabErrorBoundary,
1257
+ {
1258
+ token,
1259
+ baseUrl,
1260
+ onError,
1261
+ fallback,
1262
+ visitedPages: visitedPagesRef.current,
1263
+ children
1264
+ }
1265
+ ),
1266
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ReportDialog, { report, types, showSeverity })
1267
+ ]
1268
+ }
1269
+ );
1270
+ }
1271
+ function GlitchgrabProvider(props) {
1272
+ if (!props.token) return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children: props.children });
1273
+ const resolvedProps = {
1274
+ ...props,
1275
+ baseUrl: props.baseUrl || DEFAULT_BASE_URL2
1276
+ };
1277
+ try {
1278
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(GlitchgrabProviderInner, { ...resolvedProps });
1279
+ } catch (e) {
1280
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children: props.children });
1281
+ }
1282
+ }
1283
+
1284
+ // src/report-button.tsx
1285
+ var import_react3 = require("react");
1286
+ var import_jsx_runtime3 = require("react/jsx-runtime");
1287
+ function useGlitchgrabSafe() {
1288
+ try {
1289
+ return useGlitchgrab();
1290
+ } catch (e) {
1291
+ return null;
1292
+ }
1293
+ }
1294
+ function ReportButton({
1295
+ position = "bottom-right",
1296
+ label = "Report Bug",
1509
1297
  className,
1510
- position,
1511
- isLeft,
1512
- isTop
1298
+ children
1513
1299
  }) {
1300
+ var _a, _b;
1301
+ const [capturing, setCapturing] = (0, import_react3.useState)(false);
1302
+ const glitchgrab = useGlitchgrabSafe();
1303
+ if (!glitchgrab) return null;
1304
+ const handleClick = async () => {
1305
+ setCapturing(true);
1306
+ glitchgrab.openReportDialog();
1307
+ setCapturing(false);
1308
+ };
1309
+ if (children) {
1310
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_jsx_runtime3.Fragment, { children: children({ onClick: handleClick, capturing }) });
1311
+ }
1312
+ const isTop = (_a = position == null ? void 0 : position.startsWith("top")) != null ? _a : false;
1313
+ const isLeft = (_b = position == null ? void 0 : position.endsWith("left")) != null ? _b : false;
1514
1314
  const positionStyles = {
1515
1315
  ...isLeft ? { left: "16px" } : { right: "16px" },
1516
1316
  ...isTop ? { top: "16px" } : { bottom: "16px" }
1517
1317
  };
1518
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1318
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1519
1319
  "button",
1520
1320
  {
1521
1321
  type: "button",
1522
- onClick,
1322
+ onClick: handleClick,
1523
1323
  disabled: capturing,
1524
1324
  className,
1525
1325
  style: {
@@ -1550,7 +1350,7 @@ function DefaultTrigger({
1550
1350
  },
1551
1351
  "aria-label": label,
1552
1352
  children: [
1553
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1353
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1554
1354
  "svg",
1555
1355
  {
1556
1356
  width: "16",
@@ -1558,7 +1358,7 @@ function DefaultTrigger({
1558
1358
  viewBox: "0 0 16 16",
1559
1359
  fill: "none",
1560
1360
  style: { flexShrink: 0 },
1561
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1361
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1562
1362
  "path",
1563
1363
  {
1564
1364
  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",
@@ -1574,18 +1374,18 @@ function DefaultTrigger({
1574
1374
  }
1575
1375
 
1576
1376
  // src/use-reports.ts
1577
- var import_react3 = require("react");
1377
+ var import_react4 = require("react");
1578
1378
  var BASE_URL = "https://www.glitchgrab.dev";
1579
1379
  function useGlitchgrabReports({
1580
1380
  token,
1581
1381
  userId,
1582
1382
  limit = 100
1583
1383
  }) {
1584
- const [reports, setReports] = (0, import_react3.useState)([]);
1585
- const [isLoading, setIsLoading] = (0, import_react3.useState)(true);
1586
- const [isFetching, setIsFetching] = (0, import_react3.useState)(false);
1587
- const [error, setError] = (0, import_react3.useState)(null);
1588
- const fetchReports = (0, import_react3.useCallback)(async () => {
1384
+ const [reports, setReports] = (0, import_react4.useState)([]);
1385
+ const [isLoading, setIsLoading] = (0, import_react4.useState)(true);
1386
+ const [isFetching, setIsFetching] = (0, import_react4.useState)(false);
1387
+ const [error, setError] = (0, import_react4.useState)(null);
1388
+ const fetchReports = (0, import_react4.useCallback)(async () => {
1589
1389
  var _a, _b;
1590
1390
  if (!token || !userId) {
1591
1391
  setIsLoading(false);
@@ -1611,7 +1411,7 @@ function useGlitchgrabReports({
1611
1411
  setIsFetching(false);
1612
1412
  }
1613
1413
  }, [token, userId, limit]);
1614
- (0, import_react3.useEffect)(() => {
1414
+ (0, import_react4.useEffect)(() => {
1615
1415
  fetchReports();
1616
1416
  }, [fetchReports]);
1617
1417
  return { reports, isLoading, isFetching, error, refetch: fetchReports };
@@ -1648,9 +1448,9 @@ function useGlitchgrabActions({
1648
1448
  onSuccess,
1649
1449
  onError
1650
1450
  }) {
1651
- const [isPending, setIsPending] = (0, import_react3.useState)(false);
1652
- const [error, setError] = (0, import_react3.useState)(null);
1653
- const run = (0, import_react3.useCallback)(
1451
+ const [isPending, setIsPending] = (0, import_react4.useState)(false);
1452
+ const [error, setError] = (0, import_react4.useState)(null);
1453
+ const run = (0, import_react4.useCallback)(
1654
1454
  async (reportId, body) => {
1655
1455
  setIsPending(true);
1656
1456
  setError(null);