@jarve/bug-reporter 0.3.0 → 0.3.2

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.mjs CHANGED
@@ -20,9 +20,10 @@ var __spreadValues = (a, b) => {
20
20
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
21
21
 
22
22
  // src/bug-reporter.tsx
23
- import { useState as useState3, useEffect as useEffect3, useCallback as useCallback3 } from "react";
23
+ import { useState as useState4, useEffect as useEffect4, useCallback as useCallback3 } from "react";
24
24
 
25
25
  // src/floating-button.tsx
26
+ import { useState, useEffect, useRef } from "react";
26
27
  import { Bug } from "lucide-react";
27
28
 
28
29
  // src/cn.ts
@@ -33,32 +34,98 @@ function cn(...inputs) {
33
34
  }
34
35
 
35
36
  // src/floating-button.tsx
36
- import { jsx } from "react/jsx-runtime";
37
+ import { jsx, jsxs } from "react/jsx-runtime";
38
+ var STACK_OFFSET = 56;
37
39
  function FloatingButton({ isActive, onClick, position = "right" }) {
38
- const sideClasses = position === "left" ? "left-4 md:left-6" : "right-4 md:right-6";
39
- return /* @__PURE__ */ jsx(
40
- "button",
40
+ const [hovered, setHovered] = useState(false);
41
+ const [stackOffset, setStackOffset] = useState(0);
42
+ const ref = useRef(null);
43
+ const isLeft = position === "left";
44
+ const sideClasses = isLeft ? "left-4 md:left-6" : "right-4 md:right-6";
45
+ useEffect(() => {
46
+ const el = ref.current;
47
+ if (!el) return;
48
+ let rafId;
49
+ const recalculate = () => {
50
+ const widgets = Array.from(
51
+ document.querySelectorAll(`[data-jarve-widget][data-jarve-position="${position}"]`)
52
+ );
53
+ widgets.sort(
54
+ (a, b) => (a.getAttribute("data-jarve-widget") || "").localeCompare(
55
+ b.getAttribute("data-jarve-widget") || ""
56
+ )
57
+ );
58
+ const index = widgets.indexOf(el);
59
+ setStackOffset(index > 0 ? index * STACK_OFFSET : 0);
60
+ };
61
+ recalculate();
62
+ const observer = new MutationObserver(() => {
63
+ cancelAnimationFrame(rafId);
64
+ rafId = requestAnimationFrame(recalculate);
65
+ });
66
+ observer.observe(document.body, { childList: true, subtree: true });
67
+ return () => {
68
+ observer.disconnect();
69
+ cancelAnimationFrame(rafId);
70
+ };
71
+ }, [position]);
72
+ return /* @__PURE__ */ jsxs(
73
+ "div",
41
74
  {
42
- onClick,
43
- className: cn(
44
- "fixed z-[9999] flex items-center justify-center rounded-full shadow-lg transition-all duration-200",
45
- "hover:scale-110 focus:ring-2 focus:ring-offset-2 focus:outline-none",
46
- // size + vertical position
47
- "bottom-4 h-11 w-11 md:bottom-6 md:h-12 md:w-12",
48
- // horizontal side
49
- sideClasses,
50
- // active vs idle colors
51
- isActive ? "animate-pulse bg-red-500 text-white focus:ring-red-400" : "bg-indigo-600 text-white hover:bg-indigo-700 focus:ring-indigo-400"
52
- ),
53
- title: isActive ? "Cancel bug capture" : "Report a bug",
54
- "aria-label": isActive ? "Cancel bug capture" : "Report a bug",
55
- children: /* @__PURE__ */ jsx(Bug, { className: "h-4 w-4 md:h-5 md:w-5" })
75
+ ref,
76
+ "data-jarve-widget": "bug-reporter",
77
+ "data-jarve-position": position,
78
+ className: cn("fixed z-[9999]", "bottom-4 md:bottom-6", sideClasses),
79
+ style: stackOffset > 0 ? { transform: `translateY(-${stackOffset}px)` } : void 0,
80
+ onMouseEnter: () => setHovered(true),
81
+ onMouseLeave: () => setHovered(false),
82
+ children: [
83
+ /* @__PURE__ */ jsxs(
84
+ "div",
85
+ {
86
+ className: cn(
87
+ "pointer-events-none absolute bottom-full mb-2 w-max max-w-[200px] rounded-lg bg-gray-900 px-3 py-2 text-xs leading-relaxed text-white shadow-lg transition-all duration-200",
88
+ isLeft ? "left-0" : "right-0",
89
+ hovered && !isActive ? "translate-y-0 opacity-100" : "translate-y-1 opacity-0"
90
+ ),
91
+ children: [
92
+ /* @__PURE__ */ jsx("span", { className: "font-semibold", children: "Report a bug" }),
93
+ /* @__PURE__ */ jsx("br", {}),
94
+ "Click to screenshot an issue and chat with AI to submit a bug report.",
95
+ /* @__PURE__ */ jsx(
96
+ "div",
97
+ {
98
+ className: cn(
99
+ "absolute top-full h-0 w-0 border-x-[6px] border-t-[6px] border-x-transparent border-t-gray-900",
100
+ isLeft ? "left-4" : "right-4"
101
+ )
102
+ }
103
+ )
104
+ ]
105
+ }
106
+ ),
107
+ /* @__PURE__ */ jsx(
108
+ "button",
109
+ {
110
+ onClick,
111
+ className: cn(
112
+ "flex items-center justify-center rounded-full shadow-lg transition-all duration-200",
113
+ "hover:scale-110 focus:ring-2 focus:ring-offset-2 focus:outline-none",
114
+ "h-11 w-11 md:h-12 md:w-12",
115
+ isActive ? "animate-pulse bg-red-500 text-white focus:ring-red-400" : "bg-indigo-600 text-white hover:bg-indigo-700 focus:ring-indigo-400"
116
+ ),
117
+ title: isActive ? "Cancel bug capture" : "Report a bug",
118
+ "aria-label": isActive ? "Cancel bug capture" : "Report a bug",
119
+ children: /* @__PURE__ */ jsx(Bug, { className: "h-4 w-4 md:h-5 md:w-5" })
120
+ }
121
+ )
122
+ ]
56
123
  }
57
124
  );
58
125
  }
59
126
 
60
127
  // src/capture-overlay.tsx
61
- import { useEffect, useState, useCallback, useRef } from "react";
128
+ import { useEffect as useEffect2, useState as useState2, useCallback, useRef as useRef2 } from "react";
62
129
  import { toPng } from "html-to-image";
63
130
 
64
131
  // src/utils.ts
@@ -369,7 +436,7 @@ function clearCapturedNetworkErrors() {
369
436
  }
370
437
 
371
438
  // src/capture-overlay.tsx
372
- import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
439
+ import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
373
440
  function dataUrlToBlob(dataUrl) {
374
441
  var _a;
375
442
  const [header, base64] = dataUrl.split(",");
@@ -387,18 +454,18 @@ function CaptureOverlay({
387
454
  onCapture,
388
455
  onCancel
389
456
  }) {
390
- const [hoveredElement, setHoveredElement] = useState(null);
391
- const [hoveredRect, setHoveredRect] = useState(null);
392
- const [isCapturing3, setIsCapturing] = useState(false);
393
- const [isTouchMode, setIsTouchMode] = useState(false);
394
- const [selectedSection, setSelectedSection] = useState(null);
395
- const [selectedRect, setSelectedRect] = useState(null);
396
- const [selectedTarget, setSelectedTarget] = useState(null);
397
- const overlayRef = useRef(null);
398
- const hoveredElementRef = useRef(null);
399
- const rafRef = useRef(null);
400
- const touchCoordsRef = useRef(null);
401
- useEffect(() => {
457
+ const [hoveredElement, setHoveredElement] = useState2(null);
458
+ const [hoveredRect, setHoveredRect] = useState2(null);
459
+ const [isCapturing3, setIsCapturing] = useState2(false);
460
+ const [isTouchMode, setIsTouchMode] = useState2(false);
461
+ const [selectedSection, setSelectedSection] = useState2(null);
462
+ const [selectedRect, setSelectedRect] = useState2(null);
463
+ const [selectedTarget, setSelectedTarget] = useState2(null);
464
+ const overlayRef = useRef2(null);
465
+ const hoveredElementRef = useRef2(null);
466
+ const rafRef = useRef2(null);
467
+ const touchCoordsRef = useRef2(null);
468
+ useEffect2(() => {
402
469
  if (isActive) {
403
470
  setIsTouchMode(isTouchCapable());
404
471
  }
@@ -567,7 +634,7 @@ function CaptureOverlay({
567
634
  setSelectedRect(selectedSection.getBoundingClientRect());
568
635
  }
569
636
  }, [selectedSection]);
570
- useEffect(() => {
637
+ useEffect2(() => {
571
638
  if (!isActive) {
572
639
  setHoveredElement(null);
573
640
  setHoveredRect(null);
@@ -609,7 +676,7 @@ function CaptureOverlay({
609
676
  const highlightRect = isTouchMode ? selectedRect : hoveredRect;
610
677
  const showHighlight = isTouchMode ? !!selectedSection : !!hoveredElement && !!hoveredRect;
611
678
  if (!isActive) return null;
612
- return /* @__PURE__ */ jsxs(Fragment, { children: [
679
+ return /* @__PURE__ */ jsxs2(Fragment, { children: [
613
680
  /* @__PURE__ */ jsx2(
614
681
  "div",
615
682
  {
@@ -617,7 +684,7 @@ function CaptureOverlay({
617
684
  role: "alert",
618
685
  "aria-live": "assertive",
619
686
  className: "fixed top-0 right-0 left-0 z-[10000] flex items-center justify-center gap-3 bg-indigo-600 px-4 py-2 text-center text-sm font-medium text-white",
620
- children: isTouchMode ? /* @__PURE__ */ jsxs(Fragment, { children: [
687
+ children: isTouchMode ? /* @__PURE__ */ jsxs2(Fragment, { children: [
621
688
  /* @__PURE__ */ jsx2("span", { children: "Tap the section with the bug" }),
622
689
  /* @__PURE__ */ jsx2(
623
690
  "button",
@@ -627,7 +694,7 @@ function CaptureOverlay({
627
694
  children: "Cancel"
628
695
  }
629
696
  )
630
- ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
697
+ ] }) : /* @__PURE__ */ jsxs2(Fragment, { children: [
631
698
  "Click on the section with the bug. Press",
632
699
  " ",
633
700
  /* @__PURE__ */ jsx2("kbd", { className: "mx-1 rounded bg-indigo-800 px-1.5 py-0.5 text-xs", children: "Esc" }),
@@ -656,9 +723,9 @@ function CaptureOverlay({
656
723
  "data-bug-reporter": true,
657
724
  className: "fixed right-0 bottom-0 left-0 z-[10000] border-t border-gray-200 bg-white shadow-lg",
658
725
  style: { paddingBottom: "env(safe-area-inset-bottom, 0px)" },
659
- children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3 px-4 py-3", children: [
726
+ children: /* @__PURE__ */ jsxs2("div", { className: "flex items-center justify-between gap-3 px-4 py-3", children: [
660
727
  /* @__PURE__ */ jsx2("span", { className: "truncate text-sm font-medium text-gray-900", children: "Capture this section?" }),
661
- /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 gap-2", children: [
728
+ /* @__PURE__ */ jsxs2("div", { className: "flex shrink-0 gap-2", children: [
662
729
  /* @__PURE__ */ jsx2(
663
730
  "button",
664
731
  {
@@ -689,9 +756,9 @@ function CaptureOverlay({
689
756
  }
690
757
 
691
758
  // src/report-modal.tsx
692
- import { useState as useState2, useRef as useRef2, useEffect as useEffect2, useCallback as useCallback2, useMemo } from "react";
759
+ import { useState as useState3, useRef as useRef3, useEffect as useEffect3, useCallback as useCallback2, useMemo } from "react";
693
760
  import { X, Send, Loader2, CheckCircle2 } from "lucide-react";
694
- import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
761
+ import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
695
762
  function ReportModal({
696
763
  isOpen,
697
764
  captureResult,
@@ -700,16 +767,16 @@ function ReportModal({
700
767
  user,
701
768
  onClose
702
769
  }) {
703
- const [messages, setMessages] = useState2([]);
704
- const [input, setInput] = useState2("");
705
- const [isLoading, setIsLoading] = useState2(false);
706
- const [modalState, setModalState] = useState2("chatting");
707
- const [reportId, setReportId] = useState2(null);
708
- const [screenshotUrl, setScreenshotUrl] = useState2(null);
709
- const [errorMessage, setErrorMessage] = useState2(null);
710
- const chatEndRef = useRef2(null);
711
- const inputRef = useRef2(null);
712
- const hasInitRef = useRef2(false);
770
+ const [messages, setMessages] = useState3([]);
771
+ const [input, setInput] = useState3("");
772
+ const [isLoading, setIsLoading] = useState3(false);
773
+ const [modalState, setModalState] = useState3("chatting");
774
+ const [reportId, setReportId] = useState3(null);
775
+ const [screenshotUrl, setScreenshotUrl] = useState3(null);
776
+ const [errorMessage, setErrorMessage] = useState3(null);
777
+ const chatEndRef = useRef3(null);
778
+ const inputRef = useRef3(null);
779
+ const hasInitRef = useRef3(false);
713
780
  const apiHeaders = useMemo(
714
781
  () => ({
715
782
  "Content-Type": "application/json",
@@ -717,7 +784,7 @@ function ReportModal({
717
784
  }),
718
785
  [apiConfig.apiKey]
719
786
  );
720
- useEffect2(() => {
787
+ useEffect3(() => {
721
788
  if ((captureResult == null ? void 0 : captureResult.screenshot) && captureResult.screenshot.size > 0) {
722
789
  const url = URL.createObjectURL(captureResult.screenshot);
723
790
  setScreenshotUrl((prev) => {
@@ -775,17 +842,17 @@ function ReportModal({
775
842
  setIsLoading(false);
776
843
  }
777
844
  }, [captureResult, apiConfig.apiUrl, apiHeaders]);
778
- useEffect2(() => {
845
+ useEffect3(() => {
779
846
  if (isOpen && captureResult && !hasInitRef.current) {
780
847
  hasInitRef.current = true;
781
848
  sendInitialMessage();
782
849
  }
783
850
  }, [isOpen, captureResult, sendInitialMessage]);
784
- useEffect2(() => {
851
+ useEffect3(() => {
785
852
  var _a;
786
853
  (_a = chatEndRef.current) == null ? void 0 : _a.scrollIntoView({ behavior: "smooth" });
787
854
  }, [messages]);
788
- useEffect2(() => {
855
+ useEffect3(() => {
789
856
  var _a;
790
857
  if (isOpen && !isLoading) {
791
858
  (_a = inputRef.current) == null ? void 0 : _a.focus();
@@ -939,7 +1006,7 @@ function ReportModal({
939
1006
  onClick: (e) => {
940
1007
  if (e.target === e.currentTarget) handleClose();
941
1008
  },
942
- children: /* @__PURE__ */ jsxs2(
1009
+ children: /* @__PURE__ */ jsxs3(
943
1010
  "div",
944
1011
  {
945
1012
  className: cn(
@@ -949,8 +1016,8 @@ function ReportModal({
949
1016
  "min-[769px]:max-h-[85vh]"
950
1017
  ),
951
1018
  children: [
952
- /* @__PURE__ */ jsxs2("div", { className: "flex items-center justify-between border-b border-gray-200 bg-gray-50/30 px-4 py-3 dark:border-gray-800 dark:bg-gray-900/30", children: [
953
- /* @__PURE__ */ jsxs2("div", { children: [
1019
+ /* @__PURE__ */ jsxs3("div", { className: "flex items-center justify-between border-b border-gray-200 bg-gray-50/30 px-4 py-3 dark:border-gray-800 dark:bg-gray-900/30", children: [
1020
+ /* @__PURE__ */ jsxs3("div", { children: [
954
1021
  /* @__PURE__ */ jsx3("h2", { className: "text-sm font-semibold text-gray-900 dark:text-gray-100", children: "Bug Report" }),
955
1022
  /* @__PURE__ */ jsx3("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: siteId })
956
1023
  ] }),
@@ -972,10 +1039,10 @@ function ReportModal({
972
1039
  className: "max-h-40 w-full rounded-md border border-gray-200 object-contain dark:border-gray-700"
973
1040
  }
974
1041
  ) }),
975
- /* @__PURE__ */ jsx3("div", { className: "min-h-0 flex-1 space-y-3 overflow-y-auto px-4 py-3", children: modalState === "submitted" ? /* @__PURE__ */ jsxs2("div", { className: "flex flex-col items-center justify-center py-8 text-center", children: [
1042
+ /* @__PURE__ */ jsx3("div", { className: "min-h-0 flex-1 space-y-3 overflow-y-auto px-4 py-3", children: modalState === "submitted" ? /* @__PURE__ */ jsxs3("div", { className: "flex flex-col items-center justify-center py-8 text-center", children: [
976
1043
  /* @__PURE__ */ jsx3(CheckCircle2, { className: "mb-3 h-12 w-12 text-green-500" }),
977
1044
  /* @__PURE__ */ jsx3("h3", { className: "text-lg font-semibold text-gray-900 dark:text-gray-100", children: "Report Submitted" }),
978
- /* @__PURE__ */ jsxs2("p", { className: "mt-1 text-sm text-gray-500 dark:text-gray-400", children: [
1045
+ /* @__PURE__ */ jsxs3("p", { className: "mt-1 text-sm text-gray-500 dark:text-gray-400", children: [
979
1046
  "Reference:",
980
1047
  " ",
981
1048
  /* @__PURE__ */ jsx3("code", { className: "rounded bg-gray-100 px-1.5 py-0.5 text-xs dark:bg-gray-800", children: reportId == null ? void 0 : reportId.slice(0, 8) })
@@ -989,7 +1056,7 @@ function ReportModal({
989
1056
  children: "Done"
990
1057
  }
991
1058
  )
992
- ] }) : modalState === "error" ? /* @__PURE__ */ jsxs2("div", { className: "flex flex-col items-center justify-center py-8 text-center", children: [
1059
+ ] }) : modalState === "error" ? /* @__PURE__ */ jsxs3("div", { className: "flex flex-col items-center justify-center py-8 text-center", children: [
993
1060
  /* @__PURE__ */ jsx3(X, { className: "mb-3 h-12 w-12 text-red-500" }),
994
1061
  /* @__PURE__ */ jsx3("h3", { className: "text-lg font-semibold text-gray-900 dark:text-gray-100", children: "Submission Failed" }),
995
1062
  /* @__PURE__ */ jsx3("p", { className: "mt-1 text-sm text-gray-500 dark:text-gray-400", children: errorMessage || "Something went wrong. Please try again." }),
@@ -1001,10 +1068,10 @@ function ReportModal({
1001
1068
  children: "Try Again"
1002
1069
  }
1003
1070
  )
1004
- ] }) : modalState === "submitting" ? /* @__PURE__ */ jsxs2("div", { className: "flex flex-col items-center justify-center py-8", children: [
1071
+ ] }) : modalState === "submitting" ? /* @__PURE__ */ jsxs3("div", { className: "flex flex-col items-center justify-center py-8", children: [
1005
1072
  /* @__PURE__ */ jsx3(Loader2, { className: "mb-3 h-8 w-8 animate-spin text-indigo-500" }),
1006
1073
  /* @__PURE__ */ jsx3("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: "Submitting your report..." })
1007
- ] }) : /* @__PURE__ */ jsxs2(Fragment2, { children: [
1074
+ ] }) : /* @__PURE__ */ jsxs3(Fragment2, { children: [
1008
1075
  (captureResult == null ? void 0 : captureResult.screenshot.size) === 0 && /* @__PURE__ */ jsx3("p", { className: "text-xs text-amber-600", children: "Screenshot could not be captured. Please describe the visual issue in detail." }),
1009
1076
  messages.map((msg, i) => /* @__PURE__ */ jsx3(
1010
1077
  "div",
@@ -1017,13 +1084,13 @@ function ReportModal({
1017
1084
  },
1018
1085
  i
1019
1086
  )),
1020
- isLoading && /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2 rounded-lg bg-gray-100/50 p-3 dark:bg-gray-800/50", children: [
1087
+ isLoading && /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2 rounded-lg bg-gray-100/50 p-3 dark:bg-gray-800/50", children: [
1021
1088
  /* @__PURE__ */ jsx3(Loader2, { className: "h-3.5 w-3.5 animate-spin text-gray-500" }),
1022
1089
  /* @__PURE__ */ jsx3("span", { className: "text-sm text-gray-500 dark:text-gray-400", children: "Thinking..." })
1023
1090
  ] }),
1024
1091
  /* @__PURE__ */ jsx3("div", { ref: chatEndRef })
1025
1092
  ] }) }),
1026
- modalState === "chatting" && /* @__PURE__ */ jsx3("div", { className: "border-t border-gray-200 px-4 py-3 dark:border-gray-800", children: /* @__PURE__ */ jsxs2("div", { className: "flex flex-col gap-2", children: [
1093
+ modalState === "chatting" && /* @__PURE__ */ jsx3("div", { className: "border-t border-gray-200 px-4 py-3 dark:border-gray-800", children: /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-2", children: [
1027
1094
  /* @__PURE__ */ jsx3(
1028
1095
  "textarea",
1029
1096
  {
@@ -1037,8 +1104,8 @@ function ReportModal({
1037
1104
  disabled: isLoading
1038
1105
  }
1039
1106
  ),
1040
- /* @__PURE__ */ jsxs2("div", { className: "flex flex-col gap-2", children: [
1041
- captureResult && (captureResult.consoleErrors.length > 0 || captureResult.networkErrors.length > 0) && /* @__PURE__ */ jsxs2("p", { className: "flex-1 text-xs text-amber-600", children: [
1107
+ /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-2", children: [
1108
+ captureResult && (captureResult.consoleErrors.length > 0 || captureResult.networkErrors.length > 0) && /* @__PURE__ */ jsxs3("p", { className: "flex-1 text-xs text-amber-600", children: [
1042
1109
  [
1043
1110
  captureResult.consoleErrors.length > 0 ? `${captureResult.consoleErrors.length} console error${captureResult.consoleErrors.length !== 1 ? "s" : ""}` : null,
1044
1111
  captureResult.networkErrors.length > 0 ? `${captureResult.networkErrors.length} failed request${captureResult.networkErrors.length !== 1 ? "s" : ""}` : null
@@ -1046,8 +1113,8 @@ function ReportModal({
1046
1113
  " ",
1047
1114
  "captured \u2014 these will be included in the report."
1048
1115
  ] }),
1049
- /* @__PURE__ */ jsxs2("div", { className: "flex justify-end gap-2", children: [
1050
- /* @__PURE__ */ jsxs2(
1116
+ /* @__PURE__ */ jsxs3("div", { className: "flex justify-end gap-2", children: [
1117
+ /* @__PURE__ */ jsxs3(
1051
1118
  "button",
1052
1119
  {
1053
1120
  onClick: sendMessage,
@@ -1081,7 +1148,7 @@ function ReportModal({
1081
1148
  }
1082
1149
 
1083
1150
  // src/bug-reporter.tsx
1084
- import { Fragment as Fragment3, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
1151
+ import { Fragment as Fragment3, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
1085
1152
  function JarveBugReporter({
1086
1153
  apiUrl,
1087
1154
  apiKey,
@@ -1090,10 +1157,10 @@ function JarveBugReporter({
1090
1157
  children
1091
1158
  }) {
1092
1159
  const safeApiKey = apiKey || "";
1093
- const [captureMode, setCaptureMode] = useState3(false);
1094
- const [captureResult, setCaptureResult] = useState3(null);
1095
- const [showModal, setShowModal] = useState3(false);
1096
- useEffect3(() => {
1160
+ const [captureMode, setCaptureMode] = useState4(false);
1161
+ const [captureResult, setCaptureResult] = useState4(null);
1162
+ const [showModal, setShowModal] = useState4(false);
1163
+ useEffect4(() => {
1097
1164
  startCapturing();
1098
1165
  startNetworkCapture();
1099
1166
  return () => {
@@ -1121,7 +1188,7 @@ function JarveBugReporter({
1121
1188
  const siteId = safeApiKey.startsWith("brk_") ? safeApiKey.slice(4, 12) : "external";
1122
1189
  const reporterName = (user == null ? void 0 : user.name) || "Anonymous";
1123
1190
  const reporterEmail = (user == null ? void 0 : user.email) || "unknown@external";
1124
- return /* @__PURE__ */ jsxs3(Fragment3, { children: [
1191
+ return /* @__PURE__ */ jsxs4(Fragment3, { children: [
1125
1192
  children,
1126
1193
  /* @__PURE__ */ jsx4(
1127
1194
  FloatingButton,