diff --git a/app/print.css b/app/print.css index 5ef5540..329a2c3 100644 --- a/app/print.css +++ b/app/print.css @@ -64,7 +64,7 @@ /* Etat de vaud "signature" component */ .etat-de-vaud-div { display: flex; - margin-top: 20px; + margin-top: 10px; margin-bottom: 30px; } @@ -150,4 +150,20 @@ .less-margin-conclusion { margin-top: 33px; } + /* Date */ + .date-div { + min-width: 100px; + } + /* Signature */ + #signature-pad { + border: none; + margin: 0; + width: 200px; + height: 60px; + position: relative; + top: -30px; + } + .signature-buttons { + display: none; + } } \ No newline at end of file diff --git a/app/responsable/page.tsx b/app/responsable/page.tsx index 511eda4..2b3ed02 100644 --- a/app/responsable/page.tsx +++ b/app/responsable/page.tsx @@ -2,18 +2,40 @@ import React from "react"; import EtatDeVaudSignature from "../components/EtatDeVaudSignature"; import { reportStorageInterface } from "@/interfaces/reportStorageInterface"; +import SignaturePad from "signature_pad"; export default function Page() { const inputFile = React.useRef(null); const [rapportStorage, setRapportStorage] = React.useState({}) const [isDataLoaded, setIsDataLoaded] = React.useState(false) + const canvasRef = React.useRef(null); + const signaturePadRef = React.useRef(null); + const signatureImageFile = React.useRef(null); React.useEffect(() => { const storedData = localStorage.getItem('rapport-de-stage'); + const storedDataObject = JSON.parse(storedData || '{}'); if (storedData) { setRapportStorage(JSON.parse(storedData)); } setIsDataLoaded(true); + + const timer = setTimeout(() => { + const canvas = canvasRef.current; + if (!canvas) return; + + canvas.width = canvas.offsetWidth; + canvas.height = canvas.offsetHeight; + signaturePadRef.current = new SignaturePad(canvas, {penColor: "#1e22aa"}); + signaturePadRef.current.addEventListener("endStroke", () => { + updateStorageOnChange('signature', signaturePadRef.current?.toDataURL() || '') + }); + if(storedDataObject.signature) { + signaturePadRef.current.fromDataURL(storedDataObject.signature); + } + }, 100); + + return () => clearTimeout(timer); }, []); const handleFileUpload = (e: React.ChangeEvent) => { @@ -49,9 +71,39 @@ export default function Page() { } }; + const handleSignatureUpload = (e: React.ChangeEvent) => { + const confirm = window.confirm('Voulez-vous vraiment importer cette signature ?') + if(confirm) { + const { files } = e.target; + if (files && files.length) { + const reader = new FileReader(); + reader.onload = (event) => { + try { + if(typeof(reader.result) == 'string') { + signaturePadRef.current?.fromDataURL(reader.result) + updateStorageOnChange('signature', reader.result) + } + } catch (error) { + alert("Erreur de lecture de l'image."); + } + }; + reader.onerror = () => { + alert("Erreur lors de la lecture du fichier."); + }; + reader.readAsDataURL(files[0]); + } + } + }; + function updateStorageOnChange(element:string, elementValue:string) { - rapportStorage[element as keyof reportStorageInterface] = elementValue - localStorage.setItem('rapport-de-stage', JSON.stringify(rapportStorage)) + setRapportStorage((prevRapportStorage) => { + const updatedRapportStorage = { + ...prevRapportStorage, + [element]: elementValue, + }; + localStorage.setItem('rapport-de-stage', JSON.stringify(updatedRapportStorage)); + return updatedRapportStorage; + }) } function onButtonClick() { @@ -843,7 +895,7 @@ export default function Page() { updateStorageOnChange('bilanStage', e.target.value)} id="take-time-yes" className="radio-input" type="radio" /> -
+
updateStorageOnChange('fillUpDate', e.target.value)} id="date" className="w-2/3" type="text" placeholder={".".repeat(500)} />
@@ -855,7 +907,28 @@ export default function Page() {
- updateStorageOnChange('signature', e.target.value)} id="Signature" className="w-auto" type="text" placeholder={".".repeat(500)} /> +
+ + + + +
diff --git a/package-lock.json b/package-lock.json index 47bbf01..21b173a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,8 @@ "dependencies": { "next": "14.2.7", "react": "^18", - "react-dom": "^18" + "react-dom": "^18", + "signature_pad": "^5.0.4" }, "devDependencies": { "@types/node": "^20", @@ -4422,6 +4423,11 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/signature_pad": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/signature_pad/-/signature_pad-5.0.4.tgz", + "integrity": "sha512-nngOixbwLAUOuH3QnZwlgwmynQblxmo4iWacKFwfymJfiY+Qt+9icNtcIe/okqXKun4hJ5QTFmHyC7dmv6lf2w==" + }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", diff --git a/package.json b/package.json index a246c46..0e2e1d4 100644 --- a/package.json +++ b/package.json @@ -9,18 +9,19 @@ "lint": "next lint" }, "dependencies": { + "next": "14.2.7", "react": "^18", "react-dom": "^18", - "next": "14.2.7" + "signature_pad": "^5.0.4" }, "devDependencies": { - "typescript": "^5", "@types/node": "^20", "@types/react": "^18", "@types/react-dom": "^18", + "eslint": "^8", + "eslint-config-next": "14.2.7", "postcss": "^8", "tailwindcss": "^3.4.1", - "eslint": "^8", - "eslint-config-next": "14.2.7" + "typescript": "^5" } }