jai #1
|
|
@ -1,26 +1,27 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
// import { X, Upload, Edit3, Image, Cloud, HardDrive, Droplets } from 'lucide-react';
|
||||
import { AiOutlineClose, AiOutlineUpload, AiOutlineEdit } from 'react-icons/ai';
|
||||
import { MdImage, MdCloudUpload, MdStorage } from 'react-icons/md';
|
||||
import { MdImage, MdCloudUpload } from 'react-icons/md';
|
||||
import api from '../../../config/api';
|
||||
import DrawSignatureCanvas from './DrawSignatureCanvas';
|
||||
|
||||
|
||||
interface AddSignatureModalProps {
|
||||
setShowAddSignature?: (value: boolean) => void;
|
||||
}
|
||||
interface Account {
|
||||
id: number;
|
||||
isDefault: boolean;
|
||||
name: string;
|
||||
id: number;
|
||||
isDefault: boolean;
|
||||
name: string;
|
||||
}
|
||||
|
||||
interface UserData {
|
||||
id: string;
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
email: string;
|
||||
language: string;
|
||||
account: Account;
|
||||
id: string;
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
email: string;
|
||||
language: string;
|
||||
account: Account;
|
||||
}
|
||||
|
||||
const AddSignatureModal: React.FC<AddSignatureModalProps> = ({ setShowAddSignature }) => {
|
||||
|
|
@ -28,6 +29,17 @@ const AddSignatureModal: React.FC<AddSignatureModalProps> = ({ setShowAddSignatu
|
|||
const [fullName, setFullName] = useState('');
|
||||
const [initials, setInitials] = useState('');
|
||||
|
||||
const [signatures, setSignatures] = useState<{
|
||||
fullSignature: string | null;
|
||||
initials: string | null;
|
||||
}>({ fullSignature: null, initials: null });
|
||||
|
||||
const handleSignatureChange = (data: { fullSignature: string | null; initials: string | null }) => {
|
||||
setSignatures(data);
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Sample signature options for the CHOOSE tab
|
||||
const signatureOptions = [
|
||||
{ id: 1, name: 'print', initials: 'LA', style: 'print' },
|
||||
|
|
@ -39,6 +51,8 @@ const AddSignatureModal: React.FC<AddSignatureModalProps> = ({ setShowAddSignatu
|
|||
];
|
||||
|
||||
const [selectedSignature, setSelectedSignature] = useState<number>(1);
|
||||
console.log(selectedSignature);
|
||||
|
||||
|
||||
// Store the actual file
|
||||
const [file1, setFile1] = useState<File | null>(null);
|
||||
|
|
@ -56,11 +70,11 @@ const AddSignatureModal: React.FC<AddSignatureModalProps> = ({ setShowAddSignatu
|
|||
email: "",
|
||||
language: "",
|
||||
account: {
|
||||
id: 0,
|
||||
isDefault: false,
|
||||
name: "",
|
||||
id: 0,
|
||||
isDefault: false,
|
||||
name: "",
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
// Navigation items
|
||||
const navigationItems = [
|
||||
|
|
@ -90,6 +104,38 @@ const AddSignatureModal: React.FC<AddSignatureModalProps> = ({ setShowAddSignatu
|
|||
}
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (!signatures.fullSignature || !signatures.initials) {
|
||||
alert('Please provide both signature and initials');
|
||||
return;
|
||||
}
|
||||
|
||||
// Example: Posting the base64 data
|
||||
|
||||
try {
|
||||
const payload = {
|
||||
signatureType: "DRAW",
|
||||
// "signatureId": 0, this work on only the put req.
|
||||
signatureBase64: signatures.fullSignature,
|
||||
initialsBase64: signatures.initials,
|
||||
firstName: user.firstName,
|
||||
lastName: user.lastName,
|
||||
font: ""
|
||||
};
|
||||
|
||||
console.log('Submitting Signature:', payload);
|
||||
let res = await api.post(`/api/user/signatures`,payload)
|
||||
console.log("handleSubmit", res)
|
||||
} catch (error) {
|
||||
console.error("Error fetching user details:", error);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// fetch('/api/signature', { method: 'POST', body: JSON.stringify(payload) })
|
||||
};
|
||||
|
||||
|
||||
const renderContent = () => {
|
||||
switch (activeTab) {
|
||||
|
|
@ -149,51 +195,7 @@ const AddSignatureModal: React.FC<AddSignatureModalProps> = ({ setShowAddSignatu
|
|||
|
||||
case 'draw':
|
||||
return (
|
||||
<div className="h-full flex flex-col">
|
||||
<div className="mb-6">
|
||||
<h2 className="text-xl font-semibold text-gray-900 mb-2">Draw Signature</h2>
|
||||
<p className="text-sm text-gray-600">Create your signature by drawing directly on the canvas</p>
|
||||
</div>
|
||||
|
||||
<div className="flex-1 flex flex-col">
|
||||
<div className="grid grid-cols-12 gap-6 mb-6">
|
||||
{/* Draw area 1 */}
|
||||
<div className="col-span-8">
|
||||
<label className="block text-sm font-medium text-gray-700 mb-2">Full Signature</label>
|
||||
<div className="border-2 border-dashed border-gray-300 rounded-lg h-48 flex items-center justify-center bg-gray-50 hover:bg-gray-100 cursor-pointer transition-colors">
|
||||
<div className="text-center">
|
||||
{/* <Edit3 className="mx-auto h-12 w-12 text-gray-400 mb-3" /> */}
|
||||
<p className="text-sm text-gray-500">Click and drag to draw your signature</p>
|
||||
<p className="text-xs text-gray-400 mt-1">Use mouse or touch to create your signature</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* Draw area 2 */}
|
||||
<div className="col-span-4">
|
||||
<label className="block text-sm font-medium text-gray-700 mb-2">Initials</label>
|
||||
<div className="border-2 border-dashed border-gray-300 rounded-lg h-48 flex items-center justify-center bg-gray-50 hover:bg-gray-100 cursor-pointer transition-colors">
|
||||
<div className="text-center">
|
||||
{/* <Edit3 className="mx-auto h-8 w-8 text-gray-400 mb-2" /> */}
|
||||
<p className="text-xs text-gray-500">Draw initials</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex gap-3">
|
||||
<button className="px-4 py-2 text-sm border border-gray-300 rounded-md hover:bg-gray-50 transition-colors flex items-center gap-2">
|
||||
{/* <X className="w-4 h-4" /> */}
|
||||
Clear
|
||||
</button>
|
||||
<button className="px-4 py-2 text-sm border border-gray-300 rounded-md hover:bg-gray-50 transition-colors">
|
||||
Undo
|
||||
</button>
|
||||
<button className="px-4 py-2 text-sm border border-gray-300 rounded-md hover:bg-gray-50 transition-colors">
|
||||
Redo
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<DrawSignatureCanvas onSignatureChange={handleSignatureChange} />
|
||||
);
|
||||
|
||||
case 'upload':
|
||||
|
|
@ -261,18 +263,21 @@ const AddSignatureModal: React.FC<AddSignatureModalProps> = ({ setShowAddSignatu
|
|||
};
|
||||
|
||||
const getUserDetails = async () => {
|
||||
try {
|
||||
let res = await api.get(`/api/user/details`)
|
||||
console.log("getuser", res)
|
||||
setUser(res?.data)
|
||||
} catch (error) {
|
||||
console.error("Error fetching user details:", error);
|
||||
try {
|
||||
let res = await api.get(`/api/user/details`)
|
||||
console.log("getuser", res)
|
||||
let currUser = res?.data
|
||||
setUser(currUser)
|
||||
setFullName(currUser.firstName + " " + currUser.lastName)
|
||||
setInitials(currUser.firstName.slice(0, 1) + currUser.lastName.slice(0, 1))
|
||||
} catch (error) {
|
||||
console.error("Error fetching user details:", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
getUserDetails()
|
||||
}, [])
|
||||
useEffect(() => {
|
||||
getUserDetails()
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 backdrop-blur-sm bg-opacity-50 flex items-center justify-center z-50 p-4">
|
||||
|
|
@ -352,11 +357,11 @@ const AddSignatureModal: React.FC<AddSignatureModalProps> = ({ setShowAddSignatu
|
|||
{/* Content */}
|
||||
<div className="flex-1 py-5 px-5 overflow-hidden ">
|
||||
<button
|
||||
onClick={() => setShowAddSignature?.(false)}
|
||||
className="absolute top-2 right-3 p-2 hover:bg-gray-100 rounded-full transition-colors z-20"
|
||||
>
|
||||
<AiOutlineClose className="w-5 h-5 text-gray-500" />
|
||||
</button>
|
||||
onClick={() => setShowAddSignature?.(false)}
|
||||
className="absolute top-2 right-3 p-2 hover:bg-gray-100 rounded-full transition-colors z-20"
|
||||
>
|
||||
<AiOutlineClose className="w-5 h-5 text-gray-500" />
|
||||
</button>
|
||||
{renderContent()}
|
||||
</div>
|
||||
|
||||
|
|
@ -368,7 +373,7 @@ const AddSignatureModal: React.FC<AddSignatureModalProps> = ({ setShowAddSignatu
|
|||
>
|
||||
CANCEL
|
||||
</button>
|
||||
<button className="px-4 py-2 text-sm font-medium rounded-md bg-blue-600 text-white hover:bg-blue-700 transition-colors">
|
||||
<button className="px-4 py-2 text-sm font-medium rounded-md bg-blue-600 text-white hover:bg-blue-700 transition-colors" onClick={handleSubmit}>
|
||||
CREATE SIGNATURE
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,158 @@
|
|||
import React, { useRef, useState } from 'react';
|
||||
|
||||
type Props = {
|
||||
onSignatureChange: (data: { fullSignature: string | null; initials: string | null }) => void;
|
||||
};
|
||||
|
||||
const DrawSignatureCanvas: React.FC<Props> = ({ onSignatureChange }) => {
|
||||
const canvasRef1 = useRef<HTMLCanvasElement>(null);
|
||||
const canvasRef2 = useRef<HTMLCanvasElement>(null);
|
||||
const [isDrawing, setIsDrawing] = useState(false);
|
||||
const [paths1, setPaths1] = useState<Array<Array<{ x: number; y: number }>>>([]);
|
||||
const [paths2, setPaths2] = useState<Array<Array<{ x: number; y: number }>>>([]);
|
||||
const [currentPath, setCurrentPath] = useState<Array<{ x: number; y: number }>>([]);
|
||||
const [activeCanvas, setActiveCanvas] = useState<'full' | 'initials' | null>(null);
|
||||
|
||||
const handleMouseDown = (e: React.MouseEvent<HTMLCanvasElement>) => {
|
||||
setIsDrawing(true);
|
||||
const rect = e.currentTarget.getBoundingClientRect();
|
||||
const point = { x: e.clientX - rect.left, y: e.clientY - rect.top };
|
||||
setCurrentPath([point]);
|
||||
setActiveCanvas(e.currentTarget === canvasRef1.current ? 'full' : 'initials');
|
||||
};
|
||||
|
||||
const handleMouseMove = (e: React.MouseEvent<HTMLCanvasElement>) => {
|
||||
if (!isDrawing) return;
|
||||
const rect = e.currentTarget.getBoundingClientRect();
|
||||
const point = { x: e.clientX - rect.left, y: e.clientY - rect.top };
|
||||
const newPath = [...currentPath, point]; // <- Build new path
|
||||
setCurrentPath(newPath); // <- Save for next event
|
||||
drawPath(e.currentTarget as HTMLCanvasElement, newPath); // <- Draw current
|
||||
};
|
||||
|
||||
const exportCanvasAsImage = (canvas: HTMLCanvasElement | null): string | null => {
|
||||
if (!canvas) return null;
|
||||
return canvas.toDataURL('image/png');
|
||||
};
|
||||
|
||||
const handleMouseUp = () => {
|
||||
setIsDrawing(false);
|
||||
if (currentPath.length === 0 || !activeCanvas) return;
|
||||
|
||||
if (activeCanvas === 'full') {
|
||||
const newPaths = [...paths1, currentPath];
|
||||
setPaths1(newPaths);
|
||||
const fullSignature = exportCanvasAsImage(canvasRef1.current);
|
||||
onSignatureChange({ fullSignature, initials: exportCanvasAsImage(canvasRef2.current) });
|
||||
} else {
|
||||
const newPaths = [...paths2, currentPath];
|
||||
setPaths2(newPaths);
|
||||
const initials = exportCanvasAsImage(canvasRef2.current);
|
||||
onSignatureChange({ fullSignature: exportCanvasAsImage(canvasRef1.current), initials });
|
||||
}
|
||||
|
||||
setCurrentPath([]);
|
||||
};
|
||||
|
||||
const drawPath = (canvas: HTMLCanvasElement | null, path: Array<{ x: number; y: number }>) => {
|
||||
if (!canvas) return;
|
||||
const ctx = canvas.getContext('2d');
|
||||
if (!ctx) return;
|
||||
|
||||
const allPaths =
|
||||
canvas === canvasRef1.current ? [...paths1, path] : [...paths2, path];
|
||||
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
ctx.strokeStyle = '#000';
|
||||
ctx.lineWidth = 2;
|
||||
ctx.lineJoin = 'round';
|
||||
ctx.lineCap = 'round';
|
||||
|
||||
allPaths.forEach((p) => {
|
||||
if (p.length < 2) return;
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(p[0].x, p[0].y);
|
||||
for (let i = 1; i < p.length; i++) {
|
||||
ctx.lineTo(p[i].x, p[i].y);
|
||||
}
|
||||
ctx.stroke();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
const clearCanvas = () => {
|
||||
if (canvasRef1.current) {
|
||||
const ctx1 = canvasRef1.current.getContext('2d');
|
||||
ctx1?.clearRect(0, 0, canvasRef1.current.width, canvasRef1.current.height);
|
||||
}
|
||||
if (canvasRef2.current) {
|
||||
const ctx2 = canvasRef2.current.getContext('2d');
|
||||
ctx2?.clearRect(0, 0, canvasRef2.current.width, canvasRef2.current.height);
|
||||
}
|
||||
|
||||
setPaths1([]);
|
||||
setPaths2([]);
|
||||
onSignatureChange({ fullSignature: null, initials: null });
|
||||
};
|
||||
|
||||
|
||||
return (
|
||||
<div className="h-full flex flex-col">
|
||||
<div className="mb-6">
|
||||
<h2 className="text-xl font-semibold text-gray-900 mb-2">Draw Signature</h2>
|
||||
<p className="text-sm text-gray-600">Create your signature by drawing directly on the canvas</p>
|
||||
</div>
|
||||
|
||||
<div className="flex-1 flex flex-col">
|
||||
<div className="grid grid-cols-12 gap-6 mb-2">
|
||||
{/* Full Signature Canvas */}
|
||||
<div className="col-span-8">
|
||||
<label className="block text-sm font-medium text-gray-700 mb-2">Full Signature</label>
|
||||
<div className="border-2 border-dashed border-gray-300 rounded-lg bg-gray-50 hover:bg-gray-100 transition-colors">
|
||||
<canvas
|
||||
ref={canvasRef1}
|
||||
className="w-full h-48 cursor-crosshair"
|
||||
width={canvasRef1.current?.clientWidth || 600} // use real width
|
||||
height={canvasRef1.current?.clientHeight || 180}
|
||||
onMouseDown={handleMouseDown}
|
||||
onMouseMove={handleMouseMove}
|
||||
onMouseUp={handleMouseUp}
|
||||
onMouseLeave={handleMouseUp}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Initials Canvas */}
|
||||
<div className="col-span-4">
|
||||
<label className="block text-sm font-medium text-gray-700 mb-2">Initials</label>
|
||||
<div className="border-2 border-dashed border-gray-300 rounded-lg bg-gray-50 hover:bg-gray-100 transition-colors">
|
||||
<canvas
|
||||
ref={canvasRef2}
|
||||
width={canvasRef2.current?.clientWidth || 300}
|
||||
height={canvasRef2.current?.clientHeight || 180}
|
||||
className="w-full h-48 cursor-crosshair"
|
||||
onMouseDown={handleMouseDown}
|
||||
onMouseMove={handleMouseMove}
|
||||
onMouseUp={handleMouseUp}
|
||||
onMouseLeave={handleMouseUp}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Controls */}
|
||||
<div className="flex gap-4">
|
||||
<button
|
||||
className="px-4 py-2 text-sm border border-gray-300 rounded-md hover:bg-gray-50 transition-colors"
|
||||
onClick={clearCanvas}
|
||||
>
|
||||
Clear
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default DrawSignatureCanvas;
|
||||
|
|
@ -1,38 +1,32 @@
|
|||
import React, { useState } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { FiEdit3, FiTrash2, FiPlus, FiMoreVertical } from 'react-icons/fi';
|
||||
import AddSignatureModal from './AddSignatureModal';
|
||||
import api from '../../../config/api';
|
||||
|
||||
interface Signature {
|
||||
id: string;
|
||||
signature: string;
|
||||
initial: string;
|
||||
createdAt: string;
|
||||
email: string;
|
||||
signatureType: string;
|
||||
lastName: string;
|
||||
firstName: string
|
||||
font: string;
|
||||
initialsBlob:string;
|
||||
initialsStampedBlob:string;
|
||||
initialsHash:string;
|
||||
signatureHash:string;
|
||||
signatureBlob:string;
|
||||
signatureStampedBlob:string;
|
||||
default:boolean
|
||||
}
|
||||
|
||||
const SignatureManager: React.FC = () => {
|
||||
const [signatures, setSignatures] = useState<Signature[]>([
|
||||
{
|
||||
id: '1',
|
||||
signature: 'https://www.signwell.com/assets/vip-signatures/muhammad-ali-signature-3f9237f6fc48c3a04ba083117948e16ee7968aae521ae4ccebdfb8f22596ad22.svg',
|
||||
initial: 'AB',
|
||||
createdAt: 'dca3e646-62cd-4cc...'
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
signature: '∼∼⌒∼∼⌒∼',
|
||||
initial: 'AB',
|
||||
createdAt: 'dca3e646-62cd-4cc...'
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
signature: 'Digital Signature',
|
||||
initial: 'DS',
|
||||
createdAt: 'dca3e646-62cd-4cc...'
|
||||
}
|
||||
]);
|
||||
|
||||
|
||||
|
||||
const [signatures, setSignatures] = useState<Signature[]>([]);
|
||||
|
||||
const [activeDropdown, setActiveDropdown] = useState<string | null>(null);
|
||||
const [showAddSignature , setShowAddSignature] = useState<boolean>(false)
|
||||
const [showAddSignature, setShowAddSignature] = useState<boolean>(false)
|
||||
|
||||
const handleEdit = (id: string) => {
|
||||
console.log('Edit signature:', id);
|
||||
|
|
@ -48,6 +42,21 @@ const SignatureManager: React.FC = () => {
|
|||
setActiveDropdown(activeDropdown === id ? null : id);
|
||||
};
|
||||
|
||||
const getAllSignatures = async () => {
|
||||
try {
|
||||
let res = await api.get("/api/user/signatures")
|
||||
console.log("getAllSignatures", res.data)
|
||||
let signatureData = res?.data
|
||||
setSignatures(signatureData)
|
||||
} catch (error) {
|
||||
console.log("getAllSignatures", error)
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
getAllSignatures()
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-white p-3 rounded-md px-4 mb-6">
|
||||
<div className="max-w-[84vw] mx-auto">
|
||||
|
|
@ -57,7 +66,7 @@ const SignatureManager: React.FC = () => {
|
|||
<h1 className="text-[17px] font-medium text-gray-500 mb-2">Signatures</h1>
|
||||
<p className="text-gray-300 text-sm">Add or update your name and signature styles.</p>
|
||||
</div>
|
||||
<button className="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg font-semibold text-sm text-[14px] flex items-center cursor-pointer transition-all duration-200 shadow-lg hover:shadow-xl transform hover:-translate-y-0.5" onClick={()=>setShowAddSignature((prev) => !prev)}>
|
||||
<button className="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg font-semibold text-sm text-[14px] flex items-center cursor-pointer transition-all duration-200 shadow-lg hover:shadow-xl transform hover:-translate-y-0.5" onClick={() => setShowAddSignature((prev) => !prev)}>
|
||||
<FiPlus className="" />
|
||||
ADD
|
||||
</button>
|
||||
|
|
@ -95,7 +104,7 @@ const SignatureManager: React.FC = () => {
|
|||
{/* Signature Image */}
|
||||
<div className="bg-white rounded-lg p-1 flex items-center justify-center ">
|
||||
<img
|
||||
src="https://www.signwell.com/assets/vip-signatures/muhammad-ali-signature-3f9237f6fc48c3a04ba083117948e16ee7968aae521ae4ccebdfb8f22596ad22.svg"
|
||||
src={`data:image/png;base64,${signature.signatureBlob}`}
|
||||
className="h-[50px] w-[250px] object-contain"
|
||||
alt="Signature"
|
||||
/>
|
||||
|
|
@ -103,7 +112,7 @@ const SignatureManager: React.FC = () => {
|
|||
|
||||
{/* Signature ID */}
|
||||
<div className="text-xs text-gray-500 truncate">
|
||||
{signature.createdAt}
|
||||
{signature.signatureHash}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -120,7 +129,7 @@ const SignatureManager: React.FC = () => {
|
|||
{/* Signature Image */}
|
||||
<div className="bg-white rounded-lg p-1 flex items-center justify-center ">
|
||||
<img
|
||||
src="https://www.signwell.com/assets/vip-signatures/muhammad-ali-signature-3f9237f6fc48c3a04ba083117948e16ee7968aae521ae4ccebdfb8f22596ad22.svg"
|
||||
src={`data:image/png;base64,${signature.initialsBlob}`}
|
||||
className="h-[50px] object-contain"
|
||||
alt="DS Signature"
|
||||
/>
|
||||
|
|
@ -174,10 +183,6 @@ const SignatureManager: React.FC = () => {
|
|||
</div>
|
||||
<h3 className="text-xl font-semibold text-gray-700 mb-2">No signatures yet</h3>
|
||||
<p className="text-gray-500 mb-6">Create your first signature to get started.</p>
|
||||
<button className="bg-blue-600 hover:bg-blue-700 text-white px-6 py-3 rounded-lg font-semibold flex items-center gap-2 mx-auto transition-all duration-200">
|
||||
<FiPlus className="w-5 h-5" />
|
||||
ADD SIGNATURE
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
|
@ -191,7 +196,7 @@ const SignatureManager: React.FC = () => {
|
|||
)}
|
||||
|
||||
{showAddSignature && (
|
||||
<AddSignatureModal setShowAddSignature={setShowAddSignature}/>
|
||||
<AddSignatureModal setShowAddSignature={setShowAddSignature} />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in New Issue