SME-Web/src/components/signature/SignUpload.tsx

174 lines
5.4 KiB
TypeScript

import React, { useState, useRef } from 'react';
import { SaveType, SaveTypeEnum } from '../client/SignDocument';
interface SignUploadProps {
saved: SaveType;
setSaved: React.Dispatch<React.SetStateAction<SaveType>>;
}
const SignUpload: React.FC<SignUploadProps> = ({ saved, setSaved }) => {
const [signatureFile, setSignatureFile] = useState<string>("");
const [initialFile, setInitialFile] = useState<string>("");
const signatureInputRef = useRef<HTMLInputElement>(null);
const initialInputRef = useRef<HTMLInputElement>(null);
const handleDrop = (
e: React.DragEvent<HTMLDivElement>,
type: 'signature' | 'initial'
) => {
e.preventDefault();
const file = e.dataTransfer.files[0];
if (file && file.type.startsWith('image/')) {
type == 'signature' ? setSignatureFile(file) : setInitialFile(file);
}
};
const handleClick = (type: 'signature' | 'initial') => {
if (type == 'signature') signatureInputRef.current?.click();
else initialInputRef.current?.click();
};
// const handleFileChange = (
// e: React.ChangeEvent<HTMLInputElement>,
// type: 'signature' | 'initial'
// ) => {
// const file = e.target.files?.[0];
// if (file && file.type.startsWith('image/')) {
// type == 'signature' ? setSignatureFile(file) : setInitialFile(file);
// }
// };
const toBase64 = (file: File): Promise<string> =>
new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => {
if (typeof reader.result == 'string') {
resolve(reader.result);
} else {
reject(new Error('FileReader result is not a string'));
}
};
reader.onerror = reject;
});
const handleFileChange = async (
e: React.ChangeEvent<HTMLInputElement>,
type: 'signature' | 'initial'
): Promise<void> => {
const file = e.target.files?.[0];
if (file && file.type.startsWith('image/')) {
try {
const base64 = await toBase64(file);
type == 'signature' ? setSignatureFile(base64) : setInitialFile(base64);
} catch (error) {
console.error('Error converting file to base64:', error);
}
}
};
const handleSave = () => {
if (!signatureFile || !initialFile) {
alert('Please upload both signature and initials.');
return;
}
setSaved({
saveType: SaveTypeEnum.UPLOAD,
signature: signatureFile,
initial: initialFile,
save: true
})
alert('Files saved as Blob. Check console for details.');
};
return (
<div className="w-full border-t-1 border-slate-300">
<div className="flex gap-2 text-sm m-2.5">
{/* Signature Upload */}
<div
className="border-1 w-full border-dashed border-gray-300 rounded-lg py-8 px-6 flex flex-col items-center justify-center cursor-pointer hover:border-[var(--primary)] transition relative"
onClick={() => handleClick('signature')}
onDragOver={(e) => e.preventDefault()}
onDrop={(e) => handleDrop(e, 'signature')}
>
<input
ref={signatureInputRef}
type="file"
accept="image/*"
className="hidden"
onChange={(e) => handleFileChange(e, 'signature')}
/>
<p className="text-gray-400 text-center">
{signatureFile ? 'Signature Uploaded' : 'Drop Signature Here or Click to Upload'}
</p>
{signatureFile && (
<img
src={signatureFile}
alt="Signature Preview"
className="mt-4 h-32 object-contain"
/>
)}
</div>
{/* Initials Upload */}
<div
className="border-1 w-full border-dashed border-gray-300 rounded-lg py-8 px-6 flex flex-col items-center justify-center cursor-pointer hover:border-[var(--primary)] transition relative"
onClick={() => handleClick('initial')}
onDragOver={(e) => e.preventDefault()}
onDrop={(e) => handleDrop(e, 'initial')}
>
<input
ref={initialInputRef}
type="file"
accept="image/*"
className="hidden"
onChange={(e) => handleFileChange(e, 'initial')}
/>
<p className="text-gray-400 text-center">
{initialFile ? 'Initials Uploaded' : 'Drop Initials Here or Click to Upload'}
</p>
{initialFile && (
<img
src={initialFile}
alt="Initial Preview"
className="mt-4 h-32 object-contain"
/>
)}
</div>
</div>
{/* <button
className="mt-6 bg-blue-600 text-white px-6 py-2 rounded hover:bg-blue-700 transition"
onClick={handleSave}
>
Save as BLOB
</button> */}
<div className="m-3 flex justify-end gap-2">
{/* <button
// onClick={close}
className="border-1 border-[var(--primary)] text-[var(--primary)] px-4 text-sm py-1 rounded shadow opacity-70 hover:opacity-100 transition-all cursor-pointer"
>
Cancel
</button> */}
<button
onClick={handleSave}
// onClick={save}
className="bg-[var(--primary)] opacity-90 hover:opacity-100 text-white px-4 text-sm py-1 rounded shadow disabled:opacity-50 transition-all cursor-pointer"
>
Save
</button>
</div>
</div>
);
};
export default SignUpload;