@vinetechke/next-error-logger 0.1.0-beta.1

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.
Files changed (61) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +442 -0
  3. package/dist/adapters/drizzle.cjs +123 -0
  4. package/dist/adapters/drizzle.cjs.map +1 -0
  5. package/dist/adapters/drizzle.d.cts +76 -0
  6. package/dist/adapters/drizzle.d.ts +76 -0
  7. package/dist/adapters/drizzle.js +99 -0
  8. package/dist/adapters/drizzle.js.map +1 -0
  9. package/dist/adapters/prisma.cjs +120 -0
  10. package/dist/adapters/prisma.cjs.map +1 -0
  11. package/dist/adapters/prisma.d.cts +75 -0
  12. package/dist/adapters/prisma.d.ts +75 -0
  13. package/dist/adapters/prisma.js +96 -0
  14. package/dist/adapters/prisma.js.map +1 -0
  15. package/dist/adapters/sql.cjs +206 -0
  16. package/dist/adapters/sql.cjs.map +1 -0
  17. package/dist/adapters/sql.d.cts +111 -0
  18. package/dist/adapters/sql.d.ts +111 -0
  19. package/dist/adapters/sql.js +182 -0
  20. package/dist/adapters/sql.js.map +1 -0
  21. package/dist/api/index.cjs +257 -0
  22. package/dist/api/index.cjs.map +1 -0
  23. package/dist/api/index.d.cts +137 -0
  24. package/dist/api/index.d.ts +137 -0
  25. package/dist/api/index.js +231 -0
  26. package/dist/api/index.js.map +1 -0
  27. package/dist/auth/clerk.cjs +60 -0
  28. package/dist/auth/clerk.cjs.map +1 -0
  29. package/dist/auth/clerk.d.cts +83 -0
  30. package/dist/auth/clerk.d.ts +83 -0
  31. package/dist/auth/clerk.js +36 -0
  32. package/dist/auth/clerk.js.map +1 -0
  33. package/dist/auth/next-auth.cjs +50 -0
  34. package/dist/auth/next-auth.cjs.map +1 -0
  35. package/dist/auth/next-auth.d.cts +53 -0
  36. package/dist/auth/next-auth.d.ts +53 -0
  37. package/dist/auth/next-auth.js +26 -0
  38. package/dist/auth/next-auth.js.map +1 -0
  39. package/dist/components/index.cjs +1175 -0
  40. package/dist/components/index.cjs.map +1 -0
  41. package/dist/components/index.d.cts +141 -0
  42. package/dist/components/index.d.ts +141 -0
  43. package/dist/components/index.js +1147 -0
  44. package/dist/components/index.js.map +1 -0
  45. package/dist/index.cjs +241 -0
  46. package/dist/index.cjs.map +1 -0
  47. package/dist/index.d.cts +109 -0
  48. package/dist/index.d.ts +109 -0
  49. package/dist/index.js +212 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/schemas/drizzle.cjs +100 -0
  52. package/dist/schemas/drizzle.cjs.map +1 -0
  53. package/dist/schemas/drizzle.d.cts +32 -0
  54. package/dist/schemas/drizzle.d.ts +32 -0
  55. package/dist/schemas/drizzle.js +74 -0
  56. package/dist/schemas/drizzle.js.map +1 -0
  57. package/dist/types-C3x_Ry2e.d.cts +195 -0
  58. package/dist/types-C3x_Ry2e.d.ts +195 -0
  59. package/package.json +128 -0
  60. package/schemas/prisma.prisma +23 -0
  61. package/schemas/schema.sql +75 -0
@@ -0,0 +1,1147 @@
1
+ "use client";
2
+
3
+ // src/components/LogViewer.tsx
4
+ import { useState, useEffect, useCallback } from "react";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ var defaultTheme = {
7
+ errorBg: "rgb(254, 226, 226)",
8
+ errorText: "rgb(153, 27, 27)",
9
+ warnBg: "rgb(254, 249, 195)",
10
+ warnText: "rgb(133, 77, 14)",
11
+ infoBg: "rgb(219, 234, 254)",
12
+ infoText: "rgb(30, 64, 175)",
13
+ debugBg: "rgb(243, 244, 246)",
14
+ debugText: "rgb(55, 65, 81)"
15
+ };
16
+ function LogViewer({
17
+ apiBasePath = "/api/logs",
18
+ className = "",
19
+ pageSize = 50,
20
+ theme: customTheme,
21
+ onLogSelect,
22
+ showDelete = true,
23
+ autoRefresh = 0
24
+ }) {
25
+ const theme = { ...defaultTheme, ...customTheme };
26
+ const [logs, setLogs] = useState([]);
27
+ const [total, setTotal] = useState(0);
28
+ const [loading, setLoading] = useState(true);
29
+ const [page, setPage] = useState(1);
30
+ const [filters, setFilters] = useState({
31
+ level: "",
32
+ search: "",
33
+ userId: ""
34
+ });
35
+ const [selectedLog, setSelectedLog] = useState(null);
36
+ const [deleting, setDeleting] = useState(false);
37
+ const fetchLogs = useCallback(async () => {
38
+ setLoading(true);
39
+ try {
40
+ const params = new URLSearchParams({
41
+ page: page.toString(),
42
+ limit: pageSize.toString(),
43
+ ...filters.level && { level: filters.level },
44
+ ...filters.search && { search: filters.search },
45
+ ...filters.userId && { userId: filters.userId }
46
+ });
47
+ const res = await fetch(`${apiBasePath}?${params}`);
48
+ if (!res.ok) throw new Error("Failed to fetch logs");
49
+ const data = await res.json();
50
+ setLogs(data.logs);
51
+ setTotal(data.total);
52
+ } catch (error) {
53
+ console.error("Failed to fetch logs:", error);
54
+ } finally {
55
+ setLoading(false);
56
+ }
57
+ }, [apiBasePath, page, pageSize, filters]);
58
+ useEffect(() => {
59
+ fetchLogs();
60
+ }, [fetchLogs]);
61
+ useEffect(() => {
62
+ if (autoRefresh <= 0) return;
63
+ const interval = setInterval(fetchLogs, autoRefresh * 1e3);
64
+ return () => clearInterval(interval);
65
+ }, [autoRefresh, fetchLogs]);
66
+ const handleDelete = async (id) => {
67
+ if (!confirm("Are you sure you want to delete this log?")) return;
68
+ setDeleting(true);
69
+ try {
70
+ const res = await fetch(`${apiBasePath}/${id}`, {
71
+ method: "DELETE"
72
+ });
73
+ if (!res.ok) throw new Error("Failed to delete log");
74
+ setLogs((prev) => prev.filter((log) => log.id !== id));
75
+ setTotal((prev) => prev - 1);
76
+ if (selectedLog?.id === id) setSelectedLog(null);
77
+ } catch (error) {
78
+ console.error("Failed to delete log:", error);
79
+ alert("Failed to delete log");
80
+ } finally {
81
+ setDeleting(false);
82
+ }
83
+ };
84
+ const handleClearAll = async () => {
85
+ const confirmed = confirm(
86
+ "Are you sure you want to delete ALL logs? This cannot be undone."
87
+ );
88
+ if (!confirmed) return;
89
+ setDeleting(true);
90
+ try {
91
+ const res = await fetch(apiBasePath, {
92
+ method: "DELETE",
93
+ headers: { "Content-Type": "application/json" },
94
+ body: JSON.stringify({})
95
+ });
96
+ if (!res.ok) throw new Error("Failed to clear logs");
97
+ setLogs([]);
98
+ setTotal(0);
99
+ setSelectedLog(null);
100
+ } catch (error) {
101
+ console.error("Failed to clear logs:", error);
102
+ alert("Failed to clear logs");
103
+ } finally {
104
+ setDeleting(false);
105
+ }
106
+ };
107
+ const getLevelStyle = (level) => {
108
+ switch (level) {
109
+ case "error":
110
+ return {
111
+ backgroundColor: theme.errorBg,
112
+ color: theme.errorText
113
+ };
114
+ case "warn":
115
+ return { backgroundColor: theme.warnBg, color: theme.warnText };
116
+ case "info":
117
+ return { backgroundColor: theme.infoBg, color: theme.infoText };
118
+ case "debug":
119
+ return {
120
+ backgroundColor: theme.debugBg,
121
+ color: theme.debugText
122
+ };
123
+ }
124
+ };
125
+ const totalPages = Math.ceil(total / pageSize);
126
+ return /* @__PURE__ */ jsxs(
127
+ "div",
128
+ {
129
+ className,
130
+ style: { fontFamily: "system-ui, sans-serif" },
131
+ children: [
132
+ /* @__PURE__ */ jsxs(
133
+ "div",
134
+ {
135
+ style: {
136
+ display: "flex",
137
+ gap: "1rem",
138
+ marginBottom: "1rem",
139
+ flexWrap: "wrap",
140
+ alignItems: "center"
141
+ },
142
+ children: [
143
+ /* @__PURE__ */ jsxs(
144
+ "select",
145
+ {
146
+ value: filters.level,
147
+ onChange: (e) => {
148
+ setFilters({
149
+ ...filters,
150
+ level: e.target.value
151
+ });
152
+ setPage(1);
153
+ },
154
+ style: {
155
+ padding: "0.5rem 1rem",
156
+ borderRadius: "0.375rem",
157
+ border: "1px solid #d1d5db",
158
+ fontSize: "0.875rem"
159
+ },
160
+ children: [
161
+ /* @__PURE__ */ jsx("option", { value: "", children: "All Levels" }),
162
+ /* @__PURE__ */ jsx("option", { value: "error", children: "Error" }),
163
+ /* @__PURE__ */ jsx("option", { value: "warn", children: "Warning" }),
164
+ /* @__PURE__ */ jsx("option", { value: "info", children: "Info" }),
165
+ /* @__PURE__ */ jsx("option", { value: "debug", children: "Debug" })
166
+ ]
167
+ }
168
+ ),
169
+ /* @__PURE__ */ jsx(
170
+ "input",
171
+ {
172
+ type: "text",
173
+ placeholder: "Search logs...",
174
+ value: filters.search,
175
+ onChange: (e) => {
176
+ setFilters({ ...filters, search: e.target.value });
177
+ setPage(1);
178
+ },
179
+ style: {
180
+ padding: "0.5rem 1rem",
181
+ borderRadius: "0.375rem",
182
+ border: "1px solid #d1d5db",
183
+ flex: 1,
184
+ minWidth: "200px",
185
+ fontSize: "0.875rem"
186
+ }
187
+ }
188
+ ),
189
+ /* @__PURE__ */ jsx(
190
+ "input",
191
+ {
192
+ type: "text",
193
+ placeholder: "User ID...",
194
+ value: filters.userId,
195
+ onChange: (e) => {
196
+ setFilters({ ...filters, userId: e.target.value });
197
+ setPage(1);
198
+ },
199
+ style: {
200
+ padding: "0.5rem 1rem",
201
+ borderRadius: "0.375rem",
202
+ border: "1px solid #d1d5db",
203
+ width: "150px",
204
+ fontSize: "0.875rem"
205
+ }
206
+ }
207
+ ),
208
+ /* @__PURE__ */ jsx(
209
+ "button",
210
+ {
211
+ onClick: fetchLogs,
212
+ disabled: loading,
213
+ style: {
214
+ padding: "0.5rem 1rem",
215
+ borderRadius: "0.375rem",
216
+ backgroundColor: "#3b82f6",
217
+ color: "white",
218
+ border: "none",
219
+ cursor: loading ? "not-allowed" : "pointer",
220
+ opacity: loading ? 0.7 : 1,
221
+ fontSize: "0.875rem"
222
+ },
223
+ children: loading ? "Loading..." : "Refresh"
224
+ }
225
+ ),
226
+ showDelete && /* @__PURE__ */ jsx(
227
+ "button",
228
+ {
229
+ onClick: handleClearAll,
230
+ disabled: deleting || total === 0,
231
+ style: {
232
+ padding: "0.5rem 1rem",
233
+ borderRadius: "0.375rem",
234
+ backgroundColor: "#ef4444",
235
+ color: "white",
236
+ border: "none",
237
+ cursor: deleting || total === 0 ? "not-allowed" : "pointer",
238
+ opacity: deleting || total === 0 ? 0.7 : 1,
239
+ fontSize: "0.875rem"
240
+ },
241
+ children: "Clear All"
242
+ }
243
+ )
244
+ ]
245
+ }
246
+ ),
247
+ /* @__PURE__ */ jsxs(
248
+ "div",
249
+ {
250
+ style: {
251
+ marginBottom: "1rem",
252
+ fontSize: "0.875rem",
253
+ color: "#6b7280"
254
+ },
255
+ children: [
256
+ "Showing ",
257
+ logs.length,
258
+ " of ",
259
+ total,
260
+ " logs",
261
+ autoRefresh > 0 && ` \u2022 Auto-refreshing every ${autoRefresh}s`
262
+ ]
263
+ }
264
+ ),
265
+ /* @__PURE__ */ jsx(
266
+ "div",
267
+ {
268
+ style: {
269
+ border: "1px solid #e5e7eb",
270
+ borderRadius: "0.5rem",
271
+ overflow: "hidden"
272
+ },
273
+ children: /* @__PURE__ */ jsxs("table", { style: { width: "100%", borderCollapse: "collapse" }, children: [
274
+ /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { style: { backgroundColor: "#f9fafb" }, children: [
275
+ /* @__PURE__ */ jsx(
276
+ "th",
277
+ {
278
+ style: {
279
+ padding: "0.75rem 1rem",
280
+ textAlign: "left",
281
+ fontSize: "0.875rem",
282
+ fontWeight: 500,
283
+ borderBottom: "1px solid #e5e7eb"
284
+ },
285
+ children: "Level"
286
+ }
287
+ ),
288
+ /* @__PURE__ */ jsx(
289
+ "th",
290
+ {
291
+ style: {
292
+ padding: "0.75rem 1rem",
293
+ textAlign: "left",
294
+ fontSize: "0.875rem",
295
+ fontWeight: 500,
296
+ borderBottom: "1px solid #e5e7eb"
297
+ },
298
+ children: "Message"
299
+ }
300
+ ),
301
+ /* @__PURE__ */ jsx(
302
+ "th",
303
+ {
304
+ style: {
305
+ padding: "0.75rem 1rem",
306
+ textAlign: "left",
307
+ fontSize: "0.875rem",
308
+ fontWeight: 500,
309
+ borderBottom: "1px solid #e5e7eb"
310
+ },
311
+ children: "User"
312
+ }
313
+ ),
314
+ /* @__PURE__ */ jsx(
315
+ "th",
316
+ {
317
+ style: {
318
+ padding: "0.75rem 1rem",
319
+ textAlign: "left",
320
+ fontSize: "0.875rem",
321
+ fontWeight: 500,
322
+ borderBottom: "1px solid #e5e7eb"
323
+ },
324
+ children: "Path"
325
+ }
326
+ ),
327
+ /* @__PURE__ */ jsx(
328
+ "th",
329
+ {
330
+ style: {
331
+ padding: "0.75rem 1rem",
332
+ textAlign: "left",
333
+ fontSize: "0.875rem",
334
+ fontWeight: 500,
335
+ borderBottom: "1px solid #e5e7eb"
336
+ },
337
+ children: "Time"
338
+ }
339
+ ),
340
+ showDelete && /* @__PURE__ */ jsx(
341
+ "th",
342
+ {
343
+ style: {
344
+ padding: "0.75rem 1rem",
345
+ textAlign: "center",
346
+ fontSize: "0.875rem",
347
+ fontWeight: 500,
348
+ borderBottom: "1px solid #e5e7eb",
349
+ width: "80px"
350
+ },
351
+ children: "Actions"
352
+ }
353
+ )
354
+ ] }) }),
355
+ /* @__PURE__ */ jsx("tbody", { children: loading && logs.length === 0 ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx(
356
+ "td",
357
+ {
358
+ colSpan: showDelete ? 6 : 5,
359
+ style: {
360
+ padding: "2rem",
361
+ textAlign: "center",
362
+ color: "#6b7280"
363
+ },
364
+ children: "Loading..."
365
+ }
366
+ ) }) : logs.length === 0 ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx(
367
+ "td",
368
+ {
369
+ colSpan: showDelete ? 6 : 5,
370
+ style: {
371
+ padding: "2rem",
372
+ textAlign: "center",
373
+ color: "#6b7280"
374
+ },
375
+ children: "No logs found"
376
+ }
377
+ ) }) : logs.map((log) => /* @__PURE__ */ jsxs(
378
+ "tr",
379
+ {
380
+ onClick: () => {
381
+ setSelectedLog(log);
382
+ onLogSelect?.(log);
383
+ },
384
+ style: {
385
+ cursor: "pointer",
386
+ backgroundColor: selectedLog?.id === log.id ? "#f3f4f6" : "white"
387
+ },
388
+ onMouseEnter: (e) => {
389
+ if (selectedLog?.id !== log.id) {
390
+ e.currentTarget.style.backgroundColor = "#f9fafb";
391
+ }
392
+ },
393
+ onMouseLeave: (e) => {
394
+ if (selectedLog?.id !== log.id) {
395
+ e.currentTarget.style.backgroundColor = "white";
396
+ }
397
+ },
398
+ children: [
399
+ /* @__PURE__ */ jsx(
400
+ "td",
401
+ {
402
+ style: {
403
+ padding: "0.75rem 1rem",
404
+ borderBottom: "1px solid #e5e7eb"
405
+ },
406
+ children: /* @__PURE__ */ jsx(
407
+ "span",
408
+ {
409
+ style: {
410
+ ...getLevelStyle(log.level),
411
+ padding: "0.25rem 0.5rem",
412
+ borderRadius: "0.25rem",
413
+ fontSize: "0.75rem",
414
+ fontWeight: 500,
415
+ textTransform: "uppercase"
416
+ },
417
+ children: log.level
418
+ }
419
+ )
420
+ }
421
+ ),
422
+ /* @__PURE__ */ jsx(
423
+ "td",
424
+ {
425
+ style: {
426
+ padding: "0.75rem 1rem",
427
+ borderBottom: "1px solid #e5e7eb",
428
+ fontSize: "0.875rem",
429
+ maxWidth: "300px",
430
+ overflow: "hidden",
431
+ textOverflow: "ellipsis",
432
+ whiteSpace: "nowrap"
433
+ },
434
+ children: log.message
435
+ }
436
+ ),
437
+ /* @__PURE__ */ jsx(
438
+ "td",
439
+ {
440
+ style: {
441
+ padding: "0.75rem 1rem",
442
+ borderBottom: "1px solid #e5e7eb",
443
+ fontSize: "0.875rem",
444
+ color: "#6b7280"
445
+ },
446
+ children: log.userEmail || log.userName || log.userId || "-"
447
+ }
448
+ ),
449
+ /* @__PURE__ */ jsx(
450
+ "td",
451
+ {
452
+ style: {
453
+ padding: "0.75rem 1rem",
454
+ borderBottom: "1px solid #e5e7eb",
455
+ fontSize: "0.875rem",
456
+ color: "#6b7280"
457
+ },
458
+ children: log.path || "-"
459
+ }
460
+ ),
461
+ /* @__PURE__ */ jsx(
462
+ "td",
463
+ {
464
+ style: {
465
+ padding: "0.75rem 1rem",
466
+ borderBottom: "1px solid #e5e7eb",
467
+ fontSize: "0.875rem",
468
+ color: "#6b7280",
469
+ whiteSpace: "nowrap"
470
+ },
471
+ children: new Date(
472
+ log.createdAt
473
+ ).toLocaleString()
474
+ }
475
+ ),
476
+ showDelete && /* @__PURE__ */ jsx(
477
+ "td",
478
+ {
479
+ style: {
480
+ padding: "0.75rem 1rem",
481
+ borderBottom: "1px solid #e5e7eb",
482
+ textAlign: "center"
483
+ },
484
+ children: /* @__PURE__ */ jsx(
485
+ "button",
486
+ {
487
+ onClick: (e) => {
488
+ e.stopPropagation();
489
+ handleDelete(log.id);
490
+ },
491
+ disabled: deleting,
492
+ style: {
493
+ padding: "0.25rem 0.5rem",
494
+ borderRadius: "0.25rem",
495
+ backgroundColor: "transparent",
496
+ color: "#ef4444",
497
+ border: "1px solid #ef4444",
498
+ cursor: deleting ? "not-allowed" : "pointer",
499
+ fontSize: "0.75rem"
500
+ },
501
+ children: "Delete"
502
+ }
503
+ )
504
+ }
505
+ )
506
+ ]
507
+ },
508
+ log.id
509
+ )) })
510
+ ] })
511
+ }
512
+ ),
513
+ totalPages > 1 && /* @__PURE__ */ jsxs(
514
+ "div",
515
+ {
516
+ style: {
517
+ display: "flex",
518
+ justifyContent: "space-between",
519
+ alignItems: "center",
520
+ marginTop: "1rem"
521
+ },
522
+ children: [
523
+ /* @__PURE__ */ jsxs("span", { style: { fontSize: "0.875rem", color: "#6b7280" }, children: [
524
+ "Page ",
525
+ page,
526
+ " of ",
527
+ totalPages
528
+ ] }),
529
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "0.5rem" }, children: [
530
+ /* @__PURE__ */ jsx(
531
+ "button",
532
+ {
533
+ onClick: () => setPage(1),
534
+ disabled: page === 1,
535
+ style: {
536
+ padding: "0.5rem 0.75rem",
537
+ borderRadius: "0.375rem",
538
+ border: "1px solid #d1d5db",
539
+ backgroundColor: "white",
540
+ cursor: page === 1 ? "not-allowed" : "pointer",
541
+ opacity: page === 1 ? 0.5 : 1,
542
+ fontSize: "0.875rem"
543
+ },
544
+ children: "First"
545
+ }
546
+ ),
547
+ /* @__PURE__ */ jsx(
548
+ "button",
549
+ {
550
+ onClick: () => setPage(Math.max(1, page - 1)),
551
+ disabled: page === 1,
552
+ style: {
553
+ padding: "0.5rem 0.75rem",
554
+ borderRadius: "0.375rem",
555
+ border: "1px solid #d1d5db",
556
+ backgroundColor: "white",
557
+ cursor: page === 1 ? "not-allowed" : "pointer",
558
+ opacity: page === 1 ? 0.5 : 1,
559
+ fontSize: "0.875rem"
560
+ },
561
+ children: "Previous"
562
+ }
563
+ ),
564
+ /* @__PURE__ */ jsx(
565
+ "button",
566
+ {
567
+ onClick: () => setPage(Math.min(totalPages, page + 1)),
568
+ disabled: page === totalPages,
569
+ style: {
570
+ padding: "0.5rem 0.75rem",
571
+ borderRadius: "0.375rem",
572
+ border: "1px solid #d1d5db",
573
+ backgroundColor: "white",
574
+ cursor: page === totalPages ? "not-allowed" : "pointer",
575
+ opacity: page === totalPages ? 0.5 : 1,
576
+ fontSize: "0.875rem"
577
+ },
578
+ children: "Next"
579
+ }
580
+ ),
581
+ /* @__PURE__ */ jsx(
582
+ "button",
583
+ {
584
+ onClick: () => setPage(totalPages),
585
+ disabled: page === totalPages,
586
+ style: {
587
+ padding: "0.5rem 0.75rem",
588
+ borderRadius: "0.375rem",
589
+ border: "1px solid #d1d5db",
590
+ backgroundColor: "white",
591
+ cursor: page === totalPages ? "not-allowed" : "pointer",
592
+ opacity: page === totalPages ? 0.5 : 1,
593
+ fontSize: "0.875rem"
594
+ },
595
+ children: "Last"
596
+ }
597
+ )
598
+ ] })
599
+ ]
600
+ }
601
+ ),
602
+ selectedLog && /* @__PURE__ */ jsx(
603
+ "div",
604
+ {
605
+ style: {
606
+ position: "fixed",
607
+ inset: 0,
608
+ backgroundColor: "rgba(0, 0, 0, 0.5)",
609
+ display: "flex",
610
+ alignItems: "center",
611
+ justifyContent: "center",
612
+ padding: "1rem",
613
+ zIndex: 50
614
+ },
615
+ onClick: () => setSelectedLog(null),
616
+ children: /* @__PURE__ */ jsxs(
617
+ "div",
618
+ {
619
+ style: {
620
+ backgroundColor: "white",
621
+ borderRadius: "0.5rem",
622
+ maxWidth: "48rem",
623
+ width: "100%",
624
+ maxHeight: "80vh",
625
+ overflow: "auto",
626
+ padding: "1.5rem"
627
+ },
628
+ onClick: (e) => e.stopPropagation(),
629
+ children: [
630
+ /* @__PURE__ */ jsxs(
631
+ "div",
632
+ {
633
+ style: {
634
+ display: "flex",
635
+ justifyContent: "space-between",
636
+ alignItems: "flex-start",
637
+ marginBottom: "1rem"
638
+ },
639
+ children: [
640
+ /* @__PURE__ */ jsx(
641
+ "h2",
642
+ {
643
+ style: {
644
+ fontSize: "1.125rem",
645
+ fontWeight: 600,
646
+ margin: 0
647
+ },
648
+ children: "Log Details"
649
+ }
650
+ ),
651
+ /* @__PURE__ */ jsx(
652
+ "button",
653
+ {
654
+ onClick: () => setSelectedLog(null),
655
+ style: {
656
+ background: "none",
657
+ border: "none",
658
+ fontSize: "1.5rem",
659
+ cursor: "pointer",
660
+ color: "#6b7280",
661
+ lineHeight: 1
662
+ },
663
+ children: "\xD7"
664
+ }
665
+ )
666
+ ]
667
+ }
668
+ ),
669
+ /* @__PURE__ */ jsxs("dl", { style: { display: "grid", gap: "1rem" }, children: [
670
+ /* @__PURE__ */ jsxs("div", { children: [
671
+ /* @__PURE__ */ jsx(
672
+ "dt",
673
+ {
674
+ style: {
675
+ fontSize: "0.875rem",
676
+ fontWeight: 500,
677
+ color: "#6b7280",
678
+ marginBottom: "0.25rem"
679
+ },
680
+ children: "Level"
681
+ }
682
+ ),
683
+ /* @__PURE__ */ jsx("dd", { style: { margin: 0 }, children: /* @__PURE__ */ jsx(
684
+ "span",
685
+ {
686
+ style: {
687
+ ...getLevelStyle(selectedLog.level),
688
+ padding: "0.25rem 0.5rem",
689
+ borderRadius: "0.25rem",
690
+ fontSize: "0.75rem",
691
+ fontWeight: 500,
692
+ textTransform: "uppercase"
693
+ },
694
+ children: selectedLog.level
695
+ }
696
+ ) })
697
+ ] }),
698
+ /* @__PURE__ */ jsxs("div", { children: [
699
+ /* @__PURE__ */ jsx(
700
+ "dt",
701
+ {
702
+ style: {
703
+ fontSize: "0.875rem",
704
+ fontWeight: 500,
705
+ color: "#6b7280",
706
+ marginBottom: "0.25rem"
707
+ },
708
+ children: "Message"
709
+ }
710
+ ),
711
+ /* @__PURE__ */ jsx("dd", { style: { margin: 0, fontSize: "0.875rem" }, children: selectedLog.message })
712
+ ] }),
713
+ selectedLog.stack && /* @__PURE__ */ jsxs("div", { children: [
714
+ /* @__PURE__ */ jsx(
715
+ "dt",
716
+ {
717
+ style: {
718
+ fontSize: "0.875rem",
719
+ fontWeight: 500,
720
+ color: "#6b7280",
721
+ marginBottom: "0.25rem"
722
+ },
723
+ children: "Stack Trace"
724
+ }
725
+ ),
726
+ /* @__PURE__ */ jsx("dd", { style: { margin: 0 }, children: /* @__PURE__ */ jsx(
727
+ "pre",
728
+ {
729
+ style: {
730
+ fontSize: "0.75rem",
731
+ fontFamily: "monospace",
732
+ backgroundColor: "#f3f4f6",
733
+ padding: "0.75rem",
734
+ borderRadius: "0.375rem",
735
+ overflow: "auto",
736
+ maxHeight: "200px",
737
+ margin: 0,
738
+ whiteSpace: "pre-wrap",
739
+ wordBreak: "break-all"
740
+ },
741
+ children: selectedLog.stack
742
+ }
743
+ ) })
744
+ ] }),
745
+ /* @__PURE__ */ jsxs(
746
+ "div",
747
+ {
748
+ style: {
749
+ display: "grid",
750
+ gridTemplateColumns: "repeat(2, 1fr)",
751
+ gap: "1rem"
752
+ },
753
+ children: [
754
+ /* @__PURE__ */ jsxs("div", { children: [
755
+ /* @__PURE__ */ jsx(
756
+ "dt",
757
+ {
758
+ style: {
759
+ fontSize: "0.875rem",
760
+ fontWeight: 500,
761
+ color: "#6b7280",
762
+ marginBottom: "0.25rem"
763
+ },
764
+ children: "User"
765
+ }
766
+ ),
767
+ /* @__PURE__ */ jsx(
768
+ "dd",
769
+ {
770
+ style: {
771
+ margin: 0,
772
+ fontSize: "0.875rem"
773
+ },
774
+ children: selectedLog.userEmail || selectedLog.userName || selectedLog.userId || "-"
775
+ }
776
+ )
777
+ ] }),
778
+ /* @__PURE__ */ jsxs("div", { children: [
779
+ /* @__PURE__ */ jsx(
780
+ "dt",
781
+ {
782
+ style: {
783
+ fontSize: "0.875rem",
784
+ fontWeight: 500,
785
+ color: "#6b7280",
786
+ marginBottom: "0.25rem"
787
+ },
788
+ children: "User ID"
789
+ }
790
+ ),
791
+ /* @__PURE__ */ jsx(
792
+ "dd",
793
+ {
794
+ style: {
795
+ margin: 0,
796
+ fontSize: "0.875rem"
797
+ },
798
+ children: selectedLog.userId || "-"
799
+ }
800
+ )
801
+ ] }),
802
+ /* @__PURE__ */ jsxs("div", { children: [
803
+ /* @__PURE__ */ jsx(
804
+ "dt",
805
+ {
806
+ style: {
807
+ fontSize: "0.875rem",
808
+ fontWeight: 500,
809
+ color: "#6b7280",
810
+ marginBottom: "0.25rem"
811
+ },
812
+ children: "Path"
813
+ }
814
+ ),
815
+ /* @__PURE__ */ jsx(
816
+ "dd",
817
+ {
818
+ style: {
819
+ margin: 0,
820
+ fontSize: "0.875rem"
821
+ },
822
+ children: selectedLog.path || "-"
823
+ }
824
+ )
825
+ ] }),
826
+ /* @__PURE__ */ jsxs("div", { children: [
827
+ /* @__PURE__ */ jsx(
828
+ "dt",
829
+ {
830
+ style: {
831
+ fontSize: "0.875rem",
832
+ fontWeight: 500,
833
+ color: "#6b7280",
834
+ marginBottom: "0.25rem"
835
+ },
836
+ children: "Method"
837
+ }
838
+ ),
839
+ /* @__PURE__ */ jsx(
840
+ "dd",
841
+ {
842
+ style: {
843
+ margin: 0,
844
+ fontSize: "0.875rem"
845
+ },
846
+ children: selectedLog.method || "-"
847
+ }
848
+ )
849
+ ] }),
850
+ /* @__PURE__ */ jsxs("div", { children: [
851
+ /* @__PURE__ */ jsx(
852
+ "dt",
853
+ {
854
+ style: {
855
+ fontSize: "0.875rem",
856
+ fontWeight: 500,
857
+ color: "#6b7280",
858
+ marginBottom: "0.25rem"
859
+ },
860
+ children: "IP Address"
861
+ }
862
+ ),
863
+ /* @__PURE__ */ jsx(
864
+ "dd",
865
+ {
866
+ style: {
867
+ margin: 0,
868
+ fontSize: "0.875rem"
869
+ },
870
+ children: selectedLog.ip || "-"
871
+ }
872
+ )
873
+ ] }),
874
+ /* @__PURE__ */ jsxs("div", { children: [
875
+ /* @__PURE__ */ jsx(
876
+ "dt",
877
+ {
878
+ style: {
879
+ fontSize: "0.875rem",
880
+ fontWeight: 500,
881
+ color: "#6b7280",
882
+ marginBottom: "0.25rem"
883
+ },
884
+ children: "Time"
885
+ }
886
+ ),
887
+ /* @__PURE__ */ jsx(
888
+ "dd",
889
+ {
890
+ style: {
891
+ margin: 0,
892
+ fontSize: "0.875rem"
893
+ },
894
+ children: new Date(
895
+ selectedLog.createdAt
896
+ ).toLocaleString()
897
+ }
898
+ )
899
+ ] })
900
+ ]
901
+ }
902
+ ),
903
+ selectedLog.userAgent && /* @__PURE__ */ jsxs("div", { children: [
904
+ /* @__PURE__ */ jsx(
905
+ "dt",
906
+ {
907
+ style: {
908
+ fontSize: "0.875rem",
909
+ fontWeight: 500,
910
+ color: "#6b7280",
911
+ marginBottom: "0.25rem"
912
+ },
913
+ children: "User Agent"
914
+ }
915
+ ),
916
+ /* @__PURE__ */ jsx(
917
+ "dd",
918
+ {
919
+ style: {
920
+ margin: 0,
921
+ fontSize: "0.75rem",
922
+ color: "#6b7280",
923
+ wordBreak: "break-all"
924
+ },
925
+ children: selectedLog.userAgent
926
+ }
927
+ )
928
+ ] }),
929
+ selectedLog.metadata && Object.keys(selectedLog.metadata).length > 0 && /* @__PURE__ */ jsxs("div", { children: [
930
+ /* @__PURE__ */ jsx(
931
+ "dt",
932
+ {
933
+ style: {
934
+ fontSize: "0.875rem",
935
+ fontWeight: 500,
936
+ color: "#6b7280",
937
+ marginBottom: "0.25rem"
938
+ },
939
+ children: "Metadata"
940
+ }
941
+ ),
942
+ /* @__PURE__ */ jsx("dd", { style: { margin: 0 }, children: /* @__PURE__ */ jsx(
943
+ "pre",
944
+ {
945
+ style: {
946
+ fontSize: "0.75rem",
947
+ fontFamily: "monospace",
948
+ backgroundColor: "#f3f4f6",
949
+ padding: "0.75rem",
950
+ borderRadius: "0.375rem",
951
+ overflow: "auto",
952
+ maxHeight: "150px",
953
+ margin: 0
954
+ },
955
+ children: JSON.stringify(
956
+ selectedLog.metadata,
957
+ null,
958
+ 2
959
+ )
960
+ }
961
+ ) })
962
+ ] })
963
+ ] }),
964
+ showDelete && /* @__PURE__ */ jsx(
965
+ "div",
966
+ {
967
+ style: {
968
+ marginTop: "1.5rem",
969
+ textAlign: "right"
970
+ },
971
+ children: /* @__PURE__ */ jsx(
972
+ "button",
973
+ {
974
+ onClick: () => {
975
+ handleDelete(selectedLog.id);
976
+ },
977
+ disabled: deleting,
978
+ style: {
979
+ padding: "0.5rem 1rem",
980
+ borderRadius: "0.375rem",
981
+ backgroundColor: "#ef4444",
982
+ color: "white",
983
+ border: "none",
984
+ cursor: deleting ? "not-allowed" : "pointer",
985
+ opacity: deleting ? 0.7 : 1,
986
+ fontSize: "0.875rem"
987
+ },
988
+ children: "Delete This Log"
989
+ }
990
+ )
991
+ }
992
+ )
993
+ ]
994
+ }
995
+ )
996
+ }
997
+ )
998
+ ]
999
+ }
1000
+ );
1001
+ }
1002
+
1003
+ // src/components/ErrorBoundary.tsx
1004
+ import { Component } from "react";
1005
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
1006
+ var ErrorBoundary = class extends Component {
1007
+ constructor(props) {
1008
+ super(props);
1009
+ this.reset = () => {
1010
+ this.setState({ hasError: false, error: null });
1011
+ };
1012
+ this.state = { hasError: false, error: null };
1013
+ }
1014
+ static getDerivedStateFromError(error) {
1015
+ return { hasError: true, error };
1016
+ }
1017
+ componentDidCatch(error, errorInfo) {
1018
+ const {
1019
+ onError,
1020
+ logToConsole = process.env.NODE_ENV === "development"
1021
+ } = this.props;
1022
+ if (logToConsole) {
1023
+ console.error("ErrorBoundary caught an error:", error);
1024
+ console.error("Component stack:", errorInfo.componentStack);
1025
+ }
1026
+ onError?.(error, errorInfo);
1027
+ }
1028
+ render() {
1029
+ const { hasError, error } = this.state;
1030
+ const { children, fallback } = this.props;
1031
+ if (hasError && error) {
1032
+ if (typeof fallback === "function") {
1033
+ return fallback(error, this.reset);
1034
+ }
1035
+ if (fallback) {
1036
+ return fallback;
1037
+ }
1038
+ return /* @__PURE__ */ jsxs2(
1039
+ "div",
1040
+ {
1041
+ style: {
1042
+ padding: "2rem",
1043
+ textAlign: "center",
1044
+ fontFamily: "system-ui, sans-serif"
1045
+ },
1046
+ children: [
1047
+ /* @__PURE__ */ jsx2(
1048
+ "h2",
1049
+ {
1050
+ style: {
1051
+ fontSize: "1.5rem",
1052
+ fontWeight: 600,
1053
+ color: "#dc2626",
1054
+ marginBottom: "1rem"
1055
+ },
1056
+ children: "Something went wrong"
1057
+ }
1058
+ ),
1059
+ /* @__PURE__ */ jsx2(
1060
+ "p",
1061
+ {
1062
+ style: {
1063
+ color: "#6b7280",
1064
+ marginBottom: "1rem"
1065
+ },
1066
+ children: "An unexpected error occurred. Please try again."
1067
+ }
1068
+ ),
1069
+ /* @__PURE__ */ jsxs2(
1070
+ "details",
1071
+ {
1072
+ style: {
1073
+ marginBottom: "1rem",
1074
+ textAlign: "left",
1075
+ maxWidth: "600px",
1076
+ margin: "0 auto 1rem"
1077
+ },
1078
+ children: [
1079
+ /* @__PURE__ */ jsx2(
1080
+ "summary",
1081
+ {
1082
+ style: {
1083
+ cursor: "pointer",
1084
+ color: "#3b82f6",
1085
+ marginBottom: "0.5rem"
1086
+ },
1087
+ children: "Error details"
1088
+ }
1089
+ ),
1090
+ /* @__PURE__ */ jsxs2(
1091
+ "pre",
1092
+ {
1093
+ style: {
1094
+ fontSize: "0.75rem",
1095
+ fontFamily: "monospace",
1096
+ backgroundColor: "#f3f4f6",
1097
+ padding: "1rem",
1098
+ borderRadius: "0.5rem",
1099
+ overflow: "auto",
1100
+ textAlign: "left",
1101
+ whiteSpace: "pre-wrap",
1102
+ wordBreak: "break-all"
1103
+ },
1104
+ children: [
1105
+ error.message,
1106
+ "\n\n",
1107
+ error.stack
1108
+ ]
1109
+ }
1110
+ )
1111
+ ]
1112
+ }
1113
+ ),
1114
+ /* @__PURE__ */ jsx2(
1115
+ "button",
1116
+ {
1117
+ onClick: this.reset,
1118
+ style: {
1119
+ padding: "0.75rem 1.5rem",
1120
+ backgroundColor: "#3b82f6",
1121
+ color: "white",
1122
+ border: "none",
1123
+ borderRadius: "0.375rem",
1124
+ cursor: "pointer",
1125
+ fontSize: "1rem"
1126
+ },
1127
+ children: "Try again"
1128
+ }
1129
+ )
1130
+ ]
1131
+ }
1132
+ );
1133
+ }
1134
+ return children;
1135
+ }
1136
+ };
1137
+ function withErrorBoundary(Component2, errorBoundaryProps) {
1138
+ const WrappedComponent = (props) => /* @__PURE__ */ jsx2(ErrorBoundary, { ...errorBoundaryProps, children: /* @__PURE__ */ jsx2(Component2, { ...props }) });
1139
+ WrappedComponent.displayName = `withErrorBoundary(${Component2.displayName || Component2.name || "Component"})`;
1140
+ return WrappedComponent;
1141
+ }
1142
+ export {
1143
+ ErrorBoundary,
1144
+ LogViewer,
1145
+ withErrorBoundary
1146
+ };
1147
+ //# sourceMappingURL=index.js.map