@jarve/bug-reporter 0.2.0 → 0.3.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/README.md +8 -7
- package/dist/index.d.mts +5 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +135 -91
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +135 -91
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -34,16 +34,21 @@ function cn(...inputs) {
|
|
|
34
34
|
|
|
35
35
|
// src/floating-button.tsx
|
|
36
36
|
import { jsx } from "react/jsx-runtime";
|
|
37
|
-
function FloatingButton({ isActive, onClick }) {
|
|
37
|
+
function FloatingButton({ isActive, onClick, position = "right" }) {
|
|
38
|
+
const sideClasses = position === "left" ? "left-4 md:left-6" : "right-4 md:right-6";
|
|
38
39
|
return /* @__PURE__ */ jsx(
|
|
39
40
|
"button",
|
|
40
41
|
{
|
|
41
42
|
onClick,
|
|
42
43
|
className: cn(
|
|
43
|
-
"fixed
|
|
44
|
-
"hover:scale-110 focus:
|
|
45
|
-
|
|
46
|
-
"bottom-4
|
|
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"
|
|
47
52
|
),
|
|
48
53
|
title: isActive ? "Cancel bug capture" : "Report a bug",
|
|
49
54
|
"aria-label": isActive ? "Cancel bug capture" : "Report a bug",
|
|
@@ -173,8 +178,7 @@ var errorListener = null;
|
|
|
173
178
|
var rejectionListener = null;
|
|
174
179
|
function startCapturing() {
|
|
175
180
|
if (isCapturing) return;
|
|
176
|
-
if (console.error.__bugReporterPatched)
|
|
177
|
-
return;
|
|
181
|
+
if (console.error.__bugReporterPatched) return;
|
|
178
182
|
isCapturing = true;
|
|
179
183
|
capturedErrors = [];
|
|
180
184
|
originalConsoleError = console.error;
|
|
@@ -420,12 +424,21 @@ function CaptureOverlay({
|
|
|
420
424
|
skipFonts: true
|
|
421
425
|
});
|
|
422
426
|
const blob = dataUrlToBlob(dataUrl);
|
|
423
|
-
const metadata = collectMetadata(
|
|
427
|
+
const metadata = collectMetadata(
|
|
428
|
+
section,
|
|
429
|
+
siteId,
|
|
430
|
+
reporterName,
|
|
431
|
+
reporterEmail,
|
|
432
|
+
elementInfo
|
|
433
|
+
);
|
|
424
434
|
const consoleErrors = getCapturedErrors();
|
|
425
435
|
const networkErrors = getCapturedNetworkErrors();
|
|
426
436
|
onCapture({ screenshot: blob, metadata, consoleErrors, networkErrors });
|
|
427
437
|
} catch (err) {
|
|
428
|
-
console.warn(
|
|
438
|
+
console.warn(
|
|
439
|
+
"Bug reporter: first capture attempt failed, retrying with simpler settings",
|
|
440
|
+
err
|
|
441
|
+
);
|
|
429
442
|
try {
|
|
430
443
|
const dataUrl = await toPng(section, {
|
|
431
444
|
quality: 0.6,
|
|
@@ -434,13 +447,25 @@ function CaptureOverlay({
|
|
|
434
447
|
cacheBust: true
|
|
435
448
|
});
|
|
436
449
|
const retryBlob = dataUrlToBlob(dataUrl);
|
|
437
|
-
const metadata = collectMetadata(
|
|
450
|
+
const metadata = collectMetadata(
|
|
451
|
+
section,
|
|
452
|
+
siteId,
|
|
453
|
+
reporterName,
|
|
454
|
+
reporterEmail,
|
|
455
|
+
elementInfo
|
|
456
|
+
);
|
|
438
457
|
const consoleErrors = getCapturedErrors();
|
|
439
458
|
const networkErrors = getCapturedNetworkErrors();
|
|
440
459
|
onCapture({ screenshot: retryBlob, metadata, consoleErrors, networkErrors });
|
|
441
460
|
} catch (e) {
|
|
442
461
|
console.error("Bug reporter: screenshot capture failed after retry");
|
|
443
|
-
const metadata = collectMetadata(
|
|
462
|
+
const metadata = collectMetadata(
|
|
463
|
+
section,
|
|
464
|
+
siteId,
|
|
465
|
+
reporterName,
|
|
466
|
+
reporterEmail,
|
|
467
|
+
elementInfo
|
|
468
|
+
);
|
|
444
469
|
const consoleErrors = getCapturedErrors();
|
|
445
470
|
const networkErrors = getCapturedNetworkErrors();
|
|
446
471
|
onCapture({
|
|
@@ -571,7 +596,16 @@ function CaptureOverlay({
|
|
|
571
596
|
document.removeEventListener("click", handleClick, true);
|
|
572
597
|
if (rafRef.current) cancelAnimationFrame(rafRef.current);
|
|
573
598
|
};
|
|
574
|
-
}, [
|
|
599
|
+
}, [
|
|
600
|
+
isActive,
|
|
601
|
+
isTouchMode,
|
|
602
|
+
handleMouseMove,
|
|
603
|
+
handleClick,
|
|
604
|
+
handleTouchEnd,
|
|
605
|
+
handlePointerDown,
|
|
606
|
+
handleKeyDown,
|
|
607
|
+
handleScroll
|
|
608
|
+
]);
|
|
575
609
|
const highlightRect = isTouchMode ? selectedRect : hoveredRect;
|
|
576
610
|
const showHighlight = isTouchMode ? !!selectedSection : !!hoveredElement && !!hoveredRect;
|
|
577
611
|
if (!isActive) return null;
|
|
@@ -582,20 +616,21 @@ function CaptureOverlay({
|
|
|
582
616
|
"data-bug-reporter": true,
|
|
583
617
|
role: "alert",
|
|
584
618
|
"aria-live": "assertive",
|
|
585
|
-
className: "fixed top-0
|
|
619
|
+
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",
|
|
586
620
|
children: isTouchMode ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
587
621
|
/* @__PURE__ */ jsx2("span", { children: "Tap the section with the bug" }),
|
|
588
622
|
/* @__PURE__ */ jsx2(
|
|
589
623
|
"button",
|
|
590
624
|
{
|
|
591
625
|
onClick: onCancel,
|
|
592
|
-
className: "
|
|
626
|
+
className: "min-h-[44px] rounded-md bg-white/20 px-3 py-1 text-sm font-medium",
|
|
593
627
|
children: "Cancel"
|
|
594
628
|
}
|
|
595
629
|
)
|
|
596
630
|
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
597
|
-
"Click on the section with the bug. Press
|
|
598
|
-
|
|
631
|
+
"Click on the section with the bug. Press",
|
|
632
|
+
" ",
|
|
633
|
+
/* @__PURE__ */ jsx2("kbd", { className: "mx-1 rounded bg-indigo-800 px-1.5 py-0.5 text-xs", children: "Esc" }),
|
|
599
634
|
" to cancel."
|
|
600
635
|
] })
|
|
601
636
|
}
|
|
@@ -605,7 +640,7 @@ function CaptureOverlay({
|
|
|
605
640
|
{
|
|
606
641
|
ref: overlayRef,
|
|
607
642
|
"data-bug-reporter": true,
|
|
608
|
-
className: "
|
|
643
|
+
className: "pointer-events-none fixed z-[9998] rounded-sm border-2 border-indigo-500 transition-all duration-150 ease-out",
|
|
609
644
|
style: {
|
|
610
645
|
top: highlightRect.top - 2,
|
|
611
646
|
left: highlightRect.left - 2,
|
|
@@ -619,11 +654,11 @@ function CaptureOverlay({
|
|
|
619
654
|
"div",
|
|
620
655
|
{
|
|
621
656
|
"data-bug-reporter": true,
|
|
622
|
-
className: "fixed
|
|
657
|
+
className: "fixed right-0 bottom-0 left-0 z-[10000] border-t border-gray-200 bg-white shadow-lg",
|
|
623
658
|
style: { paddingBottom: "env(safe-area-inset-bottom, 0px)" },
|
|
624
|
-
children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-4 py-3
|
|
625
|
-
/* @__PURE__ */ jsx2("span", { className: "text-sm font-medium text-gray-900
|
|
626
|
-
/* @__PURE__ */ jsxs("div", { className: "flex gap-2
|
|
659
|
+
children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3 px-4 py-3", children: [
|
|
660
|
+
/* @__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: [
|
|
627
662
|
/* @__PURE__ */ jsx2(
|
|
628
663
|
"button",
|
|
629
664
|
{
|
|
@@ -633,7 +668,7 @@ function CaptureOverlay({
|
|
|
633
668
|
setSelectedTarget(null);
|
|
634
669
|
touchCoordsRef.current = null;
|
|
635
670
|
},
|
|
636
|
-
className: "
|
|
671
|
+
className: "min-h-[44px] rounded-md border border-gray-300 px-4 text-sm font-medium text-gray-700",
|
|
637
672
|
children: "Cancel"
|
|
638
673
|
}
|
|
639
674
|
),
|
|
@@ -641,7 +676,7 @@ function CaptureOverlay({
|
|
|
641
676
|
"button",
|
|
642
677
|
{
|
|
643
678
|
onClick: handleConfirmCapture,
|
|
644
|
-
className: "
|
|
679
|
+
className: "min-h-[44px] rounded-md bg-indigo-600 px-4 text-sm font-medium text-white",
|
|
645
680
|
children: "Capture"
|
|
646
681
|
}
|
|
647
682
|
)
|
|
@@ -715,7 +750,9 @@ function ReportModal({
|
|
|
715
750
|
})
|
|
716
751
|
});
|
|
717
752
|
if (response.status === 401) {
|
|
718
|
-
console.error(
|
|
753
|
+
console.error(
|
|
754
|
+
"Bug reporter: invalid or missing API key. Check your BugReporter apiKey prop."
|
|
755
|
+
);
|
|
719
756
|
setMessages([
|
|
720
757
|
{
|
|
721
758
|
role: "assistant",
|
|
@@ -812,9 +849,7 @@ function ReportModal({
|
|
|
812
849
|
setModalState("submitted");
|
|
813
850
|
} catch (err) {
|
|
814
851
|
console.error("Bug reporter: failed to submit report", err);
|
|
815
|
-
setErrorMessage(
|
|
816
|
-
err instanceof Error ? err.message : "Failed to submit report"
|
|
817
|
-
);
|
|
852
|
+
setErrorMessage(err instanceof Error ? err.message : "Failed to submit report");
|
|
818
853
|
setModalState("error");
|
|
819
854
|
}
|
|
820
855
|
},
|
|
@@ -827,10 +862,7 @@ function ReportModal({
|
|
|
827
862
|
if (!input.trim() || isLoading || !captureResult) return;
|
|
828
863
|
const userMessage = input.trim();
|
|
829
864
|
setInput("");
|
|
830
|
-
const newMessages = [
|
|
831
|
-
...messages,
|
|
832
|
-
{ role: "user", content: userMessage }
|
|
833
|
-
];
|
|
865
|
+
const newMessages = [...messages, { role: "user", content: userMessage }];
|
|
834
866
|
setMessages(newMessages);
|
|
835
867
|
setIsLoading(true);
|
|
836
868
|
try {
|
|
@@ -846,7 +878,9 @@ function ReportModal({
|
|
|
846
878
|
})
|
|
847
879
|
});
|
|
848
880
|
if (response.status === 401) {
|
|
849
|
-
console.error(
|
|
881
|
+
console.error(
|
|
882
|
+
"Bug reporter: invalid or missing API key. Check your BugReporter apiKey prop."
|
|
883
|
+
);
|
|
850
884
|
setMessages([
|
|
851
885
|
...newMessages,
|
|
852
886
|
{
|
|
@@ -858,10 +892,7 @@ function ReportModal({
|
|
|
858
892
|
}
|
|
859
893
|
if (!response.ok) throw new Error("Failed to get AI response");
|
|
860
894
|
const data = await response.json();
|
|
861
|
-
setMessages([
|
|
862
|
-
...newMessages,
|
|
863
|
-
{ role: "assistant", content: data.message }
|
|
864
|
-
]);
|
|
895
|
+
setMessages([...newMessages, { role: "assistant", content: data.message }]);
|
|
865
896
|
if (data.readyToSubmit && data.structuredReport) {
|
|
866
897
|
await submitReport(
|
|
867
898
|
[...newMessages, { role: "assistant", content: data.message }],
|
|
@@ -912,65 +943,66 @@ function ReportModal({
|
|
|
912
943
|
"div",
|
|
913
944
|
{
|
|
914
945
|
className: cn(
|
|
915
|
-
"
|
|
916
|
-
"w-full max-w-lg
|
|
917
|
-
"max-[768px]:mx-0 max-[768px]:
|
|
946
|
+
"flex flex-col overflow-hidden rounded-xl border border-gray-200 bg-white shadow-2xl dark:border-gray-800 dark:bg-gray-950",
|
|
947
|
+
"mx-4 w-full max-w-lg",
|
|
948
|
+
"max-[768px]:mx-0 max-[768px]:h-full max-[768px]:max-w-none max-[768px]:rounded-none",
|
|
918
949
|
"min-[769px]:max-h-[85vh]"
|
|
919
950
|
),
|
|
920
951
|
children: [
|
|
921
|
-
/* @__PURE__ */ jsxs2("div", { className: "flex items-center justify-between
|
|
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: [
|
|
922
953
|
/* @__PURE__ */ jsxs2("div", { children: [
|
|
923
|
-
/* @__PURE__ */ jsx3("h2", { className: "font-semibold text-
|
|
954
|
+
/* @__PURE__ */ jsx3("h2", { className: "text-sm font-semibold text-gray-900 dark:text-gray-100", children: "Bug Report" }),
|
|
924
955
|
/* @__PURE__ */ jsx3("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: siteId })
|
|
925
956
|
] }),
|
|
926
957
|
/* @__PURE__ */ jsx3(
|
|
927
958
|
"button",
|
|
928
959
|
{
|
|
929
960
|
onClick: handleClose,
|
|
930
|
-
className: "p-1.5
|
|
961
|
+
className: "rounded-md p-1.5 transition-colors hover:bg-gray-100 dark:hover:bg-gray-800",
|
|
931
962
|
"aria-label": "Close",
|
|
932
963
|
children: /* @__PURE__ */ jsx3(X, { className: "h-4 w-4 text-gray-600 dark:text-gray-400" })
|
|
933
964
|
}
|
|
934
965
|
)
|
|
935
966
|
] }),
|
|
936
|
-
screenshotUrl && /* @__PURE__ */ jsx3("div", { className: "
|
|
967
|
+
screenshotUrl && /* @__PURE__ */ jsx3("div", { className: "border-b border-gray-200 bg-gray-50/10 px-4 py-3 dark:border-gray-800 dark:bg-gray-900/10", children: /* @__PURE__ */ jsx3(
|
|
937
968
|
"img",
|
|
938
969
|
{
|
|
939
970
|
src: screenshotUrl,
|
|
940
971
|
alt: "Captured section",
|
|
941
|
-
className: "
|
|
972
|
+
className: "max-h-40 w-full rounded-md border border-gray-200 object-contain dark:border-gray-700"
|
|
942
973
|
}
|
|
943
974
|
) }),
|
|
944
|
-
/* @__PURE__ */ jsx3("div", { className: "flex-1 overflow-y-auto px-4 py-3
|
|
945
|
-
/* @__PURE__ */ jsx3(CheckCircle2, { className: "h-12 w-12 text-green-500
|
|
946
|
-
/* @__PURE__ */ jsx3("h3", { className: "font-semibold text-
|
|
947
|
-
/* @__PURE__ */ jsxs2("p", { className: "text-sm text-gray-500 dark:text-gray-400
|
|
948
|
-
"Reference:
|
|
949
|
-
|
|
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: [
|
|
976
|
+
/* @__PURE__ */ jsx3(CheckCircle2, { className: "mb-3 h-12 w-12 text-green-500" }),
|
|
977
|
+
/* @__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: [
|
|
979
|
+
"Reference:",
|
|
980
|
+
" ",
|
|
981
|
+
/* @__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) })
|
|
950
982
|
] }),
|
|
951
|
-
/* @__PURE__ */ jsx3("p", { className: "text-sm text-gray-500 dark:text-gray-400
|
|
983
|
+
/* @__PURE__ */ jsx3("p", { className: "mt-2 text-sm text-gray-500 dark:text-gray-400", children: "Thanks for the report \u2014 we'll look into it." }),
|
|
952
984
|
/* @__PURE__ */ jsx3(
|
|
953
985
|
"button",
|
|
954
986
|
{
|
|
955
987
|
onClick: handleClose,
|
|
956
|
-
className: "mt-4 px-4 py-2
|
|
988
|
+
className: "mt-4 rounded-md bg-indigo-600 px-4 py-2 text-sm text-white transition-colors hover:bg-indigo-700",
|
|
957
989
|
children: "Done"
|
|
958
990
|
}
|
|
959
991
|
)
|
|
960
992
|
] }) : modalState === "error" ? /* @__PURE__ */ jsxs2("div", { className: "flex flex-col items-center justify-center py-8 text-center", children: [
|
|
961
|
-
/* @__PURE__ */ jsx3(X, { className: "h-12 w-12 text-red-500
|
|
962
|
-
/* @__PURE__ */ jsx3("h3", { className: "font-semibold text-
|
|
963
|
-
/* @__PURE__ */ jsx3("p", { className: "text-sm text-gray-500 dark:text-gray-400
|
|
993
|
+
/* @__PURE__ */ jsx3(X, { className: "mb-3 h-12 w-12 text-red-500" }),
|
|
994
|
+
/* @__PURE__ */ jsx3("h3", { className: "text-lg font-semibold text-gray-900 dark:text-gray-100", children: "Submission Failed" }),
|
|
995
|
+
/* @__PURE__ */ jsx3("p", { className: "mt-1 text-sm text-gray-500 dark:text-gray-400", children: errorMessage || "Something went wrong. Please try again." }),
|
|
964
996
|
/* @__PURE__ */ jsx3(
|
|
965
997
|
"button",
|
|
966
998
|
{
|
|
967
999
|
onClick: () => setModalState("chatting"),
|
|
968
|
-
className: "mt-4 px-4 py-2
|
|
1000
|
+
className: "mt-4 rounded-md bg-indigo-600 px-4 py-2 text-sm text-white transition-colors hover:bg-indigo-700",
|
|
969
1001
|
children: "Try Again"
|
|
970
1002
|
}
|
|
971
1003
|
)
|
|
972
1004
|
] }) : modalState === "submitting" ? /* @__PURE__ */ jsxs2("div", { className: "flex flex-col items-center justify-center py-8", children: [
|
|
973
|
-
/* @__PURE__ */ jsx3(Loader2, { className: "h-8 w-8 animate-spin text-indigo-500
|
|
1005
|
+
/* @__PURE__ */ jsx3(Loader2, { className: "mb-3 h-8 w-8 animate-spin text-indigo-500" }),
|
|
974
1006
|
/* @__PURE__ */ jsx3("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: "Submitting your report..." })
|
|
975
1007
|
] }) : /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
976
1008
|
(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." }),
|
|
@@ -979,42 +1011,53 @@ function ReportModal({
|
|
|
979
1011
|
{
|
|
980
1012
|
className: cn(
|
|
981
1013
|
"text-sm leading-relaxed",
|
|
982
|
-
msg.role === "assistant" ? "
|
|
1014
|
+
msg.role === "assistant" ? "rounded-lg bg-gray-100/50 p-3 text-gray-900 dark:bg-gray-800/50 dark:text-gray-100" : "ml-8 rounded-lg bg-indigo-600 p-3 text-white"
|
|
983
1015
|
),
|
|
984
1016
|
children: msg.content
|
|
985
1017
|
},
|
|
986
1018
|
i
|
|
987
1019
|
)),
|
|
988
|
-
isLoading && /* @__PURE__ */ jsxs2("div", { className: "bg-gray-100/50 dark:bg-gray-800/50
|
|
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: [
|
|
989
1021
|
/* @__PURE__ */ jsx3(Loader2, { className: "h-3.5 w-3.5 animate-spin text-gray-500" }),
|
|
990
1022
|
/* @__PURE__ */ jsx3("span", { className: "text-sm text-gray-500 dark:text-gray-400", children: "Thinking..." })
|
|
991
1023
|
] }),
|
|
992
1024
|
/* @__PURE__ */ jsx3("div", { ref: chatEndRef })
|
|
993
1025
|
] }) }),
|
|
994
|
-
modalState === "chatting" && /* @__PURE__ */
|
|
995
|
-
/* @__PURE__ */
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
/* @__PURE__ */ jsxs2("
|
|
1010
|
-
|
|
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: [
|
|
1027
|
+
/* @__PURE__ */ jsx3(
|
|
1028
|
+
"textarea",
|
|
1029
|
+
{
|
|
1030
|
+
ref: inputRef,
|
|
1031
|
+
value: input,
|
|
1032
|
+
onChange: (e) => setInput(e.target.value),
|
|
1033
|
+
onKeyDown: handleKeyDown,
|
|
1034
|
+
placeholder: "Describe what's wrong...",
|
|
1035
|
+
rows: 2,
|
|
1036
|
+
className: "w-full resize-none rounded-md border border-gray-300 bg-white px-3 py-2 text-sm text-gray-900 focus:border-transparent focus:ring-2 focus:ring-indigo-400 focus:outline-none dark:border-gray-700 dark:bg-gray-950 dark:text-gray-100",
|
|
1037
|
+
disabled: isLoading
|
|
1038
|
+
}
|
|
1039
|
+
),
|
|
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: [
|
|
1042
|
+
[
|
|
1043
|
+
captureResult.consoleErrors.length > 0 ? `${captureResult.consoleErrors.length} console error${captureResult.consoleErrors.length !== 1 ? "s" : ""}` : null,
|
|
1044
|
+
captureResult.networkErrors.length > 0 ? `${captureResult.networkErrors.length} failed request${captureResult.networkErrors.length !== 1 ? "s" : ""}` : null
|
|
1045
|
+
].filter(Boolean).join(" + "),
|
|
1046
|
+
" ",
|
|
1047
|
+
"captured \u2014 these will be included in the report."
|
|
1048
|
+
] }),
|
|
1049
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex justify-end gap-2", children: [
|
|
1050
|
+
/* @__PURE__ */ jsxs2(
|
|
1011
1051
|
"button",
|
|
1012
1052
|
{
|
|
1013
1053
|
onClick: sendMessage,
|
|
1014
1054
|
disabled: !input.trim() || isLoading,
|
|
1015
|
-
className: "
|
|
1055
|
+
className: "flex items-center gap-1 rounded-md bg-indigo-600 px-3 py-2 text-nowrap text-white transition-colors hover:bg-indigo-700 disabled:cursor-not-allowed disabled:opacity-50",
|
|
1016
1056
|
title: "Send message",
|
|
1017
|
-
children:
|
|
1057
|
+
children: [
|
|
1058
|
+
/* @__PURE__ */ jsx3(Send, { className: "h-4 w-4" }),
|
|
1059
|
+
/* @__PURE__ */ jsx3("span", { className: "text-sm font-medium", children: "Send message" })
|
|
1060
|
+
]
|
|
1018
1061
|
}
|
|
1019
1062
|
),
|
|
1020
1063
|
messages.length >= 2 && /* @__PURE__ */ jsx3(
|
|
@@ -1022,22 +1065,14 @@ function ReportModal({
|
|
|
1022
1065
|
{
|
|
1023
1066
|
onClick: handleManualSubmit,
|
|
1024
1067
|
disabled: isLoading,
|
|
1025
|
-
className: "px-
|
|
1068
|
+
className: "rounded-md bg-green-600 px-3 py-2 text-xs font-medium text-nowrap text-white transition-colors hover:bg-green-700 disabled:opacity-50",
|
|
1026
1069
|
title: "Submit report now",
|
|
1027
|
-
children: "Submit"
|
|
1070
|
+
children: /* @__PURE__ */ jsx3("span", { className: "text-sm font-medium", children: "Submit report" })
|
|
1028
1071
|
}
|
|
1029
1072
|
)
|
|
1030
1073
|
] })
|
|
1031
|
-
] }),
|
|
1032
|
-
captureResult && (captureResult.consoleErrors.length > 0 || captureResult.networkErrors.length > 0) && /* @__PURE__ */ jsxs2("p", { className: "text-xs text-amber-600 mt-1.5", children: [
|
|
1033
|
-
[
|
|
1034
|
-
captureResult.consoleErrors.length > 0 ? `${captureResult.consoleErrors.length} console error${captureResult.consoleErrors.length !== 1 ? "s" : ""}` : null,
|
|
1035
|
-
captureResult.networkErrors.length > 0 ? `${captureResult.networkErrors.length} failed request${captureResult.networkErrors.length !== 1 ? "s" : ""}` : null
|
|
1036
|
-
].filter(Boolean).join(" + "),
|
|
1037
|
-
" ",
|
|
1038
|
-
"captured \u2014 these will be included in the report."
|
|
1039
1074
|
] })
|
|
1040
|
-
] })
|
|
1075
|
+
] }) })
|
|
1041
1076
|
]
|
|
1042
1077
|
}
|
|
1043
1078
|
)
|
|
@@ -1051,8 +1086,10 @@ function JarveBugReporter({
|
|
|
1051
1086
|
apiUrl,
|
|
1052
1087
|
apiKey,
|
|
1053
1088
|
user,
|
|
1089
|
+
buttonPosition,
|
|
1054
1090
|
children
|
|
1055
1091
|
}) {
|
|
1092
|
+
const safeApiKey = apiKey || "";
|
|
1056
1093
|
const [captureMode, setCaptureMode] = useState3(false);
|
|
1057
1094
|
const [captureResult, setCaptureResult] = useState3(null);
|
|
1058
1095
|
const [showModal, setShowModal] = useState3(false);
|
|
@@ -1081,12 +1118,19 @@ function JarveBugReporter({
|
|
|
1081
1118
|
clearCapturedErrors();
|
|
1082
1119
|
clearCapturedNetworkErrors();
|
|
1083
1120
|
}, []);
|
|
1084
|
-
const siteId =
|
|
1121
|
+
const siteId = safeApiKey.startsWith("brk_") ? safeApiKey.slice(4, 12) : "external";
|
|
1085
1122
|
const reporterName = (user == null ? void 0 : user.name) || "Anonymous";
|
|
1086
1123
|
const reporterEmail = (user == null ? void 0 : user.email) || "unknown@external";
|
|
1087
1124
|
return /* @__PURE__ */ jsxs3(Fragment3, { children: [
|
|
1088
1125
|
children,
|
|
1089
|
-
/* @__PURE__ */ jsx4(
|
|
1126
|
+
/* @__PURE__ */ jsx4(
|
|
1127
|
+
FloatingButton,
|
|
1128
|
+
{
|
|
1129
|
+
isActive: captureMode,
|
|
1130
|
+
onClick: toggleCaptureMode,
|
|
1131
|
+
position: buttonPosition
|
|
1132
|
+
}
|
|
1133
|
+
),
|
|
1090
1134
|
/* @__PURE__ */ jsx4(
|
|
1091
1135
|
CaptureOverlay,
|
|
1092
1136
|
{
|