@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.cjs
CHANGED
|
@@ -319,7 +319,7 @@ function PdfViewer({ url, placements, workerSrc, primaryColor = "#4f46e5" }) {
|
|
|
319
319
|
opacity: 0.85,
|
|
320
320
|
whiteSpace: "nowrap"
|
|
321
321
|
},
|
|
322
|
-
children: "\u270D Sign here"
|
|
322
|
+
children: pl.type === "date" ? "\u{1F4C5} Select a date" : "\u270D Sign here"
|
|
323
323
|
}
|
|
324
324
|
)
|
|
325
325
|
},
|
|
@@ -330,6 +330,27 @@ function PdfViewer({ url, placements, workerSrc, primaryColor = "#4f46e5" }) {
|
|
|
330
330
|
)
|
|
331
331
|
] });
|
|
332
332
|
}
|
|
333
|
+
|
|
334
|
+
// src/shared/fields.ts
|
|
335
|
+
var DATE_FORMATS = [
|
|
336
|
+
"DD/MM/YYYY",
|
|
337
|
+
"MM/DD/YYYY",
|
|
338
|
+
"YYYY-MM-DD",
|
|
339
|
+
"D MMM YYYY",
|
|
340
|
+
"Do MMM YYYY",
|
|
341
|
+
"Do MMMM YYYY",
|
|
342
|
+
"MMMM D, YYYY"
|
|
343
|
+
];
|
|
344
|
+
var DEFAULT_DATE_FORMAT = "Do MMMM YYYY";
|
|
345
|
+
var DATE_FORMAT_LABELS = {
|
|
346
|
+
"DD/MM/YYYY": "02/10/2026",
|
|
347
|
+
"MM/DD/YYYY": "10/02/2026",
|
|
348
|
+
"YYYY-MM-DD": "2026-10-02",
|
|
349
|
+
"D MMM YYYY": "2 Oct 2026",
|
|
350
|
+
"Do MMM YYYY": "2nd Oct 2026",
|
|
351
|
+
"Do MMMM YYYY": "2nd October 2026",
|
|
352
|
+
"MMMM D, YYYY": "October 2, 2026"
|
|
353
|
+
};
|
|
333
354
|
var clamp = (v, min, max) => Math.min(Math.max(v, min), max);
|
|
334
355
|
var MIN_W = 0.04;
|
|
335
356
|
var MIN_H = 0.02;
|
|
@@ -347,6 +368,8 @@ function FieldDesigner({
|
|
|
347
368
|
const [failed, setFailed] = react.useState(false);
|
|
348
369
|
const [selectedId, setSelectedId] = react.useState(value[0]?.id ?? null);
|
|
349
370
|
const [drawMode, setDrawMode] = react.useState(false);
|
|
371
|
+
const [pendingType, setPendingType] = react.useState("signature");
|
|
372
|
+
const [configId, setConfigId] = react.useState(null);
|
|
350
373
|
const [drag, setDrag] = react.useState(null);
|
|
351
374
|
const [live, setLive] = react.useState(null);
|
|
352
375
|
const stageRef = react.useRef(null);
|
|
@@ -439,15 +462,21 @@ function FieldDesigner({
|
|
|
439
462
|
function onPointerUp() {
|
|
440
463
|
if (drag && live && live.w >= MIN_W && live.h >= MIN_H) {
|
|
441
464
|
if (drag.mode === "new") {
|
|
465
|
+
const isDate = pendingType === "date";
|
|
466
|
+
const n = value.filter((v) => v.type === pendingType).length + 1;
|
|
467
|
+
const base = isDate ? "Date" : "Signature";
|
|
442
468
|
const f = {
|
|
443
469
|
id: newId(),
|
|
444
|
-
label:
|
|
470
|
+
label: n === 1 ? base : `${base} ${n}`,
|
|
471
|
+
type: pendingType,
|
|
472
|
+
...isDate ? { dateFormat: DEFAULT_DATE_FORMAT, minDate: null } : {},
|
|
445
473
|
page,
|
|
446
474
|
...live
|
|
447
475
|
};
|
|
448
476
|
onChange([...value, f]);
|
|
449
477
|
setSelectedId(f.id);
|
|
450
478
|
setDrawMode(false);
|
|
479
|
+
if (isDate) setConfigId(f.id);
|
|
451
480
|
} else {
|
|
452
481
|
onChange(value.map((x) => x.id === drag.id ? { ...x, ...live } : x));
|
|
453
482
|
}
|
|
@@ -458,10 +487,15 @@ function FieldDesigner({
|
|
|
458
487
|
function removeField(id) {
|
|
459
488
|
onChange(value.filter((f) => f.id !== id));
|
|
460
489
|
if (selectedId === id) setSelectedId(null);
|
|
490
|
+
if (configId === id) setConfigId(null);
|
|
461
491
|
}
|
|
462
492
|
function rename(id, label) {
|
|
463
493
|
onChange(value.map((f) => f.id === id ? { ...f, label } : f));
|
|
464
494
|
}
|
|
495
|
+
function setConfig(id, patch) {
|
|
496
|
+
onChange(value.map((f) => f.id === id ? { ...f, ...patch } : f));
|
|
497
|
+
}
|
|
498
|
+
const configField = value.find((f) => f.id === configId && f.type === "date") ?? null;
|
|
465
499
|
const handle = (id, geom, c) => {
|
|
466
500
|
const cx = c[1] === "w" ? geom.x : geom.x + geom.w;
|
|
467
501
|
const cy = c[0] === "n" ? geom.y : geom.y + geom.h;
|
|
@@ -507,25 +541,35 @@ function FieldDesigner({
|
|
|
507
541
|
flexWrap: "wrap"
|
|
508
542
|
},
|
|
509
543
|
children: [
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
544
|
+
["signature", "date"].map((t) => {
|
|
545
|
+
const active = drawMode && pendingType === t;
|
|
546
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
547
|
+
"button",
|
|
548
|
+
{
|
|
549
|
+
type: "button",
|
|
550
|
+
onClick: () => {
|
|
551
|
+
if (active) setDrawMode(false);
|
|
552
|
+
else {
|
|
553
|
+
setPendingType(t);
|
|
554
|
+
setDrawMode(true);
|
|
555
|
+
}
|
|
556
|
+
},
|
|
557
|
+
style: {
|
|
558
|
+
fontSize: 13,
|
|
559
|
+
fontWeight: 600,
|
|
560
|
+
padding: "5px 12px",
|
|
561
|
+
borderRadius: 6,
|
|
562
|
+
border: `1px solid ${primaryColor}`,
|
|
563
|
+
background: active ? primaryColor : "#fff",
|
|
564
|
+
color: active ? "#fff" : primaryColor,
|
|
565
|
+
cursor: "pointer"
|
|
566
|
+
},
|
|
567
|
+
children: t === "date" ? "+ Date" : "+ Signature"
|
|
524
568
|
},
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
),
|
|
528
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 12, color: "#6b7280" }, children: "or drag on the page
|
|
569
|
+
t
|
|
570
|
+
);
|
|
571
|
+
}),
|
|
572
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 12, color: "#6b7280" }, children: drawMode ? `Drag a ${pendingType} box on the page\u2026` : "or drag on the page." }),
|
|
529
573
|
numPages > 1 ? /* @__PURE__ */ jsxRuntime.jsxs("label", { style: { marginLeft: "auto", fontSize: 13, color: "#374151" }, children: [
|
|
530
574
|
"Page",
|
|
531
575
|
" ",
|
|
@@ -596,8 +640,9 @@ function FieldDesigner({
|
|
|
596
640
|
padding: "0 4px"
|
|
597
641
|
},
|
|
598
642
|
children: [
|
|
599
|
-
"\
|
|
600
|
-
|
|
643
|
+
f.type === "date" ? "\u{1F4C5}" : "\u270D",
|
|
644
|
+
" ",
|
|
645
|
+
f.label || (f.type === "date" ? "Date" : "Signature")
|
|
601
646
|
]
|
|
602
647
|
}
|
|
603
648
|
)
|
|
@@ -636,7 +681,39 @@ function FieldDesigner({
|
|
|
636
681
|
},
|
|
637
682
|
children: "\xD7"
|
|
638
683
|
}
|
|
639
|
-
)
|
|
684
|
+
),
|
|
685
|
+
f.type === "date" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
686
|
+
"button",
|
|
687
|
+
{
|
|
688
|
+
type: "button",
|
|
689
|
+
"aria-label": `Configure ${f.label}`,
|
|
690
|
+
onPointerDown: (e) => e.stopPropagation(),
|
|
691
|
+
onClick: (e) => {
|
|
692
|
+
e.stopPropagation();
|
|
693
|
+
setConfigId(f.id);
|
|
694
|
+
},
|
|
695
|
+
style: {
|
|
696
|
+
position: "absolute",
|
|
697
|
+
left: `${geom.x * 100}%`,
|
|
698
|
+
top: `${geom.y * 100}%`,
|
|
699
|
+
transform: "translate(-50%, -50%)",
|
|
700
|
+
marginTop: -18,
|
|
701
|
+
width: 22,
|
|
702
|
+
height: 22,
|
|
703
|
+
borderRadius: "50%",
|
|
704
|
+
background: "#fff",
|
|
705
|
+
color: primaryColor,
|
|
706
|
+
border: `2px solid ${primaryColor}`,
|
|
707
|
+
boxShadow: "0 1px 3px rgba(0,0,0,0.3)",
|
|
708
|
+
fontSize: 12,
|
|
709
|
+
lineHeight: "14px",
|
|
710
|
+
cursor: "pointer",
|
|
711
|
+
padding: 0,
|
|
712
|
+
touchAction: "none"
|
|
713
|
+
},
|
|
714
|
+
children: "\u2699"
|
|
715
|
+
}
|
|
716
|
+
) : null
|
|
640
717
|
] }) : null
|
|
641
718
|
] }, f.id);
|
|
642
719
|
}),
|
|
@@ -658,11 +735,99 @@ function FieldDesigner({
|
|
|
658
735
|
) : null
|
|
659
736
|
]
|
|
660
737
|
}
|
|
661
|
-
)
|
|
738
|
+
),
|
|
739
|
+
configField ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
740
|
+
"div",
|
|
741
|
+
{
|
|
742
|
+
style: {
|
|
743
|
+
marginTop: 10,
|
|
744
|
+
border: `1px solid ${primaryColor}66`,
|
|
745
|
+
borderRadius: 8,
|
|
746
|
+
padding: 12,
|
|
747
|
+
background: "#fff",
|
|
748
|
+
fontSize: 13,
|
|
749
|
+
color: "#374151"
|
|
750
|
+
},
|
|
751
|
+
children: [
|
|
752
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
753
|
+
"div",
|
|
754
|
+
{
|
|
755
|
+
style: {
|
|
756
|
+
display: "flex",
|
|
757
|
+
alignItems: "center",
|
|
758
|
+
justifyContent: "space-between",
|
|
759
|
+
marginBottom: 8
|
|
760
|
+
},
|
|
761
|
+
children: [
|
|
762
|
+
/* @__PURE__ */ jsxRuntime.jsxs("strong", { children: [
|
|
763
|
+
"\u{1F4C5} ",
|
|
764
|
+
configField.label || "Date"
|
|
765
|
+
] }),
|
|
766
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
767
|
+
"button",
|
|
768
|
+
{
|
|
769
|
+
type: "button",
|
|
770
|
+
onClick: () => setConfigId(null),
|
|
771
|
+
style: {
|
|
772
|
+
fontSize: 12,
|
|
773
|
+
padding: "3px 10px",
|
|
774
|
+
borderRadius: 6,
|
|
775
|
+
border: `1px solid ${primaryColor}`,
|
|
776
|
+
background: primaryColor,
|
|
777
|
+
color: "#fff",
|
|
778
|
+
cursor: "pointer"
|
|
779
|
+
},
|
|
780
|
+
children: "Done"
|
|
781
|
+
}
|
|
782
|
+
)
|
|
783
|
+
]
|
|
784
|
+
}
|
|
785
|
+
),
|
|
786
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { style: { display: "block", marginBottom: 8 }, children: [
|
|
787
|
+
"Display format",
|
|
788
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
789
|
+
"select",
|
|
790
|
+
{
|
|
791
|
+
value: configField.dateFormat ?? DEFAULT_DATE_FORMAT,
|
|
792
|
+
onChange: (e) => setConfig(configField.id, { dateFormat: e.target.value }),
|
|
793
|
+
style: {
|
|
794
|
+
display: "block",
|
|
795
|
+
marginTop: 4,
|
|
796
|
+
width: "100%",
|
|
797
|
+
padding: "4px 6px",
|
|
798
|
+
borderRadius: 6,
|
|
799
|
+
border: "1px solid #d1d5db"
|
|
800
|
+
},
|
|
801
|
+
children: DATE_FORMATS.map((fmt) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: fmt, children: DATE_FORMAT_LABELS[fmt] }, fmt))
|
|
802
|
+
}
|
|
803
|
+
)
|
|
804
|
+
] }),
|
|
805
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { style: { display: "block" }, children: [
|
|
806
|
+
"Earliest date",
|
|
807
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
808
|
+
"input",
|
|
809
|
+
{
|
|
810
|
+
type: "date",
|
|
811
|
+
value: configField.minDate ?? "",
|
|
812
|
+
onChange: (e) => setConfig(configField.id, { minDate: e.target.value || null }),
|
|
813
|
+
style: {
|
|
814
|
+
display: "block",
|
|
815
|
+
marginTop: 4,
|
|
816
|
+
padding: "4px 6px",
|
|
817
|
+
borderRadius: 6,
|
|
818
|
+
border: "1px solid #d1d5db"
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
),
|
|
822
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#9ca3af", fontSize: 11 }, children: "Leave blank to use the document's creation date." })
|
|
823
|
+
] })
|
|
824
|
+
]
|
|
825
|
+
}
|
|
826
|
+
) : null
|
|
662
827
|
] }),
|
|
663
828
|
hideFieldList ? null : /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { flex: "1 1 200px", minWidth: 180, maxWidth: 300 }, children: [
|
|
664
829
|
/* @__PURE__ */ jsxRuntime.jsxs("p", { style: { fontSize: 13, fontWeight: 600, color: "#374151", margin: "0 0 8px" }, children: [
|
|
665
|
-
"
|
|
830
|
+
"Fields (",
|
|
666
831
|
value.length,
|
|
667
832
|
")"
|
|
668
833
|
] }),
|
|
@@ -684,6 +849,7 @@ function FieldDesigner({
|
|
|
684
849
|
cursor: "pointer"
|
|
685
850
|
},
|
|
686
851
|
children: [
|
|
852
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 13 }, children: f.type === "date" ? "\u{1F4C5}" : "\u270D" }),
|
|
687
853
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
688
854
|
"input",
|
|
689
855
|
{
|
|
@@ -705,6 +871,27 @@ function FieldDesigner({
|
|
|
705
871
|
"p",
|
|
706
872
|
f.page
|
|
707
873
|
] }),
|
|
874
|
+
f.type === "date" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
875
|
+
"button",
|
|
876
|
+
{
|
|
877
|
+
type: "button",
|
|
878
|
+
"aria-label": `Configure ${f.label}`,
|
|
879
|
+
onClick: (e) => {
|
|
880
|
+
e.stopPropagation();
|
|
881
|
+
setConfigId(f.id);
|
|
882
|
+
},
|
|
883
|
+
style: {
|
|
884
|
+
border: "none",
|
|
885
|
+
background: "transparent",
|
|
886
|
+
color: "#6b7280",
|
|
887
|
+
cursor: "pointer",
|
|
888
|
+
fontSize: 13,
|
|
889
|
+
lineHeight: 1,
|
|
890
|
+
padding: 0
|
|
891
|
+
},
|
|
892
|
+
children: "\u2699"
|
|
893
|
+
}
|
|
894
|
+
) : null,
|
|
708
895
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
709
896
|
"button",
|
|
710
897
|
{
|
|
@@ -737,9 +924,12 @@ function SigningExperience(props) {
|
|
|
737
924
|
const primary = props.branding?.primaryColor ?? "#4f46e5";
|
|
738
925
|
const [signaturePng, setSignaturePng] = react.useState(null);
|
|
739
926
|
const [consent, setConsent] = react.useState({ signerName: "", consent: false });
|
|
927
|
+
const [dateValues, setDateValues] = react.useState({});
|
|
740
928
|
const [submitting, setSubmitting] = react.useState(false);
|
|
741
929
|
const [error, setError] = react.useState(null);
|
|
742
|
-
const
|
|
930
|
+
const dateFields = (props.placements ?? []).filter((p) => p.type === "date" && p.id);
|
|
931
|
+
const allDatesFilled = dateFields.every((f) => dateValues[f.id]);
|
|
932
|
+
const canSubmit = !!signaturePng && consent.consent && consent.signerName.trim().length > 0 && allDatesFilled && !submitting;
|
|
743
933
|
async function submit() {
|
|
744
934
|
if (!canSubmit) return;
|
|
745
935
|
setSubmitting(true);
|
|
@@ -751,7 +941,8 @@ function SigningExperience(props) {
|
|
|
751
941
|
body: JSON.stringify({
|
|
752
942
|
signaturePng,
|
|
753
943
|
signerName: consent.signerName.trim(),
|
|
754
|
-
consent: true
|
|
944
|
+
consent: true,
|
|
945
|
+
dateValues
|
|
755
946
|
})
|
|
756
947
|
});
|
|
757
948
|
if (!res.ok) {
|
|
@@ -796,6 +987,31 @@ function SigningExperience(props) {
|
|
|
796
987
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: { fontSize: 13, fontWeight: 600, color: "#374151" }, children: "Your signature" }),
|
|
797
988
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { marginTop: 6 }, children: /* @__PURE__ */ jsxRuntime.jsx(SignaturePad, { primaryColor: primary, onChange: setSignaturePng }) })
|
|
798
989
|
] }),
|
|
990
|
+
dateFields.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", gap: 12 }, children: dateFields.map((f) => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
991
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { style: { fontSize: 13, fontWeight: 600, color: "#374151" }, children: [
|
|
992
|
+
"\u{1F4C5} ",
|
|
993
|
+
f.label || "Date"
|
|
994
|
+
] }),
|
|
995
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
996
|
+
"input",
|
|
997
|
+
{
|
|
998
|
+
type: "date",
|
|
999
|
+
value: dateValues[f.id] ?? "",
|
|
1000
|
+
min: f.minDate ?? void 0,
|
|
1001
|
+
onChange: (e) => setDateValues((prev) => ({ ...prev, [f.id]: e.target.value })),
|
|
1002
|
+
style: {
|
|
1003
|
+
display: "block",
|
|
1004
|
+
marginTop: 6,
|
|
1005
|
+
padding: "10px 12px",
|
|
1006
|
+
borderRadius: 8,
|
|
1007
|
+
border: "1px solid #d1d5db",
|
|
1008
|
+
fontSize: 15,
|
|
1009
|
+
width: "100%",
|
|
1010
|
+
maxWidth: 280
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
)
|
|
1014
|
+
] }, f.id)) }) : null,
|
|
799
1015
|
/* @__PURE__ */ jsxRuntime.jsx(ConsentBlock, { value: consent, onChange: setConsent, primaryColor: primary }),
|
|
800
1016
|
error ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
801
1017
|
"div",
|