├── LICENSE ├── README.md ├── package-lock.json ├── package.json ├── public ├── favicon.png ├── index.html ├── logo192.png ├── logo512.png ├── manifest.json └── robots.txt ├── src ├── App.css ├── App.js ├── assests │ └── QrCode.png ├── components │ ├── QrCode.js │ ├── image.svg │ ├── logo.png │ └── sni.png └── index.js └── yarn.lock /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 ronaldchan333 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # React QR Code Scanner 2 | 3 | A simple React application to scan Quick Response code (QR code). 4 | 5 | ``````` 6 | $ npm i 7 | $ npm start 8 | `````` 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "qrcode", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.16.4", 7 | "@testing-library/react": "^13.1.1", 8 | "@testing-library/user-event": "^13.5.0", 9 | "fs": "^0.0.1-security", 10 | "jimp": "^0.22.10", 11 | "jsqr": "^1.4.0", 12 | "otpauth": "^9.2.0", 13 | "qrcode": "^1.5.3", 14 | "qrcode-reader": "^1.0.4", 15 | "qrcode.react": "^3.1.0", 16 | "react": "^18.1.0", 17 | "react-dom": "^18.1.0", 18 | "react-qr-code": "^2.0.7", 19 | "react-router-dom": "^6.3.0", 20 | "react-scripts": "5.0.1", 21 | "speakeasy": "^2.0.0", 22 | "web-vitals": "^2.1.4" 23 | }, 24 | "scripts": { 25 | "electrion": "electrion .", 26 | "start": "react-scripts start", 27 | "build": "react-scripts build", 28 | "test": "react-scripts test", 29 | "eject": "react-scripts eject" 30 | }, 31 | "eslintConfig": { 32 | "extends": [ 33 | "react-app", 34 | "react-app/jest" 35 | ] 36 | }, 37 | "browserslist": { 38 | "production": [ 39 | ">0.2%", 40 | "not dead", 41 | "not op_mini all" 42 | ], 43 | "development": [ 44 | "last 1 chrome version", 45 | "last 1 firefox version", 46 | "last 1 safari version" 47 | ] 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /public/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/max0700/QR-Code-Scan/ca55fb7042245f1cbde6f6b6b97743e30fb9571e/public/favicon.png -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 14 | 15 | 16 | Qr Code Generator App 17 | 18 | 19 | 20 | 23 |
24 | 25 | 26 | -------------------------------------------------------------------------------- /public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/max0700/QR-Code-Scan/ca55fb7042245f1cbde6f6b6b97743e30fb9571e/public/logo192.png -------------------------------------------------------------------------------- /public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/max0700/QR-Code-Scan/ca55fb7042245f1cbde6f6b6b97743e30fb9571e/public/logo512.png -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --bg-color-1: #fafafb; 3 | --bg-color-2: #ffffff; 4 | --bg-color-3: #f6f8fb; 5 | 6 | --main-color: #2f80ed; 7 | --green-color: #219653; 8 | 9 | --text-color-1: #4f4f4f; 10 | --text-color-2: #828282; 11 | --text-color-3: #bdbdbd; 12 | 13 | --box-shadow: 0px 4px 12px #0000001a; 14 | 15 | --radius: 12px; 16 | --border: 1px solid #97bef4; 17 | --input-border: 1px solid #e0e0e0; 18 | 19 | --font-family: 'Roboto', sans-serif; 20 | --transition: all 0.2s linear; 21 | } 22 | 23 | *, 24 | ::after, 25 | ::before { 26 | margin: 0; 27 | padding: 0; 28 | box-sizing: border-box; 29 | } 30 | 31 | body { 32 | font-family: var(--font-family); 33 | line-height: 1.5rem; 34 | font-size: 100%; 35 | background-color: var(--bg-color-1); 36 | color: var(--text-color-1); 37 | font-family: Arial, Helvetica, sans-serif; 38 | 39 | } 40 | 41 | .app { 42 | width: min(500px, 1000px); 43 | margin-inline: auto; 44 | display: grid; 45 | place-content: center; 46 | height: 100vh; 47 | } 48 | 49 | .img-contant { 50 | margin: 1em 18px; 51 | width: 500px; 52 | border-radius: var(--radius); 53 | box-shadow: var(--box-shadow); 54 | display: grid; 55 | padding: 1.2em 2em; 56 | background-color: var(--bg-color-2); 57 | justify-items: center; 58 | } 59 | 60 | header { 61 | text-align: center; 62 | margin: 1em; 63 | } 64 | header h1 { 65 | font-size: 24px; 66 | font-weight: 400; 67 | } 68 | header p { 69 | margin: 0.5em 0; 70 | font-size: 14px; 71 | font-weight: 500; 72 | color: var(--text-color-2); 73 | } 74 | 75 | .img-uploader { 76 | margin: 1em 0; 77 | border: var(--border); 78 | border-style: dashed; 79 | border-radius: var(--radius); 80 | cursor: pointer; 81 | display: grid; 82 | padding: 1em 0em; 83 | width: 100%; 84 | background-color: var(--bg-color-3); 85 | align-items: center; 86 | justify-items: center; 87 | } 88 | .textarea { 89 | margin-top: 20px; 90 | width: 100%; 91 | font-size: 14px; 92 | border-color: var(--main-color); 93 | border: dotted 1px var(--main-color); 94 | } 95 | .textarea:focus { 96 | outline-color: var(--main-color); 97 | } 98 | .textarea:hover { 99 | outline-color: var(--main-color); 100 | } 101 | .img-uploader img { 102 | width: min(150px, 150px); 103 | margin: 01em; 104 | } 105 | 106 | .img-uploader p, 107 | .or { 108 | font-size: 12px; 109 | font-weight: 500; 110 | margin-top: 1.5em; 111 | color: var(--text-color-3); 112 | } 113 | .or { 114 | margin: 0.5em 0; 115 | } 116 | 117 | input[type='file'] { 118 | height: 0; 119 | overflow: hidden; 120 | width: 0; 121 | } 122 | .fileload { 123 | text-align: center; 124 | min-height: 40px; 125 | min-width: 200px; 126 | background: var(--main-color); 127 | border: none; 128 | border-radius: var(--radius); 129 | color: #fff; 130 | cursor: pointer; 131 | display: inline-block; 132 | font-family: 'Rubik', sans-serif; 133 | font-size: inherit; 134 | font-weight: 500; 135 | text-transform: capitalize; 136 | outline: none; 137 | padding: 0.5em 1em; 138 | position: relative; 139 | transition: all 0.3s; 140 | vertical-align: middle; 141 | } 142 | input[type='file'] + label { 143 | 144 | background: var(--main-color); 145 | border: none; 146 | border-radius: var(--radius); 147 | color: #fff; 148 | cursor: pointer; 149 | display: inline-block; 150 | font-family: 'Rubik', sans-serif; 151 | font-size: inherit; 152 | font-weight: 500; 153 | text-transform: capitalize; 154 | outline: none; 155 | padding: 0.5em 1em; 156 | position: relative; 157 | transition: all 0.3s; 158 | vertical-align: middle; 159 | } 160 | 161 | .loading-contant { 162 | padding: 0.5em 2em; 163 | width: min(400px, 400px); 164 | box-shadow: var(--box-shadow); 165 | transition: var(--transition); 166 | } 167 | .loading-contant h1 { 168 | font-size: 20px; 169 | font-weight: 500; 170 | } 171 | .load-wrapp { 172 | margin: 01em 0; 173 | width: 250px; 174 | border-radius: var(--radius); 175 | display: flex; 176 | background: #f2f2f2; 177 | } 178 | 179 | .bar { 180 | float: left; 181 | width: 50px; 182 | height: 6px; 183 | border-radius: var(--radius); 184 | background-color: var(--main-color); 185 | } 186 | 187 | .bar { 188 | animation: loadingJ 2s cubic-bezier(0.17, 0.37, 0.43, 0.67) infinite; 189 | } 190 | 191 | @keyframes loadingJ { 192 | 0%, 193 | 100% { 194 | transform: translate(-150, 0); 195 | } 196 | 197 | 50% { 198 | transform: translate(200px, 0); 199 | background-color: var(--main-color); 200 | width: 50px; 201 | } 202 | } 203 | 204 | /* after-image-contaner */ 205 | 206 | .after-image-contaner { 207 | margin: 1em 18px; 208 | max-width: 700px; 209 | border-radius: var(--radius); 210 | box-shadow: var(--box-shadow); 211 | display: grid; 212 | padding: 1.2em 2em; 213 | background-color: var(--bg-color-2); 214 | justify-items: center; 215 | } 216 | .after-image-contaner .img { 217 | max-width: 400px; 218 | } 219 | .sucess-icon, 220 | .error-icon { 221 | color: var(--green-color); 222 | font-size: 35px; 223 | font-weight: 500; 224 | margin-bottom: 0.2em; 225 | } 226 | .error-icon { 227 | color: red; 228 | } 229 | .sucess-text, 230 | .error-text { 231 | color: var(--text-color-1); 232 | font-size: 18px; 233 | text-transform: capitalize; 234 | margin-bottom: 1em; 235 | font-weight: 500; 236 | text-align: center; 237 | } 238 | 239 | .url-contant { 240 | width: fit-content; 241 | height: fit-content; 242 | display: flex; 243 | justify-content: center; 244 | align-items: center; 245 | flex-wrap: wrap; 246 | margin: 1em 0; 247 | } 248 | 249 | .image-url { 250 | border: none; 251 | outline: none; 252 | border: var(--input-border); 253 | padding: 0.3em; 254 | color: var(--text-color-1); 255 | background-color: var(--bg-color-3); 256 | border-radius: 8px 0 0 8px; 257 | font-size: 16px; 258 | font-weight: 500; 259 | } 260 | .copy-btn, 261 | .try-btn { 262 | margin: 0; 263 | padding: 0.6em 0.8em; 264 | border-radius: 0 8px 8px 0; 265 | text-transform: capitalize; 266 | background-color: var(--main-color); 267 | color: var(--bg-color-2); 268 | font-style: 16px; 269 | font-weight: 500; 270 | cursor: pointer; 271 | outline: none; 272 | border: none; 273 | transition: var(--transition); 274 | } 275 | .copy-btn:hover { 276 | opacity: 0.9; 277 | } 278 | 279 | .try-btn { 280 | border-radius: 8px; 281 | margin: 1em; 282 | text-decoration: none; 283 | } 284 | 285 | @media screen and (max-width: 430px) { 286 | .copy-btn, 287 | .image-url { 288 | border-radius: 4px; 289 | margin: 0.2em; 290 | } 291 | } 292 | /* alert */ 293 | 294 | .alert-box { 295 | position: relative; 296 | width: 100%; 297 | display: flex; 298 | align-items: center; 299 | justify-content: center; 300 | } 301 | 302 | .alert-text { 303 | position: absolute; 304 | margin-top: 1em; 305 | display: grid; 306 | place-content: center; 307 | width: min(90%, 400px); 308 | background-color: #2196543b; 309 | color: #219653; 310 | font-weight: 500; 311 | text-transform: capitalize; 312 | } 313 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import { BrowserRouter, Route, Routes } from "react-router-dom"; 2 | import "./App.css"; 3 | import QRCodeDecoder from "./components/QrCode"; 4 | 5 | function App() { 6 | return ( 7 | <> 8 | 9 | 10 | } /> 11 | 12 | 13 | 14 | ); 15 | } 16 | 17 | export default App; 18 | -------------------------------------------------------------------------------- /src/assests/QrCode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/max0700/QR-Code-Scan/ca55fb7042245f1cbde6f6b6b97743e30fb9571e/src/assests/QrCode.png -------------------------------------------------------------------------------- /src/components/QrCode.js: -------------------------------------------------------------------------------- 1 | import { useState, useEffect } from 'react'; 2 | import { TOTP } from 'otpauth'; 3 | import QRCode from 'qrcode'; 4 | import qrCodeReader from 'qrcode-reader'; 5 | import img from './logo.png'; 6 | const QRCodeDecoder = () => { 7 | const [imageUrl, setImageUrl] = useState(img); 8 | const [decodeData, setDecodeData] = useState(''); 9 | const [imgUrl, setImgUrl] = useState(''); 10 | 11 | useEffect(() => { 12 | }, [imageUrl, decodeData]); 13 | 14 | const [file, setFile] = useState(''); 15 | 16 | const handleFileUpload = (event) => { 17 | const file = event.target.files[0]; 18 | setFile(file); 19 | const url = URL.createObjectURL(file); 20 | setImageUrl(url); 21 | setDecodeData(''); 22 | }; 23 | //const secret1 = Secret.fromRandom(); 24 | // const totp1 = new TOTP({ 25 | // issuer: 'My App', 26 | // label: 'user@example.com', 27 | // algorithm: 'SHA1', 28 | // digits: 6, 29 | // period: 30, 30 | // secret: "secret", 31 | // }); 32 | 33 | // const otpauthUrl = totp1.toString(); 34 | // const QRGenerate = () => { 35 | // QRCode.toDataURL(otpauthUrl, (err, imageUrl) => { 36 | // if (err) { 37 | // console.error(err); 38 | // } else { 39 | // setImgUrl(imageUrl); 40 | // } 41 | // }); 42 | // } 43 | 44 | const decodeHandler = () => { 45 | const qr = new qrCodeReader(); 46 | const img = new Image(); 47 | img.src = imageUrl; 48 | img.onload = () => { 49 | const canvas = document.createElement('canvas'); 50 | const context = canvas.getContext('2d'); 51 | 52 | canvas.width = img.width; 53 | canvas.height = img.height; 54 | context.drawImage(img, 0, 0, img.width, img.height); 55 | 56 | const imageData = context.getImageData(0, 0, img.width, img.height); 57 | qr.decode(imageData); 58 | const result = qr.result; 59 | setDecodeData(result.result); 60 | }; 61 | } 62 | 63 | return ( 64 |
65 |
66 |
67 |

Upload your image

68 |

File should be Jpeg, Png,...

69 |
70 |
71 | 72 | 74 |
75 |
76 | {imageUrl && 77 | Selected Image} 78 |
79 |
80 | 81 |
82 | 83 |
84 |
85 | ); 86 | }; 87 | export default QRCodeDecoder; -------------------------------------------------------------------------------- /src/components/image.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/components/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/max0700/QR-Code-Scan/ca55fb7042245f1cbde6f6b6b97743e30fb9571e/src/components/logo.png -------------------------------------------------------------------------------- /src/components/sni.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/max0700/QR-Code-Scan/ca55fb7042245f1cbde6f6b6b97743e30fb9571e/src/components/sni.png -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom/client"; 3 | import App from "./App"; 4 | 5 | const root = ReactDOM.createRoot(document.getElementById("root")); 6 | root.render( 7 | 8 | 9 | 10 | ); 11 | --------------------------------------------------------------------------------