├── 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 |
70 |
71 |
72 |
74 |
75 |
76 | {imageUrl &&
77 |

}
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 | );
86 | };
87 | export default QRCodeDecoder;
--------------------------------------------------------------------------------
/src/components/image.svg:
--------------------------------------------------------------------------------
1 |
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 |
--------------------------------------------------------------------------------