glitchgrab 1.12.0 → 1.13.0

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