@nextlyhq/plugin-form-builder 0.0.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 (37) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +122 -0
  3. package/dist/CheckboxFieldEditor-K4T6QX52.js +121 -0
  4. package/dist/CheckboxFieldEditor-K4T6QX52.js.map +1 -0
  5. package/dist/DateFieldEditor-JFJFAVOH.js +187 -0
  6. package/dist/DateFieldEditor-JFJFAVOH.js.map +1 -0
  7. package/dist/EmailFieldEditor-MMOXXL7P.js +138 -0
  8. package/dist/EmailFieldEditor-MMOXXL7P.js.map +1 -0
  9. package/dist/NumberFieldEditor-UISAYR6Z.js +175 -0
  10. package/dist/NumberFieldEditor-UISAYR6Z.js.map +1 -0
  11. package/dist/RadioFieldEditor-6UQFH4WT.js +165 -0
  12. package/dist/RadioFieldEditor-6UQFH4WT.js.map +1 -0
  13. package/dist/SelectFieldEditor-PSO4KHV4.js +213 -0
  14. package/dist/SelectFieldEditor-PSO4KHV4.js.map +1 -0
  15. package/dist/TextFieldEditor-5EU64EA5.js +187 -0
  16. package/dist/TextFieldEditor-5EU64EA5.js.map +1 -0
  17. package/dist/TextareaFieldEditor-773G3LNM.js +190 -0
  18. package/dist/TextareaFieldEditor-773G3LNM.js.map +1 -0
  19. package/dist/admin/index.css +934 -0
  20. package/dist/admin/index.css.map +1 -0
  21. package/dist/admin/index.d.ts +547 -0
  22. package/dist/admin/index.js +4030 -0
  23. package/dist/admin/index.js.map +1 -0
  24. package/dist/chunk-ABNZFTQK.js +586 -0
  25. package/dist/chunk-ABNZFTQK.js.map +1 -0
  26. package/dist/chunk-XTCEPJ7B.js +256 -0
  27. package/dist/chunk-XTCEPJ7B.js.map +1 -0
  28. package/dist/components/index.d.ts +3 -0
  29. package/dist/components/index.js +9 -0
  30. package/dist/components/index.js.map +1 -0
  31. package/dist/index-C0kBvYjm.d.ts +1012 -0
  32. package/dist/index.d.ts +1663 -0
  33. package/dist/index.js +2470 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/styles/form-builder.css +1150 -0
  36. package/dist/styles/submissions-filter.css +75 -0
  37. package/package.json +96 -0
@@ -0,0 +1,586 @@
1
+ // src/components/submissions/SubmissionList.tsx
2
+ import { useState, useCallback, useMemo } from "react";
3
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
4
+ function formatValue(value) {
5
+ if (value === null || value === void 0) return "-";
6
+ if (Array.isArray(value)) return value.join(", ");
7
+ if (typeof value === "boolean") return value ? "Yes" : "No";
8
+ if (value instanceof Date) return value.toLocaleDateString();
9
+ let str;
10
+ if (typeof value === "object") {
11
+ str = JSON.stringify(value);
12
+ } else {
13
+ str = String(value);
14
+ }
15
+ return str.length > 50 ? str.slice(0, 50) + "..." : str;
16
+ }
17
+ function formatDate(date) {
18
+ const d = typeof date === "string" ? new Date(date) : date;
19
+ return d.toLocaleString();
20
+ }
21
+ function getStatusBadgeClass(status) {
22
+ switch (status) {
23
+ case "new":
24
+ return "submission-status-badge submission-status-badge--new";
25
+ case "read":
26
+ return "submission-status-badge submission-status-badge--read";
27
+ case "archived":
28
+ return "submission-status-badge submission-status-badge--archived";
29
+ default:
30
+ return "submission-status-badge";
31
+ }
32
+ }
33
+ function SubmissionList({
34
+ form,
35
+ submissions,
36
+ isLoading = false,
37
+ onStatusChange,
38
+ onDelete,
39
+ onBulkDelete,
40
+ onBulkStatusChange,
41
+ onExport,
42
+ onViewDetail
43
+ }) {
44
+ const [selectedIds, setSelectedIds] = useState(/* @__PURE__ */ new Set());
45
+ const [filter, setFilter] = useState("all");
46
+ const [processingIds, setProcessingIds] = useState(/* @__PURE__ */ new Set());
47
+ const displayFields = useMemo(() => {
48
+ return form.fields.filter((f) => f.type !== "hidden").slice(0, 3);
49
+ }, [form.fields]);
50
+ const filteredSubmissions = useMemo(() => {
51
+ if (filter === "all") return submissions;
52
+ return submissions.filter((sub) => sub.status === filter);
53
+ }, [submissions, filter]);
54
+ const allSelected = filteredSubmissions.length > 0 && selectedIds.size === filteredSubmissions.length && filteredSubmissions.every((s) => selectedIds.has(s.id));
55
+ const someSelected = selectedIds.size > 0;
56
+ const toggleSelect = useCallback((id) => {
57
+ setSelectedIds((prev) => {
58
+ const next = new Set(prev);
59
+ if (next.has(id)) {
60
+ next.delete(id);
61
+ } else {
62
+ next.add(id);
63
+ }
64
+ return next;
65
+ });
66
+ }, []);
67
+ const toggleSelectAll = useCallback(() => {
68
+ if (allSelected) {
69
+ setSelectedIds(/* @__PURE__ */ new Set());
70
+ } else {
71
+ setSelectedIds(new Set(filteredSubmissions.map((s) => s.id)));
72
+ }
73
+ }, [allSelected, filteredSubmissions]);
74
+ const handleStatusChange = useCallback(
75
+ async (id, status) => {
76
+ if (!onStatusChange) return;
77
+ setProcessingIds((prev) => new Set(prev).add(id));
78
+ try {
79
+ await onStatusChange(id, status);
80
+ } finally {
81
+ setProcessingIds((prev) => {
82
+ const next = new Set(prev);
83
+ next.delete(id);
84
+ return next;
85
+ });
86
+ }
87
+ },
88
+ [onStatusChange]
89
+ );
90
+ const handleDelete = useCallback(
91
+ async (id) => {
92
+ if (!onDelete) return;
93
+ if (!window.confirm("Are you sure you want to delete this submission?")) {
94
+ return;
95
+ }
96
+ setProcessingIds((prev) => new Set(prev).add(id));
97
+ try {
98
+ await onDelete(id);
99
+ setSelectedIds((prev) => {
100
+ const next = new Set(prev);
101
+ next.delete(id);
102
+ return next;
103
+ });
104
+ } finally {
105
+ setProcessingIds((prev) => {
106
+ const next = new Set(prev);
107
+ next.delete(id);
108
+ return next;
109
+ });
110
+ }
111
+ },
112
+ [onDelete]
113
+ );
114
+ const handleBulkDelete = useCallback(async () => {
115
+ if (!onBulkDelete || selectedIds.size === 0) return;
116
+ if (!window.confirm(
117
+ `Are you sure you want to delete ${selectedIds.size} submission(s)?`
118
+ )) {
119
+ return;
120
+ }
121
+ const ids = Array.from(selectedIds);
122
+ ids.forEach((id) => setProcessingIds((prev) => new Set(prev).add(id)));
123
+ try {
124
+ await onBulkDelete(ids);
125
+ setSelectedIds(/* @__PURE__ */ new Set());
126
+ } finally {
127
+ setProcessingIds(/* @__PURE__ */ new Set());
128
+ }
129
+ }, [onBulkDelete, selectedIds]);
130
+ const handleBulkStatusChange = useCallback(
131
+ async (status) => {
132
+ if (!onBulkStatusChange || selectedIds.size === 0) return;
133
+ const ids = Array.from(selectedIds);
134
+ ids.forEach((id) => setProcessingIds((prev) => new Set(prev).add(id)));
135
+ try {
136
+ await onBulkStatusChange(ids, status);
137
+ setSelectedIds(/* @__PURE__ */ new Set());
138
+ } finally {
139
+ setProcessingIds(/* @__PURE__ */ new Set());
140
+ }
141
+ },
142
+ [onBulkStatusChange, selectedIds]
143
+ );
144
+ const handleRowClick = useCallback(
145
+ (submission) => {
146
+ onViewDetail?.(submission);
147
+ },
148
+ [onViewDetail]
149
+ );
150
+ return /* @__PURE__ */ jsxs("div", { className: "submission-list", children: [
151
+ /* @__PURE__ */ jsxs("div", { className: "submission-list__toolbar", children: [
152
+ /* @__PURE__ */ jsx("div", { className: "submission-list__filters", children: /* @__PURE__ */ jsxs(
153
+ "select",
154
+ {
155
+ value: filter,
156
+ onChange: (e) => setFilter(e.target.value),
157
+ className: "submission-list__filter-select",
158
+ "aria-label": "Filter by status",
159
+ children: [
160
+ /* @__PURE__ */ jsxs("option", { value: "all", children: [
161
+ "All Submissions (",
162
+ submissions.length,
163
+ ")"
164
+ ] }),
165
+ /* @__PURE__ */ jsxs("option", { value: "new", children: [
166
+ "New (",
167
+ submissions.filter((s) => s.status === "new").length,
168
+ ")"
169
+ ] }),
170
+ /* @__PURE__ */ jsxs("option", { value: "read", children: [
171
+ "Read (",
172
+ submissions.filter((s) => s.status === "read").length,
173
+ ")"
174
+ ] }),
175
+ /* @__PURE__ */ jsxs("option", { value: "archived", children: [
176
+ "Archived (",
177
+ submissions.filter((s) => s.status === "archived").length,
178
+ ")"
179
+ ] })
180
+ ]
181
+ }
182
+ ) }),
183
+ /* @__PURE__ */ jsxs("div", { className: "submission-list__actions", children: [
184
+ someSelected && /* @__PURE__ */ jsxs("div", { className: "submission-list__bulk-actions", children: [
185
+ /* @__PURE__ */ jsxs("span", { className: "submission-list__selected-count", children: [
186
+ selectedIds.size,
187
+ " selected"
188
+ ] }),
189
+ onBulkStatusChange && /* @__PURE__ */ jsxs(Fragment, { children: [
190
+ /* @__PURE__ */ jsx(
191
+ "button",
192
+ {
193
+ type: "button",
194
+ onClick: () => void handleBulkStatusChange("read"),
195
+ className: "submission-list__action-btn",
196
+ children: "Mark Read"
197
+ }
198
+ ),
199
+ /* @__PURE__ */ jsx(
200
+ "button",
201
+ {
202
+ type: "button",
203
+ onClick: () => void handleBulkStatusChange("archived"),
204
+ className: "submission-list__action-btn",
205
+ children: "Archive"
206
+ }
207
+ )
208
+ ] }),
209
+ onBulkDelete && /* @__PURE__ */ jsx(
210
+ "button",
211
+ {
212
+ type: "button",
213
+ onClick: () => void handleBulkDelete(),
214
+ className: "submission-list__action-btn submission-list__action-btn--danger",
215
+ children: "Delete"
216
+ }
217
+ )
218
+ ] }),
219
+ onExport && /* @__PURE__ */ jsxs("div", { className: "submission-list__export-actions", children: [
220
+ /* @__PURE__ */ jsx(
221
+ "button",
222
+ {
223
+ type: "button",
224
+ onClick: () => onExport("csv"),
225
+ className: "submission-list__export-btn",
226
+ children: "Export CSV"
227
+ }
228
+ ),
229
+ /* @__PURE__ */ jsx(
230
+ "button",
231
+ {
232
+ type: "button",
233
+ onClick: () => onExport("json"),
234
+ className: "submission-list__export-btn",
235
+ children: "Export JSON"
236
+ }
237
+ )
238
+ ] })
239
+ ] })
240
+ ] }),
241
+ /* @__PURE__ */ jsx("div", { className: "submission-list__table-container", children: /* @__PURE__ */ jsxs("table", { className: "submission-list__table", children: [
242
+ /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
243
+ /* @__PURE__ */ jsx("th", { className: "submission-list__th submission-list__th--checkbox", children: /* @__PURE__ */ jsx(
244
+ "input",
245
+ {
246
+ type: "checkbox",
247
+ checked: allSelected,
248
+ onChange: toggleSelectAll,
249
+ "aria-label": "Select all submissions"
250
+ }
251
+ ) }),
252
+ /* @__PURE__ */ jsx("th", { className: "submission-list__th", children: "ID" }),
253
+ /* @__PURE__ */ jsx("th", { className: "submission-list__th", children: "Status" }),
254
+ /* @__PURE__ */ jsx("th", { className: "submission-list__th", children: "Submitted" }),
255
+ displayFields.map((field) => /* @__PURE__ */ jsx("th", { className: "submission-list__th", children: field.label }, field.name)),
256
+ /* @__PURE__ */ jsx("th", { className: "submission-list__th submission-list__th--actions", children: "Actions" })
257
+ ] }) }),
258
+ /* @__PURE__ */ jsx("tbody", { children: isLoading ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx(
259
+ "td",
260
+ {
261
+ colSpan: 5 + displayFields.length,
262
+ className: "submission-list__loading",
263
+ children: "Loading submissions..."
264
+ }
265
+ ) }) : filteredSubmissions.length === 0 ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx(
266
+ "td",
267
+ {
268
+ colSpan: 5 + displayFields.length,
269
+ className: "submission-list__empty",
270
+ children: "No submissions found"
271
+ }
272
+ ) }) : filteredSubmissions.map((submission) => {
273
+ const isSelected = selectedIds.has(submission.id);
274
+ const isProcessing = processingIds.has(submission.id);
275
+ return /* @__PURE__ */ jsxs(
276
+ "tr",
277
+ {
278
+ className: `submission-list__row ${isSelected ? "submission-list__row--selected" : ""} ${isProcessing ? "submission-list__row--processing" : ""}`,
279
+ onClick: () => handleRowClick(submission),
280
+ style: { cursor: onViewDetail ? "pointer" : "default" },
281
+ children: [
282
+ /* @__PURE__ */ jsx(
283
+ "td",
284
+ {
285
+ className: "submission-list__td submission-list__td--checkbox",
286
+ onClick: (e) => e.stopPropagation(),
287
+ children: /* @__PURE__ */ jsx(
288
+ "input",
289
+ {
290
+ type: "checkbox",
291
+ checked: isSelected,
292
+ onChange: () => toggleSelect(submission.id),
293
+ disabled: isProcessing,
294
+ "aria-label": `Select submission ${submission.id}`
295
+ }
296
+ )
297
+ }
298
+ ),
299
+ /* @__PURE__ */ jsx("td", { className: "submission-list__td submission-list__td--id", children: /* @__PURE__ */ jsxs("code", { children: [
300
+ submission.id.slice(0, 8),
301
+ "..."
302
+ ] }) }),
303
+ /* @__PURE__ */ jsx("td", { className: "submission-list__td", children: /* @__PURE__ */ jsx("span", { className: getStatusBadgeClass(submission.status), children: submission.status }) }),
304
+ /* @__PURE__ */ jsx("td", { className: "submission-list__td", children: formatDate(submission.submittedAt) }),
305
+ displayFields.map((field) => /* @__PURE__ */ jsx("td", { className: "submission-list__td", children: formatValue(submission.data[field.name]) }, field.name)),
306
+ /* @__PURE__ */ jsxs(
307
+ "td",
308
+ {
309
+ className: "submission-list__td submission-list__td--actions",
310
+ onClick: (e) => e.stopPropagation(),
311
+ children: [
312
+ onStatusChange && submission.status !== "read" && /* @__PURE__ */ jsx(
313
+ "button",
314
+ {
315
+ type: "button",
316
+ onClick: () => void handleStatusChange(submission.id, "read"),
317
+ disabled: isProcessing,
318
+ className: "submission-list__row-action",
319
+ title: "Mark as read",
320
+ children: "Mark Read"
321
+ }
322
+ ),
323
+ onStatusChange && submission.status !== "archived" && /* @__PURE__ */ jsx(
324
+ "button",
325
+ {
326
+ type: "button",
327
+ onClick: () => void handleStatusChange(submission.id, "archived"),
328
+ disabled: isProcessing,
329
+ className: "submission-list__row-action",
330
+ title: "Archive",
331
+ children: "Archive"
332
+ }
333
+ ),
334
+ onDelete && /* @__PURE__ */ jsx(
335
+ "button",
336
+ {
337
+ type: "button",
338
+ onClick: () => void handleDelete(submission.id),
339
+ disabled: isProcessing,
340
+ className: "submission-list__row-action submission-list__row-action--danger",
341
+ title: "Delete",
342
+ children: "Delete"
343
+ }
344
+ )
345
+ ]
346
+ }
347
+ )
348
+ ]
349
+ },
350
+ submission.id
351
+ );
352
+ }) })
353
+ ] }) }),
354
+ /* @__PURE__ */ jsxs("div", { className: "submission-list__summary", children: [
355
+ "Showing ",
356
+ filteredSubmissions.length,
357
+ " of ",
358
+ submissions.length,
359
+ " submissions"
360
+ ] })
361
+ ] });
362
+ }
363
+
364
+ // src/components/submissions/SubmissionDetail.tsx
365
+ import { useState as useState2, useCallback as useCallback2 } from "react";
366
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
367
+ function safeString(value) {
368
+ if (typeof value === "object" && value !== null) {
369
+ return JSON.stringify(value);
370
+ }
371
+ return String(value);
372
+ }
373
+ function formatFieldValue(value, field) {
374
+ if (value === null || value === void 0) return "-";
375
+ switch (field.type) {
376
+ case "checkbox":
377
+ return value ? "Yes" : "No";
378
+ case "select":
379
+ if (Array.isArray(value)) {
380
+ return value.join(", ");
381
+ }
382
+ return safeString(value);
383
+ case "file":
384
+ if (Array.isArray(value)) {
385
+ return value.map((v) => safeString(v)).join(", ");
386
+ }
387
+ return safeString(value);
388
+ case "date":
389
+ if (value instanceof Date) {
390
+ return value.toLocaleDateString();
391
+ }
392
+ if (typeof value === "string") {
393
+ return new Date(value).toLocaleDateString();
394
+ }
395
+ return safeString(value);
396
+ case "time":
397
+ return safeString(value);
398
+ default:
399
+ return safeString(value);
400
+ }
401
+ }
402
+ function formatDate2(date) {
403
+ const d = typeof date === "string" ? new Date(date) : date;
404
+ return d.toLocaleString();
405
+ }
406
+ var STATUS_OPTIONS = [
407
+ { value: "new", label: "New" },
408
+ { value: "read", label: "Read" },
409
+ { value: "archived", label: "Archived" }
410
+ ];
411
+ function SubmissionDetail({
412
+ form,
413
+ submission,
414
+ onStatusChange,
415
+ onNotesUpdate,
416
+ onBack,
417
+ onDelete
418
+ }) {
419
+ const [isProcessing, setIsProcessing] = useState2(false);
420
+ const [notes, setNotes] = useState2(
421
+ submission.notes || ""
422
+ );
423
+ const [notesModified, setNotesModified] = useState2(false);
424
+ const handleStatusChange = useCallback2(
425
+ async (event) => {
426
+ if (!onStatusChange) return;
427
+ const newStatus = event.target.value;
428
+ setIsProcessing(true);
429
+ try {
430
+ await onStatusChange(newStatus);
431
+ } finally {
432
+ setIsProcessing(false);
433
+ }
434
+ },
435
+ [onStatusChange]
436
+ );
437
+ const handleNotesChange = useCallback2(
438
+ (event) => {
439
+ setNotes(event.target.value);
440
+ setNotesModified(true);
441
+ },
442
+ []
443
+ );
444
+ const handleNotesSave = useCallback2(async () => {
445
+ if (!onNotesUpdate || !notesModified) return;
446
+ setIsProcessing(true);
447
+ try {
448
+ await onNotesUpdate(notes);
449
+ setNotesModified(false);
450
+ } finally {
451
+ setIsProcessing(false);
452
+ }
453
+ }, [onNotesUpdate, notes, notesModified]);
454
+ const handleDelete = useCallback2(async () => {
455
+ if (!onDelete) return;
456
+ if (!window.confirm("Are you sure you want to delete this submission?")) {
457
+ return;
458
+ }
459
+ setIsProcessing(true);
460
+ try {
461
+ await onDelete();
462
+ } finally {
463
+ setIsProcessing(false);
464
+ }
465
+ }, [onDelete]);
466
+ const displayFields = form.fields;
467
+ const data = submission.data;
468
+ return /* @__PURE__ */ jsxs2("div", { className: "submission-detail", children: [
469
+ /* @__PURE__ */ jsxs2("div", { className: "submission-detail__header", children: [
470
+ /* @__PURE__ */ jsxs2("div", { className: "submission-detail__header-left", children: [
471
+ onBack && /* @__PURE__ */ jsx2(
472
+ "button",
473
+ {
474
+ type: "button",
475
+ onClick: onBack,
476
+ className: "submission-detail__back-btn",
477
+ disabled: isProcessing,
478
+ children: "\u2190 Back to List"
479
+ }
480
+ ),
481
+ /* @__PURE__ */ jsx2("h2", { className: "submission-detail__title", children: "Submission Details" })
482
+ ] }),
483
+ /* @__PURE__ */ jsxs2("div", { className: "submission-detail__header-right", children: [
484
+ onStatusChange && /* @__PURE__ */ jsxs2("div", { className: "submission-detail__status-control", children: [
485
+ /* @__PURE__ */ jsx2("label", { htmlFor: "submission-status", children: "Status:" }),
486
+ /* @__PURE__ */ jsx2(
487
+ "select",
488
+ {
489
+ id: "submission-status",
490
+ value: submission.status,
491
+ onChange: (e) => void handleStatusChange(e),
492
+ disabled: isProcessing,
493
+ className: "submission-detail__status-select",
494
+ children: STATUS_OPTIONS.map((option) => /* @__PURE__ */ jsx2("option", { value: option.value, children: option.label }, option.value))
495
+ }
496
+ )
497
+ ] }),
498
+ onDelete && /* @__PURE__ */ jsx2(
499
+ "button",
500
+ {
501
+ type: "button",
502
+ onClick: () => void handleDelete(),
503
+ disabled: isProcessing,
504
+ className: "submission-detail__delete-btn",
505
+ children: "Delete"
506
+ }
507
+ )
508
+ ] })
509
+ ] }),
510
+ /* @__PURE__ */ jsxs2("div", { className: "submission-detail__id", children: [
511
+ /* @__PURE__ */ jsx2("span", { className: "submission-detail__id-label", children: "Submission ID:" }),
512
+ /* @__PURE__ */ jsx2("code", { className: "submission-detail__id-value", children: submission.id })
513
+ ] }),
514
+ /* @__PURE__ */ jsxs2("div", { className: "submission-detail__section", children: [
515
+ /* @__PURE__ */ jsx2("h3", { className: "submission-detail__section-title", children: "Submitted Data" }),
516
+ /* @__PURE__ */ jsxs2("div", { className: "submission-detail__fields", children: [
517
+ displayFields.map((field) => /* @__PURE__ */ jsxs2("div", { className: "submission-detail__field", children: [
518
+ /* @__PURE__ */ jsx2("div", { className: "submission-detail__field-label", children: field.label }),
519
+ /* @__PURE__ */ jsx2("div", { className: "submission-detail__field-value", children: formatFieldValue(data[field.name], field) })
520
+ ] }, field.name)),
521
+ displayFields.length === 0 && /* @__PURE__ */ jsx2("div", { className: "submission-detail__empty", children: "No fields to display" })
522
+ ] })
523
+ ] }),
524
+ onNotesUpdate && /* @__PURE__ */ jsxs2("div", { className: "submission-detail__section", children: [
525
+ /* @__PURE__ */ jsx2("h3", { className: "submission-detail__section-title", children: "Internal Notes" }),
526
+ /* @__PURE__ */ jsxs2("div", { className: "submission-detail__notes", children: [
527
+ /* @__PURE__ */ jsx2(
528
+ "textarea",
529
+ {
530
+ value: notes,
531
+ onChange: handleNotesChange,
532
+ placeholder: "Add internal notes about this submission...",
533
+ disabled: isProcessing,
534
+ className: "submission-detail__notes-textarea",
535
+ rows: 4
536
+ }
537
+ ),
538
+ notesModified && /* @__PURE__ */ jsx2(
539
+ "button",
540
+ {
541
+ type: "button",
542
+ onClick: () => void handleNotesSave(),
543
+ disabled: isProcessing,
544
+ className: "submission-detail__notes-save-btn",
545
+ children: "Save Notes"
546
+ }
547
+ )
548
+ ] })
549
+ ] }),
550
+ /* @__PURE__ */ jsxs2("div", { className: "submission-detail__section", children: [
551
+ /* @__PURE__ */ jsx2("h3", { className: "submission-detail__section-title", children: "Metadata" }),
552
+ /* @__PURE__ */ jsxs2("div", { className: "submission-detail__metadata", children: [
553
+ /* @__PURE__ */ jsxs2("div", { className: "submission-detail__metadata-item", children: [
554
+ /* @__PURE__ */ jsx2("span", { className: "submission-detail__metadata-label", children: "Submitted At:" }),
555
+ /* @__PURE__ */ jsx2("span", { className: "submission-detail__metadata-value", children: formatDate2(submission.submittedAt) })
556
+ ] }),
557
+ submission.ipAddress && /* @__PURE__ */ jsxs2("div", { className: "submission-detail__metadata-item", children: [
558
+ /* @__PURE__ */ jsx2("span", { className: "submission-detail__metadata-label", children: "IP Address:" }),
559
+ /* @__PURE__ */ jsx2("span", { className: "submission-detail__metadata-value", children: /* @__PURE__ */ jsx2("code", { children: submission.ipAddress }) })
560
+ ] }),
561
+ submission.userAgent && /* @__PURE__ */ jsxs2("div", { className: "submission-detail__metadata-item", children: [
562
+ /* @__PURE__ */ jsx2("span", { className: "submission-detail__metadata-label", children: "User Agent:" }),
563
+ /* @__PURE__ */ jsx2("span", { className: "submission-detail__metadata-value submission-detail__metadata-value--truncate", children: submission.userAgent })
564
+ ] }),
565
+ /* @__PURE__ */ jsxs2("div", { className: "submission-detail__metadata-item", children: [
566
+ /* @__PURE__ */ jsx2("span", { className: "submission-detail__metadata-label", children: "Created At:" }),
567
+ /* @__PURE__ */ jsx2("span", { className: "submission-detail__metadata-value", children: formatDate2(submission.createdAt) })
568
+ ] }),
569
+ /* @__PURE__ */ jsxs2("div", { className: "submission-detail__metadata-item", children: [
570
+ /* @__PURE__ */ jsx2("span", { className: "submission-detail__metadata-label", children: "Updated At:" }),
571
+ /* @__PURE__ */ jsx2("span", { className: "submission-detail__metadata-value", children: formatDate2(submission.updatedAt) })
572
+ ] })
573
+ ] })
574
+ ] }),
575
+ /* @__PURE__ */ jsxs2("details", { className: "submission-detail__raw-data", children: [
576
+ /* @__PURE__ */ jsx2("summary", { className: "submission-detail__raw-data-summary", children: "View Raw JSON Data" }),
577
+ /* @__PURE__ */ jsx2("pre", { className: "submission-detail__raw-data-content", children: JSON.stringify(submission.data, null, 2) })
578
+ ] })
579
+ ] });
580
+ }
581
+
582
+ export {
583
+ SubmissionList,
584
+ SubmissionDetail
585
+ };
586
+ //# sourceMappingURL=chunk-ABNZFTQK.js.map