From dbe2aeff2d627a71e43aba538ddb3845662e6a7d Mon Sep 17 00:00:00 2001 From: Kaosara18 Date: Sun, 18 Oct 2026 17:24:59 +0100 Subject: [PATCH 1/4] feat(deliveries): create signature canvas component --- components/deliveries/SignatureCanvas.tsx | 115 ++++++++++ .../__tests__/SignatureCanvas.test.tsx | 197 ++++++++++++++++++ hooks/useSignatureCanvas.ts | 183 ++++++++++++++++ .../__tests__/signatureCaptureService.test.ts | 28 +++ services/signatureCaptureService.ts | 23 ++ 5 files changed, 546 insertions(+) create mode 100644 components/deliveries/SignatureCanvas.tsx create mode 100644 components/deliveries/__tests__/SignatureCanvas.test.tsx create mode 100644 hooks/useSignatureCanvas.ts create mode 100644 services/__tests__/signatureCaptureService.test.ts create mode 100644 services/signatureCaptureService.ts diff --git a/components/deliveries/SignatureCanvas.tsx b/components/deliveries/SignatureCanvas.tsx new file mode 100644 index 00000000..3487329f --- /dev/null +++ b/components/deliveries/SignatureCanvas.tsx @@ -0,0 +1,115 @@ +'use client'; + +import { useRef } from 'react'; +import { Eraser, Save } from 'lucide-react'; +import { useSignatureCanvas } from '@/hooks/useSignatureCanvas'; + +export interface SignatureCanvasProps { + onSave: (_dataUrl: string) => void; + width?: number; + height?: number; + disabled?: boolean; + className?: string; +} + +/** Canvas signature capture with a keyboard-accessible typed fallback. */ +export function SignatureCanvas({ + onSave, + width = 720, + height = 260, + disabled = false, + className = '', +}: SignatureCanvasProps) { + const canvasRef = useRef(null); + const { + beginStroke, + clear, + continueStroke, + endStroke, + hasSignature, + isTooLight, + save, + setTypedSignature, + typedSignature, + } = useSignatureCanvas({ canvasRef, onSave, disabled }); + + const cannotSave = disabled || !hasSignature || isTooLight; + + return ( +
+
+

+ Recipient signature +

+

+ Sign inside the box using a mouse, stylus, or touch screen. +

+
+ + + + {hasSignature && isTooLight && ( +

+ Signature is too light. Add a longer stroke before saving. +

+ )} + +
+ +

+ Type the recipient's name when drawing is not accessible. +

+