diff --git a/.gitignore b/.gitignore index 4d29575..8c39a17 100644 --- a/.gitignore +++ b/.gitignore @@ -2,14 +2,17 @@ # dependencies /node_modules +*/node_modules /.pnp .pnp.js # testing /coverage +/serverside-agent # production /build +*/build # misc .DS_Store diff --git a/README.md b/README.md index 5babdeb..b3344b3 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,12 @@ # Admin Dashboard writed on React This project is a simple admin panel designed for managing servers. \ It utilizes Material UI for the user interface components. \ +## Screenshots +![Image](/screenshots/screenshot1.png) +![Image](/screenshots/screenshot2.png) + + +## How to run To run the project, you can download/clone the repository and use these commands to run: ```bash npm install diff --git a/database.sql b/database.sql index 4cb4bdb..b6f6453 100644 --- a/database.sql +++ b/database.sql @@ -1,8 +1,10 @@ CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) NOT NULL UNIQUE, - email VARCHAR(100) NOT NULL UNIQUE, password_hash VARCHAR(255) NOT NULL, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP + perms VARCHAR(255) NOT NULL ); + +-- Test user with admin permissions +INSERT INTO users (username, password_hash, perms) +VALUES ('admin', 'ecd71870d1963316a97e3ac3408c9835ad8cf0f3c1bc703527c30265534f75ae', 'admin'); diff --git a/package-lock.json b/package-lock.json index d22afc2..0e0faeb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,7 @@ "@xterm/xterm": "^5.5.0", "codegen": "^0.1.0", "eslint-plugin-react": "^7.37.1", + "js-sha256": "^0.11.0", "react": "^18.3.1", "react-dom": "^18.3.1", "react-router-dom": "^6.27.0", @@ -11707,6 +11708,12 @@ "jiti": "bin/jiti.js" } }, + "node_modules/js-sha256": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.11.0.tgz", + "integrity": "sha512-6xNlKayMZvds9h1Y1VWc0fQHQ82BxTXizWPEtEeGvmOUYpBRy4gbWroHLpzowe6xiQhHpelCQiE7HEdznyBL9Q==", + "license": "MIT" + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", diff --git a/package.json b/package.json index 0cab2ca..9785172 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "@xterm/xterm": "^5.5.0", "codegen": "^0.1.0", "eslint-plugin-react": "^7.37.1", + "js-sha256": "^0.11.0", "react": "^18.3.1", "react-dom": "^18.3.1", "react-router-dom": "^6.27.0", diff --git a/screenshots/screenshot1.png b/screenshots/screenshot1.png new file mode 100644 index 0000000..7b31ffe Binary files /dev/null and b/screenshots/screenshot1.png differ diff --git a/screenshots/screenshot2.png b/screenshots/screenshot2.png new file mode 100644 index 0000000..841ea1a Binary files /dev/null and b/screenshots/screenshot2.png differ diff --git a/server.js b/server.js deleted file mode 100644 index 53900ad..0000000 --- a/server.js +++ /dev/null @@ -1,13 +0,0 @@ -const express = require('express'); -const cors = require('cors'); -const app = express(); - -app.use(cors()); - -app.use('/login', (req, res) =>{ - res.send({ - token: 'snippetsx' - }) -}) - -app.listen(8080, () => console.log('API Running on localhost:8080')) \ No newline at end of file diff --git a/src/Dashboard/DashboardMain.js b/src/Dashboard/DashboardMain.js index d504d29..ce670e1 100644 --- a/src/Dashboard/DashboardMain.js +++ b/src/Dashboard/DashboardMain.js @@ -30,20 +30,9 @@ import {SystemMon, WebsiteAvailability} from '../widgets/WidgetsStatistics' const drawerWidth = 240; export default function DashboardMain() { - const [open, setOpen] = useState(false); const [anchorEl, setAnchorEl] = useState(null); const openMenu = Boolean(anchorEl); - const handleDrawer = () => { - if(open === false){ - setOpen(true); - } - else{ - setOpen(false); - } - }; - - const handleMenuClick = (event) => { setAnchorEl(event.currentTarget); }; @@ -144,6 +133,7 @@ export default function DashboardMain() { sx={{ flexGrow: 1, bgcolor: 'background.default', p: 3 }} > + {/* Hi {localStorage.getItem('token')} */} diff --git a/src/Login/LoginPage.css b/src/Login/LoginPage.css index e69de29..3c83161 100644 --- a/src/Login/LoginPage.css +++ b/src/Login/LoginPage.css @@ -0,0 +1,9 @@ +@keyframes shake { + 0% { transform: translateX(0); } + 10%, 30%, 50%, 70%, 90% { transform: translateX(-10px); } + 20%, 40%, 60%, 80% { transform: translateX(10px); } + 100% { transform: translateX(0); } + } + .shake-animation { + animation: shake 0.82s cubic-bezier(.36,.07,.19,.97) both; + } \ No newline at end of file diff --git a/src/Login/LoginPage.js b/src/Login/LoginPage.js index 9ec6063..9720d10 100644 --- a/src/Login/LoginPage.js +++ b/src/Login/LoginPage.js @@ -4,18 +4,27 @@ import { Button, Container, TextField, Typography, AppBar, Toolbar, Box } from ' import { ThemeProvider } from '@mui/material/styles'; import theme from '../theme'; import {loginUser} from './LoginServerSend' +import './LoginPage.css' +import { sha256 } from 'js-sha256'; export default function Login({ setToken }) { const [username, setUserName] = useState(''); const [password, setPassword] = useState(''); + const [msg, setMsg] = useState(''); const handleSubmit = async e => { e.preventDefault(); - const token = await loginUser({ - username, - password - }); - setToken(token); + try { + + const token = await loginUser({ + username, + password + }); + setToken(token); + } catch (error) { + // Add shake animation and red color to form if error + setMsg(true); + } } return( @@ -63,8 +72,11 @@ export default function Login({ setToken }) { label="Password" type="password" id="password" + error={!!msg} + helperText={msg ? "Incorrect password" : ""} + className={msg ? 'shake-animation' : ''} autoComplete="current-password" - onChange={e => setPassword(e.target.value)} + onChange={e => setPassword(sha256(e.target.value))} />