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.d.mts +27 -8
- package/dist/index.d.ts +27 -8
- package/dist/index.js +527 -731
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +525 -729
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
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
|
|
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/
|
|
363
|
-
var
|
|
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
|
|
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
|
|
618
|
-
|
|
619
|
-
label = "Report Bug",
|
|
620
|
-
className,
|
|
621
|
-
variant = "classic",
|
|
622
|
-
showSeverity = true,
|
|
383
|
+
function ReportDialog({
|
|
384
|
+
report,
|
|
623
385
|
types,
|
|
624
|
-
|
|
386
|
+
showSeverity = true
|
|
625
387
|
}) {
|
|
626
|
-
|
|
627
|
-
const [
|
|
628
|
-
const [
|
|
629
|
-
const [
|
|
630
|
-
const [
|
|
631
|
-
const [
|
|
632
|
-
const
|
|
633
|
-
const
|
|
634
|
-
const
|
|
635
|
-
const
|
|
636
|
-
const
|
|
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
|
|
647
|
-
const file = (
|
|
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 (
|
|
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,
|
|
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
|
-
|
|
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
|
|
709
|
-
(0,
|
|
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 (
|
|
487
|
+
if (showSeverity && reportType === "BUG") {
|
|
733
488
|
metadata.severity = severity;
|
|
734
489
|
}
|
|
735
|
-
const result =
|
|
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
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
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,
|
|
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:
|
|
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,
|
|
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,
|
|
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,
|
|
824
|
-
|
|
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,
|
|
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,
|
|
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:
|
|
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,
|
|
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,
|
|
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
|
-
|
|
875
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
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:
|
|
639
|
+
children: [
|
|
640
|
+
getTypeLabel(reportType),
|
|
641
|
+
" sent. Thank you!"
|
|
642
|
+
]
|
|
903
643
|
}
|
|
904
|
-
) :
|
|
905
|
-
/*
|
|
906
|
-
|
|
907
|
-
|
|
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
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
setStep(2);
|
|
914
|
-
},
|
|
685
|
+
value: description,
|
|
686
|
+
onChange: (e) => setDescription(e.target.value),
|
|
687
|
+
placeholder: getPlaceholder(reportType),
|
|
915
688
|
style: {
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
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
|
-
|
|
924
|
-
cursor: "pointer",
|
|
925
|
-
color: t.text,
|
|
694
|
+
fontSize: "14px",
|
|
926
695
|
fontFamily: "inherit",
|
|
927
|
-
|
|
696
|
+
resize: "vertical",
|
|
697
|
+
outline: "none",
|
|
698
|
+
boxSizing: "border-box",
|
|
699
|
+
color: t.text,
|
|
700
|
+
backgroundColor: t.inputBg
|
|
928
701
|
},
|
|
929
|
-
|
|
930
|
-
e.
|
|
702
|
+
onFocus: (e) => {
|
|
703
|
+
e.target.style.borderColor = t.accent;
|
|
931
704
|
},
|
|
932
|
-
|
|
933
|
-
e.
|
|
705
|
+
onBlur: (e) => {
|
|
706
|
+
e.target.style.borderColor = t.inputBorder;
|
|
934
707
|
},
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
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: () =>
|
|
1004
|
-
disabled: !description.trim(),
|
|
717
|
+
onClick: () => setSeverity(s),
|
|
1005
718
|
style: {
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
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:
|
|
727
|
+
cursor: "pointer",
|
|
1016
728
|
fontFamily: "inherit",
|
|
1017
|
-
|
|
729
|
+
textTransform: "capitalize",
|
|
730
|
+
transition: "all 0.15s ease"
|
|
1018
731
|
},
|
|
1019
|
-
children:
|
|
1020
|
-
}
|
|
1021
|
-
|
|
732
|
+
children: s
|
|
733
|
+
},
|
|
734
|
+
s
|
|
735
|
+
)) })
|
|
1022
736
|
] }),
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
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
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
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
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
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
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
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: "
|
|
814
|
+
maxHeight: "80px",
|
|
1189
815
|
objectFit: "cover",
|
|
1190
816
|
objectPosition: "top",
|
|
1191
817
|
cursor: "pointer"
|
|
1192
818
|
}
|
|
1193
819
|
}
|
|
1194
820
|
),
|
|
1195
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
1219
|
-
"
|
|
868
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
869
|
+
"button",
|
|
1220
870
|
{
|
|
871
|
+
type: "button",
|
|
872
|
+
onClick: retakeScreenshot,
|
|
1221
873
|
style: {
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
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
|
-
|
|
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:
|
|
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:
|
|
1358
|
-
color:
|
|
899
|
+
backgroundColor: isSubmitting ? t.bgSecondary : t.accent,
|
|
900
|
+
color: isSubmitting ? t.textMuted : t.accentText,
|
|
1359
901
|
fontSize: "14px",
|
|
1360
902
|
fontWeight: 600,
|
|
1361
|
-
cursor:
|
|
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,
|
|
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,
|
|
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,
|
|
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 &&
|
|
1399
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
1498
|
-
/* @__PURE__ */ (0,
|
|
1499
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
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
|
-
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
|
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,
|
|
1585
|
-
const [isLoading, setIsLoading] = (0,
|
|
1586
|
-
const [isFetching, setIsFetching] = (0,
|
|
1587
|
-
const [error, setError] = (0,
|
|
1588
|
-
const fetchReports = (0,
|
|
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,
|
|
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,
|
|
1652
|
-
const [error, setError] = (0,
|
|
1653
|
-
const run = (0,
|
|
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);
|