@fatagnus/convex-feedback 0.1.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/LICENSE +177 -0
- package/README.md +382 -0
- package/dist/convex/agents/bugReportAgent.d.ts +30 -0
- package/dist/convex/agents/bugReportAgent.d.ts.map +1 -0
- package/dist/convex/agents/bugReportAgent.js +243 -0
- package/dist/convex/agents/bugReportAgent.js.map +1 -0
- package/dist/convex/agents/feedbackAgent.d.ts +29 -0
- package/dist/convex/agents/feedbackAgent.d.ts.map +1 -0
- package/dist/convex/agents/feedbackAgent.js +232 -0
- package/dist/convex/agents/feedbackAgent.js.map +1 -0
- package/dist/convex/bugReports.d.ts +49 -0
- package/dist/convex/bugReports.d.ts.map +1 -0
- package/dist/convex/bugReports.js +321 -0
- package/dist/convex/bugReports.js.map +1 -0
- package/dist/convex/convex.config.d.ts +3 -0
- package/dist/convex/convex.config.d.ts.map +1 -0
- package/dist/convex/convex.config.js +6 -0
- package/dist/convex/convex.config.js.map +1 -0
- package/dist/convex/emails/bugReportEmails.d.ts +16 -0
- package/dist/convex/emails/bugReportEmails.d.ts.map +1 -0
- package/dist/convex/emails/bugReportEmails.js +403 -0
- package/dist/convex/emails/bugReportEmails.js.map +1 -0
- package/dist/convex/emails/feedbackEmails.d.ts +16 -0
- package/dist/convex/emails/feedbackEmails.d.ts.map +1 -0
- package/dist/convex/emails/feedbackEmails.js +389 -0
- package/dist/convex/emails/feedbackEmails.js.map +1 -0
- package/dist/convex/feedback.d.ts +49 -0
- package/dist/convex/feedback.d.ts.map +1 -0
- package/dist/convex/feedback.js +327 -0
- package/dist/convex/feedback.js.map +1 -0
- package/dist/convex/index.d.ts +10 -0
- package/dist/convex/index.d.ts.map +1 -0
- package/dist/convex/index.js +12 -0
- package/dist/convex/index.js.map +1 -0
- package/dist/convex/schema.d.ts +200 -0
- package/dist/convex/schema.d.ts.map +1 -0
- package/dist/convex/schema.js +150 -0
- package/dist/convex/schema.js.map +1 -0
- package/dist/convex/supportTeams.d.ts +29 -0
- package/dist/convex/supportTeams.d.ts.map +1 -0
- package/dist/convex/supportTeams.js +159 -0
- package/dist/convex/supportTeams.js.map +1 -0
- package/dist/index.d.ts +70 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +63 -0
- package/dist/index.js.map +1 -0
- package/dist/react/BugReportButton.d.ts +70 -0
- package/dist/react/BugReportButton.d.ts.map +1 -0
- package/dist/react/BugReportButton.js +371 -0
- package/dist/react/BugReportButton.js.map +1 -0
- package/dist/react/BugReportContext.d.ts +59 -0
- package/dist/react/BugReportContext.d.ts.map +1 -0
- package/dist/react/BugReportContext.js +107 -0
- package/dist/react/BugReportContext.js.map +1 -0
- package/dist/react/index.d.ts +36 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +36 -0
- package/dist/react/index.js.map +1 -0
- package/dist/types.d.ts +89 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/package.json +101 -0
- package/src/convex/agents/bugReportAgent.ts +277 -0
- package/src/convex/agents/feedbackAgent.ts +264 -0
- package/src/convex/bugReports.ts +350 -0
- package/src/convex/convex.config.ts +7 -0
- package/src/convex/emails/bugReportEmails.ts +479 -0
- package/src/convex/emails/feedbackEmails.ts +465 -0
- package/src/convex/feedback.ts +356 -0
- package/src/convex/index.ts +28 -0
- package/src/convex/schema.ts +207 -0
- package/src/convex/supportTeams.ts +179 -0
- package/src/index.ts +77 -0
- package/src/react/BugReportButton.tsx +755 -0
- package/src/react/BugReportContext.tsx +146 -0
- package/src/react/index.ts +46 -0
- package/src/types.ts +93 -0
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useCallback } from 'react';
|
|
3
|
+
import { ActionIcon, Modal, TextInput, Textarea, Select, Button, Group, Stack, Text, Image, Tooltip, Affix, Transition, Paper, Badge, LoadingOverlay, SegmentedControl, FileButton, } from '@mantine/core';
|
|
4
|
+
import { useForm } from '@mantine/form';
|
|
5
|
+
import { useDisclosure } from '@mantine/hooks';
|
|
6
|
+
import { notifications } from '@mantine/notifications';
|
|
7
|
+
import * as TablerIcons from '@tabler/icons-react';
|
|
8
|
+
const IconBug = TablerIcons.IconBug;
|
|
9
|
+
const IconCamera = TablerIcons.IconCamera;
|
|
10
|
+
const IconX = TablerIcons.IconX;
|
|
11
|
+
const IconCheck = TablerIcons.IconCheck;
|
|
12
|
+
const IconMessagePlus = TablerIcons.IconMessagePlus;
|
|
13
|
+
const IconUpload = TablerIcons.IconUpload;
|
|
14
|
+
import { useMutation } from 'convex/react';
|
|
15
|
+
import html2canvas from 'html2canvas';
|
|
16
|
+
import { useBugReportContext } from './BugReportContext';
|
|
17
|
+
/**
|
|
18
|
+
* Floating action button for submitting bug reports and feedback.
|
|
19
|
+
* Captures browser diagnostics, console errors, and optional screenshots.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```tsx
|
|
23
|
+
* import { BugReportButton } from '@convex-dev/feedback/react';
|
|
24
|
+
* import { api } from './convex/_generated/api';
|
|
25
|
+
*
|
|
26
|
+
* function App() {
|
|
27
|
+
* return (
|
|
28
|
+
* <BugReportButton
|
|
29
|
+
* reporterType="staff"
|
|
30
|
+
* reporterId={user.id}
|
|
31
|
+
* reporterEmail={user.email}
|
|
32
|
+
* reporterName={user.name}
|
|
33
|
+
* bugReportApi={{
|
|
34
|
+
* create: api.feedback.bugReports.create,
|
|
35
|
+
* generateUploadUrl: api.feedback.bugReports.generateUploadUrl,
|
|
36
|
+
* }}
|
|
37
|
+
* feedbackApi={{
|
|
38
|
+
* create: api.feedback.feedback.create,
|
|
39
|
+
* generateUploadUrl: api.feedback.feedback.generateUploadUrl,
|
|
40
|
+
* }}
|
|
41
|
+
* />
|
|
42
|
+
* );
|
|
43
|
+
* }
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export function BugReportButton({ reporterType, reporterId, reporterEmail, reporterName, bugReportApi, feedbackApi, position = { bottom: 20, right: 20 }, buttonColor = 'red', showFeedback = true, onSuccess, onError, }) {
|
|
47
|
+
const [opened, { open, close }] = useDisclosure(false);
|
|
48
|
+
const [formMode, setFormMode] = useState('bug');
|
|
49
|
+
const [screenshot, setScreenshot] = useState(null);
|
|
50
|
+
const [screenshotBlob, setScreenshotBlob] = useState(null);
|
|
51
|
+
const [isCapturing, setIsCapturing] = useState(false);
|
|
52
|
+
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
53
|
+
const { getConsoleErrors, clearConsoleErrors } = useBugReportContext();
|
|
54
|
+
const createBugReport = useMutation(bugReportApi.create);
|
|
55
|
+
const createFeedback = useMutation(feedbackApi.create);
|
|
56
|
+
const generateBugUploadUrl = useMutation(bugReportApi.generateUploadUrl);
|
|
57
|
+
const generateFeedbackUploadUrl = useMutation(feedbackApi.generateUploadUrl);
|
|
58
|
+
// Bug report form
|
|
59
|
+
const bugForm = useForm({
|
|
60
|
+
initialValues: {
|
|
61
|
+
title: '',
|
|
62
|
+
description: '',
|
|
63
|
+
severity: 'medium',
|
|
64
|
+
},
|
|
65
|
+
validate: {
|
|
66
|
+
title: (value) => value.trim().length < 5 ? 'Title must be at least 5 characters' : null,
|
|
67
|
+
description: (value) => value.trim().length < 10
|
|
68
|
+
? 'Please provide more details (at least 10 characters)'
|
|
69
|
+
: null,
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
// Feedback form
|
|
73
|
+
const feedbackForm = useForm({
|
|
74
|
+
initialValues: {
|
|
75
|
+
title: '',
|
|
76
|
+
description: '',
|
|
77
|
+
type: 'feature_request',
|
|
78
|
+
priority: 'important',
|
|
79
|
+
},
|
|
80
|
+
validate: {
|
|
81
|
+
title: (value) => value.trim().length < 5 ? 'Title must be at least 5 characters' : null,
|
|
82
|
+
description: (value) => value.trim().length < 10
|
|
83
|
+
? 'Please provide more details (at least 10 characters)'
|
|
84
|
+
: null,
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
const getBrowserInfo = useCallback(() => {
|
|
88
|
+
return {
|
|
89
|
+
userAgent: navigator.userAgent,
|
|
90
|
+
platform: navigator.platform,
|
|
91
|
+
language: navigator.language,
|
|
92
|
+
cookiesEnabled: navigator.cookieEnabled,
|
|
93
|
+
onLine: navigator.onLine,
|
|
94
|
+
screenWidth: window.screen.width,
|
|
95
|
+
screenHeight: window.screen.height,
|
|
96
|
+
colorDepth: window.screen.colorDepth,
|
|
97
|
+
pixelRatio: window.devicePixelRatio,
|
|
98
|
+
};
|
|
99
|
+
}, []);
|
|
100
|
+
const captureScreenshot = useCallback(async () => {
|
|
101
|
+
setIsCapturing(true);
|
|
102
|
+
try {
|
|
103
|
+
// Hide the modal temporarily for screenshot
|
|
104
|
+
const modalElement = document.querySelector('[data-bug-report-modal]');
|
|
105
|
+
if (modalElement) {
|
|
106
|
+
modalElement.style.visibility = 'hidden';
|
|
107
|
+
}
|
|
108
|
+
// Small delay to ensure modal is hidden
|
|
109
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
110
|
+
const canvas = await html2canvas(document.body, {
|
|
111
|
+
logging: false,
|
|
112
|
+
useCORS: true,
|
|
113
|
+
allowTaint: true,
|
|
114
|
+
scale: 1,
|
|
115
|
+
});
|
|
116
|
+
// Show modal again
|
|
117
|
+
if (modalElement) {
|
|
118
|
+
modalElement.style.visibility = 'visible';
|
|
119
|
+
}
|
|
120
|
+
const dataUrl = canvas.toDataURL('image/png');
|
|
121
|
+
setScreenshot(dataUrl);
|
|
122
|
+
// Convert to blob for upload
|
|
123
|
+
canvas.toBlob((blob) => {
|
|
124
|
+
if (blob) {
|
|
125
|
+
setScreenshotBlob(blob);
|
|
126
|
+
}
|
|
127
|
+
}, 'image/png');
|
|
128
|
+
notifications.show({
|
|
129
|
+
title: 'Screenshot captured',
|
|
130
|
+
message: 'Screenshot has been attached to your report',
|
|
131
|
+
color: 'green',
|
|
132
|
+
icon: _jsx(IconCheck, { size: 16 }),
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
console.error('Failed to capture screenshot:', error);
|
|
137
|
+
notifications.show({
|
|
138
|
+
title: 'Screenshot failed',
|
|
139
|
+
message: 'Could not capture screenshot. You can still submit the report.',
|
|
140
|
+
color: 'yellow',
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
finally {
|
|
144
|
+
setIsCapturing(false);
|
|
145
|
+
}
|
|
146
|
+
}, []);
|
|
147
|
+
const removeScreenshot = useCallback(() => {
|
|
148
|
+
setScreenshot(null);
|
|
149
|
+
setScreenshotBlob(null);
|
|
150
|
+
}, []);
|
|
151
|
+
const handleFileUpload = useCallback((file) => {
|
|
152
|
+
if (!file)
|
|
153
|
+
return;
|
|
154
|
+
// Validate file type
|
|
155
|
+
if (!file.type.startsWith('image/')) {
|
|
156
|
+
notifications.show({
|
|
157
|
+
title: 'Invalid file type',
|
|
158
|
+
message: 'Please upload an image file (PNG, JPG, GIF, etc.)',
|
|
159
|
+
color: 'red',
|
|
160
|
+
});
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
// Validate file size (max 10MB)
|
|
164
|
+
const maxSize = 10 * 1024 * 1024;
|
|
165
|
+
if (file.size > maxSize) {
|
|
166
|
+
notifications.show({
|
|
167
|
+
title: 'File too large',
|
|
168
|
+
message: 'Please upload an image smaller than 10MB',
|
|
169
|
+
color: 'red',
|
|
170
|
+
});
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
// Read the file and set as screenshot
|
|
174
|
+
const reader = new FileReader();
|
|
175
|
+
reader.onload = (e) => {
|
|
176
|
+
const dataUrl = e.target?.result;
|
|
177
|
+
setScreenshot(dataUrl);
|
|
178
|
+
setScreenshotBlob(file);
|
|
179
|
+
notifications.show({
|
|
180
|
+
title: 'Screenshot uploaded',
|
|
181
|
+
message: 'Screenshot has been attached to your report',
|
|
182
|
+
color: 'green',
|
|
183
|
+
icon: _jsx(IconCheck, { size: 16 }),
|
|
184
|
+
});
|
|
185
|
+
};
|
|
186
|
+
reader.onerror = () => {
|
|
187
|
+
notifications.show({
|
|
188
|
+
title: 'Upload failed',
|
|
189
|
+
message: 'Could not read the image file. Please try again.',
|
|
190
|
+
color: 'red',
|
|
191
|
+
});
|
|
192
|
+
};
|
|
193
|
+
reader.readAsDataURL(file);
|
|
194
|
+
}, []);
|
|
195
|
+
const handleBugSubmit = async (values) => {
|
|
196
|
+
setIsSubmitting(true);
|
|
197
|
+
try {
|
|
198
|
+
// Upload screenshot if exists
|
|
199
|
+
let screenshotStorageId;
|
|
200
|
+
if (screenshotBlob) {
|
|
201
|
+
const uploadUrl = await generateBugUploadUrl({});
|
|
202
|
+
const response = await fetch(uploadUrl, {
|
|
203
|
+
method: 'POST',
|
|
204
|
+
headers: { 'Content-Type': screenshotBlob.type || 'image/png' },
|
|
205
|
+
body: screenshotBlob,
|
|
206
|
+
});
|
|
207
|
+
const { storageId } = await response.json();
|
|
208
|
+
screenshotStorageId = storageId;
|
|
209
|
+
}
|
|
210
|
+
// Get console errors
|
|
211
|
+
const consoleErrors = getConsoleErrors();
|
|
212
|
+
// Create the report
|
|
213
|
+
await createBugReport({
|
|
214
|
+
title: values.title,
|
|
215
|
+
description: values.description,
|
|
216
|
+
severity: values.severity,
|
|
217
|
+
reporterType,
|
|
218
|
+
reporterId,
|
|
219
|
+
reporterEmail,
|
|
220
|
+
reporterName,
|
|
221
|
+
url: window.location.href,
|
|
222
|
+
route: window.location.pathname,
|
|
223
|
+
browserInfo: JSON.stringify(getBrowserInfo()),
|
|
224
|
+
consoleErrors: consoleErrors.length > 0 ? JSON.stringify(consoleErrors) : undefined,
|
|
225
|
+
screenshotStorageId,
|
|
226
|
+
viewportWidth: window.innerWidth,
|
|
227
|
+
viewportHeight: window.innerHeight,
|
|
228
|
+
networkState: navigator.onLine ? 'online' : 'offline',
|
|
229
|
+
});
|
|
230
|
+
// Clear console errors after successful submission
|
|
231
|
+
clearConsoleErrors();
|
|
232
|
+
notifications.show({
|
|
233
|
+
title: 'Bug report submitted',
|
|
234
|
+
message: 'Thank you for your feedback! We will look into this issue.',
|
|
235
|
+
color: 'green',
|
|
236
|
+
icon: _jsx(IconCheck, { size: 16 }),
|
|
237
|
+
});
|
|
238
|
+
onSuccess?.('bug');
|
|
239
|
+
// Reset form and close modal
|
|
240
|
+
bugForm.reset();
|
|
241
|
+
setScreenshot(null);
|
|
242
|
+
setScreenshotBlob(null);
|
|
243
|
+
close();
|
|
244
|
+
}
|
|
245
|
+
catch (error) {
|
|
246
|
+
console.error('Failed to submit bug report:', error);
|
|
247
|
+
notifications.show({
|
|
248
|
+
title: 'Submission failed',
|
|
249
|
+
message: 'Could not submit bug report. Please try again.',
|
|
250
|
+
color: 'red',
|
|
251
|
+
});
|
|
252
|
+
onError?.(error instanceof Error ? error : new Error(String(error)), 'bug');
|
|
253
|
+
}
|
|
254
|
+
finally {
|
|
255
|
+
setIsSubmitting(false);
|
|
256
|
+
}
|
|
257
|
+
};
|
|
258
|
+
const handleFeedbackSubmit = async (values) => {
|
|
259
|
+
setIsSubmitting(true);
|
|
260
|
+
try {
|
|
261
|
+
// Upload screenshot if exists
|
|
262
|
+
let screenshotStorageId;
|
|
263
|
+
if (screenshotBlob) {
|
|
264
|
+
const uploadUrl = await generateFeedbackUploadUrl({});
|
|
265
|
+
const response = await fetch(uploadUrl, {
|
|
266
|
+
method: 'POST',
|
|
267
|
+
headers: { 'Content-Type': screenshotBlob.type || 'image/png' },
|
|
268
|
+
body: screenshotBlob,
|
|
269
|
+
});
|
|
270
|
+
const { storageId } = await response.json();
|
|
271
|
+
screenshotStorageId = storageId;
|
|
272
|
+
}
|
|
273
|
+
// Get console errors
|
|
274
|
+
const consoleErrors = getConsoleErrors();
|
|
275
|
+
// Create the feedback
|
|
276
|
+
await createFeedback({
|
|
277
|
+
type: values.type,
|
|
278
|
+
title: values.title,
|
|
279
|
+
description: values.description,
|
|
280
|
+
priority: values.priority,
|
|
281
|
+
reporterType,
|
|
282
|
+
reporterId,
|
|
283
|
+
reporterEmail,
|
|
284
|
+
reporterName,
|
|
285
|
+
url: window.location.href,
|
|
286
|
+
route: window.location.pathname,
|
|
287
|
+
browserInfo: JSON.stringify(getBrowserInfo()),
|
|
288
|
+
consoleErrors: consoleErrors.length > 0 ? JSON.stringify(consoleErrors) : undefined,
|
|
289
|
+
screenshotStorageId,
|
|
290
|
+
viewportWidth: window.innerWidth,
|
|
291
|
+
viewportHeight: window.innerHeight,
|
|
292
|
+
networkState: navigator.onLine ? 'online' : 'offline',
|
|
293
|
+
});
|
|
294
|
+
// Clear console errors after successful submission
|
|
295
|
+
clearConsoleErrors();
|
|
296
|
+
notifications.show({
|
|
297
|
+
title: 'Feedback submitted',
|
|
298
|
+
message: 'Thank you for your feedback! We appreciate your input.',
|
|
299
|
+
color: 'green',
|
|
300
|
+
icon: _jsx(IconCheck, { size: 16 }),
|
|
301
|
+
});
|
|
302
|
+
onSuccess?.('feedback');
|
|
303
|
+
// Reset form and close modal
|
|
304
|
+
feedbackForm.reset();
|
|
305
|
+
setScreenshot(null);
|
|
306
|
+
setScreenshotBlob(null);
|
|
307
|
+
close();
|
|
308
|
+
}
|
|
309
|
+
catch (error) {
|
|
310
|
+
console.error('Failed to submit feedback:', error);
|
|
311
|
+
notifications.show({
|
|
312
|
+
title: 'Submission failed',
|
|
313
|
+
message: 'Could not submit feedback. Please try again.',
|
|
314
|
+
color: 'red',
|
|
315
|
+
});
|
|
316
|
+
onError?.(error instanceof Error ? error : new Error(String(error)), 'feedback');
|
|
317
|
+
}
|
|
318
|
+
finally {
|
|
319
|
+
setIsSubmitting(false);
|
|
320
|
+
}
|
|
321
|
+
};
|
|
322
|
+
const handleOpen = () => {
|
|
323
|
+
bugForm.reset();
|
|
324
|
+
feedbackForm.reset();
|
|
325
|
+
setScreenshot(null);
|
|
326
|
+
setScreenshotBlob(null);
|
|
327
|
+
setFormMode('bug');
|
|
328
|
+
open();
|
|
329
|
+
};
|
|
330
|
+
const handleModeChange = (mode) => {
|
|
331
|
+
setFormMode(mode);
|
|
332
|
+
setScreenshot(null);
|
|
333
|
+
setScreenshotBlob(null);
|
|
334
|
+
};
|
|
335
|
+
return (_jsxs(_Fragment, { children: [_jsx(Affix, { position: position, children: _jsx(Transition, { transition: "slide-up", mounted: true, children: (transitionStyles) => (_jsx(Tooltip, { label: "Report a bug", position: "left", withArrow: true, children: _jsx(ActionIcon, { style: transitionStyles, variant: "filled", color: buttonColor, size: "xl", radius: "xl", onClick: handleOpen, "aria-label": "Report a bug", children: _jsx(IconBug, { size: 24 }) }) })) }) }), _jsxs(Modal, { opened: opened, onClose: close, title: _jsxs(Group, { gap: "xs", children: [formMode === 'bug' ? (_jsx(IconBug, { size: 20 })) : (_jsx(IconMessagePlus, { size: 20 })), _jsx(Text, { fw: 600, children: formMode === 'bug' ? 'Report a Bug' : 'Submit Feedback' })] }), size: "md", "data-bug-report-modal": true, children: [_jsx(LoadingOverlay, { visible: isSubmitting }), _jsxs(Stack, { gap: "md", children: [showFeedback && (_jsx(SegmentedControl, { value: formMode, onChange: handleModeChange, data: [
|
|
336
|
+
{ value: 'bug', label: 'Bug Report' },
|
|
337
|
+
{ value: 'feedback', label: 'Feedback' },
|
|
338
|
+
], fullWidth: true })), formMode === 'bug' ? (_jsx("form", { onSubmit: bugForm.onSubmit(handleBugSubmit), children: _jsxs(Stack, { gap: "md", children: [_jsx(TextInput, { label: "Title", placeholder: "Brief summary of the issue", required: true, ...bugForm.getInputProps('title') }), _jsx(Textarea, { label: "Description", placeholder: "What happened? What were you trying to do? What did you expect to happen?", required: true, minRows: 4, ...bugForm.getInputProps('description') }), _jsx(Select, { label: "Severity", placeholder: "How severe is this issue?", data: [
|
|
339
|
+
{ value: 'low', label: 'Low - Minor inconvenience' },
|
|
340
|
+
{ value: 'medium', label: 'Medium - Affects workflow' },
|
|
341
|
+
{ value: 'high', label: 'High - Major functionality broken' },
|
|
342
|
+
{ value: 'critical', label: 'Critical - System unusable' },
|
|
343
|
+
], ...bugForm.getInputProps('severity') }), _jsxs(Stack, { gap: "xs", children: [_jsxs(Group, { justify: "space-between", children: [_jsx(Text, { size: "sm", fw: 500, children: "Screenshot" }), screenshot ? (_jsx(Button, { variant: "subtle", color: "red", size: "xs", leftSection: _jsx(IconX, { size: 14 }), onClick: removeScreenshot, children: "Remove" })) : (_jsxs(Group, { gap: "xs", children: [_jsx(Button, { variant: "light", size: "xs", leftSection: _jsx(IconCamera, { size: 14 }), onClick: captureScreenshot, loading: isCapturing, children: "Capture" }), _jsx(FileButton, { onChange: handleFileUpload, accept: "image/*", children: (props) => (_jsx(Button, { ...props, variant: "light", size: "xs", leftSection: _jsx(IconUpload, { size: 14 }), children: "Upload" })) })] }))] }), screenshot && (_jsx(Paper, { withBorder: true, p: "xs", radius: "md", children: _jsx(Image, { src: screenshot, alt: "Bug screenshot", radius: "md", fit: "contain", h: 150 }) }))] }), _jsx(Paper, { withBorder: true, p: "xs", radius: "md", children: _jsxs(Group, { gap: "xs", children: [_jsx(Badge, { size: "xs", variant: "outline", color: "gray", children: "Auto-captured" }), _jsx(Text, { size: "xs", c: "dimmed", children: "Browser info, URL, viewport size, and console errors will be included automatically." })] }) }), _jsxs(Group, { justify: "flex-end", mt: "md", children: [_jsx(Button, { variant: "subtle", onClick: close, disabled: isSubmitting, children: "Cancel" }), _jsx(Button, { type: "submit", loading: isSubmitting, children: "Submit Report" })] })] }) })) : (_jsx("form", { onSubmit: feedbackForm.onSubmit(handleFeedbackSubmit), children: _jsxs(Stack, { gap: "md", children: [_jsx(Select, { label: "Feedback Type", placeholder: "What kind of feedback is this?", data: [
|
|
344
|
+
{
|
|
345
|
+
value: 'feature_request',
|
|
346
|
+
label: 'Feature Request - Idea for new functionality',
|
|
347
|
+
},
|
|
348
|
+
{
|
|
349
|
+
value: 'change_request',
|
|
350
|
+
label: 'Change Request - Modify existing feature',
|
|
351
|
+
},
|
|
352
|
+
{
|
|
353
|
+
value: 'general',
|
|
354
|
+
label: 'General Feedback - Comments or suggestions',
|
|
355
|
+
},
|
|
356
|
+
], ...feedbackForm.getInputProps('type') }), _jsx(TextInput, { label: "Title", placeholder: "Brief summary of your feedback", required: true, ...feedbackForm.getInputProps('title') }), _jsx(Textarea, { label: "Description", placeholder: "Describe your idea or suggestion in detail. What problem does it solve? How would it improve your workflow?", required: true, minRows: 4, ...feedbackForm.getInputProps('description') }), _jsx(Select, { label: "Priority", placeholder: "How important is this to you?", data: [
|
|
357
|
+
{
|
|
358
|
+
value: 'nice_to_have',
|
|
359
|
+
label: 'Nice to Have - Would be a welcome addition',
|
|
360
|
+
},
|
|
361
|
+
{
|
|
362
|
+
value: 'important',
|
|
363
|
+
label: 'Important - Would significantly improve my work',
|
|
364
|
+
},
|
|
365
|
+
{
|
|
366
|
+
value: 'critical',
|
|
367
|
+
label: 'Critical - Blocking my workflow',
|
|
368
|
+
},
|
|
369
|
+
], ...feedbackForm.getInputProps('priority') }), _jsxs(Stack, { gap: "xs", children: [_jsxs(Group, { justify: "space-between", children: [_jsx(Text, { size: "sm", fw: 500, children: "Screenshot (optional)" }), screenshot ? (_jsx(Button, { variant: "subtle", color: "red", size: "xs", leftSection: _jsx(IconX, { size: 14 }), onClick: removeScreenshot, children: "Remove" })) : (_jsxs(Group, { gap: "xs", children: [_jsx(Button, { variant: "light", size: "xs", leftSection: _jsx(IconCamera, { size: 14 }), onClick: captureScreenshot, loading: isCapturing, children: "Capture" }), _jsx(FileButton, { onChange: handleFileUpload, accept: "image/*", children: (props) => (_jsx(Button, { ...props, variant: "light", size: "xs", leftSection: _jsx(IconUpload, { size: 14 }), children: "Upload" })) })] }))] }), screenshot && (_jsx(Paper, { withBorder: true, p: "xs", radius: "md", children: _jsx(Image, { src: screenshot, alt: "Feedback screenshot", radius: "md", fit: "contain", h: 150 }) }))] }), _jsx(Paper, { withBorder: true, p: "xs", radius: "md", children: _jsxs(Group, { gap: "xs", children: [_jsx(Badge, { size: "xs", variant: "outline", color: "gray", children: "Auto-captured" }), _jsx(Text, { size: "xs", c: "dimmed", children: "Browser info and page context will be included automatically." })] }) }), _jsxs(Group, { justify: "flex-end", mt: "md", children: [_jsx(Button, { variant: "subtle", onClick: close, disabled: isSubmitting, children: "Cancel" }), _jsx(Button, { type: "submit", loading: isSubmitting, color: "teal", children: "Submit Feedback" })] })] }) }))] })] })] }));
|
|
370
|
+
}
|
|
371
|
+
//# sourceMappingURL=BugReportButton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BugReportButton.js","sourceRoot":"","sources":["../../src/react/BugReportButton.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAC9C,OAAO,EACL,UAAU,EACV,KAAK,EACL,SAAS,EACT,QAAQ,EACR,MAAM,EACN,MAAM,EACN,KAAK,EACL,KAAK,EACL,IAAI,EACJ,KAAK,EACL,OAAO,EACP,KAAK,EACL,UAAU,EACV,KAAK,EACL,KAAK,EACL,cAAc,EACd,gBAAgB,EAChB,UAAU,GACX,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,KAAK,WAAW,MAAM,qBAAqB,CAAC;AAEnD,MAAM,OAAO,GAAG,WAAW,CAAC,OAAsC,CAAC;AACnE,MAAM,UAAU,GAAG,WAAW,CAAC,UAAyC,CAAC;AACzE,MAAM,KAAK,GAAG,WAAW,CAAC,KAAoC,CAAC;AAC/D,MAAM,SAAS,GAAG,WAAW,CAAC,SAAwC,CAAC;AACvE,MAAM,eAAe,GAAG,WAAW,CAAC,eAA8C,CAAC;AACnF,MAAM,UAAU,GAAG,WAAW,CAAC,UAAyC,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,WAAW,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAmDzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,UAAU,eAAe,CAAC,EAC9B,YAAY,EACZ,UAAU,EACV,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,QAAQ,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EACpC,WAAW,GAAG,KAAK,EACnB,YAAY,GAAG,IAAI,EACnB,SAAS,EACT,OAAO,GACc;IACrB,MAAM,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IACvD,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAW,KAAK,CAAC,CAAC;IAC1D,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAClE,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,QAAQ,CAAc,IAAI,CAAC,CAAC;IACxE,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACtD,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAExD,MAAM,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,GAAG,mBAAmB,EAAE,CAAC;IACvE,MAAM,eAAe,GAAG,WAAW,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;IACzD,MAAM,cAAc,GAAG,WAAW,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IACvD,MAAM,oBAAoB,GAAG,WAAW,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAC;IACzE,MAAM,yBAAyB,GAAG,WAAW,CAAC,WAAW,CAAC,iBAAiB,CAAC,CAAC;IAE7E,kBAAkB;IAClB,MAAM,OAAO,GAAG,OAAO,CAAC;QACtB,aAAa,EAAE;YACb,KAAK,EAAE,EAAE;YACT,WAAW,EAAE,EAAE;YACf,QAAQ,EAAE,QAAkD;SAC7D;QACD,QAAQ,EAAE;YACR,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CACf,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,qCAAqC,CAAC,CAAC,CAAC,IAAI;YACxE,WAAW,EAAE,CAAC,KAAK,EAAE,EAAE,CACrB,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,EAAE;gBACtB,CAAC,CAAC,sDAAsD;gBACxD,CAAC,CAAC,IAAI;SACX;KACF,CAAC,CAAC;IAEH,gBAAgB;IAChB,MAAM,YAAY,GAAG,OAAO,CAAC;QAC3B,aAAa,EAAE;YACb,KAAK,EAAE,EAAE;YACT,WAAW,EAAE,EAAE;YACf,IAAI,EAAE,iBAAqE;YAC3E,QAAQ,EAAE,WAAwD;SACnE;QACD,QAAQ,EAAE;YACR,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CACf,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,qCAAqC,CAAC,CAAC,CAAC,IAAI;YACxE,WAAW,EAAE,CAAC,KAAK,EAAE,EAAE,CACrB,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,EAAE;gBACtB,CAAC,CAAC,sDAAsD;gBACxD,CAAC,CAAC,IAAI;SACX;KACF,CAAC,CAAC;IAEH,MAAM,cAAc,GAAG,WAAW,CAAC,GAAgB,EAAE;QACnD,OAAO;YACL,SAAS,EAAE,SAAS,CAAC,SAAS;YAC9B,QAAQ,EAAE,SAAS,CAAC,QAAQ;YAC5B,QAAQ,EAAE,SAAS,CAAC,QAAQ;YAC5B,cAAc,EAAE,SAAS,CAAC,aAAa;YACvC,MAAM,EAAE,SAAS,CAAC,MAAM;YACxB,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK;YAChC,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM;YAClC,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,UAAU;YACpC,UAAU,EAAE,MAAM,CAAC,gBAAgB;SACpC,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,iBAAiB,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QAC/C,cAAc,CAAC,IAAI,CAAC,CAAC;QACrB,IAAI,CAAC;YACH,4CAA4C;YAC5C,MAAM,YAAY,GAAG,QAAQ,CAAC,aAAa,CAAC,yBAAyB,CAAC,CAAC;YACvE,IAAI,YAAY,EAAE,CAAC;gBAChB,YAA4B,CAAC,KAAK,CAAC,UAAU,GAAG,QAAQ,CAAC;YAC5D,CAAC;YAED,wCAAwC;YACxC,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;YAEzD,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,QAAQ,CAAC,IAAI,EAAE;gBAC9C,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,IAAI;gBACb,UAAU,EAAE,IAAI;gBAChB,KAAK,EAAE,CAAC;aACT,CAAC,CAAC;YAEH,mBAAmB;YACnB,IAAI,YAAY,EAAE,CAAC;gBAChB,YAA4B,CAAC,KAAK,CAAC,UAAU,GAAG,SAAS,CAAC;YAC7D,CAAC;YAED,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;YAC9C,aAAa,CAAC,OAAO,CAAC,CAAC;YAEvB,6BAA6B;YAC7B,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;gBACrB,IAAI,IAAI,EAAE,CAAC;oBACT,iBAAiB,CAAC,IAAI,CAAC,CAAC;gBAC1B,CAAC;YACH,CAAC,EAAE,WAAW,CAAC,CAAC;YAEhB,aAAa,CAAC,IAAI,CAAC;gBACjB,KAAK,EAAE,qBAAqB;gBAC5B,OAAO,EAAE,6CAA6C;gBACtD,KAAK,EAAE,OAAO;gBACd,IAAI,EAAE,KAAC,SAAS,IAAC,IAAI,EAAE,EAAE,GAAI;aAC9B,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,+BAA+B,EAAE,KAAK,CAAC,CAAC;YACtD,aAAa,CAAC,IAAI,CAAC;gBACjB,KAAK,EAAE,mBAAmB;gBAC1B,OAAO,EAAE,gEAAgE;gBACzE,KAAK,EAAE,QAAQ;aAChB,CAAC,CAAC;QACL,CAAC;gBAAS,CAAC;YACT,cAAc,CAAC,KAAK,CAAC,CAAC;QACxB,CAAC;IACH,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,gBAAgB,GAAG,WAAW,CAAC,GAAG,EAAE;QACxC,aAAa,CAAC,IAAI,CAAC,CAAC;QACpB,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,gBAAgB,GAAG,WAAW,CAAC,CAAC,IAAiB,EAAE,EAAE;QACzD,IAAI,CAAC,IAAI;YAAE,OAAO;QAElB,qBAAqB;QACrB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YACpC,aAAa,CAAC,IAAI,CAAC;gBACjB,KAAK,EAAE,mBAAmB;gBAC1B,OAAO,EAAE,mDAAmD;gBAC5D,KAAK,EAAE,KAAK;aACb,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,gCAAgC;QAChC,MAAM,OAAO,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;QACjC,IAAI,IAAI,CAAC,IAAI,GAAG,OAAO,EAAE,CAAC;YACxB,aAAa,CAAC,IAAI,CAAC;gBACjB,KAAK,EAAE,gBAAgB;gBACvB,OAAO,EAAE,0CAA0C;gBACnD,KAAK,EAAE,KAAK;aACb,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,sCAAsC;QACtC,MAAM,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAChC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,EAAE;YACpB,MAAM,OAAO,GAAG,CAAC,CAAC,MAAM,EAAE,MAAgB,CAAC;YAC3C,aAAa,CAAC,OAAO,CAAC,CAAC;YACvB,iBAAiB,CAAC,IAAI,CAAC,CAAC;YACxB,aAAa,CAAC,IAAI,CAAC;gBACjB,KAAK,EAAE,qBAAqB;gBAC5B,OAAO,EAAE,6CAA6C;gBACtD,KAAK,EAAE,OAAO;gBACd,IAAI,EAAE,KAAC,SAAS,IAAC,IAAI,EAAE,EAAE,GAAI;aAC9B,CAAC,CAAC;QACL,CAAC,CAAC;QACF,MAAM,CAAC,OAAO,GAAG,GAAG,EAAE;YACpB,aAAa,CAAC,IAAI,CAAC;gBACjB,KAAK,EAAE,eAAe;gBACtB,OAAO,EAAE,kDAAkD;gBAC3D,KAAK,EAAE,KAAK;aACb,CAAC,CAAC;QACL,CAAC,CAAC;QACF,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,eAAe,GAAG,KAAK,EAAE,MAA6B,EAAE,EAAE;QAC9D,eAAe,CAAC,IAAI,CAAC,CAAC;QACtB,IAAI,CAAC;YACH,8BAA8B;YAC9B,IAAI,mBAAuC,CAAC;YAC5C,IAAI,cAAc,EAAE,CAAC;gBACnB,MAAM,SAAS,GAAG,MAAM,oBAAoB,CAAC,EAAE,CAAC,CAAC;gBACjD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,SAAS,EAAE;oBACtC,MAAM,EAAE,MAAM;oBACd,OAAO,EAAE,EAAE,cAAc,EAAE,cAAc,CAAC,IAAI,IAAI,WAAW,EAAE;oBAC/D,IAAI,EAAE,cAAc;iBACrB,CAAC,CAAC;gBACH,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;gBAC5C,mBAAmB,GAAG,SAAS,CAAC;YAClC,CAAC;YAED,qBAAqB;YACrB,MAAM,aAAa,GAAG,gBAAgB,EAAE,CAAC;YAEzC,oBAAoB;YACpB,MAAM,eAAe,CAAC;gBACpB,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,WAAW,EAAE,MAAM,CAAC,WAAW;gBAC/B,QAAQ,EAAE,MAAM,CAAC,QAAQ;gBACzB,YAAY;gBACZ,UAAU;gBACV,aAAa;gBACb,YAAY;gBACZ,GAAG,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI;gBACzB,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,QAAQ;gBAC/B,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE,CAAC;gBAC7C,aAAa,EACX,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,SAAS;gBACtE,mBAAmB;gBACnB,aAAa,EAAE,MAAM,CAAC,UAAU;gBAChC,cAAc,EAAE,MAAM,CAAC,WAAW;gBAClC,YAAY,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS;aACtD,CAAC,CAAC;YAEH,mDAAmD;YACnD,kBAAkB,EAAE,CAAC;YAErB,aAAa,CAAC,IAAI,CAAC;gBACjB,KAAK,EAAE,sBAAsB;gBAC7B,OAAO,EAAE,4DAA4D;gBACrE,KAAK,EAAE,OAAO;gBACd,IAAI,EAAE,KAAC,SAAS,IAAC,IAAI,EAAE,EAAE,GAAI;aAC9B,CAAC,CAAC;YAEH,SAAS,EAAE,CAAC,KAAK,CAAC,CAAC;YAEnB,6BAA6B;YAC7B,OAAO,CAAC,KAAK,EAAE,CAAC;YAChB,aAAa,CAAC,IAAI,CAAC,CAAC;YACpB,iBAAiB,CAAC,IAAI,CAAC,CAAC;YACxB,KAAK,EAAE,CAAC;QACV,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAC;YACrD,aAAa,CAAC,IAAI,CAAC;gBACjB,KAAK,EAAE,mBAAmB;gBAC1B,OAAO,EAAE,gDAAgD;gBACzD,KAAK,EAAE,KAAK;aACb,CAAC,CAAC;YACH,OAAO,EAAE,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;QAC9E,CAAC;gBAAS,CAAC;YACT,eAAe,CAAC,KAAK,CAAC,CAAC;QACzB,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,oBAAoB,GAAG,KAAK,EAAE,MAAkC,EAAE,EAAE;QACxE,eAAe,CAAC,IAAI,CAAC,CAAC;QACtB,IAAI,CAAC;YACH,8BAA8B;YAC9B,IAAI,mBAAuC,CAAC;YAC5C,IAAI,cAAc,EAAE,CAAC;gBACnB,MAAM,SAAS,GAAG,MAAM,yBAAyB,CAAC,EAAE,CAAC,CAAC;gBACtD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,SAAS,EAAE;oBACtC,MAAM,EAAE,MAAM;oBACd,OAAO,EAAE,EAAE,cAAc,EAAE,cAAc,CAAC,IAAI,IAAI,WAAW,EAAE;oBAC/D,IAAI,EAAE,cAAc;iBACrB,CAAC,CAAC;gBACH,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;gBAC5C,mBAAmB,GAAG,SAAS,CAAC;YAClC,CAAC;YAED,qBAAqB;YACrB,MAAM,aAAa,GAAG,gBAAgB,EAAE,CAAC;YAEzC,sBAAsB;YACtB,MAAM,cAAc,CAAC;gBACnB,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,WAAW,EAAE,MAAM,CAAC,WAAW;gBAC/B,QAAQ,EAAE,MAAM,CAAC,QAAQ;gBACzB,YAAY;gBACZ,UAAU;gBACV,aAAa;gBACb,YAAY;gBACZ,GAAG,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI;gBACzB,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,QAAQ;gBAC/B,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE,CAAC;gBAC7C,aAAa,EACX,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,SAAS;gBACtE,mBAAmB;gBACnB,aAAa,EAAE,MAAM,CAAC,UAAU;gBAChC,cAAc,EAAE,MAAM,CAAC,WAAW;gBAClC,YAAY,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS;aACtD,CAAC,CAAC;YAEH,mDAAmD;YACnD,kBAAkB,EAAE,CAAC;YAErB,aAAa,CAAC,IAAI,CAAC;gBACjB,KAAK,EAAE,oBAAoB;gBAC3B,OAAO,EAAE,wDAAwD;gBACjE,KAAK,EAAE,OAAO;gBACd,IAAI,EAAE,KAAC,SAAS,IAAC,IAAI,EAAE,EAAE,GAAI;aAC9B,CAAC,CAAC;YAEH,SAAS,EAAE,CAAC,UAAU,CAAC,CAAC;YAExB,6BAA6B;YAC7B,YAAY,CAAC,KAAK,EAAE,CAAC;YACrB,aAAa,CAAC,IAAI,CAAC,CAAC;YACpB,iBAAiB,CAAC,IAAI,CAAC,CAAC;YACxB,KAAK,EAAE,CAAC;QACV,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,4BAA4B,EAAE,KAAK,CAAC,CAAC;YACnD,aAAa,CAAC,IAAI,CAAC;gBACjB,KAAK,EAAE,mBAAmB;gBAC1B,OAAO,EAAE,8CAA8C;gBACvD,KAAK,EAAE,KAAK;aACb,CAAC,CAAC;YACH,OAAO,EAAE,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;QACnF,CAAC;gBAAS,CAAC;YACT,eAAe,CAAC,KAAK,CAAC,CAAC;QACzB,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,UAAU,GAAG,GAAG,EAAE;QACtB,OAAO,CAAC,KAAK,EAAE,CAAC;QAChB,YAAY,CAAC,KAAK,EAAE,CAAC;QACrB,aAAa,CAAC,IAAI,CAAC,CAAC;QACpB,iBAAiB,CAAC,IAAI,CAAC,CAAC;QACxB,WAAW,CAAC,KAAK,CAAC,CAAC;QACnB,IAAI,EAAE,CAAC;IACT,CAAC,CAAC;IAEF,MAAM,gBAAgB,GAAG,CAAC,IAAY,EAAE,EAAE;QACxC,WAAW,CAAC,IAAgB,CAAC,CAAC;QAC9B,aAAa,CAAC,IAAI,CAAC,CAAC;QACpB,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC,CAAC;IAEF,OAAO,CACL,8BAEE,KAAC,KAAK,IAAC,QAAQ,EAAE,QAAQ,YACvB,KAAC,UAAU,IAAC,UAAU,EAAC,UAAU,EAAC,OAAO,EAAE,IAAI,YAC5C,CAAC,gBAAgB,EAAE,EAAE,CAAC,CACrB,KAAC,OAAO,IAAC,KAAK,EAAC,cAAc,EAAC,QAAQ,EAAC,MAAM,EAAC,SAAS,kBACrD,KAAC,UAAU,IACT,KAAK,EAAE,gBAAgB,EACvB,OAAO,EAAC,QAAQ,EAChB,KAAK,EAAE,WAAW,EAClB,IAAI,EAAC,IAAI,EACT,MAAM,EAAC,IAAI,EACX,OAAO,EAAE,UAAU,gBACR,cAAc,YAEzB,KAAC,OAAO,IAAC,IAAI,EAAE,EAAE,GAAI,GACV,GACL,CACX,GACU,GACP,EAGR,MAAC,KAAK,IACJ,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,KAAK,EACd,KAAK,EACH,MAAC,KAAK,IAAC,GAAG,EAAC,IAAI,aACZ,QAAQ,KAAK,KAAK,CAAC,CAAC,CAAC,CACpB,KAAC,OAAO,IAAC,IAAI,EAAE,EAAE,GAAI,CACtB,CAAC,CAAC,CAAC,CACF,KAAC,eAAe,IAAC,IAAI,EAAE,EAAE,GAAI,CAC9B,EACD,KAAC,IAAI,IAAC,EAAE,EAAE,GAAG,YACV,QAAQ,KAAK,KAAK,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,iBAAiB,GACnD,IACD,EAEV,IAAI,EAAC,IAAI,4CAGT,KAAC,cAAc,IAAC,OAAO,EAAE,YAAY,GAAI,EACzC,MAAC,KAAK,IAAC,GAAG,EAAC,IAAI,aAEZ,YAAY,IAAI,CACf,KAAC,gBAAgB,IACf,KAAK,EAAE,QAAQ,EACf,QAAQ,EAAE,gBAAgB,EAC1B,IAAI,EAAE;oCACJ,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE;oCACrC,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE;iCACzC,EACD,SAAS,SACT,CACH,EAEA,QAAQ,KAAK,KAAK,CAAC,CAAC,CAAC,CACpB,eAAM,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,YAC/C,MAAC,KAAK,IAAC,GAAG,EAAC,IAAI,aACb,KAAC,SAAS,IACR,KAAK,EAAC,OAAO,EACb,WAAW,EAAC,4BAA4B,EACxC,QAAQ,WACJ,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,GAClC,EAEF,KAAC,QAAQ,IACP,KAAK,EAAC,aAAa,EACnB,WAAW,EAAC,2EAA2E,EACvF,QAAQ,QACR,OAAO,EAAE,CAAC,KACN,OAAO,CAAC,aAAa,CAAC,aAAa,CAAC,GACxC,EAEF,KAAC,MAAM,IACL,KAAK,EAAC,UAAU,EAChB,WAAW,EAAC,2BAA2B,EACvC,IAAI,EAAE;gDACJ,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,2BAA2B,EAAE;gDACpD,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,2BAA2B,EAAE;gDACvD,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,mCAAmC,EAAE;gDAC7D,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,4BAA4B,EAAE;6CAC3D,KACG,OAAO,CAAC,aAAa,CAAC,UAAU,CAAC,GACrC,EAGF,MAAC,KAAK,IAAC,GAAG,EAAC,IAAI,aACb,MAAC,KAAK,IAAC,OAAO,EAAC,eAAe,aAC5B,KAAC,IAAI,IAAC,IAAI,EAAC,IAAI,EAAC,EAAE,EAAE,GAAG,2BAEhB,EACN,UAAU,CAAC,CAAC,CAAC,CACZ,KAAC,MAAM,IACL,OAAO,EAAC,QAAQ,EAChB,KAAK,EAAC,KAAK,EACX,IAAI,EAAC,IAAI,EACT,WAAW,EAAE,KAAC,KAAK,IAAC,IAAI,EAAE,EAAE,GAAI,EAChC,OAAO,EAAE,gBAAgB,uBAGlB,CACV,CAAC,CAAC,CAAC,CACF,MAAC,KAAK,IAAC,GAAG,EAAC,IAAI,aACb,KAAC,MAAM,IACL,OAAO,EAAC,OAAO,EACf,IAAI,EAAC,IAAI,EACT,WAAW,EAAE,KAAC,UAAU,IAAC,IAAI,EAAE,EAAE,GAAI,EACrC,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,WAAW,wBAGb,EACT,KAAC,UAAU,IAAC,QAAQ,EAAE,gBAAgB,EAAE,MAAM,EAAC,SAAS,YACrD,CAAC,KAAK,EAAE,EAAE,CAAC,CACV,KAAC,MAAM,OACD,KAAK,EACT,OAAO,EAAC,OAAO,EACf,IAAI,EAAC,IAAI,EACT,WAAW,EAAE,KAAC,UAAU,IAAC,IAAI,EAAE,EAAE,GAAI,uBAG9B,CACV,GACU,IACP,CACT,IACK,EACP,UAAU,IAAI,CACb,KAAC,KAAK,IAAC,UAAU,QAAC,CAAC,EAAC,IAAI,EAAC,MAAM,EAAC,IAAI,YAClC,KAAC,KAAK,IACJ,GAAG,EAAE,UAAU,EACf,GAAG,EAAC,gBAAgB,EACpB,MAAM,EAAC,IAAI,EACX,GAAG,EAAC,SAAS,EACb,CAAC,EAAE,GAAG,GACN,GACI,CACT,IACK,EAGR,KAAC,KAAK,IAAC,UAAU,QAAC,CAAC,EAAC,IAAI,EAAC,MAAM,EAAC,IAAI,YAClC,MAAC,KAAK,IAAC,GAAG,EAAC,IAAI,aACb,KAAC,KAAK,IAAC,IAAI,EAAC,IAAI,EAAC,OAAO,EAAC,SAAS,EAAC,KAAK,EAAC,MAAM,8BAEvC,EACR,KAAC,IAAI,IAAC,IAAI,EAAC,IAAI,EAAC,CAAC,EAAC,QAAQ,qGAGnB,IACD,GACF,EAGR,MAAC,KAAK,IAAC,OAAO,EAAC,UAAU,EAAC,EAAE,EAAC,IAAI,aAC/B,KAAC,MAAM,IAAC,OAAO,EAAC,QAAQ,EAAC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,YAAY,uBAEtD,EACT,KAAC,MAAM,IAAC,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAE,YAAY,8BAElC,IACH,IACF,GACH,CACR,CAAC,CAAC,CAAC,CACF,eAAM,QAAQ,EAAE,YAAY,CAAC,QAAQ,CAAC,oBAAoB,CAAC,YACzD,MAAC,KAAK,IAAC,GAAG,EAAC,IAAI,aACb,KAAC,MAAM,IACL,KAAK,EAAC,eAAe,EACrB,WAAW,EAAC,gCAAgC,EAC5C,IAAI,EAAE;gDACJ;oDACE,KAAK,EAAE,iBAAiB;oDACxB,KAAK,EAAE,8CAA8C;iDACtD;gDACD;oDACE,KAAK,EAAE,gBAAgB;oDACvB,KAAK,EAAE,0CAA0C;iDAClD;gDACD;oDACE,KAAK,EAAE,SAAS;oDAChB,KAAK,EAAE,4CAA4C;iDACpD;6CACF,KACG,YAAY,CAAC,aAAa,CAAC,MAAM,CAAC,GACtC,EAEF,KAAC,SAAS,IACR,KAAK,EAAC,OAAO,EACb,WAAW,EAAC,gCAAgC,EAC5C,QAAQ,WACJ,YAAY,CAAC,aAAa,CAAC,OAAO,CAAC,GACvC,EAEF,KAAC,QAAQ,IACP,KAAK,EAAC,aAAa,EACnB,WAAW,EAAC,6GAA6G,EACzH,QAAQ,QACR,OAAO,EAAE,CAAC,KACN,YAAY,CAAC,aAAa,CAAC,aAAa,CAAC,GAC7C,EAEF,KAAC,MAAM,IACL,KAAK,EAAC,UAAU,EAChB,WAAW,EAAC,+BAA+B,EAC3C,IAAI,EAAE;gDACJ;oDACE,KAAK,EAAE,cAAc;oDACrB,KAAK,EAAE,4CAA4C;iDACpD;gDACD;oDACE,KAAK,EAAE,WAAW;oDAClB,KAAK,EAAE,iDAAiD;iDACzD;gDACD;oDACE,KAAK,EAAE,UAAU;oDACjB,KAAK,EAAE,iCAAiC;iDACzC;6CACF,KACG,YAAY,CAAC,aAAa,CAAC,UAAU,CAAC,GAC1C,EAGF,MAAC,KAAK,IAAC,GAAG,EAAC,IAAI,aACb,MAAC,KAAK,IAAC,OAAO,EAAC,eAAe,aAC5B,KAAC,IAAI,IAAC,IAAI,EAAC,IAAI,EAAC,EAAE,EAAE,GAAG,sCAEhB,EACN,UAAU,CAAC,CAAC,CAAC,CACZ,KAAC,MAAM,IACL,OAAO,EAAC,QAAQ,EAChB,KAAK,EAAC,KAAK,EACX,IAAI,EAAC,IAAI,EACT,WAAW,EAAE,KAAC,KAAK,IAAC,IAAI,EAAE,EAAE,GAAI,EAChC,OAAO,EAAE,gBAAgB,uBAGlB,CACV,CAAC,CAAC,CAAC,CACF,MAAC,KAAK,IAAC,GAAG,EAAC,IAAI,aACb,KAAC,MAAM,IACL,OAAO,EAAC,OAAO,EACf,IAAI,EAAC,IAAI,EACT,WAAW,EAAE,KAAC,UAAU,IAAC,IAAI,EAAE,EAAE,GAAI,EACrC,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,WAAW,wBAGb,EACT,KAAC,UAAU,IAAC,QAAQ,EAAE,gBAAgB,EAAE,MAAM,EAAC,SAAS,YACrD,CAAC,KAAK,EAAE,EAAE,CAAC,CACV,KAAC,MAAM,OACD,KAAK,EACT,OAAO,EAAC,OAAO,EACf,IAAI,EAAC,IAAI,EACT,WAAW,EAAE,KAAC,UAAU,IAAC,IAAI,EAAE,EAAE,GAAI,uBAG9B,CACV,GACU,IACP,CACT,IACK,EACP,UAAU,IAAI,CACb,KAAC,KAAK,IAAC,UAAU,QAAC,CAAC,EAAC,IAAI,EAAC,MAAM,EAAC,IAAI,YAClC,KAAC,KAAK,IACJ,GAAG,EAAE,UAAU,EACf,GAAG,EAAC,qBAAqB,EACzB,MAAM,EAAC,IAAI,EACX,GAAG,EAAC,SAAS,EACb,CAAC,EAAE,GAAG,GACN,GACI,CACT,IACK,EAGR,KAAC,KAAK,IAAC,UAAU,QAAC,CAAC,EAAC,IAAI,EAAC,MAAM,EAAC,IAAI,YAClC,MAAC,KAAK,IAAC,GAAG,EAAC,IAAI,aACb,KAAC,KAAK,IAAC,IAAI,EAAC,IAAI,EAAC,OAAO,EAAC,SAAS,EAAC,KAAK,EAAC,MAAM,8BAEvC,EACR,KAAC,IAAI,IAAC,IAAI,EAAC,IAAI,EAAC,CAAC,EAAC,QAAQ,8EAEnB,IACD,GACF,EAGR,MAAC,KAAK,IAAC,OAAO,EAAC,UAAU,EAAC,EAAE,EAAC,IAAI,aAC/B,KAAC,MAAM,IAAC,OAAO,EAAC,QAAQ,EAAC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,YAAY,uBAEtD,EACT,KAAC,MAAM,IAAC,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAE,YAAY,EAAE,KAAK,EAAC,MAAM,gCAEhD,IACH,IACF,GACH,CACR,IACK,IACF,IACP,CACJ,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Captured console error with metadata
|
|
4
|
+
*/
|
|
5
|
+
export interface ConsoleError {
|
|
6
|
+
message: string;
|
|
7
|
+
source?: string;
|
|
8
|
+
lineno?: number;
|
|
9
|
+
colno?: number;
|
|
10
|
+
timestamp: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Context value for bug report error capture
|
|
14
|
+
*/
|
|
15
|
+
export interface BugReportContextValue {
|
|
16
|
+
/** Get all captured console errors */
|
|
17
|
+
getConsoleErrors: () => ConsoleError[];
|
|
18
|
+
/** Clear all captured console errors */
|
|
19
|
+
clearConsoleErrors: () => void;
|
|
20
|
+
}
|
|
21
|
+
export interface BugReportProviderProps {
|
|
22
|
+
children: ReactNode;
|
|
23
|
+
/** Maximum number of errors to capture (default: 20) */
|
|
24
|
+
maxErrors?: number;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Provider component that captures console errors for bug reports.
|
|
28
|
+
* Wrap your app with this provider to enable error capture.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```tsx
|
|
32
|
+
* import { BugReportProvider } from '@convex-dev/feedback/react';
|
|
33
|
+
*
|
|
34
|
+
* function App() {
|
|
35
|
+
* return (
|
|
36
|
+
* <BugReportProvider>
|
|
37
|
+
* <YourApp />
|
|
38
|
+
* </BugReportProvider>
|
|
39
|
+
* );
|
|
40
|
+
* }
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export declare function BugReportProvider({ children, maxErrors }: BugReportProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
44
|
+
/**
|
|
45
|
+
* Hook to access bug report context for error capture.
|
|
46
|
+
* Must be used within a BugReportProvider.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```tsx
|
|
50
|
+
* import { useBugReportContext } from '@convex-dev/feedback/react';
|
|
51
|
+
*
|
|
52
|
+
* function MyComponent() {
|
|
53
|
+
* const { getConsoleErrors, clearConsoleErrors } = useBugReportContext();
|
|
54
|
+
* // ...
|
|
55
|
+
* }
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
export declare function useBugReportContext(): BugReportContextValue;
|
|
59
|
+
//# sourceMappingURL=BugReportContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BugReportContext.d.ts","sourceRoot":"","sources":["../../src/react/BugReportContext.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAgD,SAAS,EAAE,MAAM,OAAO,CAAC;AAEhF;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,sCAAsC;IACtC,gBAAgB,EAAE,MAAM,YAAY,EAAE,CAAC;IACvC,wCAAwC;IACxC,kBAAkB,EAAE,MAAM,IAAI,CAAC;CAChC;AAOD,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,SAAS,CAAC;IACpB,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,QAAQ,EAAE,SAAsB,EAAE,EAAE,sBAAsB,2CAwE7F;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,IAAI,qBAAqB,CAM3D"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, useContext, useEffect, useRef } from 'react';
|
|
3
|
+
const BugReportContext = createContext(null);
|
|
4
|
+
/** Maximum number of errors to retain */
|
|
5
|
+
const MAX_ERRORS = 20;
|
|
6
|
+
/**
|
|
7
|
+
* Provider component that captures console errors for bug reports.
|
|
8
|
+
* Wrap your app with this provider to enable error capture.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```tsx
|
|
12
|
+
* import { BugReportProvider } from '@convex-dev/feedback/react';
|
|
13
|
+
*
|
|
14
|
+
* function App() {
|
|
15
|
+
* return (
|
|
16
|
+
* <BugReportProvider>
|
|
17
|
+
* <YourApp />
|
|
18
|
+
* </BugReportProvider>
|
|
19
|
+
* );
|
|
20
|
+
* }
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export function BugReportProvider({ children, maxErrors = MAX_ERRORS }) {
|
|
24
|
+
const errorsRef = useRef([]);
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
// Capture window.onerror
|
|
27
|
+
const originalOnError = window.onerror;
|
|
28
|
+
window.onerror = (message, source, lineno, colno, error) => {
|
|
29
|
+
errorsRef.current.push({
|
|
30
|
+
message: String(message),
|
|
31
|
+
source,
|
|
32
|
+
lineno: lineno ?? undefined,
|
|
33
|
+
colno: colno ?? undefined,
|
|
34
|
+
timestamp: Date.now(),
|
|
35
|
+
});
|
|
36
|
+
// Keep only last N errors
|
|
37
|
+
if (errorsRef.current.length > maxErrors) {
|
|
38
|
+
errorsRef.current = errorsRef.current.slice(-maxErrors);
|
|
39
|
+
}
|
|
40
|
+
// Call original handler if exists
|
|
41
|
+
if (originalOnError) {
|
|
42
|
+
return originalOnError(message, source, lineno, colno, error);
|
|
43
|
+
}
|
|
44
|
+
return false;
|
|
45
|
+
};
|
|
46
|
+
// Capture unhandled promise rejections
|
|
47
|
+
const handleUnhandledRejection = (event) => {
|
|
48
|
+
errorsRef.current.push({
|
|
49
|
+
message: `Unhandled Promise Rejection: ${String(event.reason)}`,
|
|
50
|
+
timestamp: Date.now(),
|
|
51
|
+
});
|
|
52
|
+
if (errorsRef.current.length > maxErrors) {
|
|
53
|
+
errorsRef.current = errorsRef.current.slice(-maxErrors);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
window.addEventListener('unhandledrejection', handleUnhandledRejection);
|
|
57
|
+
// Override console.error
|
|
58
|
+
const originalConsoleError = console.error;
|
|
59
|
+
console.error = (...args) => {
|
|
60
|
+
errorsRef.current.push({
|
|
61
|
+
message: args.map((arg) => {
|
|
62
|
+
if (arg instanceof Error) {
|
|
63
|
+
return `${arg.name}: ${arg.message}`;
|
|
64
|
+
}
|
|
65
|
+
return String(arg);
|
|
66
|
+
}).join(' '),
|
|
67
|
+
timestamp: Date.now(),
|
|
68
|
+
});
|
|
69
|
+
if (errorsRef.current.length > maxErrors) {
|
|
70
|
+
errorsRef.current = errorsRef.current.slice(-maxErrors);
|
|
71
|
+
}
|
|
72
|
+
originalConsoleError.apply(console, args);
|
|
73
|
+
};
|
|
74
|
+
return () => {
|
|
75
|
+
window.onerror = originalOnError;
|
|
76
|
+
window.removeEventListener('unhandledrejection', handleUnhandledRejection);
|
|
77
|
+
console.error = originalConsoleError;
|
|
78
|
+
};
|
|
79
|
+
}, [maxErrors]);
|
|
80
|
+
const getConsoleErrors = () => [...errorsRef.current];
|
|
81
|
+
const clearConsoleErrors = () => {
|
|
82
|
+
errorsRef.current = [];
|
|
83
|
+
};
|
|
84
|
+
return (_jsx(BugReportContext.Provider, { value: { getConsoleErrors, clearConsoleErrors }, children: children }));
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Hook to access bug report context for error capture.
|
|
88
|
+
* Must be used within a BugReportProvider.
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```tsx
|
|
92
|
+
* import { useBugReportContext } from '@convex-dev/feedback/react';
|
|
93
|
+
*
|
|
94
|
+
* function MyComponent() {
|
|
95
|
+
* const { getConsoleErrors, clearConsoleErrors } = useBugReportContext();
|
|
96
|
+
* // ...
|
|
97
|
+
* }
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
export function useBugReportContext() {
|
|
101
|
+
const context = useContext(BugReportContext);
|
|
102
|
+
if (!context) {
|
|
103
|
+
throw new Error('useBugReportContext must be used within a BugReportProvider');
|
|
104
|
+
}
|
|
105
|
+
return context;
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=BugReportContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BugReportContext.js","sourceRoot":"","sources":["../../src/react/BugReportContext.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @convex-dev/feedback - React Components
|
|
3
|
+
*
|
|
4
|
+
* React components for bug reports and feedback collection.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```tsx
|
|
8
|
+
* import { BugReportProvider, BugReportButton } from '@convex-dev/feedback/react';
|
|
9
|
+
* import { api } from './convex/_generated/api';
|
|
10
|
+
*
|
|
11
|
+
* function App() {
|
|
12
|
+
* return (
|
|
13
|
+
* <BugReportProvider>
|
|
14
|
+
* <YourApp />
|
|
15
|
+
* <BugReportButton
|
|
16
|
+
* reporterType="staff"
|
|
17
|
+
* reporterId={user.id}
|
|
18
|
+
* reporterEmail={user.email}
|
|
19
|
+
* reporterName={user.name}
|
|
20
|
+
* bugReportApi={{
|
|
21
|
+
* create: api.feedback.bugReports.create,
|
|
22
|
+
* generateUploadUrl: api.feedback.bugReports.generateUploadUrl,
|
|
23
|
+
* }}
|
|
24
|
+
* feedbackApi={{
|
|
25
|
+
* create: api.feedback.feedback.create,
|
|
26
|
+
* generateUploadUrl: api.feedback.feedback.generateUploadUrl,
|
|
27
|
+
* }}
|
|
28
|
+
* />
|
|
29
|
+
* </BugReportProvider>
|
|
30
|
+
* );
|
|
31
|
+
* }
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export { BugReportProvider, useBugReportContext, type BugReportProviderProps, type BugReportContextValue, type ConsoleError, } from './BugReportContext';
|
|
35
|
+
export { BugReportButton, type BugReportButtonProps, } from './BugReportButton';
|
|
36
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,YAAY,GAClB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,eAAe,EACf,KAAK,oBAAoB,GAC1B,MAAM,mBAAmB,CAAC"}
|