Compare commits

..

No commits in common. "da37cbe16a91b49cb7b7294050952dd9b1a530e6" and "79b121c25b0575918f71866c20d6c9339469af67" have entirely different histories.

4 changed files with 69 additions and 322 deletions

View File

@ -39,7 +39,6 @@ const SettingNav = () => {
className="p-2 rounded-full hover:bg-gray-100 transition-colors text-gray-600" className="p-2 rounded-full hover:bg-gray-100 transition-colors text-gray-600"
> >
<FaCog className="text-sm" /> <FaCog className="text-sm" />
</Link> </Link>
</div> </div>

View File

@ -1,34 +1,15 @@
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { AiOutlineUpload, AiOutlineEdit } from 'react-icons/ai'; import { AiOutlineClose, AiOutlineUpload, AiOutlineEdit } from 'react-icons/ai';
import { MdCloudUpload } from 'react-icons/md'; import { MdImage, MdCloudUpload } from 'react-icons/md';
import api from '../../../config/api'; import api from '../../../config/api';
import DrawSignatureCanvas from './DrawSignatureCanvas'; import DrawSignatureCanvas from './DrawSignatureCanvas';
import { FaSpinner } from "react-icons/fa"; import { FaSpinner } from "react-icons/fa";
import { GrCheckboxSelected } from "react-icons/gr"; import { GrCheckboxSelected } from "react-icons/gr";
import { Bounce, toast } from "react-toastify";
interface Signature {
id: 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
}
interface AddSignatureModalProps { interface AddSignatureModalProps {
setShowAddSignature?: (value: boolean) => void; setShowAddSignature?: (value: boolean) => void;
getAllSignatures: () => Promise<void>; getAllSignatures: () => Promise<void>;
editingSignature?: Signature | null;
} }
interface Account { interface Account {
id: number; id: number;
isDefault: boolean; isDefault: boolean;
@ -48,12 +29,7 @@ interface SelectStyle {
id: number, id: number,
style: string style: string
} }
const AddSignatureModal: React.FC<AddSignatureModalProps> = ({ setShowAddSignature , getAllSignatures }) => {
const AddSignatureModal: React.FC<AddSignatureModalProps> = ({
setShowAddSignature,
getAllSignatures,
editingSignature
}) => {
const [activeTab, setActiveTab] = useState<'SELECT' | 'DRAW' | 'UPLOAD'>('SELECT'); const [activeTab, setActiveTab] = useState<'SELECT' | 'DRAW' | 'UPLOAD'>('SELECT');
const [fullName, setFullName] = useState(''); const [fullName, setFullName] = useState('');
const [initials, setInitials] = useState(''); const [initials, setInitials] = useState('');
@ -62,7 +38,6 @@ const AddSignatureModal: React.FC<AddSignatureModalProps> = ({
fullSignature: string | null; fullSignature: string | null;
initials: string | null; initials: string | null;
}>({ fullSignature: null, initials: null }); }>({ fullSignature: null, initials: null });
const signatureOptions = [ const signatureOptions = [
{ id: 1, name: 'print', initials: 'LA', style: 'print' }, { id: 1, name: 'print', initials: 'LA', style: 'print' },
{ id: 2, name: 'cursive', initials: 'LA', style: 'cursive' }, { id: 2, name: 'cursive', initials: 'LA', style: 'cursive' },
@ -71,7 +46,6 @@ const AddSignatureModal: React.FC<AddSignatureModalProps> = ({
{ id: 5, name: 'modern', initials: 'LA', style: 'modern' }, { id: 5, name: 'modern', initials: 'LA', style: 'modern' },
{ id: 6, name: 'classic', initials: 'LA', style: 'classic' }, { id: 6, name: 'classic', initials: 'LA', style: 'classic' },
]; ];
const [selectedSignature, setSelectedSignature] = useState<SelectStyle>( const [selectedSignature, setSelectedSignature] = useState<SelectStyle>(
signatureOptions.length > 0 ? { id: signatureOptions[0].id, style: signatureOptions[0].style } : { id: 0, style: "" } signatureOptions.length > 0 ? { id: signatureOptions[0].id, style: signatureOptions[0].style } : { id: 0, style: "" }
); );
@ -84,7 +58,7 @@ const AddSignatureModal: React.FC<AddSignatureModalProps> = ({
const [preview1, setPreview1] = useState<string | null>(null); const [preview1, setPreview1] = useState<string | null>(null);
const [preview2, setPreview2] = useState<string | null>(null); const [preview2, setPreview2] = useState<string | null>(null);
// User data //user
const [user, setUser] = useState<UserData>({ const [user, setUser] = useState<UserData>({
id: "", id: "",
firstName: "", firstName: "",
@ -97,48 +71,22 @@ const AddSignatureModal: React.FC<AddSignatureModalProps> = ({
name: "", name: "",
}, },
}); });
const isEditMode = !!editingSignature;
// Navigation items // Navigation items
const navigationItems = [ const navigationItems = [
{ id: 'SELECT', label: 'SELECT', icon: <GrCheckboxSelected className="w-4 h-4" /> }, { id: 'SELECT', label: 'SELECT', icon: <GrCheckboxSelected className="w-4 h-4" /> },
{ id: 'DRAW', label: 'DRAW', icon: <AiOutlineEdit className="w-5 h-5" /> }, { id: 'DRAW', label: 'DRAW', icon: <AiOutlineEdit className="w-5 h-5" /> },
{ id: 'UPLOAD', label: 'UPLOAD', icon: <AiOutlineUpload className="w-5 h-5" /> }, { id: 'UPLOAD', label: 'UPLOAD', icon: <AiOutlineUpload className="w-5 h-5" /> },
]; ];
console.log("signatures", signatures)
// Initialize form with editing signature data
useEffect(() => {
if (editingSignature) {
setFullName(`${editingSignature.firstName} ${editingSignature.lastName}`);
setInitials(`${editingSignature.firstName.slice(0, 1)}${editingSignature.lastName.slice(0, 1)}`);
setActiveTab(editingSignature.signatureType as 'SELECT' | 'DRAW' | 'UPLOAD');
// Set font for SELECT tab
const fontOption = signatureOptions.find(option => option.style === editingSignature.font);
if (fontOption) {
setSelectedSignature({ id: fontOption.id, style: fontOption.style });
}
// Set signature blobs for all tabs
if (editingSignature.signatureBlob && editingSignature.initialsBlob) {
setSignatures({
fullSignature: `data:image/png;base64,${editingSignature.signatureBlob}`,
initials: `data:image/png;base64,${editingSignature.initialsBlob}`
});
// Set preview URLs for UPLOAD tab
if (editingSignature.signatureType === 'UPLOAD') {
setPreview1(`data:image/png;base64,${editingSignature.signatureBlob}`);
setPreview2(`data:image/png;base64,${editingSignature.initialsBlob}`);
}
}
}
}, [editingSignature]);
const handleSignatureChange = (data: { fullSignature: string | null; initials: string | null }) => { const handleSignatureChange = (data: { fullSignature: string | null; initials: string | null }) => {
setSignatures(data); setSignatures(data);
}; };
console.log("activeTab", activeTab)
console.log("selectedSignature", selectedSignature);
console.log('file1', file1)
console.log("file1", file2)
// Cleanup preview URLs when component unmounts or image changes // Cleanup preview URLs when component unmounts or image changes
useEffect(() => { useEffect(() => {
@ -181,85 +129,37 @@ const AddSignatureModal: React.FC<AddSignatureModalProps> = ({
}; };
const handleSubmit = async () => { const handleSubmit = async () => {
setIsSubmitting(true); setIsSubmitting(true)
if (!signatures.fullSignature || !signatures.initials) { if (!signatures.fullSignature || !signatures.initials) {
alert('Please provide both signature and initials'); alert('Please provide both signature and initials');
setIsSubmitting(false);
return; return;
} }
try { try {
const payload = { const payload = {
signatureType: activeTab, signatureType: activeTab,
// "signatureId": 0, this work on only the put req.
signatureBase64: signatures.fullSignature, signatureBase64: signatures.fullSignature,
initialsBase64: signatures.initials, initialsBase64: signatures.initials,
firstName: fullName.split(' ')[0] || user.firstName, firstName: user.firstName,
lastName: fullName.split(' ')[1] || user.lastName, lastName: user.lastName,
font: selectedSignature.style font: selectedSignature.style
}; };
let res; console.log('Submitting Signature:', payload);
if (isEditMode && editingSignature) { let res = await api.post(`/api/user/signatures`, payload)
// Update existing signature console.log("handleSubmit", res)
const updatePayload = {
...payload,
signatureId: editingSignature.id
};
res = await api.put(`/api/user/signatures`, updatePayload);
console.log("handleUpdate", res);
toast.success("Signature Updated Successfully", {
position: "top-center",
autoClose: 500,
hideProgressBar: false,
closeOnClick: false,
pauseOnHover: true,
draggable: true,
progress: undefined,
theme: "light",
transition: Bounce,
});
} else {
// Create new signature
res = await api.post(`/api/user/signatures`, payload);
console.log("handleSubmit", res);
toast.success("Signature Created Successfully", {
position: "top-center",
autoClose: 500,
hideProgressBar: false,
closeOnClick: false,
pauseOnHover: true,
draggable: true,
progress: undefined,
theme: "light",
transition: Bounce,
});
}
if (res?.data) { if (res?.data) {
await getAllSignatures(); getAllSignatures()
setShowAddSignature?.(false); setShowAddSignature?.(false)
} }
} catch (error) { } catch (error) {
console.error("Error submitting signature:", error); console.error("Error fetching user details:", error);
toast.error(isEditMode ? "Failed to update signature" : "Failed to create signature", {
position: "top-center",
autoClose: 2000,
hideProgressBar: false,
closeOnClick: false,
pauseOnHover: true,
draggable: true,
progress: undefined,
theme: "light",
transition: Bounce,
});
} finally { } finally {
setIsSubmitting(false); setIsSubmitting(false)
} }
}; };
const renderContent = () => { const renderContent = () => {
switch (activeTab) { switch (activeTab) {
case 'SELECT': case 'SELECT':
@ -318,10 +218,7 @@ const AddSignatureModal: React.FC<AddSignatureModalProps> = ({
case 'DRAW': case 'DRAW':
return ( return (
<DrawSignatureCanvas <DrawSignatureCanvas onSignatureChange={handleSignatureChange} />
onSignatureChange={handleSignatureChange}
initialSignatures={isEditMode ? signatures : undefined}
/>
); );
case 'UPLOAD': case 'UPLOAD':
@ -390,24 +287,20 @@ const AddSignatureModal: React.FC<AddSignatureModalProps> = ({
const getUserDetails = async () => { const getUserDetails = async () => {
try { try {
let res = await api.get(`/api/user/details`); let res = await api.get(`/api/user/details`)
console.log("getuser", res); console.log("getuser", res)
let currUser = res?.data; let currUser = res?.data
setUser(currUser); setUser(currUser)
setFullName(currUser.firstName + " " + currUser.lastName)
// Only set default values if not in edit mode setInitials(currUser.firstName.slice(0, 1) + currUser.lastName.slice(0, 1))
if (!isEditMode) {
setFullName(currUser.firstName + " " + currUser.lastName);
setInitials(currUser.firstName.slice(0, 1) + currUser.lastName.slice(0, 1));
}
} catch (error) { } catch (error) {
console.error("Error fetching user details:", error); console.error("Error fetching user details:", error);
} }
}; }
useEffect(() => { useEffect(() => {
getUserDetails(); getUserDetails()
}, []); }, [])
return ( return (
<div className="fixed inset-0 backdrop-blur-sm bg-opacity-50 flex items-center justify-center z-50 p-4"> <div className="fixed inset-0 backdrop-blur-sm bg-opacity-50 flex items-center justify-center z-50 p-4">
@ -512,10 +405,10 @@ const AddSignatureModal: React.FC<AddSignatureModalProps> = ({
{isSubmitting ? ( {isSubmitting ? (
<> <>
<FaSpinner className="animate-spin" /> <FaSpinner className="animate-spin" />
{isEditMode ? 'UPDATING...' : 'CREATING...'} CREATING...
</> </>
) : ( ) : (
isEditMode ? 'UPDATE SIGNATURE' : 'CREATE SIGNATURE' "CREATE SIGNATURE"
)} )}
</button> </button>
</div> </div>

View File

@ -1,11 +1,10 @@
import React, { useRef, useState, useEffect } from 'react'; import React, { useRef, useState } from 'react';
type Props = { type Props = {
onSignatureChange: (data: { fullSignature: string | null; initials: string | null }) => void; onSignatureChange: (data: { fullSignature: string | null; initials: string | null }) => void;
initialSignatures?: { fullSignature: string | null; initials: string | null };
}; };
const DrawSignatureCanvas: React.FC<Props> = ({ onSignatureChange, initialSignatures }) => { const DrawSignatureCanvas: React.FC<Props> = ({ onSignatureChange }) => {
const canvasRef1 = useRef<HTMLCanvasElement>(null); const canvasRef1 = useRef<HTMLCanvasElement>(null);
const canvasRef2 = useRef<HTMLCanvasElement>(null); const canvasRef2 = useRef<HTMLCanvasElement>(null);
const [isDrawing, setIsDrawing] = useState(false); const [isDrawing, setIsDrawing] = useState(false);
@ -13,84 +12,6 @@ const DrawSignatureCanvas: React.FC<Props> = ({ onSignatureChange, initialSignat
const [paths2, setPaths2] = 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 [currentPath, setCurrentPath] = useState<Array<{ x: number; y: number }>>([]);
const [activeCanvas, setActiveCanvas] = useState<'full' | 'initials' | null>(null); const [activeCanvas, setActiveCanvas] = useState<'full' | 'initials' | null>(null);
const [initialLoaded, setInitialLoaded] = useState(false);
// Store initial signature images to avoid reloading
const [initialImage1, setInitialImage1] = useState<HTMLImageElement | null>(null);
const [initialImage2, setInitialImage2] = useState<HTMLImageElement | null>(null);
// Setup canvas dimensions when component mounts
useEffect(() => {
const setupCanvas = () => {
if (canvasRef1.current) {
const rect1 = canvasRef1.current.getBoundingClientRect();
canvasRef1.current.width = rect1.width;
canvasRef1.current.height = rect1.height;
}
if (canvasRef2.current) {
const rect2 = canvasRef2.current.getBoundingClientRect();
canvasRef2.current.width = rect2.width;
canvasRef2.current.height = rect2.height;
}
};
setupCanvas();
// Load initial signatures after canvas setup
if (initialSignatures && !initialLoaded) {
setTimeout(() => {
loadInitialSignatures();
}, 100);
}
}, []);
const loadInitialSignatures = () => {
if (!initialSignatures) return;
let loadedCount = 0;
const totalToLoad = (initialSignatures.fullSignature ? 1 : 0) + (initialSignatures.initials ? 1 : 0);
const checkComplete = () => {
loadedCount++;
if (loadedCount === totalToLoad) {
setInitialLoaded(true);
}
};
// Load full signature
if (initialSignatures.fullSignature && canvasRef1.current) {
const img1 = new Image();
img1.onload = () => {
setInitialImage1(img1);
const ctx1 = canvasRef1.current?.getContext('2d');
if (ctx1) {
ctx1.clearRect(0, 0, canvasRef1.current!.width, canvasRef1.current!.height);
ctx1.drawImage(img1, 0, 0);
}
checkComplete();
};
img1.src = initialSignatures.fullSignature;
}
// Load initials
if (initialSignatures.initials && canvasRef2.current) {
const img2 = new Image();
img2.onload = () => {
setInitialImage2(img2);
const ctx2 = canvasRef2.current?.getContext('2d');
if (ctx2) {
ctx2.clearRect(0, 0, canvasRef2.current!.width, canvasRef2.current!.height);
ctx2.drawImage(img2, 0, 0);
}
checkComplete();
};
img2.src = initialSignatures.initials;
}
if (totalToLoad === 0) {
setInitialLoaded(true);
}
};
const handleMouseDown = (e: React.MouseEvent<HTMLCanvasElement>) => { const handleMouseDown = (e: React.MouseEvent<HTMLCanvasElement>) => {
setIsDrawing(true); setIsDrawing(true);
@ -104,31 +25,9 @@ const DrawSignatureCanvas: React.FC<Props> = ({ onSignatureChange, initialSignat
if (!isDrawing) return; if (!isDrawing) return;
const rect = e.currentTarget.getBoundingClientRect(); const rect = e.currentTarget.getBoundingClientRect();
const point = { x: e.clientX - rect.left, y: e.clientY - rect.top }; const point = { x: e.clientX - rect.left, y: e.clientY - rect.top };
const newPath = [...currentPath, point]; const newPath = [...currentPath, point]; // <- Build new path
setCurrentPath(newPath); setCurrentPath(newPath); // <- Save for next event
drawPath(e.currentTarget as HTMLCanvasElement, newPath); // <- Draw current
// Draw immediately for smooth experience
drawCurrentPath(e.currentTarget as HTMLCanvasElement, newPath);
};
const drawCurrentPath = (canvas: HTMLCanvasElement, path: Array<{ x: number; y: number }>) => {
if (!canvas || path.length < 2) return;
const ctx = canvas.getContext('2d');
if (!ctx) return;
// Only draw the current path segment without clearing the canvas
ctx.strokeStyle = '#000';
ctx.lineWidth = 2;
ctx.lineJoin = 'round';
ctx.lineCap = 'round';
const lastPoint = path[path.length - 2];
const currentPoint = path[path.length - 1];
ctx.beginPath();
ctx.moveTo(lastPoint.x, lastPoint.y);
ctx.lineTo(currentPoint.x, currentPoint.y);
ctx.stroke();
}; };
const exportCanvasAsImage = (canvas: HTMLCanvasElement | null): string | null => { const exportCanvasAsImage = (canvas: HTMLCanvasElement | null): string | null => {
@ -143,48 +42,45 @@ const DrawSignatureCanvas: React.FC<Props> = ({ onSignatureChange, initialSignat
if (activeCanvas === 'full') { if (activeCanvas === 'full') {
const newPaths = [...paths1, currentPath]; const newPaths = [...paths1, currentPath];
setPaths1(newPaths); setPaths1(newPaths);
const fullSignature = exportCanvasAsImage(canvasRef1.current);
onSignatureChange({ fullSignature, initials: exportCanvasAsImage(canvasRef2.current) });
} else { } else {
const newPaths = [...paths2, currentPath]; const newPaths = [...paths2, currentPath];
setPaths2(newPaths); setPaths2(newPaths);
const initials = exportCanvasAsImage(canvasRef2.current);
onSignatureChange({ fullSignature: exportCanvasAsImage(canvasRef1.current), initials });
} }
setCurrentPath([]); setCurrentPath([]);
// Export both canvases and notify parent
const fullSignature = exportCanvasAsImage(canvasRef1.current);
const initials = exportCanvasAsImage(canvasRef2.current);
onSignatureChange({ fullSignature, initials });
}; };
const redrawCanvas = (canvas: HTMLCanvasElement, paths: Array<Array<{ x: number; y: number }>>, initialImage: HTMLImageElement | null) => { const drawPath = (canvas: HTMLCanvasElement | null, path: Array<{ x: number; y: number }>) => {
if (!canvas) return;
const ctx = canvas.getContext('2d'); const ctx = canvas.getContext('2d');
if (!ctx) return; if (!ctx) return;
// Clear canvas const allPaths =
canvas === canvasRef1.current ? [...paths1, path] : [...paths2, path];
ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.clearRect(0, 0, canvas.width, canvas.height);
// Draw initial signature if exists
if (initialImage) {
ctx.drawImage(initialImage, 0, 0);
}
// Draw all paths
ctx.strokeStyle = '#000'; ctx.strokeStyle = '#000';
ctx.lineWidth = 2; ctx.lineWidth = 2;
ctx.lineJoin = 'round'; ctx.lineJoin = 'round';
ctx.lineCap = 'round'; ctx.lineCap = 'round';
paths.forEach((path) => { allPaths.forEach((p) => {
if (path.length < 2) return; if (p.length < 2) return;
ctx.beginPath(); ctx.beginPath();
ctx.moveTo(path[0].x, path[0].y); ctx.moveTo(p[0].x, p[0].y);
for (let i = 1; i < path.length; i++) { for (let i = 1; i < p.length; i++) {
ctx.lineTo(path[i].x, path[i].y); ctx.lineTo(p[i].x, p[i].y);
} }
ctx.stroke(); ctx.stroke();
}); });
}; };
const clearCanvas = () => { const clearCanvas = () => {
if (canvasRef1.current) { if (canvasRef1.current) {
const ctx1 = canvasRef1.current.getContext('2d'); const ctx1 = canvasRef1.current.getContext('2d');
@ -197,30 +93,9 @@ const DrawSignatureCanvas: React.FC<Props> = ({ onSignatureChange, initialSignat
setPaths1([]); setPaths1([]);
setPaths2([]); setPaths2([]);
setInitialImage1(null);
setInitialImage2(null);
setInitialLoaded(false);
onSignatureChange({ fullSignature: null, initials: null }); onSignatureChange({ fullSignature: null, initials: null });
}; };
const undoLastPath = () => {
if (activeCanvas === 'full' && paths1.length > 0) {
const newPaths = paths1.slice(0, -1);
setPaths1(newPaths);
redrawCanvas(canvasRef1.current!, newPaths, initialImage1);
} else if (activeCanvas === 'initials' && paths2.length > 0) {
const newPaths = paths2.slice(0, -1);
setPaths2(newPaths);
redrawCanvas(canvasRef2.current!, newPaths, initialImage2);
}
// Update parent with new signature data
setTimeout(() => {
const fullSignature = exportCanvasAsImage(canvasRef1.current);
const initials = exportCanvasAsImage(canvasRef2.current);
onSignatureChange({ fullSignature, initials });
}, 10);
};
return ( return (
<div className="h-full flex flex-col"> <div className="h-full flex flex-col">
@ -238,6 +113,8 @@ const DrawSignatureCanvas: React.FC<Props> = ({ onSignatureChange, initialSignat
<canvas <canvas
ref={canvasRef1} ref={canvasRef1}
className="w-full h-48 cursor-crosshair" className="w-full h-48 cursor-crosshair"
width={canvasRef1.current?.clientWidth || 600} // use real width
height={canvasRef1.current?.clientHeight || 180}
onMouseDown={handleMouseDown} onMouseDown={handleMouseDown}
onMouseMove={handleMouseMove} onMouseMove={handleMouseMove}
onMouseUp={handleMouseUp} onMouseUp={handleMouseUp}
@ -252,6 +129,8 @@ const DrawSignatureCanvas: React.FC<Props> = ({ onSignatureChange, initialSignat
<div className="border-2 border-dashed border-gray-300 rounded-lg bg-gray-50 hover:bg-gray-100 transition-colors"> <div className="border-2 border-dashed border-gray-300 rounded-lg bg-gray-50 hover:bg-gray-100 transition-colors">
<canvas <canvas
ref={canvasRef2} ref={canvasRef2}
width={canvasRef2.current?.clientWidth || 300}
height={canvasRef2.current?.clientHeight || 180}
className="w-full h-48 cursor-crosshair" className="w-full h-48 cursor-crosshair"
onMouseDown={handleMouseDown} onMouseDown={handleMouseDown}
onMouseMove={handleMouseMove} onMouseMove={handleMouseMove}
@ -268,14 +147,7 @@ const DrawSignatureCanvas: React.FC<Props> = ({ onSignatureChange, initialSignat
className="px-4 py-2 text-sm border border-gray-300 rounded-md hover:bg-gray-50 transition-colors" className="px-4 py-2 text-sm border border-gray-300 rounded-md hover:bg-gray-50 transition-colors"
onClick={clearCanvas} onClick={clearCanvas}
> >
Clear All Clear
</button>
<button
className="px-4 py-2 text-sm border border-gray-300 rounded-md hover:bg-gray-50 transition-colors"
onClick={undoLastPath}
disabled={!activeCanvas || (activeCanvas === 'full' ? paths1.length === 0 : paths2.length === 0)}
>
Undo Last
</button> </button>
</div> </div>
</div> </div>
@ -283,4 +155,4 @@ const DrawSignatureCanvas: React.FC<Props> = ({ onSignatureChange, initialSignat
); );
}; };
export default DrawSignatureCanvas; export default DrawSignatureCanvas;

View File

@ -25,8 +25,7 @@ const SignatureManager: React.FC = () => {
const [loading, setLoading] = useState<boolean>(false) const [loading, setLoading] = useState<boolean>(false)
const [signatures, setSignatures] = useState<Signature[]>([]); const [signatures, setSignatures] = useState<Signature[]>([]);
const [activeDropdown, setActiveDropdown] = useState<string | null>(null); const [activeDropdown, setActiveDropdown] = useState<string | null>(null);
const [showAddSignature, setShowAddSignature] = useState<boolean>(false); const [showAddSignature, setShowAddSignature] = useState<boolean>(false)
const [editingSignature, setEditingSignature] = useState<Signature | null>(null);
const getAllSignatures = async () => { const getAllSignatures = async () => {
setLoading(true) setLoading(true)
@ -48,13 +47,6 @@ const SignatureManager: React.FC = () => {
const handleEdit = (id: string) => { const handleEdit = (id: string) => {
console.log('Edit signature:', id); console.log('Edit signature:', id);
let editSignature = signatures.find((item) => item.id === id);
console.log("editSignature", editSignature);
if (editSignature) {
setEditingSignature(editSignature);
setShowAddSignature(true);
}
setActiveDropdown(null); setActiveDropdown(null);
}; };
@ -82,21 +74,14 @@ const SignatureManager: React.FC = () => {
setActiveDropdown(null); setActiveDropdown(null);
setLoading(false) setLoading(false)
} }
}; };
const toggleDropdown = (id: string) => { const toggleDropdown = (id: string) => {
setActiveDropdown(activeDropdown === id ? null : id); setActiveDropdown(activeDropdown === id ? null : id);
}; };
const handleAddNew = () => {
setEditingSignature(null);
setShowAddSignature(true);
};
const handleModalClose = () => {
setShowAddSignature(false);
setEditingSignature(null);
};
return ( return (
<> <>
@ -117,7 +102,7 @@ const SignatureManager: React.FC = () => {
<h1 className="text-[17px] font-medium text-gray-500 mb-2">Signatures</h1> <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> <p className="text-gray-300 text-sm">Add or update your name and signature styles.</p>
</div> </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={handleAddNew}> <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="" /> <FiPlus className="" />
ADD ADD
</button> </button>
@ -168,6 +153,7 @@ const SignatureManager: React.FC = () => {
</div> </div>
</div> </div>
{/* Initial Column */} {/* Initial Column */}
<div className="col-span-5"> <div className="col-span-5">
<div className="flex flex-col space-y-2 relative ps-6 border-l-3 border-green-600 rounded-bl-2xl rounded-tl-2xl"> <div className="flex flex-col space-y-2 relative ps-6 border-l-3 border-green-600 rounded-bl-2xl rounded-tl-2xl">
@ -187,6 +173,7 @@ const SignatureManager: React.FC = () => {
</div> </div>
</div> </div>
{/* Actions Column */} {/* Actions Column */}
<div className="col-span-2 flex justify-between items-start pt-9 ps-8 "> <div className="col-span-2 flex justify-between items-start pt-9 ps-8 ">
<div className="relative "> <div className="relative ">
@ -246,11 +233,7 @@ const SignatureManager: React.FC = () => {
)} )}
{showAddSignature && ( {showAddSignature && (
<AddSignatureModal <AddSignatureModal setShowAddSignature={setShowAddSignature} getAllSignatures={getAllSignatures} />
setShowAddSignature={handleModalClose}
getAllSignatures={getAllSignatures}
editingSignature={editingSignature}
/>
)} )}
</div> </div>
}</> }</>