mirror of
https://github.com/documenso/documenso.git
synced 2026-08-23 23:02:22 +10:00
fix: reviewed
This commit is contained in:
@@ -2,14 +2,16 @@ import { DocumentSignatureType } from '@documenso/lib/constants/document';
|
||||
import { isBase64Image } from '@documenso/lib/constants/signatures';
|
||||
|
||||
import { Trans } from '@lingui/react/macro';
|
||||
import { KeyboardIcon, UploadCloudIcon } from 'lucide-react';
|
||||
import { KeyboardIcon, SmartphoneIcon, UploadCloudIcon } from 'lucide-react';
|
||||
import type { HTMLAttributes } from 'react';
|
||||
import { useState } from 'react';
|
||||
import { match } from 'ts-pattern';
|
||||
import { match, P } from 'ts-pattern';
|
||||
|
||||
import { SignatureIcon } from '../../icons/signature';
|
||||
import { cn } from '../../lib/utils';
|
||||
import { SignaturePadDraw } from './signature-pad-draw';
|
||||
import type { QrSignatureSession } from './signature-pad-qr';
|
||||
import { SignaturePadQr } from './signature-pad-qr';
|
||||
import { SignaturePadType } from './signature-pad-type';
|
||||
import { SignaturePadUpload } from './signature-pad-upload';
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from './signature-tabs';
|
||||
@@ -29,6 +31,7 @@ export type SignaturePadProps = Omit<HTMLAttributes<HTMLCanvasElement>, 'onChang
|
||||
typedSignatureEnabled?: boolean;
|
||||
uploadSignatureEnabled?: boolean;
|
||||
drawSignatureEnabled?: boolean;
|
||||
qrSignatureEnabled?: boolean;
|
||||
|
||||
onValidityChange?: (isValid: boolean) => void;
|
||||
};
|
||||
@@ -41,11 +44,14 @@ export const SignaturePad = ({
|
||||
typedSignatureEnabled = true,
|
||||
uploadSignatureEnabled = true,
|
||||
drawSignatureEnabled = true,
|
||||
qrSignatureEnabled = true,
|
||||
}: SignaturePadProps) => {
|
||||
const [imageSignature, setImageSignature] = useState(isBase64Image(value) ? value : '');
|
||||
const [drawSignature, setDrawSignature] = useState(isBase64Image(value) ? value : '');
|
||||
const [typedSignature, setTypedSignature] = useState(isBase64Image(value) ? '' : value);
|
||||
|
||||
const [qrSession, setQrSession] = useState<QrSignatureSession | null>(null);
|
||||
|
||||
/**
|
||||
* This is cooked.
|
||||
*
|
||||
@@ -53,7 +59,7 @@ export const SignaturePad = ({
|
||||
* the first enabled tab.
|
||||
*/
|
||||
const [tab, setTab] = useState(
|
||||
((): 'draw' | 'text' | 'image' => {
|
||||
((): 'draw' | 'text' | 'image' | 'qr' => {
|
||||
// First passthrough to check to see if there's a signature for a given tab.
|
||||
if (drawSignatureEnabled && drawSignature) {
|
||||
return 'draw';
|
||||
@@ -80,6 +86,10 @@ export const SignaturePad = ({
|
||||
return 'image';
|
||||
}
|
||||
|
||||
if (qrSignatureEnabled) {
|
||||
return 'qr';
|
||||
}
|
||||
|
||||
throw new Error('No signature enabled');
|
||||
})(),
|
||||
);
|
||||
@@ -111,7 +121,7 @@ export const SignaturePad = ({
|
||||
});
|
||||
};
|
||||
|
||||
const onTabChange = (value: 'draw' | 'text' | 'image') => {
|
||||
const onTabChange = (value: 'draw' | 'text' | 'image' | 'qr') => {
|
||||
if (disabled) {
|
||||
return;
|
||||
}
|
||||
@@ -119,7 +129,7 @@ export const SignaturePad = ({
|
||||
setTab(value);
|
||||
|
||||
match(value)
|
||||
.with('draw', () => {
|
||||
.with(P.union('draw', 'qr'), () => {
|
||||
onDrawSignatureChange(drawSignature);
|
||||
})
|
||||
.with('text', () => {
|
||||
@@ -131,7 +141,7 @@ export const SignaturePad = ({
|
||||
.exhaustive();
|
||||
};
|
||||
|
||||
if (!drawSignatureEnabled && !typedSignatureEnabled && !uploadSignatureEnabled) {
|
||||
if (!drawSignatureEnabled && !typedSignatureEnabled && !uploadSignatureEnabled && !qrSignatureEnabled) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -142,7 +152,7 @@ export const SignaturePad = ({
|
||||
'pointer-events-none': disabled,
|
||||
})}
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||
onValueChange={(value) => onTabChange(value as 'draw' | 'text' | 'image')}
|
||||
onValueChange={(value) => onTabChange(value as 'draw' | 'text' | 'image' | 'qr')}
|
||||
>
|
||||
<TabsList>
|
||||
{drawSignatureEnabled && (
|
||||
@@ -152,6 +162,13 @@ export const SignaturePad = ({
|
||||
</TabsTrigger>
|
||||
)}
|
||||
|
||||
{qrSignatureEnabled && (
|
||||
<TabsTrigger value="qr" className="max-sm:hidden">
|
||||
<SmartphoneIcon className="mr-2 size-4" />
|
||||
<Trans context="Sign using a mobile phone">Mobile</Trans>
|
||||
</TabsTrigger>
|
||||
)}
|
||||
|
||||
{typedSignatureEnabled && (
|
||||
<TabsTrigger value="text">
|
||||
<KeyboardIcon className="mr-2 size-4" />
|
||||
@@ -174,6 +191,18 @@ export const SignaturePad = ({
|
||||
<SignaturePadDraw className="h-full w-full" onChange={onDrawSignatureChange} value={drawSignature} />
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent
|
||||
value="qr"
|
||||
className="relative flex aspect-signature-pad items-center justify-center rounded-md border border-border bg-muted/25 text-center"
|
||||
>
|
||||
<SignaturePadQr
|
||||
value={drawSignature}
|
||||
onChange={onDrawSignatureChange}
|
||||
session={qrSession}
|
||||
onSessionChange={setQrSession}
|
||||
/>
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent
|
||||
value="text"
|
||||
className="relative flex aspect-signature-pad items-center justify-center rounded-md border border-border bg-muted/25 text-center"
|
||||
|
||||
Reference in New Issue
Block a user