diff --git a/frontend/package-lock.json b/frontend/package-lock.json index f48f4b7..2374fe4 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -17,6 +17,8 @@ "@types/react-dom": "^18.3.1", "axios": "^1.7.9", "framer-motion": "^11.15.0", + "qrcode": "^1.5.4", + "qrcode.react": "^4.2.0", "react": "^18.3.1", "react-dom": "^18.3.1", "react-icons": "^5.4.0", @@ -6051,6 +6053,14 @@ } } }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/decimal.js": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", @@ -6245,6 +6255,11 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, + "node_modules/dijkstrajs": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.3.tgz", + "integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==" + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -11349,6 +11364,14 @@ "node": ">=4" } }, + "node_modules/pngjs": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz", + "integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==", + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/possible-typed-array-names": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", @@ -12729,6 +12752,99 @@ "teleport": ">=0.2.0" } }, + "node_modules/qrcode": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.4.tgz", + "integrity": "sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==", + "dependencies": { + "dijkstrajs": "^1.0.1", + "pngjs": "^5.0.0", + "yargs": "^15.3.1" + }, + "bin": { + "qrcode": "bin/qrcode" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/qrcode.react": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/qrcode.react/-/qrcode.react-4.2.0.tgz", + "integrity": "sha512-QpgqWi8rD9DsS9EP3z7BT+5lY5SFhsqGjpgW5DY/i3mK4M9DTBNz3ErMi8BWYEfI3L0d8GIbGmcdFAS1uIRGjA==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/qrcode/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/qrcode/node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/qrcode/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/qrcode/node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" + }, + "node_modules/qrcode/node_modules/yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/qrcode/node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/qs": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", @@ -13309,6 +13425,11 @@ "node": ">=0.10.0" } }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" + }, "node_modules/requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -13858,6 +13979,11 @@ "node": ">= 0.8.0" } }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" + }, "node_modules/set-cookie-parser": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", @@ -15838,6 +15964,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/which-module": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==" + }, "node_modules/which-typed-array": { "version": "1.1.16", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.16.tgz", diff --git a/frontend/package.json b/frontend/package.json index 95164d8..189c5df 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -12,6 +12,8 @@ "@types/react-dom": "^18.3.1", "axios": "^1.7.9", "framer-motion": "^11.15.0", + "qrcode": "^1.5.4", + "qrcode.react": "^4.2.0", "react": "^18.3.1", "react-dom": "^18.3.1", "react-icons": "^5.4.0", diff --git a/frontend/src/components/URLShortener/URLShortener.tsx b/frontend/src/components/URLShortener/URLShortener.tsx index a56dae2..68cb781 100644 --- a/frontend/src/components/URLShortener/URLShortener.tsx +++ b/frontend/src/components/URLShortener/URLShortener.tsx @@ -3,6 +3,7 @@ import "./URLShortener.css"; import axios from "axios"; import { ToastContainer, toast } from "react-toastify"; import "react-toastify/dist/ReactToastify.css"; +import QRCodeGenerator from "../qrCode/qrCodeGenerator"; export default function () { const [url, setUrl] = useState(""); @@ -74,39 +75,40 @@ export default function () { } } return ( -
-
-

Paste the URL

-
- setUrl(e.target.value)} - /> - -
- - {shortenedUrl && showInput && ( -
- - -
- )} -
-
-
-

Shorten It

+ <> +
+
+

Paste the URL

+
+ setUrl(e.target.value)} + /> + +
+ {shortenedUrl && ( +
+ + +
+ )}
-
-

- Shortenit is a free and open-source URL shortening service designed - for simplicity and efficiency. -

+
+
+

Shorten It

+
+
+

+ Shortenit is a free and open-source URL shortening service + designed for simplicity and efficiency. +

+
-
+ ); } diff --git a/frontend/src/components/footer/Footer.css b/frontend/src/components/footer/Footer.css index 291323a..8d4ec62 100644 --- a/frontend/src/components/footer/Footer.css +++ b/frontend/src/components/footer/Footer.css @@ -1,5 +1,8 @@ .footer { - width: 100%; - height: 200px; - background-color: var(--color-secondary); -} \ No newline at end of file + width: 100%; + height: 100px; + background-color: var(--color-secondary); + display: flex; + justify-content: center; + align-items: center; +} diff --git a/frontend/src/components/footer/Footer.tsx b/frontend/src/components/footer/Footer.tsx index 28a57f6..febf4fd 100644 --- a/frontend/src/components/footer/Footer.tsx +++ b/frontend/src/components/footer/Footer.tsx @@ -1,10 +1,10 @@ import React from "react"; import "./Footer.css"; +import { FaGithub } from "react-icons/fa"; +import { Link } from "react-router-dom"; function Footer() { - return ( -
- ); + return
; } export default Footer; diff --git a/frontend/src/components/qrCode/qrCodeGenerator.css b/frontend/src/components/qrCode/qrCodeGenerator.css new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/components/qrCode/qrCodeGenerator.tsx b/frontend/src/components/qrCode/qrCodeGenerator.tsx new file mode 100644 index 0000000..8c3c8ad --- /dev/null +++ b/frontend/src/components/qrCode/qrCodeGenerator.tsx @@ -0,0 +1,13 @@ +import React from "react"; +import { QRCodeSVG } from "qrcode.react"; +import { qrCodeGeneratorProps } from "./qrCodeGeneratorProps"; + +const QRCodeGenerator: React.FC = ({ url }) => { + return ( +
+ +
+ ); +}; + +export default QRCodeGenerator; diff --git a/frontend/src/components/qrCode/qrCodeGeneratorProps.ts b/frontend/src/components/qrCode/qrCodeGeneratorProps.ts new file mode 100644 index 0000000..ebca946 --- /dev/null +++ b/frontend/src/components/qrCode/qrCodeGeneratorProps.ts @@ -0,0 +1,3 @@ +export interface qrCodeGeneratorProps { + url: string; +}