@josephomills/esign 0.7.1 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{ports-CkBaAepo.d.cts → ports--YsOnh8H.d.cts} +120 -15
- package/dist/{ports-CkBaAepo.d.ts → ports--YsOnh8H.d.ts} +120 -15
- package/dist/prisma/index.cjs +21 -4
- package/dist/prisma/index.cjs.map +1 -1
- package/dist/prisma/index.d.cts +1 -1
- package/dist/prisma/index.d.ts +1 -1
- package/dist/prisma/index.js +21 -4
- package/dist/prisma/index.js.map +1 -1
- package/dist/server/index.cjs +112 -12
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.d.cts +9 -5
- package/dist/server/index.d.ts +9 -5
- package/dist/server/index.js +108 -13
- package/dist/server/index.js.map +1 -1
- package/dist/ui/index.cjs +246 -29
- package/dist/ui/index.cjs.map +1 -1
- package/dist/ui/index.d.cts +23 -1
- package/dist/ui/index.d.ts +23 -1
- package/dist/ui/index.js +246 -29
- package/dist/ui/index.js.map +1 -1
- package/package.json +1 -1
package/dist/ui/index.js
CHANGED
|
@@ -313,7 +313,7 @@ function PdfViewer({ url, placements, workerSrc, primaryColor = "#4f46e5" }) {
|
|
|
313
313
|
opacity: 0.85,
|
|
314
314
|
whiteSpace: "nowrap"
|
|
315
315
|
},
|
|
316
|
-
children: "\u270D Sign here"
|
|
316
|
+
children: pl.type === "date" ? "\u{1F4C5} Select a date" : "\u270D Sign here"
|
|
317
317
|
}
|
|
318
318
|
)
|
|
319
319
|
},
|
|
@@ -324,6 +324,27 @@ function PdfViewer({ url, placements, workerSrc, primaryColor = "#4f46e5" }) {
|
|
|
324
324
|
)
|
|
325
325
|
] });
|
|
326
326
|
}
|
|
327
|
+
|
|
328
|
+
// src/shared/fields.ts
|
|
329
|
+
var DATE_FORMATS = [
|
|
330
|
+
"DD/MM/YYYY",
|
|
331
|
+
"MM/DD/YYYY",
|
|
332
|
+
"YYYY-MM-DD",
|
|
333
|
+
"D MMM YYYY",
|
|
334
|
+
"Do MMM YYYY",
|
|
335
|
+
"Do MMMM YYYY",
|
|
336
|
+
"MMMM D, YYYY"
|
|
337
|
+
];
|
|
338
|
+
var DEFAULT_DATE_FORMAT = "Do MMMM YYYY";
|
|
339
|
+
var DATE_FORMAT_LABELS = {
|
|
340
|
+
"DD/MM/YYYY": "02/10/2026",
|
|
341
|
+
"MM/DD/YYYY": "10/02/2026",
|
|
342
|
+
"YYYY-MM-DD": "2026-10-02",
|
|
343
|
+
"D MMM YYYY": "2 Oct 2026",
|
|
344
|
+
"Do MMM YYYY": "2nd Oct 2026",
|
|
345
|
+
"Do MMMM YYYY": "2nd October 2026",
|
|
346
|
+
"MMMM D, YYYY": "October 2, 2026"
|
|
347
|
+
};
|
|
327
348
|
var clamp = (v, min, max) => Math.min(Math.max(v, min), max);
|
|
328
349
|
var MIN_W = 0.04;
|
|
329
350
|
var MIN_H = 0.02;
|
|
@@ -333,13 +354,16 @@ function FieldDesigner({
|
|
|
333
354
|
value,
|
|
334
355
|
onChange,
|
|
335
356
|
workerSrc,
|
|
336
|
-
primaryColor = "#4f46e5"
|
|
357
|
+
primaryColor = "#4f46e5",
|
|
358
|
+
hideFieldList = false
|
|
337
359
|
}) {
|
|
338
360
|
const [numPages, setNumPages] = useState(0);
|
|
339
361
|
const [page, setPage] = useState(value[0]?.page ?? 1);
|
|
340
362
|
const [failed, setFailed] = useState(false);
|
|
341
363
|
const [selectedId, setSelectedId] = useState(value[0]?.id ?? null);
|
|
342
364
|
const [drawMode, setDrawMode] = useState(false);
|
|
365
|
+
const [pendingType, setPendingType] = useState("signature");
|
|
366
|
+
const [configId, setConfigId] = useState(null);
|
|
343
367
|
const [drag, setDrag] = useState(null);
|
|
344
368
|
const [live, setLive] = useState(null);
|
|
345
369
|
const stageRef = useRef(null);
|
|
@@ -432,15 +456,21 @@ function FieldDesigner({
|
|
|
432
456
|
function onPointerUp() {
|
|
433
457
|
if (drag && live && live.w >= MIN_W && live.h >= MIN_H) {
|
|
434
458
|
if (drag.mode === "new") {
|
|
459
|
+
const isDate = pendingType === "date";
|
|
460
|
+
const n = value.filter((v) => v.type === pendingType).length + 1;
|
|
461
|
+
const base = isDate ? "Date" : "Signature";
|
|
435
462
|
const f = {
|
|
436
463
|
id: newId(),
|
|
437
|
-
label:
|
|
464
|
+
label: n === 1 ? base : `${base} ${n}`,
|
|
465
|
+
type: pendingType,
|
|
466
|
+
...isDate ? { dateFormat: DEFAULT_DATE_FORMAT, minDate: null } : {},
|
|
438
467
|
page,
|
|
439
468
|
...live
|
|
440
469
|
};
|
|
441
470
|
onChange([...value, f]);
|
|
442
471
|
setSelectedId(f.id);
|
|
443
472
|
setDrawMode(false);
|
|
473
|
+
if (isDate) setConfigId(f.id);
|
|
444
474
|
} else {
|
|
445
475
|
onChange(value.map((x) => x.id === drag.id ? { ...x, ...live } : x));
|
|
446
476
|
}
|
|
@@ -451,10 +481,15 @@ function FieldDesigner({
|
|
|
451
481
|
function removeField(id) {
|
|
452
482
|
onChange(value.filter((f) => f.id !== id));
|
|
453
483
|
if (selectedId === id) setSelectedId(null);
|
|
484
|
+
if (configId === id) setConfigId(null);
|
|
454
485
|
}
|
|
455
486
|
function rename(id, label) {
|
|
456
487
|
onChange(value.map((f) => f.id === id ? { ...f, label } : f));
|
|
457
488
|
}
|
|
489
|
+
function setConfig(id, patch) {
|
|
490
|
+
onChange(value.map((f) => f.id === id ? { ...f, ...patch } : f));
|
|
491
|
+
}
|
|
492
|
+
const configField = value.find((f) => f.id === configId && f.type === "date") ?? null;
|
|
458
493
|
const handle = (id, geom, c) => {
|
|
459
494
|
const cx = c[1] === "w" ? geom.x : geom.x + geom.w;
|
|
460
495
|
const cy = c[0] === "n" ? geom.y : geom.y + geom.h;
|
|
@@ -500,25 +535,35 @@ function FieldDesigner({
|
|
|
500
535
|
flexWrap: "wrap"
|
|
501
536
|
},
|
|
502
537
|
children: [
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
538
|
+
["signature", "date"].map((t) => {
|
|
539
|
+
const active = drawMode && pendingType === t;
|
|
540
|
+
return /* @__PURE__ */ jsx(
|
|
541
|
+
"button",
|
|
542
|
+
{
|
|
543
|
+
type: "button",
|
|
544
|
+
onClick: () => {
|
|
545
|
+
if (active) setDrawMode(false);
|
|
546
|
+
else {
|
|
547
|
+
setPendingType(t);
|
|
548
|
+
setDrawMode(true);
|
|
549
|
+
}
|
|
550
|
+
},
|
|
551
|
+
style: {
|
|
552
|
+
fontSize: 13,
|
|
553
|
+
fontWeight: 600,
|
|
554
|
+
padding: "5px 12px",
|
|
555
|
+
borderRadius: 6,
|
|
556
|
+
border: `1px solid ${primaryColor}`,
|
|
557
|
+
background: active ? primaryColor : "#fff",
|
|
558
|
+
color: active ? "#fff" : primaryColor,
|
|
559
|
+
cursor: "pointer"
|
|
560
|
+
},
|
|
561
|
+
children: t === "date" ? "+ Date" : "+ Signature"
|
|
517
562
|
},
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
),
|
|
521
|
-
/* @__PURE__ */ jsx("span", { style: { fontSize: 12, color: "#6b7280" }, children: "or drag on the page
|
|
563
|
+
t
|
|
564
|
+
);
|
|
565
|
+
}),
|
|
566
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: 12, color: "#6b7280" }, children: drawMode ? `Drag a ${pendingType} box on the page\u2026` : "or drag on the page." }),
|
|
522
567
|
numPages > 1 ? /* @__PURE__ */ jsxs("label", { style: { marginLeft: "auto", fontSize: 13, color: "#374151" }, children: [
|
|
523
568
|
"Page",
|
|
524
569
|
" ",
|
|
@@ -589,8 +634,9 @@ function FieldDesigner({
|
|
|
589
634
|
padding: "0 4px"
|
|
590
635
|
},
|
|
591
636
|
children: [
|
|
592
|
-
"\
|
|
593
|
-
|
|
637
|
+
f.type === "date" ? "\u{1F4C5}" : "\u270D",
|
|
638
|
+
" ",
|
|
639
|
+
f.label || (f.type === "date" ? "Date" : "Signature")
|
|
594
640
|
]
|
|
595
641
|
}
|
|
596
642
|
)
|
|
@@ -629,7 +675,39 @@ function FieldDesigner({
|
|
|
629
675
|
},
|
|
630
676
|
children: "\xD7"
|
|
631
677
|
}
|
|
632
|
-
)
|
|
678
|
+
),
|
|
679
|
+
f.type === "date" ? /* @__PURE__ */ jsx(
|
|
680
|
+
"button",
|
|
681
|
+
{
|
|
682
|
+
type: "button",
|
|
683
|
+
"aria-label": `Configure ${f.label}`,
|
|
684
|
+
onPointerDown: (e) => e.stopPropagation(),
|
|
685
|
+
onClick: (e) => {
|
|
686
|
+
e.stopPropagation();
|
|
687
|
+
setConfigId(f.id);
|
|
688
|
+
},
|
|
689
|
+
style: {
|
|
690
|
+
position: "absolute",
|
|
691
|
+
left: `${geom.x * 100}%`,
|
|
692
|
+
top: `${geom.y * 100}%`,
|
|
693
|
+
transform: "translate(-50%, -50%)",
|
|
694
|
+
marginTop: -18,
|
|
695
|
+
width: 22,
|
|
696
|
+
height: 22,
|
|
697
|
+
borderRadius: "50%",
|
|
698
|
+
background: "#fff",
|
|
699
|
+
color: primaryColor,
|
|
700
|
+
border: `2px solid ${primaryColor}`,
|
|
701
|
+
boxShadow: "0 1px 3px rgba(0,0,0,0.3)",
|
|
702
|
+
fontSize: 12,
|
|
703
|
+
lineHeight: "14px",
|
|
704
|
+
cursor: "pointer",
|
|
705
|
+
padding: 0,
|
|
706
|
+
touchAction: "none"
|
|
707
|
+
},
|
|
708
|
+
children: "\u2699"
|
|
709
|
+
}
|
|
710
|
+
) : null
|
|
633
711
|
] }) : null
|
|
634
712
|
] }, f.id);
|
|
635
713
|
}),
|
|
@@ -651,11 +729,99 @@ function FieldDesigner({
|
|
|
651
729
|
) : null
|
|
652
730
|
]
|
|
653
731
|
}
|
|
654
|
-
)
|
|
732
|
+
),
|
|
733
|
+
configField ? /* @__PURE__ */ jsxs(
|
|
734
|
+
"div",
|
|
735
|
+
{
|
|
736
|
+
style: {
|
|
737
|
+
marginTop: 10,
|
|
738
|
+
border: `1px solid ${primaryColor}66`,
|
|
739
|
+
borderRadius: 8,
|
|
740
|
+
padding: 12,
|
|
741
|
+
background: "#fff",
|
|
742
|
+
fontSize: 13,
|
|
743
|
+
color: "#374151"
|
|
744
|
+
},
|
|
745
|
+
children: [
|
|
746
|
+
/* @__PURE__ */ jsxs(
|
|
747
|
+
"div",
|
|
748
|
+
{
|
|
749
|
+
style: {
|
|
750
|
+
display: "flex",
|
|
751
|
+
alignItems: "center",
|
|
752
|
+
justifyContent: "space-between",
|
|
753
|
+
marginBottom: 8
|
|
754
|
+
},
|
|
755
|
+
children: [
|
|
756
|
+
/* @__PURE__ */ jsxs("strong", { children: [
|
|
757
|
+
"\u{1F4C5} ",
|
|
758
|
+
configField.label || "Date"
|
|
759
|
+
] }),
|
|
760
|
+
/* @__PURE__ */ jsx(
|
|
761
|
+
"button",
|
|
762
|
+
{
|
|
763
|
+
type: "button",
|
|
764
|
+
onClick: () => setConfigId(null),
|
|
765
|
+
style: {
|
|
766
|
+
fontSize: 12,
|
|
767
|
+
padding: "3px 10px",
|
|
768
|
+
borderRadius: 6,
|
|
769
|
+
border: `1px solid ${primaryColor}`,
|
|
770
|
+
background: primaryColor,
|
|
771
|
+
color: "#fff",
|
|
772
|
+
cursor: "pointer"
|
|
773
|
+
},
|
|
774
|
+
children: "Done"
|
|
775
|
+
}
|
|
776
|
+
)
|
|
777
|
+
]
|
|
778
|
+
}
|
|
779
|
+
),
|
|
780
|
+
/* @__PURE__ */ jsxs("label", { style: { display: "block", marginBottom: 8 }, children: [
|
|
781
|
+
"Display format",
|
|
782
|
+
/* @__PURE__ */ jsx(
|
|
783
|
+
"select",
|
|
784
|
+
{
|
|
785
|
+
value: configField.dateFormat ?? DEFAULT_DATE_FORMAT,
|
|
786
|
+
onChange: (e) => setConfig(configField.id, { dateFormat: e.target.value }),
|
|
787
|
+
style: {
|
|
788
|
+
display: "block",
|
|
789
|
+
marginTop: 4,
|
|
790
|
+
width: "100%",
|
|
791
|
+
padding: "4px 6px",
|
|
792
|
+
borderRadius: 6,
|
|
793
|
+
border: "1px solid #d1d5db"
|
|
794
|
+
},
|
|
795
|
+
children: DATE_FORMATS.map((fmt) => /* @__PURE__ */ jsx("option", { value: fmt, children: DATE_FORMAT_LABELS[fmt] }, fmt))
|
|
796
|
+
}
|
|
797
|
+
)
|
|
798
|
+
] }),
|
|
799
|
+
/* @__PURE__ */ jsxs("label", { style: { display: "block" }, children: [
|
|
800
|
+
"Earliest date",
|
|
801
|
+
/* @__PURE__ */ jsx(
|
|
802
|
+
"input",
|
|
803
|
+
{
|
|
804
|
+
type: "date",
|
|
805
|
+
value: configField.minDate ?? "",
|
|
806
|
+
onChange: (e) => setConfig(configField.id, { minDate: e.target.value || null }),
|
|
807
|
+
style: {
|
|
808
|
+
display: "block",
|
|
809
|
+
marginTop: 4,
|
|
810
|
+
padding: "4px 6px",
|
|
811
|
+
borderRadius: 6,
|
|
812
|
+
border: "1px solid #d1d5db"
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
),
|
|
816
|
+
/* @__PURE__ */ jsx("span", { style: { color: "#9ca3af", fontSize: 11 }, children: "Leave blank to use the document's creation date." })
|
|
817
|
+
] })
|
|
818
|
+
]
|
|
819
|
+
}
|
|
820
|
+
) : null
|
|
655
821
|
] }),
|
|
656
|
-
/* @__PURE__ */ jsxs("div", { style: { flex: "1 1 200px", minWidth: 180, maxWidth: 300 }, children: [
|
|
822
|
+
hideFieldList ? null : /* @__PURE__ */ jsxs("div", { style: { flex: "1 1 200px", minWidth: 180, maxWidth: 300 }, children: [
|
|
657
823
|
/* @__PURE__ */ jsxs("p", { style: { fontSize: 13, fontWeight: 600, color: "#374151", margin: "0 0 8px" }, children: [
|
|
658
|
-
"
|
|
824
|
+
"Fields (",
|
|
659
825
|
value.length,
|
|
660
826
|
")"
|
|
661
827
|
] }),
|
|
@@ -677,6 +843,7 @@ function FieldDesigner({
|
|
|
677
843
|
cursor: "pointer"
|
|
678
844
|
},
|
|
679
845
|
children: [
|
|
846
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: 13 }, children: f.type === "date" ? "\u{1F4C5}" : "\u270D" }),
|
|
680
847
|
/* @__PURE__ */ jsx(
|
|
681
848
|
"input",
|
|
682
849
|
{
|
|
@@ -698,6 +865,27 @@ function FieldDesigner({
|
|
|
698
865
|
"p",
|
|
699
866
|
f.page
|
|
700
867
|
] }),
|
|
868
|
+
f.type === "date" ? /* @__PURE__ */ jsx(
|
|
869
|
+
"button",
|
|
870
|
+
{
|
|
871
|
+
type: "button",
|
|
872
|
+
"aria-label": `Configure ${f.label}`,
|
|
873
|
+
onClick: (e) => {
|
|
874
|
+
e.stopPropagation();
|
|
875
|
+
setConfigId(f.id);
|
|
876
|
+
},
|
|
877
|
+
style: {
|
|
878
|
+
border: "none",
|
|
879
|
+
background: "transparent",
|
|
880
|
+
color: "#6b7280",
|
|
881
|
+
cursor: "pointer",
|
|
882
|
+
fontSize: 13,
|
|
883
|
+
lineHeight: 1,
|
|
884
|
+
padding: 0
|
|
885
|
+
},
|
|
886
|
+
children: "\u2699"
|
|
887
|
+
}
|
|
888
|
+
) : null,
|
|
701
889
|
/* @__PURE__ */ jsx(
|
|
702
890
|
"button",
|
|
703
891
|
{
|
|
@@ -730,9 +918,12 @@ function SigningExperience(props) {
|
|
|
730
918
|
const primary = props.branding?.primaryColor ?? "#4f46e5";
|
|
731
919
|
const [signaturePng, setSignaturePng] = useState(null);
|
|
732
920
|
const [consent, setConsent] = useState({ signerName: "", consent: false });
|
|
921
|
+
const [dateValues, setDateValues] = useState({});
|
|
733
922
|
const [submitting, setSubmitting] = useState(false);
|
|
734
923
|
const [error, setError] = useState(null);
|
|
735
|
-
const
|
|
924
|
+
const dateFields = (props.placements ?? []).filter((p) => p.type === "date" && p.id);
|
|
925
|
+
const allDatesFilled = dateFields.every((f) => dateValues[f.id]);
|
|
926
|
+
const canSubmit = !!signaturePng && consent.consent && consent.signerName.trim().length > 0 && allDatesFilled && !submitting;
|
|
736
927
|
async function submit() {
|
|
737
928
|
if (!canSubmit) return;
|
|
738
929
|
setSubmitting(true);
|
|
@@ -744,7 +935,8 @@ function SigningExperience(props) {
|
|
|
744
935
|
body: JSON.stringify({
|
|
745
936
|
signaturePng,
|
|
746
937
|
signerName: consent.signerName.trim(),
|
|
747
|
-
consent: true
|
|
938
|
+
consent: true,
|
|
939
|
+
dateValues
|
|
748
940
|
})
|
|
749
941
|
});
|
|
750
942
|
if (!res.ok) {
|
|
@@ -789,6 +981,31 @@ function SigningExperience(props) {
|
|
|
789
981
|
/* @__PURE__ */ jsx("label", { style: { fontSize: 13, fontWeight: 600, color: "#374151" }, children: "Your signature" }),
|
|
790
982
|
/* @__PURE__ */ jsx("div", { style: { marginTop: 6 }, children: /* @__PURE__ */ jsx(SignaturePad, { primaryColor: primary, onChange: setSignaturePng }) })
|
|
791
983
|
] }),
|
|
984
|
+
dateFields.length > 0 ? /* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column", gap: 12 }, children: dateFields.map((f) => /* @__PURE__ */ jsxs("div", { children: [
|
|
985
|
+
/* @__PURE__ */ jsxs("label", { style: { fontSize: 13, fontWeight: 600, color: "#374151" }, children: [
|
|
986
|
+
"\u{1F4C5} ",
|
|
987
|
+
f.label || "Date"
|
|
988
|
+
] }),
|
|
989
|
+
/* @__PURE__ */ jsx(
|
|
990
|
+
"input",
|
|
991
|
+
{
|
|
992
|
+
type: "date",
|
|
993
|
+
value: dateValues[f.id] ?? "",
|
|
994
|
+
min: f.minDate ?? void 0,
|
|
995
|
+
onChange: (e) => setDateValues((prev) => ({ ...prev, [f.id]: e.target.value })),
|
|
996
|
+
style: {
|
|
997
|
+
display: "block",
|
|
998
|
+
marginTop: 6,
|
|
999
|
+
padding: "10px 12px",
|
|
1000
|
+
borderRadius: 8,
|
|
1001
|
+
border: "1px solid #d1d5db",
|
|
1002
|
+
fontSize: 15,
|
|
1003
|
+
width: "100%",
|
|
1004
|
+
maxWidth: 280
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
)
|
|
1008
|
+
] }, f.id)) }) : null,
|
|
792
1009
|
/* @__PURE__ */ jsx(ConsentBlock, { value: consent, onChange: setConsent, primaryColor: primary }),
|
|
793
1010
|
error ? /* @__PURE__ */ jsx(
|
|
794
1011
|
"div",
|