├── README.md ├── _metadata.json ├── package.json ├── server.js └── App.tsx /README.md: -------------------------------------------------------------------------------- 1 | cd backend 2 | npm install 3 | npm run dev 4 | 5 | cd frontend 6 | npm install 7 | npm run dev -------------------------------------------------------------------------------- /_metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "hash": "41563d49", 3 | "configHash": "2230fbfd", 4 | "lockfileHash": "286322be", 5 | "browserHash": "9498c5b9", 6 | "optimized": {}, 7 | "chunks": {} 8 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "qr-code-backend", 3 | "version": "1.0.0", 4 | "description": "QR Code encoder/decoder backend", 5 | "main": "server.js", 6 | "scripts": { 7 | "start": "node server.js", 8 | "dev": "nodemon server.js" 9 | }, 10 | "dependencies": { 11 | "express": "^4.18.2", 12 | "cors": "^2.8.5", 13 | "qrcode": "^1.5.3", 14 | "jimp": "^0.22.10", 15 | "qrcode-reader": "^1.0.4", 16 | "multer": "^1.4.5-lts.1" 17 | }, 18 | "devDependencies": { 19 | "nodemon": "^3.0.2" 20 | } 21 | } -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const cors = require('cors'); 3 | const QRCode = require('qrcode'); 4 | const Jimp = require('jimp'); 5 | const QrCode = require('qrcode-reader'); 6 | const multer = require('multer'); 7 | const path = require('path'); 8 | 9 | const app = express(); 10 | const port = 5000; 11 | 12 | // Middleware 13 | app.use(cors()); 14 | app.use(express.json()); 15 | 16 | // Configure multer for file upload 17 | const storage = multer.memoryStorage(); 18 | const upload = multer({ storage: storage }); 19 | 20 | // Generate QR Code 21 | app.post('/generate-qr', async (req, res) => { 22 | try { 23 | const { text } = req.body; 24 | if (!text) { 25 | return res.status(400).json({ error: 'Text is required' }); 26 | } 27 | 28 | const qrCode = await QRCode.toDataURL(text); 29 | res.json({ qrCode }); 30 | } catch (error) { 31 | res.status(500).json({ error: 'Failed to generate QR code' }); 32 | } 33 | }); 34 | 35 | // Decode QR Code 36 | app.post('/decode-qr', upload.single('qrImage'), async (req, res) => { 37 | try { 38 | if (!req.file) { 39 | return res.status(400).json({ error: 'No image uploaded' }); 40 | } 41 | 42 | const image = await Jimp.read(req.file.buffer); 43 | const qrCodeInstance = new QrCode(); 44 | 45 | const value = await new Promise((resolve, reject) => { 46 | qrCodeInstance.callback = (err, value) => { 47 | if (err) reject(err); 48 | resolve(value); 49 | }; 50 | qrCodeInstance.decode(image.bitmap); 51 | }); 52 | 53 | if (value && value.result) { 54 | res.json({ text: value.result }); 55 | } else { 56 | res.status(400).json({ error: 'Could not decode QR code' }); 57 | } 58 | } catch (error) { 59 | res.status(500).json({ error: 'Failed to decode QR code' }); 60 | } 61 | }); 62 | 63 | app.listen(port, () => { 64 | console.log(`Server running on port ${port}`); 65 | }); -------------------------------------------------------------------------------- /App.tsx: -------------------------------------------------------------------------------- 1 | import { useState } from 'react'; 2 | import { 3 | ChakraProvider, 4 | Box, 5 | VStack, 6 | Heading, 7 | Input, 8 | Button, 9 | Image, 10 | Text, 11 | useToast, 12 | Tabs, 13 | TabList, 14 | Tab, 15 | TabPanels, 16 | TabPanel, 17 | } from '@chakra-ui/react'; 18 | import axios from 'axios'; 19 | 20 | const API_URL = 'http://localhost:5000'; 21 | 22 | function App() { 23 | const [text, setText] = useState(''); 24 | const [qrCode, setQrCode] = useState(''); 25 | const [decodedText, setDecodedText] = useState(''); 26 | const [loading, setLoading] = useState(false); 27 | const toast = useToast(); 28 | 29 | const generateQRCode = async () => { 30 | if (!text) { 31 | toast({ 32 | title: 'Error', 33 | description: 'Please enter some text', 34 | status: 'error', 35 | duration: 3000, 36 | isClosable: true, 37 | }); 38 | return; 39 | } 40 | 41 | try { 42 | setLoading(true); 43 | const response = await axios.post(`${API_URL}/generate-qr`, { text }); 44 | setQrCode(response.data.qrCode); 45 | } catch (error) { 46 | toast({ 47 | title: 'Error', 48 | description: 'Failed to generate QR code', 49 | status: 'error', 50 | duration: 3000, 51 | isClosable: true, 52 | }); 53 | } finally { 54 | setLoading(false); 55 | } 56 | }; 57 | 58 | const handleFileUpload = async (event: React.ChangeEvent) => { 59 | const file = event.target.files?.[0]; 60 | if (!file) return; 61 | 62 | const formData = new FormData(); 63 | formData.append('qrImage', file); 64 | 65 | try { 66 | setLoading(true); 67 | const response = await axios.post(`${API_URL}/decode-qr`, formData, { 68 | headers: { 69 | 'Content-Type': 'multipart/form-data', 70 | }, 71 | }); 72 | setDecodedText(response.data.text); 73 | } catch (error) { 74 | toast({ 75 | title: 'Error', 76 | description: 'Failed to decode QR code', 77 | status: 'error', 78 | duration: 3000, 79 | isClosable: true, 80 | }); 81 | } finally { 82 | setLoading(false); 83 | } 84 | }; 85 | 86 | return ( 87 | 88 | 89 | 90 | QR Code Generator & Scanner 91 | 92 | 93 | 94 | Generate QR Code 95 | Scan QR Code 96 | 97 | 98 | 99 | 100 | 101 | setText(e.target.value)} 105 | /> 106 | 114 | {qrCode && ( 115 | 122 | QR Code 123 | 124 | )} 125 | 126 | 127 | 128 | 129 | 130 | 136 | {decodedText && ( 137 | 144 | Decoded Text: 145 | {decodedText} 146 | 147 | )} 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | ); 156 | } 157 | 158 | export default App; --------------------------------------------------------------------------------