feat: Finalisation formulaire dynamique

This commit is contained in:
N3WT DE COMPET
2026-04-04 20:08:25 +02:00
parent ae06b6fef7
commit 90b0d14418
29 changed files with 1071 additions and 306 deletions

View File

@ -11,6 +11,8 @@ const SignatureField = ({
backgroundColor = '#ffffff',
penColor = '#000000',
penWidth = 2,
displayWidth = 400,
displayHeight = 200,
}) => {
const canvasRef = useRef(null);
const [isDrawing, setIsDrawing] = useState(false);
@ -29,9 +31,6 @@ const SignatureField = ({
// Support High DPI / Retina displays
const devicePixelRatio = window.devicePixelRatio || 1;
const displayWidth = 400;
const displayHeight = 200;
// Ajuster la taille physique du canvas pour la haute résolution
canvas.width = displayWidth * devicePixelRatio;
canvas.height = displayHeight * devicePixelRatio;
@ -56,7 +55,7 @@ const SignatureField = ({
context.lineCap = 'round';
context.lineJoin = 'round';
context.globalCompositeOperation = 'source-over';
}, [backgroundColor, penColor, penWidth]);
}, [backgroundColor, penColor, penWidth, displayWidth, displayHeight]);
useEffect(() => {
initializeCanvas();
@ -226,11 +225,12 @@ const SignatureField = ({
setCurrentPath('');
}
// Notifier le parent du changement avec SVG
// Notifier le parent du changement avec PNG pour garantir
// la compatibilite de rendu cote backend/PDF.
if (onChange) {
const newPaths = [...svgPaths, currentPath].filter((p) => p.length > 0);
const svgData = generateSVG(newPaths);
onChange(svgData);
const canvas = canvasRef.current;
const pngData = canvas ? canvas.toDataURL('image/png') : '';
onChange(pngData);
}
},
[isDrawing, onChange, svgPaths, currentPath]
@ -238,7 +238,7 @@ const SignatureField = ({
// Générer le SVG à partir des paths
const generateSVG = (paths) => {
const svgContent = `<svg width="400" height="200" xmlns="http://www.w3.org/2000/svg">
const svgContent = `<svg width="${displayWidth}" height="${displayHeight}" xmlns="http://www.w3.org/2000/svg">
<rect width="100%" height="100%" fill="${backgroundColor}"/>
${paths
.map(
@ -257,9 +257,6 @@ const SignatureField = ({
const context = canvas.getContext('2d');
// Effacer en tenant compte des dimensions d'affichage
const displayWidth = 400;
const displayHeight = 200;
context.clearRect(0, 0, displayWidth, displayHeight);
context.fillStyle = backgroundColor;
context.fillRect(0, 0, displayWidth, displayHeight);
@ -273,6 +270,14 @@ const SignatureField = ({
}
};
const hintText = readOnly
? isEmpty
? 'Aucune signature'
: 'Signature'
: isEmpty
? 'Signez dans la zone ci-dessus'
: 'Signature capturée';
return (
<div className="signature-field">
{label && (
@ -282,7 +287,7 @@ const SignatureField = ({
</label>
)}
<div className="border border-gray-300 rounded-lg p-4 bg-gray-50">
<div className="border border-gray-300 rounded-lg p-3 bg-gray-50">
<canvas
ref={canvasRef}
className={`border border-gray-200 bg-white rounded touch-none ${
@ -307,16 +312,8 @@ const SignatureField = ({
onTouchEnd={readOnly ? undefined : stopDrawing}
/>
<div className="flex justify-between items-center mt-3">
<div className="text-xs text-gray-500">
{readOnly
? isEmpty
? 'Aucune signature'
: 'Signature'
: isEmpty
? 'Signez dans la zone ci-dessus'
: 'Signature capturée'}
</div>
<div className="flex justify-between items-center mt-2">
<div className="text-xs text-gray-500">{hintText}</div>
{!readOnly && (
<div className="flex gap-2">