Employee Details
+ +Name: {qrData.name}
+Employee Number: {qrData.employeeNumber}
+ +Family Members:
+ {qrData.familyMembers.map((member) => ( +{error}
+diff --git a/frontend/package-lock.json b/frontend/package-lock.json index e02197e..6914248 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -8,6 +8,7 @@ "name": "frontend", "version": "0.1.0", "dependencies": { + "@zxing/browser": "^0.1.5", "next": "15.1.0", "react": "^19.0.0", "react-dom": "^19.0.0" @@ -1157,6 +1158,38 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@zxing/browser": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@zxing/browser/-/browser-0.1.5.tgz", + "integrity": "sha512-4Lmrn/il4+UNb87Gk8h1iWnhj39TASEHpd91CwwSJtY5u+wa0iH9qS0wNLAWbNVYXR66WmT5uiMhZ7oVTrKfxw==", + "optionalDependencies": { + "@zxing/text-encoding": "^0.9.0" + }, + "peerDependencies": { + "@zxing/library": "^0.21.0" + } + }, + "node_modules/@zxing/library": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/@zxing/library/-/library-0.21.3.tgz", + "integrity": "sha512-hZHqFe2JyH/ZxviJZosZjV+2s6EDSY0O24R+FQmlWZBZXP9IqMo7S3nb3+2LBWxodJQkSurdQGnqE7KXqrYgow==", + "peer": true, + "dependencies": { + "ts-custom-error": "^3.2.1" + }, + "engines": { + "node": ">= 10.4.0" + }, + "optionalDependencies": { + "@zxing/text-encoding": "~0.9.0" + } + }, + "node_modules/@zxing/text-encoding": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@zxing/text-encoding/-/text-encoding-0.9.0.tgz", + "integrity": "sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA==", + "optional": true + }, "node_modules/acorn": { "version": "8.14.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", @@ -5362,6 +5395,15 @@ "typescript": ">=4.2.0" } }, + "node_modules/ts-custom-error": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/ts-custom-error/-/ts-custom-error-3.3.1.tgz", + "integrity": "sha512-5OX1tzOjxWEgsr/YEUWSuPrQ00deKLh6D7OTWcvNHm12/7QPyRh8SYpyWvA4IZv8H/+GQWQEh/kwo95Q9OVW1A==", + "peer": true, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/ts-interface-checker": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", diff --git a/frontend/package.json b/frontend/package.json index e091da4..4a96a50 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -9,15 +9,16 @@ "lint": "next lint" }, "dependencies": { + "@zxing/browser": "^0.1.5", + "next": "15.1.0", "react": "^19.0.0", - "react-dom": "^19.0.0", - "next": "15.1.0" + "react-dom": "^19.0.0" }, "devDependencies": { - "postcss": "^8", - "tailwindcss": "^3.4.1", + "@eslint/eslintrc": "^3", "eslint": "^9", "eslint-config-next": "15.1.0", - "@eslint/eslintrc": "^3" + "postcss": "^8", + "tailwindcss": "^3.4.1" } } diff --git a/frontend/src/app/admin/page.js b/frontend/src/app/admin/page.js new file mode 100644 index 0000000..affe3e9 --- /dev/null +++ b/frontend/src/app/admin/page.js @@ -0,0 +1,128 @@ +"use client" +import React, { useEffect, useRef, useState } from "react"; +import { BrowserMultiFormatReader } from "@zxing/browser"; + +const QRCodeScanner = () => { + const [qrData, setQrData] = useState(null); + const [error, setError] = useState(null); + const [attendance, setAttendance] = useState({}); + const videoRef = useRef(null); + + useEffect(() => { + const codeReader = new BrowserMultiFormatReader(); + + codeReader + .decodeOnceFromVideoDevice( + undefined, + videoRef.current, + { video: { facingMode: "environment" } } + ) + .then((result) => { + const parsedData = JSON.parse(result.text); // Parse JSON data from the QR code + setQrData(parsedData); + setAttendance( + parsedData.familyMembers.reduce((acc, member) => { + acc[member.name] = false; // Initialize all family members as not present + return acc; + }, {}) + ); + }) + .catch((err) => { + setError( + err.name === "NotAllowedError" + ? "Camera access denied. Please enable it in browser settings." + : "QR Code scanning failed" + ); + }); + + return () => { + codeReader.reset(); // Clean up when the component is unmounted + }; + }, []); + + const handleAttendanceChange = (name) => { + setAttendance((prev) => ({ ...prev, [name]: !prev[name] })); + }; + + const handleSubmit = () => { + console.log("Attendance Submitted:", attendance); + alert("Attendance has been submitted successfully!"); + }; + + return ( +
+ Streamlined event management made easy +
+Name: {qrData.name}
+Employee Number: {qrData.employeeNumber}
+ +{error}
+