diff --git a/index.html b/index.html index 038b9c4..5f2afa4 100644 --- a/index.html +++ b/index.html @@ -3,6 +3,7 @@ + Wifi Extender diff --git a/package-lock.json b/package-lock.json index 5f03f74..0395236 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "0.0.0", "dependencies": { "react": "^18.3.1", + "react-cookie": "^7.2.0", "react-dom": "^18.3.1", "react-router-dom": "^6.25.1" }, @@ -1193,23 +1194,35 @@ "@babel/types": "^7.20.7" } }, + "node_modules/@types/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==" + }, "node_modules/@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, + "node_modules/@types/hoist-non-react-statics": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz", + "integrity": "sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==", + "dependencies": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, "node_modules/@types/prop-types": { "version": "15.7.12", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", - "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==", - "dev": true + "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==" }, "node_modules/@types/react": { "version": "18.3.3", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz", "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==", - "dev": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -1653,8 +1666,7 @@ "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "dev": true + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, "node_modules/debug": { "version": "4.3.6", @@ -2290,6 +2302,14 @@ "node": ">=4" } }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": { + "react-is": "^16.7.0" + } + }, "node_modules/ignore": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", @@ -2780,6 +2800,19 @@ "node": ">=0.10.0" } }, + "node_modules/react-cookie": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/react-cookie/-/react-cookie-7.2.0.tgz", + "integrity": "sha512-mqhPERUyfOljq5yJ4woDFI33bjEtigsl8JDJdPPeNhr0eSVZmBc/2Vdf8mFxOUktQxhxTR1T+uF0/FRTZyBEgw==", + "dependencies": { + "@types/hoist-non-react-statics": "^3.3.5", + "hoist-non-react-statics": "^3.3.2", + "universal-cookie": "^7.0.0" + }, + "peerDependencies": { + "react": ">= 16.3.0" + } + }, "node_modules/react-dom": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", @@ -2792,6 +2825,11 @@ "react": "^18.3.1" } }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, "node_modules/react-refresh": { "version": "0.14.2", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", @@ -3095,6 +3133,23 @@ "node": ">=14.17" } }, + "node_modules/universal-cookie": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/universal-cookie/-/universal-cookie-7.2.0.tgz", + "integrity": "sha512-PvcyflJAYACJKr28HABxkGemML5vafHmiL4ICe3e+BEKXRMt0GaFLZhAwgv637kFFnnfiSJ8e6jknrKkMrU+PQ==", + "dependencies": { + "@types/cookie": "^0.6.0", + "cookie": "^0.6.0" + } + }, + "node_modules/universal-cookie/node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/update-browserslist-db": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", diff --git a/package.json b/package.json index d87115a..84e890f 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ }, "dependencies": { "react": "^18.3.1", + "react-cookie": "^7.2.0", "react-dom": "^18.3.1", "react-router-dom": "^6.25.1" }, diff --git a/public/logo.ico b/public/logo.ico new file mode 100644 index 0000000..9bcd862 Binary files /dev/null and b/public/logo.ico differ diff --git a/src/Index.tsx b/src/Index.tsx index d2ae483..89a20fb 100644 --- a/src/Index.tsx +++ b/src/Index.tsx @@ -1,9 +1,45 @@ +import { useState, useEffect } from 'react' +import { Routes, Route, useNavigate } from 'react-router-dom'; +import Dashboard from './pages/Dashboard' +import Devices from './pages/DeviceList.tsx' +import Extend from './pages/ExtendWirelessNetwork.tsx' +import WirelessSettings from './pages/SystemSettings.tsx' +import SystemSettings from './pages/WirelessSettings.tsx' +import Login from './pages/Login' +import Register from './pages/Register' +import Navbar from './components/Navbar' +import './styles/Main.css' + function Index() { - return ( + let [loginState, setLoginState] = useState(false); + let [loggedUser, setLoggedUser] = useState('') + + const navigate = useNavigate(); + + useEffect(() => { + if(!loginState) { + navigate("/login"); + } + if(loggedUser === '') { + setLoggedUser('Not Logged In') + } + }, [loginState, setLoggedUser]); + + return( <> -

hi

- +

{ loginState }

+ + + } /> + } /> + } /> + } /> + } /> + } /> + } /> + + ) } -export default Index +export default Index; \ No newline at end of file diff --git a/src/assets/logo.png b/src/assets/logo.png new file mode 100644 index 0000000..eb504be Binary files /dev/null and b/src/assets/logo.png differ diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx new file mode 100644 index 0000000..baa889a --- /dev/null +++ b/src/components/Navbar.tsx @@ -0,0 +1,14 @@ +interface Props { + LoggedUser: string; +} + +function Navbar({ LoggedUser }: Props) { + return ( + + ) +} + +export default Navbar; \ No newline at end of file diff --git a/src/data/login.json b/src/data/login.json new file mode 100644 index 0000000..e69de29 diff --git a/src/main.tsx b/src/main.tsx index 85d408f..7cabaec 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,38 +1,12 @@ import React from 'react' import ReactDOM from 'react-dom/client' -import { RouterProvider, createBrowserRouter } from 'react-router-dom' -import Index from './Index.tsx' -import Devices from './pages/DeviceList.tsx' -import Extend from './pages/ExtendWirelessNetwork.tsx' -import WirelessSettings from './pages/SystemSettings.tsx' -import SystemSettings from './pages/WirelessSettings.tsx' -import './styles/Main.css' - -const router = createBrowserRouter([ - { - path: "/", - element: - }, - { - path: "/devices", - element: - }, - { - path: "/extend", - element: - }, - { - path: "/wireless", - element: - }, - { - path: "/settings", - element: - } -]); +import { BrowserRouter as Router } from 'react-router-dom'; +import Index from './Index' ReactDOM.createRoot(document.getElementById('root')!).render( - + + + , ) \ No newline at end of file diff --git a/src/pages/Dashboard.tsx b/src/pages/Dashboard.tsx new file mode 100644 index 0000000..3490919 --- /dev/null +++ b/src/pages/Dashboard.tsx @@ -0,0 +1,9 @@ +function Dashboard() { + return ( + <> +

hi

+ + ) +} + +export default Dashboard diff --git a/src/pages/DeviceList.tsx b/src/pages/DeviceList.tsx index bafb3ca..b1def69 100644 --- a/src/pages/DeviceList.tsx +++ b/src/pages/DeviceList.tsx @@ -2,4 +2,4 @@ function DeviceList() { return

device list

} -export default DeviceList \ No newline at end of file +export default DeviceList; \ No newline at end of file diff --git a/src/pages/ExtendWirelessNetwork.tsx b/src/pages/ExtendWirelessNetwork.tsx index e41ff5e..d068d35 100644 --- a/src/pages/ExtendWirelessNetwork.tsx +++ b/src/pages/ExtendWirelessNetwork.tsx @@ -2,4 +2,4 @@ function ExtendWirelessNetwork() { return

Extend Wireless Network

} -export default ExtendWirelessNetwork \ No newline at end of file +export default ExtendWirelessNetwork; \ No newline at end of file diff --git a/src/pages/Login.tsx b/src/pages/Login.tsx index e69de29..d549e40 100644 --- a/src/pages/Login.tsx +++ b/src/pages/Login.tsx @@ -0,0 +1,68 @@ +import { Dispatch, SetStateAction, useState } from 'react'; +import { useNavigate, Link } from 'react-router-dom'; +import '../styles/Login.css' + +let usernames = ['root']; +let passwords = ['123', 'hello']; + +interface Props { + setLogin: Dispatch>; + setUser: Dispatch>; +} + +function Login({ setLogin, setUser }: Props) { + const navigate = useNavigate(); + + let [usernameError, setUsernameError] = useState(false); + let [passwordError, setPasswordError] = useState(false); + + const handleLogin = (e: React.FormEvent) => { + e.preventDefault(); + + const userElement = document.getElementById('username') as HTMLInputElement | null; + const passwordElement = document.getElementById('password') as HTMLInputElement | null; + + if(!userElement || !passwordElement) return; + + let user = userElement?.value; + let password = passwordElement?.value; + + for (let i = 0; i < usernames.length; i++) { + if(user === usernames[i] && password === passwords[i]) { + setLogin(true); + setUser(user); + return navigate("/"); + } + } + + setUsernameError(true); + setPasswordError(true); + }; + + return ( +
+
+

Welcome back!

+

Enter your username and password.

+
+

Username

+ + + { passwordError && +

Wrong username.

} + +

Password

+ + + { usernameError && +

Wrong password.

} + +

Forgot password? Reset it

+ +
+
+
+ ) +} + +export default Login; \ No newline at end of file diff --git a/src/pages/Register.tsx b/src/pages/Register.tsx index e69de29..3989ed2 100644 --- a/src/pages/Register.tsx +++ b/src/pages/Register.tsx @@ -0,0 +1,5 @@ +function Register() { + return

register

+} + +export default Register; \ No newline at end of file diff --git a/src/pages/SystemSettings.tsx b/src/pages/SystemSettings.tsx index 0837151..ece2db8 100644 --- a/src/pages/SystemSettings.tsx +++ b/src/pages/SystemSettings.tsx @@ -2,4 +2,4 @@ function SystemSettings() { return

} -export default SystemSettings \ No newline at end of file +export default SystemSettings; \ No newline at end of file diff --git a/src/pages/WirelessSettings.tsx b/src/pages/WirelessSettings.tsx index 28203d0..f3b083a 100644 --- a/src/pages/WirelessSettings.tsx +++ b/src/pages/WirelessSettings.tsx @@ -2,4 +2,4 @@ function WirelessName() { return

Wireless Name

} -export default WirelessName \ No newline at end of file +export default WirelessName; \ No newline at end of file diff --git a/src/styles/Login.css b/src/styles/Login.css index e69de29..4eaf2ff 100644 --- a/src/styles/Login.css +++ b/src/styles/Login.css @@ -0,0 +1,80 @@ +body { + height: 100vh; +} + +#root { + height: 100%; +} + +#login { + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; + background-color: #071e42; + max-width: 500px; + height: 600px; + border-radius: 20px; + font-size: 1.5rem; + padding: 50px; + + h1 { + text-align: center; + font-weight: normal; + } + p { + color: #ffffffd5; + } +} + +#noinput { + color: red !important; +} + +form { + display: flex; + flex-direction: inherit; + margin-top: 20px; + max-width: 360px; + font-weight: normal; + gap: 5px; + + h2 { + font-size: 1.5rem; + font-weight: normal; + color: #ffffffd5; + } + input { + color: #ffffffb4; + border: none; + background-color: #071436; + height: 40px; + width: 360px; + border-radius: 10px; + padding: 5px; + font-size: 1rem; + } + p { + font-size: 0.8rem; + color: #ffffffd5; + max-width: fit-content; + } + a { + color: cyan; + } + button { + background-color: #071436; + border: none; + color: #fff; + margin-top: 20px; + height: 50px; + width: 100%; + border-radius: 10px; + font-size: 1.3rem; + cursor: pointer; + transition: 0.3s background-color; + } + button:hover { + background-color: #0069ff; + } +} diff --git a/src/styles/Main.css b/src/styles/Main.css index ab157d5..b66cf8b 100644 --- a/src/styles/Main.css +++ b/src/styles/Main.css @@ -1,3 +1,15 @@ +@font-face { + font-family: Poppins; + src: url(../fonts/Poppins/Poppins-Bold.ttf); + font-weight: bold; +} + +@font-face { + font-family: Poppins; + src: url(../fonts/Poppins/Poppins-Regular.ttf); + font-weight: normal; +} + * { margin: 0; padding: 0; @@ -5,6 +17,30 @@ } body { - background-color: #121212; + background-color: #071935; color: #fff; + padding: 20px; + font-family: 'Poppins', sans-serif; +} + +a { + color: inherit; + text-decoration: none; +} + +nav { + display: flex; + justify-content: space-between; + align-items: center; + + p { + float: right; + } +} + +.center { + display: flex; + align-items: center; + justify-content: center; + height: calc(100% - 40px); } \ No newline at end of file