@josephomills/esign 0.8.0 → 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 +243 -27
- package/dist/ui/index.cjs.map +1 -1
- package/dist/ui/index.d.cts +20 -0
- package/dist/ui/index.d.ts +20 -0
- package/dist/ui/index.js +243 -27
- 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;
|
|
@@ -341,6 +362,8 @@ function FieldDesigner({
|
|
|
341
362
|
const [failed, setFailed] = useState(false);
|
|
342
363
|
const [selectedId, setSelectedId] = useState(value[0]?.id ?? null);
|
|
343
364
|
const [drawMode, setDrawMode] = useState(false);
|
|
365
|
+
const [pendingType, setPendingType] = useState("signature");
|
|
366
|
+
const [configId, setConfigId] = useState(null);
|
|
344
367
|
const [drag, setDrag] = useState(null);
|
|
345
368
|
const [live, setLive] = useState(null);
|
|
346
369
|
const stageRef = useRef(null);
|
|
@@ -433,15 +456,21 @@ function FieldDesigner({
|
|
|
433
456
|
function onPointerUp() {
|
|
434
457
|
if (drag && live && live.w >= MIN_W && live.h >= MIN_H) {
|
|
435
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";
|
|
436
462
|
const f = {
|
|
437
463
|
id: newId(),
|
|
438
|
-
label:
|
|
464
|
+
label: n === 1 ? base : `${base} ${n}`,
|
|
465
|
+
type: pendingType,
|
|
466
|
+
...isDate ? { dateFormat: DEFAULT_DATE_FORMAT, minDate: null } : {},
|
|
439
467
|
page,
|
|
440
468
|
...live
|
|
441
469
|
};
|
|
442
470
|
onChange([...value, f]);
|
|
443
471
|
setSelectedId(f.id);
|
|
444
472
|
setDrawMode(false);
|
|
473
|
+
if (isDate) setConfigId(f.id);
|
|
445
474
|
} else {
|
|
446
475
|
onChange(value.map((x) => x.id === drag.id ? { ...x, ...live } : x));
|
|
447
476
|
}
|
|
@@ -452,10 +481,15 @@ function FieldDesigner({
|
|
|
452
481
|
function removeField(id) {
|
|
453
482
|
onChange(value.filter((f) => f.id !== id));
|
|
454
483
|
if (selectedId === id) setSelectedId(null);
|
|
484
|
+
if (configId === id) setConfigId(null);
|
|
455
485
|
}
|
|
456
486
|
function rename(id, label) {
|
|
457
487
|
onChange(value.map((f) => f.id === id ? { ...f, label } : f));
|
|
458
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;
|
|
459
493
|
const handle = (id, geom, c) => {
|
|
460
494
|
const cx = c[1] === "w" ? geom.x : geom.x + geom.w;
|
|
461
495
|
const cy = c[0] === "n" ? geom.y : geom.y + geom.h;
|
|
@@ -501,25 +535,35 @@ function FieldDesigner({
|
|
|
501
535
|
flexWrap: "wrap"
|
|
502
536
|
},
|
|
503
537
|
children: [
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
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"
|
|
518
562
|
},
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
),
|
|
522
|
-
/* @__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." }),
|
|
523
567
|
numPages > 1 ? /* @__PURE__ */ jsxs("label", { style: { marginLeft: "auto", fontSize: 13, color: "#374151" }, children: [
|
|
524
568
|
"Page",
|
|
525
569
|
" ",
|
|
@@ -590,8 +634,9 @@ function FieldDesigner({
|
|
|
590
634
|
padding: "0 4px"
|
|
591
635
|
},
|
|
592
636
|
children: [
|
|
593
|
-
"\
|
|
594
|
-
|
|
637
|
+
f.type === "date" ? "\u{1F4C5}" : "\u270D",
|
|
638
|
+
" ",
|
|
639
|
+
f.label || (f.type === "date" ? "Date" : "Signature")
|
|
595
640
|
]
|
|
596
641
|
}
|
|
597
642
|
)
|
|
@@ -630,7 +675,39 @@ function FieldDesigner({
|
|
|
630
675
|
},
|
|
631
676
|
children: "\xD7"
|
|
632
677
|
}
|
|
633
|
-
)
|
|
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
|
|
634
711
|
] }) : null
|
|
635
712
|
] }, f.id);
|
|
636
713
|
}),
|
|
@@ -652,11 +729,99 @@ function FieldDesigner({
|
|
|
652
729
|
) : null
|
|
653
730
|
]
|
|
654
731
|
}
|
|
655
|
-
)
|
|
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
|
|
656
821
|
] }),
|
|
657
822
|
hideFieldList ? null : /* @__PURE__ */ jsxs("div", { style: { flex: "1 1 200px", minWidth: 180, maxWidth: 300 }, children: [
|
|
658
823
|
/* @__PURE__ */ jsxs("p", { style: { fontSize: 13, fontWeight: 600, color: "#374151", margin: "0 0 8px" }, children: [
|
|
659
|
-
"
|
|
824
|
+
"Fields (",
|
|
660
825
|
value.length,
|
|
661
826
|
")"
|
|
662
827
|
] }),
|
|
@@ -678,6 +843,7 @@ function FieldDesigner({
|
|
|
678
843
|
cursor: "pointer"
|
|
679
844
|
},
|
|
680
845
|
children: [
|
|
846
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: 13 }, children: f.type === "date" ? "\u{1F4C5}" : "\u270D" }),
|
|
681
847
|
/* @__PURE__ */ jsx(
|
|
682
848
|
"input",
|
|
683
849
|
{
|
|
@@ -699,6 +865,27 @@ function FieldDesigner({
|
|
|
699
865
|
"p",
|
|
700
866
|
f.page
|
|
701
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,
|
|
702
889
|
/* @__PURE__ */ jsx(
|
|
703
890
|
"button",
|
|
704
891
|
{
|
|
@@ -731,9 +918,12 @@ function SigningExperience(props) {
|
|
|
731
918
|
const primary = props.branding?.primaryColor ?? "#4f46e5";
|
|
732
919
|
const [signaturePng, setSignaturePng] = useState(null);
|
|
733
920
|
const [consent, setConsent] = useState({ signerName: "", consent: false });
|
|
921
|
+
const [dateValues, setDateValues] = useState({});
|
|
734
922
|
const [submitting, setSubmitting] = useState(false);
|
|
735
923
|
const [error, setError] = useState(null);
|
|
736
|
-
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;
|
|
737
927
|
async function submit() {
|
|
738
928
|
if (!canSubmit) return;
|
|
739
929
|
setSubmitting(true);
|
|
@@ -745,7 +935,8 @@ function SigningExperience(props) {
|
|
|
745
935
|
body: JSON.stringify({
|
|
746
936
|
signaturePng,
|
|
747
937
|
signerName: consent.signerName.trim(),
|
|
748
|
-
consent: true
|
|
938
|
+
consent: true,
|
|
939
|
+
dateValues
|
|
749
940
|
})
|
|
750
941
|
});
|
|
751
942
|
if (!res.ok) {
|
|
@@ -790,6 +981,31 @@ function SigningExperience(props) {
|
|
|
790
981
|
/* @__PURE__ */ jsx("label", { style: { fontSize: 13, fontWeight: 600, color: "#374151" }, children: "Your signature" }),
|
|
791
982
|
/* @__PURE__ */ jsx("div", { style: { marginTop: 6 }, children: /* @__PURE__ */ jsx(SignaturePad, { primaryColor: primary, onChange: setSignaturePng }) })
|
|
792
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,
|
|
793
1009
|
/* @__PURE__ */ jsx(ConsentBlock, { value: consent, onChange: setConsent, primaryColor: primary }),
|
|
794
1010
|
error ? /* @__PURE__ */ jsx(
|
|
795
1011
|
"div",
|