// import React from 'react' // import { SaveType } from '../client/SignDocument'; // interface SignConProps { // setOpenSign: React.Dispatch>; // recipientId: string; // saved: SaveType; // setSaved: React.Dispatch>; // // save: () => void; // } // const SignCon: React.FC = ({ setOpenSign, recipientId, saved, setSaved }) => { // return ( //
SignCon
// ) // } // export default SignCon import React, { useEffect, useState } from 'react'; // import api from '../../config/api'; import DrawSignatureCanvas from '../setting/Signature/DrawSignatureCanvas'; import { AiOutlineUpload, AiOutlineEdit } from 'react-icons/ai'; import { MdCloudUpload } from 'react-icons/md'; import { FaSpinner } from "react-icons/fa"; import { GrCheckboxSelected } from "react-icons/gr"; import { Bounce, toast } from "react-toastify"; import axios from 'axios'; import { SaveType } from '../client/SignDocument'; import { CiSaveDown1 } from 'react-icons/ci'; import api from '../../config/api'; 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 { // setShowAddSignature?: (value: boolean) => void; // getAllSignatures: () => Promise; // editingSignature?: Signature | null; recipientId?: string; setOpenSign: React.Dispatch>; saved: SaveType; setSaved: React.Dispatch>; signTagId: boolean } interface Account { id: number; isDefault: boolean; name: string; } interface UserData { id: string; firstName: string; lastName: string; email: string; language: string; account: Account; } interface SelectStyle { id: number, style: string } const AddSignatureModal: React.FC = ({ setOpenSign, recipientId, saved, setSaved, signTagId }) => { console.log("savedModal", saved) const [activeTab, setActiveTab] = useState<'TYPED' | 'DRAW' | 'UPLOAD' | 'SAVED'>('TYPED'); const [fullName, setFullName] = useState(''); const [initials, setInitials] = useState(''); const [isSubmitting, setIsSubmitting] = useState(false); const [signatures, setSignatures] = useState<{ fullSignature: string | null; initials: string | null; }>({ fullSignature: null, initials: null }); const signatureOptions = [ { id: 1, name: 'print', initials: 'LA', style: 'print' }, { id: 2, name: 'cursive', initials: 'LA', style: 'cursive' }, { id: 3, name: 'script', initials: 'LA', style: 'script' }, { id: 4, name: 'elegant', initials: 'LA', style: 'elegant' }, { id: 5, name: 'modern', initials: 'LA', style: 'modern' }, { id: 6, name: 'classic', initials: 'LA', style: 'classic' }, ]; // User data const [user, setUser] = useState({ id: "", firstName: "", lastName: "", email: "", language: "", account: { id: 0, isDefault: false, name: "", }, }); console.log("User data", user) const [selectedSignature, setSelectedSignature] = useState( signatureOptions.length > 0 ? { id: signatureOptions[0].id, style: signatureOptions[0].style } : { id: 0, style: "" } ); // Store the actual file const [file1, setFile1] = useState(null); const [file2, setFile2] = useState(null); // Store the preview URL const [preview1, setPreview1] = useState(null); const [preview2, setPreview2] = useState(null); const [preSaveSignatures, setPreSaveSignatures] = useState([]) // Navigation items const navigationItems = [ { id: 'TYPED', label: 'TYPED', icon: }, { id: 'DRAW', label: 'DRAW', icon: }, { id: 'UPLOAD', label: 'UPLOAD', icon: }, { id: 'SAVED', label: 'SAVED', icon: }, ]; const handleSignatureChange = (data: { fullSignature: string | null; initials: string | null }) => { setSignatures(data); }; // Getting Signatures - START useEffect(() => { (async () => { const res = await axios.get(`${import.meta.env.VITE_BASE_URI}/api/sign/signatures?recipientId=${recipientId}`, { headers: { "ngrok-skip-browser-warning": "69420" } }) if (res?.data) { let preSavedSignatures = res?.data setPreSaveSignatures(preSavedSignatures) } })() }, []) // Getting Signatures - END // Cleanup preview URLs when component unmounts or image changes useEffect(() => { return () => { if (preview1) URL.revokeObjectURL(preview1); if (preview2) URL.revokeObjectURL(preview2); }; }, [preview1, preview2]); const handleImageChange = async ( e: React.ChangeEvent, setFile: React.Dispatch>, setPreview: React.Dispatch>, type: "fullSignature" | "initials" ) => { const file = e.target.files?.[0]; if (file) { setFile(file); const previewUrl = URL.createObjectURL(file); setPreview(previewUrl); // Convert to base64 const base64 = await convertToBase64(file); // Update the appropriate signature setSignatures((prev) => ({ ...prev, [type]: base64, })); } }; const convertToBase64 = (file: File): Promise => { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.readAsDataURL(file); reader.onload = () => resolve(reader.result as string); reader.onerror = (error) => reject(error); }); }; const handleSubmit = async () => { setIsSubmitting(true); console.log("handleSubmit Called") if (!signatures.fullSignature || !signatures.initials) { alert('Please provide both signature and initials'); setIsSubmitting(false); return; } try { const payload = { tagId: signTagId, // signatureId: signatureId, type: activeTab, firstName: fullName.split(' ')[0] || user.firstName, lastName: fullName.split(' ')[1] || user.lastName, initials: "", initialsBase64: signatures.initials, signatureBase64: signatures.fullSignature, font: selectedSignature.style }; console.log("payload", payload) // if (isEditMode && editingSignature) { // // Update existing signature // const updatePayload = { // ...payload, // signatureId: editingSignature.id // }; // res = await axios.put(`${import.meta.env.VITE_BASE_URI}/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 let res = await axios.post(`${import.meta.env.VITE_BASE_URI}/api/sign/signatures?recipientId=${recipientId}`, payload, { headers: { "ngrok-skip-browser-warning": "69420" } }); 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) { setSignatures({ fullSignature:"", initials:"", }) setSaved({ saveType: res.data.signatureType ?? null, save: true, signature: res.data.signatureBlob ?? null, initial: res.data.initialsBlob ?? null, }); setOpenSign(false); } } catch (error) { console.error("Error submitting signature:", 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 { setIsSubmitting(false); } }; const renderContent = () => { switch (activeTab) { case 'TYPED': return (

Choose Signature Style

Select from pre-designed signature styles

{signatureOptions.map((option) => (
setSelectedSignature({ id: option.id, style: option.style })} className="w-4 h-4 text-blue-600 focus:ring-blue-500" />
Signed by:
{fullName || option.name}
dca3e646-62cd-4cc...
DS
{initials || option.initials}
))}
); case 'DRAW': return ( ); case 'UPLOAD': return (

Upload Signature

{/* Upload 1 */}
handleImageChange(e, setFile1, setPreview1, "fullSignature")} />
{/* Upload 2 */}
handleImageChange(e, setFile2, setPreview2, "initials")} />
); case 'SAVED': return (

Saved Signature's

{/*

Select from pre-designed signature styles

*/}
{preSaveSignatures.map((signature) => (
{/* Signature Column */}
Signed by:
{/* Signature Image or Fallback Text */}
{signature?.signatureBlob ? ( Signature ) : (
No Signature
)}
{/* Name */}
{signature?.signatureHash ?? ' '}
{/* Initial Column */}
Initials
{/* Initials Image */}
{signature?.initialsBlob ? ( Initials ) : (
No Initials
)}
{/* Optional initials hash or font */}
{signature?.initialsHash || " "}
))}
); default: return null; } }; const getUserDetails = async () => { try { let res = await axios.get(`/api/user/details`, { headers: { "ngrok-skip-browser-warning": "69420", } }); 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(); }, []); return (
{/* Sidebar Navigation */}
{/* Header */}

Add Signature Sign

Create your digital signature

{/* Form Inputs */}
setFullName(e.target.value)} placeholder="Enter full name" className="w-full px-3 py-2 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent" />
setInitials(e.target.value)} placeholder="Enter initials" className="w-full px-3 py-2 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent" />
{/* Navigation Menu */}
{/* Main Content Area */}
{/* Header with close button */} {/* Content */}
{/* */} {renderContent()}
{/* Footer Buttons in Main Area */}
); }; export default AddSignatureModal;