@arbidocs/blocks 0.4.69 → 0.4.70

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 (48) hide show
  1. package/README.md +85 -1
  2. package/dist/agents/index.cjs +220 -220
  3. package/dist/agents/index.js +4 -4
  4. package/dist/chat/index.cjs +66 -66
  5. package/dist/chat/index.js +2 -2
  6. package/dist/chunk-4DVEGXZQ.cjs +72 -0
  7. package/dist/chunk-4DVEGXZQ.cjs.map +1 -0
  8. package/dist/{chunk-ZYZMCNIS.cjs → chunk-7M22KND4.cjs} +5 -5
  9. package/dist/{chunk-ZYZMCNIS.cjs.map → chunk-7M22KND4.cjs.map} +1 -1
  10. package/dist/{chunk-ZQB7HNE6.js → chunk-BMWZTNZB.js} +3 -3
  11. package/dist/{chunk-ZQB7HNE6.js.map → chunk-BMWZTNZB.js.map} +1 -1
  12. package/dist/{chunk-4HZ46XP2.js → chunk-HLMFU7L2.js} +5 -5
  13. package/dist/{chunk-4HZ46XP2.js.map → chunk-HLMFU7L2.js.map} +1 -1
  14. package/dist/chunk-ODWCTAH7.js +66 -0
  15. package/dist/chunk-ODWCTAH7.js.map +1 -0
  16. package/dist/{chunk-WKNAFILY.cjs → chunk-XNRGCQPZ.cjs} +3 -3
  17. package/dist/{chunk-WKNAFILY.cjs.map → chunk-XNRGCQPZ.cjs.map} +1 -1
  18. package/dist/connect/index.cjs +1 -1
  19. package/dist/connect/index.js +1 -1
  20. package/dist/document-tools/DocumentToolButtons.d.ts +29 -0
  21. package/dist/document-tools/MarkupNotices.d.ts +12 -0
  22. package/dist/document-tools/MarkupViewNote.d.ts +11 -0
  23. package/dist/document-tools/SignDocumentDialog.d.ts +20 -0
  24. package/dist/document-tools/SignatureCertificate.d.ts +26 -0
  25. package/dist/document-tools/SignatureStatus.d.ts +22 -0
  26. package/dist/document-tools/VersionSnapshotBar.d.ts +27 -0
  27. package/dist/document-tools/index.cjs +633 -0
  28. package/dist/document-tools/index.cjs.map +1 -0
  29. package/dist/document-tools/index.d.ts +7 -0
  30. package/dist/document-tools/index.js +619 -0
  31. package/dist/document-tools/index.js.map +1 -0
  32. package/dist/document-tools/viewer/AnnotatedPdfViewer.d.ts +54 -0
  33. package/dist/document-tools/viewer/SignaturePlacementViewer.d.ts +20 -0
  34. package/dist/document-tools/viewer/index.cjs +273 -0
  35. package/dist/document-tools/viewer/index.cjs.map +1 -0
  36. package/dist/document-tools/viewer/index.d.ts +2 -0
  37. package/dist/document-tools/viewer/index.js +268 -0
  38. package/dist/document-tools/viewer/index.js.map +1 -0
  39. package/dist/files/cells/DocumentNameCell.d.ts +3 -1
  40. package/dist/files/index.cjs +38 -67
  41. package/dist/files/index.cjs.map +1 -1
  42. package/dist/files/index.js +19 -63
  43. package/dist/files/index.js.map +1 -1
  44. package/dist/index.cjs +480 -480
  45. package/dist/index.js +7 -7
  46. package/dist/settings/index.cjs +1 -1
  47. package/dist/settings/index.js +1 -1
  48. package/package.json +20 -4
@@ -0,0 +1,633 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ var chunk4DVEGXZQ_cjs = require('../chunk-4DVEGXZQ.cjs');
5
+ var chunk2ZTONLT5_cjs = require('../chunk-2ZTONLT5.cjs');
6
+ require('../chunk-DCDVWPMB.cjs');
7
+ var lucideReact = require('lucide-react');
8
+ var ui = require('@arbidocs/react/ui');
9
+ var jsxRuntime = require('react/jsx-runtime');
10
+ var react = require('react');
11
+ var documentTools = require('@arbidocs/react/document-tools');
12
+
13
+ var TOUCH = "pointer-coarse:min-h-11";
14
+ function AnnotateButton({ active, onClick, compact }) {
15
+ return /* @__PURE__ */ jsxRuntime.jsxs(
16
+ ui.Button,
17
+ {
18
+ type: "button",
19
+ variant: active ? "default" : "outline",
20
+ size: compact ? "icon" : "sm",
21
+ "aria-pressed": active,
22
+ title: "Annotate: highlight, comment, stamp, redact",
23
+ "aria-label": "Annotate",
24
+ "data-testid": "annotate-toggle",
25
+ className: TOUCH,
26
+ onClick,
27
+ children: [
28
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PencilLine, { className: "size-4" }),
29
+ !compact && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1", children: "Annotate" })
30
+ ]
31
+ }
32
+ );
33
+ }
34
+ function ShowOriginalButton({ active, onClick, compact }) {
35
+ return /* @__PURE__ */ jsxRuntime.jsxs(
36
+ ui.Button,
37
+ {
38
+ type: "button",
39
+ variant: active ? "default" : "outline",
40
+ size: compact ? "icon" : "sm",
41
+ "aria-pressed": active,
42
+ title: active ? "Show the markup again" : "Show the original, without markup",
43
+ "aria-label": "Show original",
44
+ "data-testid": "markup-show-original",
45
+ className: TOUCH,
46
+ onClick,
47
+ children: [
48
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileText, { className: "size-4" }),
49
+ !compact && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1", children: "Show original" })
50
+ ]
51
+ }
52
+ );
53
+ }
54
+ function DownloadMarkupButton({
55
+ onClick,
56
+ disabledReason
57
+ }) {
58
+ const button = /* @__PURE__ */ jsxRuntime.jsx(
59
+ ui.Button,
60
+ {
61
+ type: "button",
62
+ variant: "outline",
63
+ size: "icon",
64
+ title: disabledReason ?? "Download with markup: the PDF with its annotations (opens in Acrobat or Preview)",
65
+ "aria-label": "Download with markup",
66
+ "aria-description": disabledReason,
67
+ disabled: !!disabledReason,
68
+ "data-testid": "markup-download",
69
+ className: TOUCH,
70
+ onClick,
71
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Download, { className: "size-4" })
72
+ }
73
+ );
74
+ return disabledReason ? /* @__PURE__ */ jsxRuntime.jsx("span", { title: disabledReason, className: "inline-flex", "data-testid": "markup-download-locked", children: button }) : button;
75
+ }
76
+ function SignedEditNote() {
77
+ return /* @__PURE__ */ jsxRuntime.jsx(
78
+ "p",
79
+ {
80
+ className: "border-b px-3 py-1.5 text-xs text-muted-foreground",
81
+ "data-testid": "signed-edit-note",
82
+ children: "Editing creates a new unsigned version"
83
+ }
84
+ );
85
+ }
86
+ function SignButton({ active, onClick, compact }) {
87
+ return /* @__PURE__ */ jsxRuntime.jsxs(
88
+ ui.Button,
89
+ {
90
+ type: "button",
91
+ variant: active ? "default" : "outline",
92
+ size: compact ? "icon" : "sm",
93
+ "aria-pressed": active,
94
+ title: "Sign document",
95
+ "aria-label": "Sign",
96
+ "data-testid": "sign-document-button",
97
+ className: TOUCH,
98
+ onClick,
99
+ children: [
100
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PenLine, { className: "size-4" }),
101
+ !compact && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1", children: "Sign" })
102
+ ]
103
+ }
104
+ );
105
+ }
106
+ var BAR = "flex flex-wrap items-center justify-between gap-2 border-b px-3 py-2 text-xs";
107
+ var LINK = "font-medium text-primary hover:underline disabled:opacity-50 disabled:no-underline pointer-coarse:min-h-11";
108
+ function MarkupNotices({ legacyPrompt, olderNote, onOpenVersion }) {
109
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
110
+ legacyPrompt && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: BAR, role: "status", "data-testid": "markup-migration-prompt", children: [
111
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
112
+ legacyPrompt.count,
113
+ " annotation",
114
+ legacyPrompt.count === 1 ? "" : "s",
115
+ " on this document",
116
+ legacyPrompt.count === 1 ? " is" : " are",
117
+ " saved only in this browser. Add",
118
+ " ",
119
+ legacyPrompt.count === 1 ? "it" : "them",
120
+ " to the shared markup, where everyone with access sees ",
121
+ legacyPrompt.count === 1 ? "it" : "them",
122
+ "?"
123
+ ] }),
124
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-3", children: [
125
+ /* @__PURE__ */ jsxRuntime.jsx(
126
+ "button",
127
+ {
128
+ type: "button",
129
+ className: LINK,
130
+ disabled: legacyPrompt.busy,
131
+ "data-testid": "markup-migration-add",
132
+ onClick: legacyPrompt.add,
133
+ children: legacyPrompt.busy ? "Adding\u2026" : "Add to shared markup"
134
+ }
135
+ ),
136
+ /* @__PURE__ */ jsxRuntime.jsx(
137
+ "button",
138
+ {
139
+ type: "button",
140
+ className: LINK,
141
+ disabled: legacyPrompt.busy,
142
+ "data-testid": "markup-migration-discard",
143
+ onClick: legacyPrompt.discard,
144
+ children: "Discard"
145
+ }
146
+ )
147
+ ] })
148
+ ] }),
149
+ olderNote && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: BAR, "data-testid": "markup-older-version-note", children: [
150
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
151
+ "The markup is on version ",
152
+ olderNote.version,
153
+ ". This version started without it.",
154
+ olderNote.signed && /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-testid": "markup-older-version-signed", children: [
155
+ " ",
156
+ "It is signed: comments copied here are kept beside it, and the signed PDF does not change."
157
+ ] })
158
+ ] }),
159
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-3", children: [
160
+ /* @__PURE__ */ jsxRuntime.jsxs(
161
+ "button",
162
+ {
163
+ type: "button",
164
+ className: LINK,
165
+ "data-testid": "markup-open-older-version",
166
+ onClick: () => onOpenVersion(olderNote.version),
167
+ children: [
168
+ "Open version ",
169
+ olderNote.version
170
+ ]
171
+ }
172
+ ),
173
+ /* @__PURE__ */ jsxRuntime.jsx(
174
+ "button",
175
+ {
176
+ type: "button",
177
+ className: LINK,
178
+ disabled: olderNote.busy,
179
+ "data-testid": "markup-copy-open-threads",
180
+ title: "Copy the unresolved comment threads onto this version (redactions never carry over)",
181
+ onClick: olderNote.copy,
182
+ children: olderNote.busy ? "Copying\u2026" : "Copy open comments here"
183
+ }
184
+ )
185
+ ] })
186
+ ] })
187
+ ] });
188
+ }
189
+ function MarkupViewNote({ showOriginal, onToggle }) {
190
+ return /* @__PURE__ */ jsxRuntime.jsxs(chunk4DVEGXZQ_cjs.ViewerStatusNote, { testId: "markup-view-note", children: [
191
+ showOriginal ? "Original, without markup" : "With markup",
192
+ " \xB7 ",
193
+ /* @__PURE__ */ jsxRuntime.jsx(
194
+ "button",
195
+ {
196
+ type: "button",
197
+ className: "font-medium text-primary hover:underline pointer-coarse:min-h-11",
198
+ "data-testid": "markup-view-note-toggle",
199
+ onClick: onToggle,
200
+ children: showOriginal ? "Show markup" : "Show original"
201
+ }
202
+ )
203
+ ] });
204
+ }
205
+ function SignDocumentDialog({
206
+ open,
207
+ onOpenChange,
208
+ documentId,
209
+ pdfBlob,
210
+ appearance
211
+ }) {
212
+ const { user, notify, openDocument, emailDocument } = documentTools.useDocumentTools();
213
+ const [name, setName] = react.useState(() => user?.name ?? "");
214
+ const [includeDate, setIncludeDate] = react.useState(false);
215
+ const [password, setPassword] = react.useState("");
216
+ const [error, setError] = react.useState(null);
217
+ const sign = documentTools.useSignDocument();
218
+ const signer = { name };
219
+ const handleSubmit = async (e) => {
220
+ e.preventDefault();
221
+ if (!user?.email) return;
222
+ setError(null);
223
+ try {
224
+ const result = await sign.mutateAsync({
225
+ documentId,
226
+ pdfBlob,
227
+ email: user.email,
228
+ password,
229
+ signer,
230
+ appearance,
231
+ includeDate
232
+ });
233
+ const signedId = result.doc_ext_id;
234
+ notify(
235
+ `Signed. The signed copy is saved as version ${result.version}.`,
236
+ "success",
237
+ emailDocument ? { action: { label: "Email it", onClick: () => emailDocument(signedId) } } : result.signature.certificate_url ? {
238
+ action: {
239
+ label: "View certificate",
240
+ onClick: () => {
241
+ window.open(result.signature.certificate_url, "_blank", "noopener,noreferrer");
242
+ }
243
+ }
244
+ } : void 0
245
+ );
246
+ setPassword("");
247
+ onOpenChange(false);
248
+ openDocument?.(signedId);
249
+ } catch (err) {
250
+ setError(err instanceof Error ? err.message : "Signing failed");
251
+ }
252
+ };
253
+ return /* @__PURE__ */ jsxRuntime.jsx(
254
+ chunk2ZTONLT5_cjs.ModalScaffold,
255
+ {
256
+ open,
257
+ onOpenChange: (next) => !sign.isPending && onOpenChange(next),
258
+ title: "Sign document",
259
+ description: "Sign this document electronically. The signed copy is saved as a new version.",
260
+ showDescription: true,
261
+ testId: "sign-document-dialog",
262
+ children: /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handleSubmit, children: [
263
+ /* @__PURE__ */ jsxRuntime.jsxs(chunk2ZTONLT5_cjs.ModalScaffold.Body, { children: [
264
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
265
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { htmlFor: "sign-name", children: "Name" }),
266
+ /* @__PURE__ */ jsxRuntime.jsx(
267
+ ui.Input,
268
+ {
269
+ id: "sign-name",
270
+ value: name,
271
+ onChange: (e) => setName(e.target.value),
272
+ "data-testid": "sign-document-name-input",
273
+ required: true
274
+ }
275
+ )
276
+ ] }),
277
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 pointer-coarse:min-h-11", children: [
278
+ /* @__PURE__ */ jsxRuntime.jsx(
279
+ ui.Checkbox,
280
+ {
281
+ id: "sign-include-date",
282
+ checked: includeDate,
283
+ onCheckedChange: (checked) => setIncludeDate(checked === true),
284
+ "data-testid": "sign-document-include-date"
285
+ }
286
+ ),
287
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { htmlFor: "sign-include-date", className: "font-normal", children: "Include date" })
288
+ ] }),
289
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-muted-foreground", "data-testid": "sign-document-appearance-note", children: [
290
+ "Only your signature",
291
+ includeDate ? " and the date appear" : " appears",
292
+ " on the page. Anyone can click it to check it."
293
+ ] }),
294
+ name.trim() && /* @__PURE__ */ jsxRuntime.jsx(
295
+ "blockquote",
296
+ {
297
+ className: "border-l-2 border-border pl-3 text-sm text-muted-foreground",
298
+ "data-testid": "sign-document-intent",
299
+ children: documentTools.intentText(signer)
300
+ }
301
+ ),
302
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
303
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { htmlFor: "sign-password", children: "Password" }),
304
+ /* @__PURE__ */ jsxRuntime.jsx(
305
+ ui.Input,
306
+ {
307
+ id: "sign-password",
308
+ type: "password",
309
+ autoComplete: "current-password",
310
+ value: password,
311
+ onChange: (e) => setPassword(e.target.value),
312
+ "data-testid": "sign-document-password-input",
313
+ required: true
314
+ }
315
+ )
316
+ ] }),
317
+ error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-red-text", role: "alert", "data-testid": "sign-document-error", children: error })
318
+ ] }),
319
+ /* @__PURE__ */ jsxRuntime.jsxs(chunk2ZTONLT5_cjs.ModalScaffold.Footer, { children: [
320
+ /* @__PURE__ */ jsxRuntime.jsx(
321
+ ui.Button,
322
+ {
323
+ type: "button",
324
+ variant: "outline",
325
+ onClick: () => onOpenChange(false),
326
+ disabled: sign.isPending,
327
+ children: "Cancel"
328
+ }
329
+ ),
330
+ /* @__PURE__ */ jsxRuntime.jsx(
331
+ ui.Button,
332
+ {
333
+ type: "submit",
334
+ disabled: sign.isPending || !name.trim() || !password,
335
+ "data-testid": "sign-document-submit-button",
336
+ children: sign.isPending ? "Signing..." : "Sign"
337
+ }
338
+ )
339
+ ] })
340
+ ] })
341
+ }
342
+ );
343
+ }
344
+ function formatSignedAt(iso) {
345
+ const date = new Date(iso);
346
+ if (Number.isNaN(date.getTime())) return iso;
347
+ return date.toLocaleString([], { dateStyle: "medium", timeStyle: "short" });
348
+ }
349
+ function Row({ label, field, children }) {
350
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[5.5rem_1fr] gap-2", children: [
351
+ /* @__PURE__ */ jsxRuntime.jsx("dt", { className: "text-muted-foreground", children: label }),
352
+ /* @__PURE__ */ jsxRuntime.jsx("dd", { className: "min-w-0 break-words", "data-testid": `signature-detail-${field}`, children })
353
+ ] });
354
+ }
355
+ function SignatureStatus({
356
+ status,
357
+ formatDate = formatSignedAt,
358
+ certificateUrl = documentTools.defaultCertificateUrl
359
+ }) {
360
+ const signatures = status.signatures ?? [];
361
+ const isCounterSigned = signatures.length > 1;
362
+ return /* @__PURE__ */ jsxRuntime.jsxs(ui.Popover, { children: [
363
+ /* @__PURE__ */ jsxRuntime.jsx(ui.PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
364
+ "button",
365
+ {
366
+ type: "button",
367
+ className: "flex-shrink-0 text-sm text-muted-foreground underline decoration-dotted underline-offset-4 hover:text-foreground pointer-coarse:min-h-11",
368
+ "data-testid": "document-signature-status",
369
+ "aria-label": `${status.intact ? "Signed, locked" : "Modified after signing"}: show signature details`,
370
+ children: status.intact ? "Signed \u2014 locked" : "Modified after signing"
371
+ }
372
+ ) }),
373
+ /* @__PURE__ */ jsxRuntime.jsxs(
374
+ ui.PopoverContent,
375
+ {
376
+ className: "max-h-[70vh] w-80 overflow-y-auto p-3 text-sm",
377
+ align: "start",
378
+ "data-testid": "signature-details",
379
+ children: [
380
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-2 font-medium", "data-testid": "signature-details-title", children: isCounterSigned ? `Electronic signatures (${signatures.length})` : "Electronic signature" }),
381
+ signatures.map((signature, index) => /* @__PURE__ */ jsxRuntime.jsxs(
382
+ "dl",
383
+ {
384
+ className: `mb-3 space-y-1 ${index > 0 ? "border-t border-border pt-2" : ""}`,
385
+ "data-testid": `signature-item-${index}`,
386
+ children: [
387
+ /* @__PURE__ */ jsxRuntime.jsx(Row, { label: "Signed by", field: "signer", children: signature.signer_name || signature.signer_email }),
388
+ /* @__PURE__ */ jsxRuntime.jsx(Row, { label: "On", field: "time", children: formatDate(signature.signed_at) }),
389
+ /* @__PURE__ */ jsxRuntime.jsx("dd", { children: /* @__PURE__ */ jsxRuntime.jsx(
390
+ "a",
391
+ {
392
+ href: signature.certificate_url || certificateUrl(signature.reference),
393
+ target: "_blank",
394
+ rel: "noopener noreferrer",
395
+ className: "inline-flex items-center font-medium text-primary hover:underline pointer-coarse:min-h-11",
396
+ "data-testid": `signature-certificate-link-${index}`,
397
+ children: "View certificate"
398
+ }
399
+ ) })
400
+ ]
401
+ },
402
+ signature.reference
403
+ )),
404
+ /* @__PURE__ */ jsxRuntime.jsx(
405
+ "p",
406
+ {
407
+ className: `border-t border-border pt-2 ${status.intact ? "" : "text-red-text"}`,
408
+ "data-testid": "signature-detail-intact",
409
+ children: status.intact ? isCounterSigned ? "\u2713 Unchanged since the last signature" : "\u2713 Unchanged since signing" : "\u2717 Changed after it was signed"
410
+ }
411
+ ),
412
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-xs text-muted-foreground", "data-testid": "signature-detail-locked", children: "Locked: only further signatures can be added." })
413
+ ]
414
+ }
415
+ )
416
+ ] });
417
+ }
418
+ function Frame({ children }) {
419
+ return /* @__PURE__ */ jsxRuntime.jsxs(
420
+ "main",
421
+ {
422
+ className: "mx-auto w-full max-w-xl px-4 py-10 text-foreground",
423
+ "data-testid": "signature-certificate",
424
+ children: [
425
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "mb-6 text-xl font-semibold", children: "Signature certificate" }),
426
+ children
427
+ ]
428
+ }
429
+ );
430
+ }
431
+ function copyResult(name, match) {
432
+ if (match.kind === "current") return `\u2713 ${name} is the signed document, unchanged.`;
433
+ if (match.kind === "earlier") {
434
+ return `\u2713 ${name}: this is the version signed by ${match.signature.signer_name || "an ARBI user"}.`;
435
+ }
436
+ return `\u2717 ${name} is not the signed document: it differs from what was signed.`;
437
+ }
438
+ function SignatureCertificate({
439
+ reference,
440
+ verification,
441
+ isLoading = false,
442
+ error,
443
+ isErrorTransient = false,
444
+ formatDate = formatSignedAt,
445
+ allowCopyCheck = true
446
+ }) {
447
+ const [copy, setCopy] = react.useState({ state: "idle" });
448
+ const [dragging, setDragging] = react.useState(false);
449
+ const input = react.useRef(null);
450
+ if (isLoading) {
451
+ return /* @__PURE__ */ jsxRuntime.jsx(Frame, { children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground", "data-testid": "signature-certificate-loading", children: "Checking the signature\u2026" }) });
452
+ }
453
+ if (error || !verification) {
454
+ return /* @__PURE__ */ jsxRuntime.jsx(Frame, { children: /* @__PURE__ */ jsxRuntime.jsx(
455
+ "p",
456
+ {
457
+ className: isErrorTransient ? "text-muted-foreground" : "text-red-text",
458
+ role: isErrorTransient ? "status" : "alert",
459
+ "data-testid": "signature-certificate-error",
460
+ children: error || "The signature could not be checked."
461
+ }
462
+ ) });
463
+ }
464
+ const [first, ...counter] = verification.signatures;
465
+ const check = async (file) => {
466
+ if (!file) return;
467
+ setCopy({ state: "checking", name: file.name });
468
+ try {
469
+ setCopy({ state: "done", name: file.name, match: await documentTools.matchSignedCopy(file, verification) });
470
+ } catch {
471
+ setCopy({ state: "failed", name: file.name });
472
+ }
473
+ };
474
+ const onDrop = (e) => {
475
+ e.preventDefault();
476
+ setDragging(false);
477
+ void check(e.dataTransfer.files[0]);
478
+ };
479
+ return /* @__PURE__ */ jsxRuntime.jsxs(Frame, { children: [
480
+ /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "space-y-3", children: [
481
+ first && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-base", "data-testid": "signature-certificate-signer", children: [
482
+ "Signed by ",
483
+ /* @__PURE__ */ jsxRuntime.jsx("strong", { children: first.signer_name || "an ARBI user" }),
484
+ " on",
485
+ " ",
486
+ formatDate(first.signed_at)
487
+ ] }),
488
+ counter.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "space-y-1 text-sm", "data-testid": "signature-certificate-counter", children: counter.map((s, i) => /* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
489
+ "Also signed by ",
490
+ /* @__PURE__ */ jsxRuntime.jsx("strong", { children: s.signer_name || "an ARBI user" }),
491
+ " on",
492
+ " ",
493
+ formatDate(s.signed_at)
494
+ ] }, `${s.sha256}-${i}`)) }),
495
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: "ARBI checks that this document hasn\u2019t changed since it was signed. If anything changed, this check fails." }),
496
+ /* @__PURE__ */ jsxRuntime.jsx(
497
+ "p",
498
+ {
499
+ className: ui.cn(
500
+ "rounded-md border px-3 py-2 font-medium",
501
+ verification.intact ? "border-green-border bg-green-bg text-green-text" : "border-red-text text-red-text"
502
+ ),
503
+ role: "status",
504
+ "data-testid": "signature-certificate-result",
505
+ "data-intact": verification.intact,
506
+ children: verification.intact ? "\u2713 Unchanged since signing" : "\u2717 Changed since signing: this is not the document that was signed"
507
+ }
508
+ )
509
+ ] }),
510
+ allowCopyCheck && /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "mt-8 space-y-2", children: [
511
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-sm font-medium", children: "Check your copy" }),
512
+ /* @__PURE__ */ jsxRuntime.jsxs(
513
+ "div",
514
+ {
515
+ role: "button",
516
+ tabIndex: 0,
517
+ className: ui.cn(
518
+ "flex min-h-24 cursor-pointer flex-col items-center justify-center rounded-md border border-dashed px-4 py-6 text-center text-sm text-muted-foreground pointer-coarse:min-h-32",
519
+ dragging && "border-primary bg-muted"
520
+ ),
521
+ "data-testid": "signature-certificate-dropzone",
522
+ onClick: () => input.current?.click(),
523
+ onKeyDown: (e) => {
524
+ if (e.key === "Enter" || e.key === " ") {
525
+ e.preventDefault();
526
+ input.current?.click();
527
+ }
528
+ },
529
+ onDragOver: (e) => {
530
+ e.preventDefault();
531
+ setDragging(true);
532
+ },
533
+ onDragLeave: () => setDragging(false),
534
+ onDrop,
535
+ children: [
536
+ "Drop the PDF you were sent here, or choose it",
537
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mt-1 text-xs", children: "It is checked in this browser and never uploaded." }),
538
+ /* @__PURE__ */ jsxRuntime.jsx(
539
+ "input",
540
+ {
541
+ ref: input,
542
+ type: "file",
543
+ accept: "application/pdf,.pdf",
544
+ className: "sr-only",
545
+ "data-testid": "signature-certificate-file-input",
546
+ onChange: (e) => void check(e.target.files?.[0])
547
+ }
548
+ )
549
+ ]
550
+ }
551
+ ),
552
+ copy.state !== "idle" && /* @__PURE__ */ jsxRuntime.jsx(
553
+ "p",
554
+ {
555
+ className: ui.cn(
556
+ "text-sm",
557
+ copy.state === "done" && copy.match.kind !== "none" && "text-green-text",
558
+ (copy.state === "done" && copy.match.kind === "none" || copy.state === "failed") && "text-red-text"
559
+ ),
560
+ role: "status",
561
+ "data-testid": "signature-certificate-copy-result",
562
+ children: copy.state === "checking" ? `Checking ${copy.name}\u2026` : copy.state === "failed" ? `${copy.name} could not be read.` : copyResult(copy.name, copy.match)
563
+ }
564
+ )
565
+ ] }),
566
+ reference && /* @__PURE__ */ jsxRuntime.jsxs(
567
+ "p",
568
+ {
569
+ className: "mt-8 text-xs text-muted-foreground",
570
+ "data-testid": "signature-certificate-reference",
571
+ children: [
572
+ "Reference ",
573
+ reference
574
+ ]
575
+ }
576
+ )
577
+ ] });
578
+ }
579
+ var LINK2 = "font-medium text-primary hover:underline pointer-coarse:min-h-11";
580
+ var DEFAULT_VERSION_SNAPSHOT_BAR_LABELS = {
581
+ title: (number) => `${number ? `Version ${number}` : "Saved version"} \xB7 read only`,
582
+ ask: "Ask about this version",
583
+ returnToCurrent: "Return to current version",
584
+ returnToLive: "Return to live document"
585
+ };
586
+ function VersionSnapshotBar({
587
+ versionNumber,
588
+ live = false,
589
+ onAsk,
590
+ onReturn,
591
+ labels: overrides
592
+ }) {
593
+ const labels = { ...DEFAULT_VERSION_SNAPSHOT_BAR_LABELS, ...overrides };
594
+ return /* @__PURE__ */ jsxRuntime.jsxs(
595
+ "div",
596
+ {
597
+ className: "flex items-center justify-between border-b px-3 py-2 text-xs",
598
+ "data-testid": "version-snapshot-bar",
599
+ children: [
600
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: labels.title(versionNumber) }),
601
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-3", children: [
602
+ onAsk && /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: LINK2, "data-testid": "version-snapshot-ask", onClick: onAsk, children: labels.ask }),
603
+ /* @__PURE__ */ jsxRuntime.jsx(
604
+ "button",
605
+ {
606
+ type: "button",
607
+ className: LINK2,
608
+ "data-testid": "version-snapshot-return",
609
+ onClick: onReturn,
610
+ children: live ? labels.returnToLive : labels.returnToCurrent
611
+ }
612
+ )
613
+ ] })
614
+ ]
615
+ }
616
+ );
617
+ }
618
+
619
+ exports.AnnotateButton = AnnotateButton;
620
+ exports.DEFAULT_VERSION_SNAPSHOT_BAR_LABELS = DEFAULT_VERSION_SNAPSHOT_BAR_LABELS;
621
+ exports.DownloadMarkupButton = DownloadMarkupButton;
622
+ exports.MarkupNotices = MarkupNotices;
623
+ exports.MarkupViewNote = MarkupViewNote;
624
+ exports.ShowOriginalButton = ShowOriginalButton;
625
+ exports.SignButton = SignButton;
626
+ exports.SignDocumentDialog = SignDocumentDialog;
627
+ exports.SignatureCertificate = SignatureCertificate;
628
+ exports.SignatureStatus = SignatureStatus;
629
+ exports.SignedEditNote = SignedEditNote;
630
+ exports.VersionSnapshotBar = VersionSnapshotBar;
631
+ exports.formatSignedAt = formatSignedAt;
632
+ //# sourceMappingURL=index.cjs.map
633
+ //# sourceMappingURL=index.cjs.map