From f2de5779c8ee45e1ac17a4dd4ae539c262a35f87 Mon Sep 17 00:00:00 2001 From: Teja Date: Sat, 13 Jul 2024 15:04:32 +0530 Subject: [PATCH 1/4] fix admins automation --- client/src/ast-console/ast-console-login.js | 29 +++-- .../src/ast-console/ast-console-register.js | 100 +++++++++++++++--- client/src/ast-console/ast-console.css | 11 +- .../console-action/console-actions.js | 16 +++ client/src/ast-console/sigin.js | 34 ++++-- client/src/ast-console/signup.js | 26 +++++ client/src/ast-console/styles/ast.css | 46 ++++---- client/src/ast-console/styles/ast.js | 2 +- client/src/collection/menu/menu.js | 10 +- server/src/ast-console/console.server.js | 42 ++++++++ .../src/ast-console/signin/anothersignup.js | 36 +++++++ server/src/ast-console/signin/signin.js | 17 +++ server/src/ast-console/signin/signup.js | 24 +++++ server/src/db.js | 28 +++-- server/src/server.js | 12 +-- 15 files changed, 343 insertions(+), 90 deletions(-) create mode 100644 client/src/ast-console/console-action/console-actions.js create mode 100644 client/src/ast-console/signup.js create mode 100644 server/src/ast-console/console.server.js create mode 100644 server/src/ast-console/signin/anothersignup.js create mode 100644 server/src/ast-console/signin/signin.js create mode 100644 server/src/ast-console/signin/signup.js diff --git a/client/src/ast-console/ast-console-login.js b/client/src/ast-console/ast-console-login.js index aba38259..44acf4fb 100644 --- a/client/src/ast-console/ast-console-login.js +++ b/client/src/ast-console/ast-console-login.js @@ -1,37 +1,39 @@ import { Box, Button, - Checkbox, Flex, FormControl, FormErrorMessage, FormLabel, Input, + Link, VStack } from "@chakra-ui/react"; import { Field, Formik } from "formik"; import './ast-console.css'; -import { Motion } from "./styles/motion"; import { AST } from "./styles/ast"; +import { Motion } from "./styles/motion"; -export default function ASTConsole() { +export const ASTConsole = ({ gmail, password, action,change}) => { return (
-
+ +

Welcome, To AST console

- Email Address + Email Address gmail(e.target.value)} /> @@ -42,27 +44,20 @@ export default function ASTConsole() { name="password" type="password" variant="filled" - validate={(value) => { - let error; - - if (value?.length < 6) { - error = "Password must contain at least 6 characters"; - } - - return error; - }} + onChange={(e) => password(e.target.value)} /> change()} > - Remember me? + Register? -
diff --git a/client/src/ast-console/ast-console-register.js b/client/src/ast-console/ast-console-register.js index 04cca233..9ad19a8e 100644 --- a/client/src/ast-console/ast-console-register.js +++ b/client/src/ast-console/ast-console-register.js @@ -1,36 +1,46 @@ -import { Formik, Field } from "formik"; import { Box, Button, - Checkbox, Flex, FormControl, - FormLabel, FormErrorMessage, + FormLabel, Input, + Link, VStack } from "@chakra-ui/react"; -import './ast-console.css' +import { Field, Formik } from "formik"; +import './ast-console.css'; +import { AST } from "./styles/ast"; +import { Motion } from "./styles/motion"; -export default function App() { +export const ASTConsoleRegister = ({ data, change }) => { return ( - - + +
+ + +
+ { - alert(JSON.stringify(values, null, 2)); + data(values) }} > {({ handleSubmit, errors, touched }) => (
- Email Address + Admin Email Address + Password {errors.password} + + + Phone Number + + + + + + Event Name + + + + + Club Name + + + + + + Event Counduct Time + + + + + How Many Accounts you want less than 10 + + + change()} > - Remember me? + Sign In?
)}
+
+ + +
); } \ No newline at end of file diff --git a/client/src/ast-console/ast-console.css b/client/src/ast-console/ast-console.css index 412c88d9..b25eb498 100644 --- a/client/src/ast-console/ast-console.css +++ b/client/src/ast-console/ast-console.css @@ -22,11 +22,6 @@ h1 { justify-content: space-evenly; } -.astname{ - color: blue; - font-size: x-large; -} - @media (max-width:500px) { #motion{ @@ -35,4 +30,10 @@ h1 { #signinform{ width: 90%; } + .boxmotion{ + display: none; + } + .astname{ + display: none; + } } \ No newline at end of file diff --git a/client/src/ast-console/console-action/console-actions.js b/client/src/ast-console/console-action/console-actions.js new file mode 100644 index 00000000..f0e4b2f7 --- /dev/null +++ b/client/src/ast-console/console-action/console-actions.js @@ -0,0 +1,16 @@ +import { api } from "../../actions/api" +import axios from "axios" + +export const ConsoleActions={ + ConsoleLogin: async (mail, password) => { + return await axios.post(api + "/consolelogin", { mail, password }) + }, + + ConsoleRegister: async (mail, password,phone,event,date,club,members) => { + return await axios.post(api + "/consoleregister", { mail, password,phone,event,club,date,members}) + }, + + AnotherConsoleRegister: async (mail, password,phone,adminmail) => { + return await axios.post(api + "/consoleregister", { mail, password,phone,adminmail}) + }, +} \ No newline at end of file diff --git a/client/src/ast-console/sigin.js b/client/src/ast-console/sigin.js index 37365e3e..17237bd5 100644 --- a/client/src/ast-console/sigin.js +++ b/client/src/ast-console/sigin.js @@ -1,12 +1,30 @@ -import ASTConsole from "./ast-console-login" -import { Motion, Motion1 } from "./styles/motion" +import { useToast } from "@chakra-ui/react" +import { useState } from "react" +import { ASTConsole } from "./ast-console-login" +import { ConsoleActions } from "./console-action/console-actions" +import { ConsoleSignup } from "./signup" -export const ConsoleLogin=()=>{ - return( -
- {/* */} - - {/* */} +export const ConsoleLogin = () => { + const [gmail, setGmail] = useState() + const [password, setPassword] = useState() + const [sigup,setSignup]=useState(false) + const toast = useToast() + const Submit = async () => { + await ConsoleActions.ConsoleLogin(gmail, password) + .then((res) => { + if (res?.data?.message) { + toast({ title: res?.data?.message, status: 'success', position: 'top-right', isClosable: true }) + } + else { + toast({ title: res?.data?.error, status: 'error', position: 'bottom-right', isClosable: true }) + } + }) + .catch((e) => console.log(e)) + } + return ( +
+ {sigup?setSignup(false)}/> + : setGmail(value)} password={(value) => setPassword(value)} action={() => Submit()} change={()=>setSignup(true)}/>}
) } \ No newline at end of file diff --git a/client/src/ast-console/signup.js b/client/src/ast-console/signup.js new file mode 100644 index 00000000..73aa2303 --- /dev/null +++ b/client/src/ast-console/signup.js @@ -0,0 +1,26 @@ +import { useToast } from "@chakra-ui/react" +import { ASTConsoleRegister } from "./ast-console-register" +import { ConsoleActions } from "./console-action/console-actions" + +export const ConsoleSignup = ({ change }) => { + const toast = useToast() + const Submit = async (data) => { + if (data?.email && data?.password && data?.phonenumber && data?.event && data?.start && data?.club && data?.noofpersons) { + await ConsoleActions.ConsoleRegister(data?.email, data?.password, data?.phonenumber, data?.event, data?.start, data?.club, data?.noofpersons) + .then((res) => { + if (res?.data?.message) { + toast({ title: res?.data?.message, status: 'success', position: 'top-right', isClosable: true }) + } + else { + toast({ title: res?.data?.error, status: 'error', position: 'bottom-right', isClosable: true }) + } + }) + .catch((e) => console.log(e)) + } else { + toast({ title: "required all fields", status: 'error', position: 'bottom-right', isClosable: true }) + } + } + return ( + Submit(values)} change={() => change()} /> + ) +} \ No newline at end of file diff --git a/client/src/ast-console/styles/ast.css b/client/src/ast-console/styles/ast.css index 81fde619..2a2918e9 100644 --- a/client/src/ast-console/styles/ast.css +++ b/client/src/ast-console/styles/ast.css @@ -1,24 +1,28 @@ @keyframes colorChange { - 0% { - color: red; - } - 25% { - color: orange; - } - 50% { - color: yellow; - } - 75% { - color: green; - } - 100% { - color: blue; - } + 0% { + color: red; } - - .color-animation { - font-size: 50px; - font-weight: bold; - animation: colorChange 5s infinite; + + 25% { + color: white; } - \ No newline at end of file + + 50% { + color: green; + } + + 75% { + color: blue; + } + + 100% { + color: rgb(251, 0, 251); + } +} + +.color-animation { + font-size: 50px; + font-weight: bold; + animation: colorChange 5s infinite; + background: linear-gradient(to-l, #7928CA, #FF0080); +} \ No newline at end of file diff --git a/client/src/ast-console/styles/ast.js b/client/src/ast-console/styles/ast.js index 59110e04..58c68627 100644 --- a/client/src/ast-console/styles/ast.js +++ b/client/src/ast-console/styles/ast.js @@ -3,7 +3,7 @@ import "./ast.css"; export const AST = () => { return ( -
+

AST

); diff --git a/client/src/collection/menu/menu.js b/client/src/collection/menu/menu.js index 019570ea..033fdc66 100644 --- a/client/src/collection/menu/menu.js +++ b/client/src/collection/menu/menu.js @@ -9,20 +9,20 @@ export const Menu = () => {
-
+
-
+
Team Members
-
+
-
- +
+
AST console
diff --git a/server/src/ast-console/console.server.js b/server/src/ast-console/console.server.js new file mode 100644 index 00000000..55536c9a --- /dev/null +++ b/server/src/ast-console/console.server.js @@ -0,0 +1,42 @@ +import cors from 'cors'; +import express from 'express'; +import { connectToDB } from '../db.js'; +import { ConsoleSignin } from './signin/signin.js'; +import { ConsoleRegister } from './signin/signup.js'; + +const app = express(); +const PORT = process.env.PORT || 8000; + +app.use(cors()); + +let database = null; + +app.post('/consolelogin', async (req, res) => { + await ConsoleSignin(req) + .then((result) => { + database = result + }) + .catch((e) => console.log(e)) +}) + +app.post('/consoleregister', async (req, res) => { + await ConsoleRegister(req, res) +}) + +connectToDB({ + database: database, + datacb: () => { + app.listen(PORT, () => { + console.log(`Server is running on port ${PORT}`); + console.log("user db connected"); + }); + }, + cb: () => { + app.listen(PORT, () => { + console.log(`Server is running on port ${PORT}`); + console.log("Admin db connected"); + }); + }, +}); + +export default app; diff --git a/server/src/ast-console/signin/anothersignup.js b/server/src/ast-console/signin/anothersignup.js new file mode 100644 index 00000000..0b9b08a1 --- /dev/null +++ b/server/src/ast-console/signin/anothersignup.js @@ -0,0 +1,36 @@ +import { db1, db2 } from "../../db.js"; +export const ConsoleAnotherRegister = async (data, res) => { + const { mail, password, phone, event, adminmail } = data; + try { + const admin = await db2.collection('Hacthonadmin').findOne({ Gmail: adminmail }); + if (!admin) { + return res.json({ error: 'admin not found' }); + } + else { + if (admin?.Admins?.length <= admin?.NoOfAdmins) { + const subadmin = await db2.collection('Hacthonadmin').findOne({ Gmail: mail }); + if (subadmin) { + return res.json({ error: 'exist admin' }); + } + await db1.collection('Hacthonadmin').insertOne({ Gmail: mail, Event: event, Number: phone, Password: password, Admin: false }) + .then(async (details) => { + if (details) { + await db2.collection("Hacthonadmin").findOneAndUpdate({ Gmail: adminmail }, { $set: { Admins: [...admin?.Admins, mail] } }) + .then((result) => { + if (result) { + res.json({ message: "sucess", data: details }); + } + }) + .catch((e) => console.log(e)) + } + }) + .catch((e) => console.log(e)) + } else { + return res.json({ error: 'admins limit over' }); + } + } + } catch (e) { + console.error(e); + res.status(500).json({ message: 'Error during signup' }); + } +} \ No newline at end of file diff --git a/server/src/ast-console/signin/signin.js b/server/src/ast-console/signin/signin.js new file mode 100644 index 00000000..0476930e --- /dev/null +++ b/server/src/ast-console/signin/signin.js @@ -0,0 +1,17 @@ +import { db2 } from "../../db.js"; + +export const ConsoleSignin = async (data) => { + const { mail, password } = data; + try { + const admin = await db2.collection('Hacthonadmin').findOne({ Gmail: mail }); + if (!admin) { + return res.json({ error: 'admin not found' }); + } + if (admin?.Password === password) { + return admin?.Club + admin?.Event + } + } catch (e) { + console.error(e); + res.status(500).json({ message: 'Error during signup' }); + } +} \ No newline at end of file diff --git a/server/src/ast-console/signin/signup.js b/server/src/ast-console/signin/signup.js new file mode 100644 index 00000000..d52438ca --- /dev/null +++ b/server/src/ast-console/signin/signup.js @@ -0,0 +1,24 @@ +import { db2 } from "../../db.js"; +export const ConsoleRegister = async (data, res) => { + const { mail, password, phone, event, club, date, members } = data; + try { + const admin = await db2.collection('Hacthonadmin').findOne({ Gmail: mail }); + if (admin) { + return res.json({ error: 'exist admin' }); + } + else { + if (admin?.Admins?.length <= admin?.NoOfAdmins) { + await db2.collection('Hacthonadmin').insertOne({ Gmail: mail, Event: event, Number: phone, Password: password, Club: club, Date: date, NoOfAdmins: members, Admin:true,Admins: [...admin?.Admins, mail] }) + .then((details) => { + res.json({ message: "sucess", data: details }); + }) + .catch((e) => console.log(e)) + } else { + return res.json({ error: 'admins limit over' }); + } + } + } catch (e) { + console.error(e); + res.status(500).json({ message: 'Error during signup' }); + } +} \ No newline at end of file diff --git a/server/src/db.js b/server/src/db.js index d292ff0c..806eb4a5 100644 --- a/server/src/db.js +++ b/server/src/db.js @@ -1,21 +1,27 @@ import dotenv from 'dotenv'; -import { GridFSBucket, MongoClient } from "mongodb"; -dotenv.config() -let db, db1, bucket; -async function connectToDB(cb) { - const url = process.env.database +import { GridFSBucket, MongoClient } from 'mongodb'; +dotenv.config(); + +let db, db1,db2, bucket; + +async function connectToDB({ database, datacb, cb }) { + const url = process.env.database; const client = new MongoClient(url); await client.connect(); db = client.db("Mern_Attendance"); - const url1 = process.env.database1 + const url1 = process.env.database1; const client1 = new MongoClient(url1); await client1.connect(); - db1 = client1.db("Hackathon"); + db2 = client1.db("Hackathon"); + + if (cb) cb(); - bucket = new GridFSBucket(db1, { bucketName: 'uploads' }); - cb(); + if (database) { + db1 = client1.db(database); + bucket = new GridFSBucket(db1, { bucketName: 'uploads' }); + if (datacb) datacb(); + } } -export { bucket, connectToDB, db, db1 }; - +export { bucket, connectToDB, db, db1,db2 }; diff --git a/server/src/server.js b/server/src/server.js index 27df3e88..285a79da 100644 --- a/server/src/server.js +++ b/server/src/server.js @@ -1,12 +1,13 @@ import cors from 'cors'; import dotenv from 'dotenv'; import express from 'express'; +import astconsole from '../src/ast-console/console.server.js'; import attendance from './attendance/attendance.server.js'; -import { connectToDB } from "./db.js"; import hackathon from './hackathon/hackathon.server.js'; dotenv.config() const app = express() + app.use(cors()) app.use(express.json()) app.use(express.urlencoded({ extended: true })); @@ -16,15 +17,8 @@ app.get('/', (req, res) => { }) - - - app.use(attendance) app.use(hackathon) -connectToDB(() => { - app.listen(8000, () => { - console.log("server running at 8000"); - }) -}) \ No newline at end of file +app.use(astconsole) \ No newline at end of file From 68681ec2716f3d5a6bbb49328a8c85efc4969138 Mon Sep 17 00:00:00 2001 From: Teja Date: Sat, 13 Jul 2024 18:08:31 +0530 Subject: [PATCH 2/4] console register setup --- client/src/App.js | 3 -- .../src/ast-console/ast-console-register.js | 42 ++++++++++++++++++- .../console-action/console-actions.js | 2 +- client/src/ast-console/sigin.js | 6 +-- client/src/ast-console/signup.js | 4 ++ server/src/ast-console/console.server.js | 42 ------------------- .../src/ast-console/signin/anothersignup.js | 4 +- server/src/ast-console/signin/signin.js | 2 +- server/src/ast-console/signin/signup.js | 17 ++++---- server/src/db.js | 18 ++++---- server/src/server.js | 31 ++++++++++++-- 11 files changed, 93 insertions(+), 78 deletions(-) delete mode 100644 server/src/ast-console/console.server.js diff --git a/client/src/App.js b/client/src/App.js index ed25477a..e9923818 100644 --- a/client/src/App.js +++ b/client/src/App.js @@ -38,7 +38,6 @@ function App() { const password = useSelector((state) => state.user.bootpassword); const salt = CryptoENC - // Admin login check const AdminLogin = async () => { await axios.post(process.env.REACT_APP_database + "/admincheck/" + sessionStorage.gmail) .then((res) => { @@ -50,7 +49,6 @@ function App() { }).catch((e) => {}) } - // Bootcamp login check const BootCamp = async () => { await Actions.BootAdminLogin(mail, CryptoAES.decrypt(password ? password : "1234", mail ? mail : "1234").toString(salt)) .then((res) => { @@ -62,7 +60,6 @@ function App() { }).catch((e) => {}) } - // Call all checks on component mount useEffect(() => { AdminLogin() BootCamp() diff --git a/client/src/ast-console/ast-console-register.js b/client/src/ast-console/ast-console-register.js index 9ad19a8e..d6211ba9 100644 --- a/client/src/ast-console/ast-console-register.js +++ b/client/src/ast-console/ast-console-register.js @@ -1,6 +1,7 @@ import { Box, Button, + Checkbox, Flex, FormControl, FormErrorMessage, @@ -13,8 +14,10 @@ import { Field, Formik } from "formik"; import './ast-console.css'; import { AST } from "./styles/ast"; import { Motion } from "./styles/motion"; +import { useState } from "react"; export const ASTConsoleRegister = ({ data, change }) => { + const [check, setCheck] = useState(false) return (
@@ -31,6 +34,7 @@ export const ASTConsoleRegister = ({ data, change }) => { start: "", club: "", noofpersons: "", + admin: "", }} onSubmit={(values) => { data(values) @@ -47,6 +51,7 @@ export const ASTConsoleRegister = ({ data, change }) => { name="email" type="email" variant="filled" + placeholder="Enter email" /> @@ -58,6 +63,7 @@ export const ASTConsoleRegister = ({ data, change }) => { name="password" type="password" variant="filled" + placeholder="Enter password" validate={(value) => { let error; @@ -79,6 +85,7 @@ export const ASTConsoleRegister = ({ data, change }) => { name="phonenumber" type="number" variant="filled" + placeholder="Enter phone number" /> @@ -91,6 +98,7 @@ export const ASTConsoleRegister = ({ data, change }) => { name="event" type="text" variant="filled" + placeholder="Enter event name" /> @@ -102,10 +110,12 @@ export const ASTConsoleRegister = ({ data, change }) => { name="club" type="text" variant="filled" + placeholder="Enter club name" /> + Event Counduct Time { name="start" type="date" variant="filled" + placeholder="Enter date" /> - How Many Accounts you want less than 10 + How Many Accounts + + + {setCheck(check?false:true) }} + > + Super Admin? + + + { + check&& + Enter Password + + + } { > Sign In? + diff --git a/client/src/ast-console/console-action/console-actions.js b/client/src/ast-console/console-action/console-actions.js index f0e4b2f7..2508d661 100644 --- a/client/src/ast-console/console-action/console-actions.js +++ b/client/src/ast-console/console-action/console-actions.js @@ -11,6 +11,6 @@ export const ConsoleActions={ }, AnotherConsoleRegister: async (mail, password,phone,adminmail) => { - return await axios.post(api + "/consoleregister", { mail, password,phone,adminmail}) + return await axios.post(api + "/anotherconsoleregister", { mail, password,phone,adminmail}) }, } \ No newline at end of file diff --git a/client/src/ast-console/sigin.js b/client/src/ast-console/sigin.js index 17237bd5..9c14a7ed 100644 --- a/client/src/ast-console/sigin.js +++ b/client/src/ast-console/sigin.js @@ -7,7 +7,7 @@ import { ConsoleSignup } from "./signup" export const ConsoleLogin = () => { const [gmail, setGmail] = useState() const [password, setPassword] = useState() - const [sigup,setSignup]=useState(false) + const [sigup, setSignup] = useState(false) const toast = useToast() const Submit = async () => { await ConsoleActions.ConsoleLogin(gmail, password) @@ -23,8 +23,8 @@ export const ConsoleLogin = () => { } return (
- {sigup?setSignup(false)}/> - : setGmail(value)} password={(value) => setPassword(value)} action={() => Submit()} change={()=>setSignup(true)}/>} + {sigup ? setSignup(false)} /> + : setGmail(value)} password={(value) => setPassword(value)} action={() => Submit()} change={() => setSignup(true)} />}
) } \ No newline at end of file diff --git a/client/src/ast-console/signup.js b/client/src/ast-console/signup.js index 73aa2303..c286d3ac 100644 --- a/client/src/ast-console/signup.js +++ b/client/src/ast-console/signup.js @@ -5,11 +5,15 @@ import { ConsoleActions } from "./console-action/console-actions" export const ConsoleSignup = ({ change }) => { const toast = useToast() const Submit = async (data) => { + console.log(data) if (data?.email && data?.password && data?.phonenumber && data?.event && data?.start && data?.club && data?.noofpersons) { await ConsoleActions.ConsoleRegister(data?.email, data?.password, data?.phonenumber, data?.event, data?.start, data?.club, data?.noofpersons) .then((res) => { if (res?.data?.message) { toast({ title: res?.data?.message, status: 'success', position: 'top-right', isClosable: true }) + setTimeout(() => { + window.location.reload(10) + }, 1000); } else { toast({ title: res?.data?.error, status: 'error', position: 'bottom-right', isClosable: true }) diff --git a/server/src/ast-console/console.server.js b/server/src/ast-console/console.server.js deleted file mode 100644 index 55536c9a..00000000 --- a/server/src/ast-console/console.server.js +++ /dev/null @@ -1,42 +0,0 @@ -import cors from 'cors'; -import express from 'express'; -import { connectToDB } from '../db.js'; -import { ConsoleSignin } from './signin/signin.js'; -import { ConsoleRegister } from './signin/signup.js'; - -const app = express(); -const PORT = process.env.PORT || 8000; - -app.use(cors()); - -let database = null; - -app.post('/consolelogin', async (req, res) => { - await ConsoleSignin(req) - .then((result) => { - database = result - }) - .catch((e) => console.log(e)) -}) - -app.post('/consoleregister', async (req, res) => { - await ConsoleRegister(req, res) -}) - -connectToDB({ - database: database, - datacb: () => { - app.listen(PORT, () => { - console.log(`Server is running on port ${PORT}`); - console.log("user db connected"); - }); - }, - cb: () => { - app.listen(PORT, () => { - console.log(`Server is running on port ${PORT}`); - console.log("Admin db connected"); - }); - }, -}); - -export default app; diff --git a/server/src/ast-console/signin/anothersignup.js b/server/src/ast-console/signin/anothersignup.js index 0b9b08a1..3e339864 100644 --- a/server/src/ast-console/signin/anothersignup.js +++ b/server/src/ast-console/signin/anothersignup.js @@ -1,6 +1,6 @@ import { db1, db2 } from "../../db.js"; export const ConsoleAnotherRegister = async (data, res) => { - const { mail, password, phone, event, adminmail } = data; + const { mail, password, phone, adminmail } = data; try { const admin = await db2.collection('Hacthonadmin').findOne({ Gmail: adminmail }); if (!admin) { @@ -12,7 +12,7 @@ export const ConsoleAnotherRegister = async (data, res) => { if (subadmin) { return res.json({ error: 'exist admin' }); } - await db1.collection('Hacthonadmin').insertOne({ Gmail: mail, Event: event, Number: phone, Password: password, Admin: false }) + await db2.collection('Hacthonadmin').insertOne({ Gmail: mail, Event: admin?.Event, Club: admin?.Club, Number: phone, Password: password, Admin: false }) .then(async (details) => { if (details) { await db2.collection("Hacthonadmin").findOneAndUpdate({ Gmail: adminmail }, { $set: { Admins: [...admin?.Admins, mail] } }) diff --git a/server/src/ast-console/signin/signin.js b/server/src/ast-console/signin/signin.js index 0476930e..b01a0bd4 100644 --- a/server/src/ast-console/signin/signin.js +++ b/server/src/ast-console/signin/signin.js @@ -8,7 +8,7 @@ export const ConsoleSignin = async (data) => { return res.json({ error: 'admin not found' }); } if (admin?.Password === password) { - return admin?.Club + admin?.Event + return admin } } catch (e) { console.error(e); diff --git a/server/src/ast-console/signin/signup.js b/server/src/ast-console/signin/signup.js index d52438ca..44dd7748 100644 --- a/server/src/ast-console/signin/signup.js +++ b/server/src/ast-console/signin/signup.js @@ -1,21 +1,18 @@ import { db2 } from "../../db.js"; + export const ConsoleRegister = async (data, res) => { - const { mail, password, phone, event, club, date, members } = data; + const { mail, password, phone, event, club, date, members } = data.body; try { const admin = await db2.collection('Hacthonadmin').findOne({ Gmail: mail }); if (admin) { return res.json({ error: 'exist admin' }); } else { - if (admin?.Admins?.length <= admin?.NoOfAdmins) { - await db2.collection('Hacthonadmin').insertOne({ Gmail: mail, Event: event, Number: phone, Password: password, Club: club, Date: date, NoOfAdmins: members, Admin:true,Admins: [...admin?.Admins, mail] }) - .then((details) => { - res.json({ message: "sucess", data: details }); - }) - .catch((e) => console.log(e)) - } else { - return res.json({ error: 'admins limit over' }); - } + await db2.collection('Hacthonadmin').insertOne({ Gmail: mail, Event: event, Number: phone, Password: password, Club: club, Date: date, NoOfAdmins: members, Admin: true,Admins:[mail] }) + .then((details) => { + res.json({ message: "sucess", data: details }); + }) + .catch((e) => console.log(e)) } } catch (e) { console.error(e); diff --git a/server/src/db.js b/server/src/db.js index 806eb4a5..f579e2f8 100644 --- a/server/src/db.js +++ b/server/src/db.js @@ -2,9 +2,9 @@ import dotenv from 'dotenv'; import { GridFSBucket, MongoClient } from 'mongodb'; dotenv.config(); -let db, db1,db2, bucket; +let db, db1, db2, bucket; -async function connectToDB({ database, datacb, cb }) { +async function connectToDB({ database, cb }) { const url = process.env.database; const client = new MongoClient(url); await client.connect(); @@ -13,15 +13,11 @@ async function connectToDB({ database, datacb, cb }) { const url1 = process.env.database1; const client1 = new MongoClient(url1); await client1.connect(); - db2 = client1.db("Hackathon"); - - if (cb) cb(); + db1 = client1.db(database); + db2 = client1.db("AdminData"); + bucket = new GridFSBucket(db1, { bucketName: 'uploads' }); - if (database) { - db1 = client1.db(database); - bucket = new GridFSBucket(db1, { bucketName: 'uploads' }); - if (datacb) datacb(); - } + if (cb) cb(); } -export { bucket, connectToDB, db, db1,db2 }; +export { bucket, connectToDB, db, db1, db2 }; diff --git a/server/src/server.js b/server/src/server.js index 285a79da..49f0a45b 100644 --- a/server/src/server.js +++ b/server/src/server.js @@ -1,8 +1,10 @@ import cors from 'cors'; import dotenv from 'dotenv'; import express from 'express'; -import astconsole from '../src/ast-console/console.server.js'; +import { ConsoleSignin } from './ast-console/signin/signin.js'; +import { ConsoleRegister } from './ast-console/signin/signup.js'; import attendance from './attendance/attendance.server.js'; +import { connectToDB } from './db.js'; import hackathon from './hackathon/hackathon.server.js'; dotenv.config() @@ -16,9 +18,32 @@ app.get('/', (req, res) => { res.json("server is running successfully!"); }) - app.use(attendance) app.use(hackathon) -app.use(astconsole) \ No newline at end of file +let database; + +app.post('/consolelogin', async (req, res) => { + await ConsoleSignin(req) + .then(async (result) => { + if (result?.Club && result?.Event) { + database = result?.Club + result?.Event + res.send({ message: 'login successfully', data: result }) + } + }) + .catch((e) => console.log(e)) +}) + +app.post('/consoleregister', async (req, res) => { + await ConsoleRegister(req, res) +}) + +connectToDB({ + database: database, + cb: () => { + app.listen(8000, () => { + console.log(`Server is running on port ${8000}`); + }); + }, +}); \ No newline at end of file From 636d479162c0082ff259a73b9c48e70f765fead0 Mon Sep 17 00:00:00 2001 From: Teja Date: Tue, 19 May 2026 00:26:56 +0530 Subject: [PATCH 3/4] Refactor styles and components for improved UI consistency and responsiveness - Updated home.css to enhance layout and typography, including new styles for headings and input fields. - Modified homes.js to incorporate Chakra UI components for better loading states and layout structure. - Improved menu.css for a cleaner design and responsive behavior. - Revamped nav.js to utilize Chakra UI for a modern navigation experience with hover effects. - Enhanced application.css for better card designs and slider functionality. - Updated hackathonsidebar.css for improved sidebar styling and responsiveness. - Added global styles and animations in index.css for a cohesive look across the application. - Integrated a custom theme in theme.js for consistent color and component styling throughout the app. - Updated index.js to apply the new Chakra UI theme. --- PROJECT_DESCRIPTION.md | 125 +++++ PROJECT_SUMMARY.md | 14 + client/.env.sample | 16 +- client/src/ast-console/ast-console.css | 126 +++-- .../bootcampsidebar/bootcampsidebar.css | 37 +- .../src/collection/attendance/attendance.css | 45 +- client/src/collection/boot&hack/boot&hack.css | 97 +++- client/src/collection/boot&hack/boot&hack.js | 21 +- client/src/collection/cerdentials/login.js | 447 +++++++----------- client/src/collection/cerdentials/signup.css | 104 ++-- client/src/collection/cerdentials/signup.js | 172 +++---- client/src/collection/home/fivestreak.js | 126 ++--- client/src/collection/home/home.css | 306 ++++++------ client/src/collection/home/homes.js | 47 +- client/src/collection/menu/menu.css | 42 +- client/src/collection/nav&foot/nav.js | 111 +++-- .../otheraplications/application.css | 245 +++++----- .../hackathonsidebar/hackathonsidebar.css | 34 +- client/src/index.css | 94 +++- client/src/index.js | 3 +- client/src/theme.js | 226 +++++++++ 21 files changed, 1493 insertions(+), 945 deletions(-) create mode 100644 PROJECT_DESCRIPTION.md create mode 100644 PROJECT_SUMMARY.md create mode 100644 client/src/theme.js diff --git a/PROJECT_DESCRIPTION.md b/PROJECT_DESCRIPTION.md new file mode 100644 index 00000000..7f2d167a --- /dev/null +++ b/PROJECT_DESCRIPTION.md @@ -0,0 +1,125 @@ +# AST Admin — Arkha Sodhara Tech Administrative Dashboard + +A full-stack administrative dashboard built for the **ARKHA SODHARA TECH (AST) Team** at **SRKR Engineering College, CSE Department**. This platform serves as a centralized management hub for running a college tech team's daily operations — from attendance tracking and bootcamp management to hackathon lifecycle orchestration. + +--- + +## 🎯 Purpose + +To streamline the administrative workflow of a student tech team by replacing manual processes with a unified digital platform. The system handles everything from daily attendance (with OTP and face recognition) to full hackathon management with real-time countdowns and round-based evaluation. + +--- + +## ✨ Key Features + +### 📋 Attendance Management +- Dual-track attendance for **Technology** and **Sadhana (Yoga)** sessions +- OTP-based verification via email (Resend API) +- Optional **face-recognition attendance** using `face-api.js` + webcam capture +- Streak tracking with visual charts (Chart.js) +- Year-wise filtering and student CRUD + +### 🏕️ Bootcamp Management +- Structured training program with task assignment by day +- Multi-dimensional scoring (given marks, internal marks, activity marks) +- Material uploads — PDFs and images stored in MongoDB GridFS +- Student data upload via XLSX parsing +- Attendance marking and feedback collection + +### 🏆 Hackathon Management +- Full lifecycle management: problem statements → team registration → scoring +- Round-based evaluation with configurable tasks +- Real-time countdown timer via **Socket.IO** +- Photo gallery uploads +- Internal and activity marks tracking + +### 🔐 AST Console (Admin Panel) +- Role-based access control: `superAdmin`, `admin`, `edit`, `org` +- Dynamic route management (add/edit/delete/toggle visibility) +- Admin account management with granular permissions +- Middleware-protected API routes + +### 🚀 Project Showcase +- Students upload and display their projects +- Like/unlike and share via WhatsApp, Telegram, and Email +- Student login to manage own project listings + +### 🤖 AI-Powered Chat +- PDF content analysis using **OctoAI (Llama 2)** model +- "Chat With Me" feature for document Q&A + +### 🧑‍💼 Scrum Master Tools +- Daily attendance recording +- Daily work submission tracking + +--- + +## 🛠️ Tech Stack + +| Layer | Technologies | +|---|---| +| **Frontend** | React 18, Redux + redux-persist (cookie storage), Chakra UI, Material UI, React Bootstrap, Tailwind CSS, Framer Motion, Formik, Chart.js, react-webcam | +| **Backend** | Node.js, Express (ES Modules), MongoDB (native driver + GridFS), Mongoose | +| **Real-time** | Socket.IO (hackathon countdown timer) | +| **AI/ML** | face-api.js (face recognition), OctoAI SDK (Llama 2 for PDF chat) | +| **Auth & Security** | AES encryption (crypto-js), express-session, role-based middleware | +| **File Storage** | MongoDB GridFS (uploads bucket in VedicVision database) | +| **File Upload** | Multer, XLSX parsing | +| **Notifications** | Resend (email OTP), Twilio (SMS), SMTP.js | +| **Deployment** | Vercel (serverless-ready with vercel.json) | + +--- + +## 🏗️ Architecture + +**Monorepo structure:** +``` +ASTadmin/ +├── client/ # React SPA (Create React App, Webpack) +│ └── src/ +│ ├── collection/ # Feature modules (attendance, face, project, etc.) +│ ├── ast-console/ # Admin panel module +│ ├── bootcamp/ # Bootcamp module +│ ├── hackathon/ # Hackathon module +│ └── actions/ # API helpers, auth, Redux store +├── server/ # Express API (ES Modules) +│ └── src/ +│ ├── attendance/ # Attendance routes + OTP logic +│ ├── bootcamp/ # Bootcamp CRUD + scoring +│ ├── hackathon/ # Hackathon lifecycle +│ ├── ast-console/ # Console admin + middleware +│ └── multer/ # Upload config +``` + +**Key architectural decisions:** +- **Two MongoDB databases**: `Mern_Attendance` (primary data) and `VedicVision` (GridFS file storage) +- **Cookie-persisted Redux state** with 12-hour expiration via `redux-persist-cookie-storage` +- **URL query parameter navigation** (`?page=attendance`) for sub-page routing within modules +- **Conditional route rendering** — routes appear only after authentication checks complete +- **Mixed UI library usage** — evolved organically, leveraging Chakra UI modals/toasts, MUI Data Grid, Bootstrap navbar, and Tailwind utilities side by side + +--- + +## 🔐 Authentication & Security + +- Admin credentials AES-encrypted in sessionStorage +- Role-based access enforced via Express middleware (`ConsoleMiddleware`, `BootcamEditMiddlware`) +- Origin-check middleware restricts API access to approved domains +- Student login via register number + OTP + +--- + +## 📦 External Integrations + +- **OctoAI** — LLM-powered PDF chat +- **Resend** — Transactional email for OTP delivery +- **Twilio** — SMS notifications +- **Socket.IO** — Real-time hackathon timer (external server) +- **face-api.js** — Browser-based face detection and recognition + +--- + +> **Role:** Full-stack Developer +> **Timeline:** [Add your timeline here] +> **Live Demo:** [Add URL if deployed] +> **Repository:** Private/Internal diff --git a/PROJECT_SUMMARY.md b/PROJECT_SUMMARY.md new file mode 100644 index 00000000..57937733 --- /dev/null +++ b/PROJECT_SUMMARY.md @@ -0,0 +1,14 @@ +## AST Admin — Arkha Sodhara Tech Administrative Dashboard + +**What it is:** A full-stack administrative dashboard for a college student tech team (**ARKHA SODHARA TECH** at SRKR Engineering College, CSE Dept). It's a monorepo with a React frontend (`/client`) and Node.js/Express backend (`/server`). + +**Core features:** +- **Attendance management** with OTP verification (tech + yoga sessions), streak tracking, and face-recognition-based attendance via `face-api.js` +- **Bootcamp management** — task assignment, scoring/grading, file uploads (PDFs/images), student data, attendance, feedback +- **Hackathon management** — problem statements, team registration, round-based evaluation, scoring, photo galleries, real-time countdown timer (Socket.IO) +- **AST Console** — internal admin panel with role-based access (superAdmin, admin, edit) for managing routes, admins, and system config +- **Project showcase** — students upload projects with like/share (WhatsApp, Telegram, Email) +- **Scrum master tools** — daily attendance and work submission tracking +- **AI chatbot** — OctoAI-powered PDF chat (Llama 2) + +**Tech stack:** React 18, Redux + redux-persist (cookie storage), Chakra UI + MUI + Bootstrap + Tailwind (mixed), MongoDB with native driver + GridFS, Express, Socket.IO, face-api.js, Formik, Framer Motion, Chart.js, Multer, Nodemailer/Resend, Twilio. diff --git a/client/.env.sample b/client/.env.sample index 96428486..19a2c70d 100644 --- a/client/.env.sample +++ b/client/.env.sample @@ -1,3 +1,13 @@ -REACT_APP_database="" -REACT_APP_host="" -React_App_BootLogin="" \ No newline at end of file +# Backend API base URL +REACT_APP_database="http://localhost:8000" + +# Host URL (frontend) +REACT_APP_host="http://localhost:3000" + +# Bootcamp admin login endpoint +React_App_BootLogin="http://localhost:5000/bootcampadminlogin" + +# External integrations +React_App_goole="" +React_App_face_api="" +React_App_Students="" \ No newline at end of file diff --git a/client/src/ast-console/ast-console.css b/client/src/ast-console/ast-console.css index b25eb498..3899c065 100644 --- a/client/src/ast-console/ast-console.css +++ b/client/src/ast-console/ast-console.css @@ -1,39 +1,95 @@ body { - font-family: sans-serif; - -webkit-font-smoothing: auto; - -moz-font-smoothing: auto; - -moz-osx-font-smoothing: grayscale; - font-smoothing: auto; - text-rendering: optimizeLegibility; - font-smooth: always; - -webkit-tap-highlight-color: transparent; - -webkit-touch-callout: none; + font-family: 'Inter', sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + text-rendering: optimizeLegibility; + -webkit-tap-highlight-color: transparent; } h1 { - font-size: 1.5rem; -} - -.boxmotion{ - width: 100%; - height: 100vh; - align-items: center; - display: grid; - justify-content: space-evenly; -} - - -@media (max-width:500px) { - #motion{ - display: none; - } - #signinform{ - width: 90%; - } - .boxmotion{ - display: none; - } - .astname{ - display: none; - } -} \ No newline at end of file + font-size: 1.5rem; +} + +.boxmotion { + width: 100%; + height: 100vh; + align-items: center; + display: grid; + justify-content: space-evenly; +} + +.console-layout { + min-height: 100vh; + background: #f8fafc; +} + +.console-header { + background: white; + border-bottom: 1px solid #e2e8f0; + padding: 0.75rem 1.5rem; + position: sticky; + top: 0; + z-index: 50; + backdrop-filter: blur(12px); +} + +.console-logo { + display: flex; + align-items: center; + gap: 0.75rem; +} + +.console-title { + font-size: 1.25rem; + font-weight: 800; + background: linear-gradient(135deg, #6366f1, #d946ef); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + letter-spacing: -0.02em; +} + +.console-content { + padding: 1.5rem; + max-width: 1200px; + margin: 0 auto; +} + +.console-nav { + position: fixed; + bottom: 0; + left: 0; + right: 0; + display: flex; + justify-content: center; + gap: 8px; + height: 64px; + align-items: center; + background: white; + border-top: 1px solid #e2e8f0; + box-shadow: 0 -4px 12px rgba(0,0,0,0.04); + z-index: 50; + padding: 0 1rem; +} + +.console-nav > * { + flex-shrink: 0; +} + +@media (max-width: 500px) { + #motion { + display: none; + } + #signinform { + width: 90%; + } + .boxmotion { + display: none; + } + .astname { + display: none; + } + .console-content { + padding: 1rem; + } +} diff --git a/client/src/bootcamp/bootcampsidebar/bootcampsidebar.css b/client/src/bootcamp/bootcampsidebar/bootcampsidebar.css index 663e358a..7326d003 100644 --- a/client/src/bootcamp/bootcampsidebar/bootcampsidebar.css +++ b/client/src/bootcamp/bootcampsidebar/bootcampsidebar.css @@ -6,14 +6,17 @@ #sidebar { height: 100vh; + border-right: 1px solid #e2e8f0 !important; + background: white !important; + transition: all 0.2s ease; } .main-content { flex: 1; padding: 2rem; height: 100vh; - overflow-y: scroll; - background-color: white; + overflow-y: auto; + background: #f8fafc; } .mati { @@ -29,11 +32,9 @@ .allmetirials { width: 100%; - /* height: 80vh; */ display: flex; justify-content: center; align-items: center; - } .allmeti { @@ -42,7 +43,8 @@ .file-inputs input, Select { - border: black 3px solid; + border: 1px solid #e2e8f0; + border-radius: 8px; } .matform { @@ -50,14 +52,33 @@ Select { height: 20vh; } +/* Modern sidebar styling */ +.modern-sidebar .ps-sidebar-container { + background: white !important; +} + +.modern-sidebar .ps-menu-button:hover { + background: rgba(99, 102, 241, 0.08) !important; + color: #4f46e5 !important; + border-radius: 8px !important; +} + +.modern-sidebar .ps-menu-button { + margin: 2px 8px !important; + border-radius: 8px !important; + transition: all 0.15s ease !important; +} + +.modern-sidebar .ps-sidebar-container { + padding-top: 8px; +} -@media (max-width:500px) { +@media (max-width: 500px) { #sidebar { position: fixed; } - .main-content { padding-left: 5rem; width: 100%; } -} \ No newline at end of file +} diff --git a/client/src/collection/attendance/attendance.css b/client/src/collection/attendance/attendance.css index d724a312..f56ba901 100644 --- a/client/src/collection/attendance/attendance.css +++ b/client/src/collection/attendance/attendance.css @@ -1,31 +1,26 @@ .list { - display: flex; - justify-content: center; - align-items: center; - width: 100%; - height: 90vh; + display: flex; + justify-content: center; + align-items: center; + width: 100%; + min-height: calc(100vh - 80px); + padding: 2rem; } -.listgrid{ - width: 50%; - height: 300px; - display: flex; - justify-content: center; +.listgrid { + width: 100%; + max-width: 600px; + display: flex; + justify-content: center; } -.listgrid h6 -{ - text-align: center; +@media (max-width: 700px) { + .list { + width: 100%; + padding: 1rem; + } + .listgrid { + margin-top: 2rem; + width: 100%; + } } - -@media (max-width:700px) { - .list { - width: 100%; - height:100%; - } - .listgrid{ - margin-top: 10%; - width: 200px; - height: 100px; - } -} \ No newline at end of file diff --git a/client/src/collection/boot&hack/boot&hack.css b/client/src/collection/boot&hack/boot&hack.css index 72c29592..c96bbde6 100644 --- a/client/src/collection/boot&hack/boot&hack.css +++ b/client/src/collection/boot&hack/boot&hack.css @@ -1,27 +1,76 @@ -.hackboot{ - width: 60%; - height: 30vh; - display: flex; - justify-content: space-evenly; - align-items: center; - /* background-color: black; */ - border-radius: 20px; +.hackboot { + width: 100%; + max-width: 600px; + display: flex; + justify-content: center; + gap: 24px; + padding: 1rem; } -.hackboot button{ - width: 30%; - height: 10vh; - font-size: large; - align-items: center; + +.hackboot-card { + flex: 1; + max-width: 260px; + background: white; + border: 1px solid #e2e8f0; + border-radius: 16px; + padding: 2rem 1.5rem; + text-align: center; + cursor: pointer; + transition: all 0.25s ease; + box-shadow: 0 1px 3px rgba(0,0,0,0.04); + position: relative; + overflow: hidden; +} + +.hackboot-card::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 4px; + border-radius: 16px 16px 0 0; } -@media (max-width:500px) { - .hackboot{ - width: 80%; - height: 30vh; - display: grid; - } - .hackboot button{ - width: 100%; - height: 8vh; - } -} \ No newline at end of file +.hackboot-card:first-child::before { + background: linear-gradient(90deg, #6366f1, #a855f7); +} + +.hackboot-card:last-child::before { + background: linear-gradient(90deg, #f43f5e, #f97316); +} + +.hackboot-card:hover { + transform: translateY(-4px); + box-shadow: 0 12px 24px rgba(0,0,0,0.08); + border-color: #c7d2fe; +} + +.hackboot-icon { + font-size: 2.5rem; + margin-bottom: 0.75rem; +} + +.hackboot-label { + font-size: 1.25rem; + font-weight: 700; + color: #1e293b; + margin-bottom: 0.25rem; +} + +.hackboot-desc { + font-size: 0.8125rem; + color: #94a3b8; + font-weight: 400; +} + +@media (max-width: 500px) { + .hackboot { + flex-direction: column; + align-items: center; + } + .hackboot-card { + width: 100%; + max-width: 100%; + } +} diff --git a/client/src/collection/boot&hack/boot&hack.js b/client/src/collection/boot&hack/boot&hack.js index e384482a..29a3632f 100644 --- a/client/src/collection/boot&hack/boot&hack.js +++ b/client/src/collection/boot&hack/boot&hack.js @@ -1,10 +1,19 @@ -import { Button } from "flowbite-react"; +import { Box, Button, Text } from "@chakra-ui/react"; import './boot&hack.css'; + export const BootHack = () => { return ( -
- - -
+ + window.location.href = 'bootcamp'}> + 🏕️ + Bootcamp + Training & Tasks + + window.location.href = 'hackathon'}> + 🏆 + Hackathon + Events & Scoring + + ) -} \ No newline at end of file +} diff --git a/client/src/collection/cerdentials/login.js b/client/src/collection/cerdentials/login.js index a59ad568..07de180e 100644 --- a/client/src/collection/cerdentials/login.js +++ b/client/src/collection/cerdentials/login.js @@ -15,6 +15,10 @@ import { Kbd, InputRightElement, Text, + Spinner, + VStack, + HStack, + Badge, } from "@chakra-ui/react"; import axios from "axios"; import React, { useEffect, useRef, useState } from "react"; @@ -34,8 +38,8 @@ const Login = () => { const [otp, setOtp] = useState(); const [tat, setTat] = useState({}); const [isLoading, setIsLoading] = useState(true); - const [ showdelete, setShowdelete] = useState(false) - const [deletestudent,setDeletestudent] = useState(); + const [showdelete, setShowdelete] = useState(false); + const [deletestudent, setDeletestudent] = useState(); const date = new Date(); const toast = useToast(); const searchRef = useRef(null); @@ -45,28 +49,12 @@ const Login = () => { const res = await Actions.SendOtp(regd); if (res?.data?.message) { setData(res?.data); - toast({ - title: res.data.message, - status: "success", - position: "top-right", - isClosable: true, - }); + toast({ title: res.data.message, status: "success", position: "top-right", isClosable: true }); } else { - toast({ - title: res.data.error, - status: "error", - position: "bottom-right", - isClosable: true, - }); + toast({ title: res.data.error, status: "error", position: "bottom-right", isClosable: true }); } } catch (error) { - console.error(error); - toast({ - title: "Failed to send OTP", - status: "error", - position: "bottom-right", - isClosable: true, - }); + toast({ title: "Failed to send OTP", status: "error", position: "bottom-right", isClosable: true }); } }; @@ -76,65 +64,37 @@ const Login = () => { }; const handleDeleteStudent = (stu) => { - - setDeletestudent(stu) - setShowdelete(true) - }; + setDeletestudent(stu); + setShowdelete(true); + }; const handleDelete = async () => { document.getElementById("password").style.display = "block"; try { - const adminCheckRes = await axios.post( - `${process.env.REACT_APP_database}/admincheck/${sessionStorage.gmail}/${otp}` - ); + const adminCheckRes = await axios.post(`${process.env.REACT_APP_database}/admincheck/${sessionStorage.gmail}/${otp}`); if (adminCheckRes.data) { - await axios.post( - `${process.env.REACT_APP_database}/deletestudent/${atnd}` - ); + await axios.post(`${process.env.REACT_APP_database}/deletestudent/${atnd}`); window.location.reload(); } else { - toast({ - title: "Enter correct password", - status: "error", - position: "bottom-left", - isClosable: true, - }); + toast({ title: "Enter correct password", status: "error", position: "bottom-left", isClosable: true }); } } catch (error) { - console.error(error); - toast({ - title: "Failed to delete student", - status: "error", - position: "bottom-left", - isClosable: true, - }); + toast({ title: "Failed to delete student", status: "error", position: "bottom-left", isClosable: true }); } }; - const handleRegister = () => { - sessionStorage.removeItem("yoga"); - }; + const handleRegister = () => sessionStorage.removeItem("yoga"); const fetchData = async () => { try { - const studentRes = await axios.post( - `${process.env.REACT_APP_database}/students` - ); + const studentRes = await axios.post(`${process.env.REACT_APP_database}/students`); const storeddata = studentRes.data.sort((a, b) => b?.Num - a?.Num); setDat(storeddata); - const totalDaysRes = await axios.post( - `${process.env.REACT_APP_database}/totaldays` - ); + const totalDaysRes = await axios.post(`${process.env.REACT_APP_database}/totaldays`); setTat(totalDaysRes.data); setIsLoading(false); } catch (error) { - console.error(error); - toast({ - title: "Failed to fetch data", - status: "error", - position: "bottom-right", - isClosable: true, - }); + toast({ title: "Failed to fetch data", status: "error", position: "bottom-right", isClosable: true }); } }; @@ -148,251 +108,172 @@ const Login = () => { } }; window.addEventListener("keydown", handleKeyDown); - return () => { - window.removeEventListener("keydown", handleKeyDown); - }; + return () => window.removeEventListener("keydown", handleKeyDown); }, []); + const handleAttendName = () => { - console.log(atnd, "Attend"); const updatedDat = dat.map((student) => - student.Reg_No === atnd - ? { ...student, Login: date.toDateString(),Num: parseInt(student.Num)+1 } - : student + student.Reg_No === atnd ? { ...student, Login: date.toDateString(), Num: parseInt(student.Num) + 1 } : student ); setDat(updatedDat); }; + const yearColors = { 1: '#6366f1', 2: '#d946ef', 3: '#f59e0b', 4: '#22c55e' }; + return ( - <> + - setShow(false)} - data={data} - refresh={handleAttendName} + setShow(false)} data={data} refresh={handleAttendName} /> + setShowdelete(false)} /> - /> - setShowdelete(false)} - /> - setOtp(e.target.value)} - /> + setOtp(e.target.value)} /> - - + + - - SRKREC CSE DEPT. - - - - - - - - - - - Total days - {tat?.Days} - + + SRKREC CSE DEPT. + + + {[1, 2, 3, 4].map((year) => ( + + ))} + - - - Scrum Master + + + + Total Days + {tat?.Days || '-'} - {tat?.Scum} - - - - - + + Scrum Master + {tat?.Scum || '-'} + + + + + + + + + + + setSelect(e.target.value)} + ref={searchRef} + bg="surface.50" + border="1px solid" + borderColor="surface.200" + _focus={{ borderColor: 'brand.400', boxShadow: 'glow' }} + /> + + Shift + + + F + + - - - - setSelect(e.target.value)} - ref={searchRef} - /> - - Shift + F - - - - - - - {isLoading ? ( - - - - - - ) : ( - <> - - - - - - - - - - - - {dat - ?.filter( - (user) => - user?.Reg_No.toLowerCase().includes( - select?.toLowerCase() - ) || - user?.Name.toLowerCase().includes(select?.toLowerCase()) - ) - ?.map( - (x, index) => - x.Year === sessionStorage.year && ( - - - - - - - - + +
- Loading... -
SNOREGISTER NUMBERNAMECLICKStreakRemove
{index + 1}{x?.Reg_No.toUpperCase()} - {x?.Name.toUpperCase()} - - {x.Login !== date.toDateString() && ( - - )} - - - - {parseInt(x?.Num)} - - - - -
+ {isLoading ? ( + + + + + + ) : ( + <> + + + + + + + + + + + + {dat + ?.filter( + (user) => + user?.Reg_No.toLowerCase().includes(select?.toLowerCase()) || + user?.Name.toLowerCase().includes(select?.toLowerCase()) ) - )} - - - )} -
+ +
SNOREGISTER NUMBERNAMEATTENDSTREAKREMOVE
+ ?.map( + (x, index) => + x.Year === sessionStorage.year && ( + + {index + 1} + {x?.Reg_No.toUpperCase()} + {x?.Name.toUpperCase()} + + {x.Login !== date.toDateString() && ( + + )} + {x.Login === date.toDateString() && ( + Done + )} + + + + {parseInt(x?.Num)} + + + + + + + ) + )} + + + )} + +
- + ); }; diff --git a/client/src/collection/cerdentials/signup.css b/client/src/collection/cerdentials/signup.css index 683c7835..d233ba4a 100644 --- a/client/src/collection/cerdentials/signup.css +++ b/client/src/collection/cerdentials/signup.css @@ -1,83 +1,49 @@ -/* same css is used in scrum.js and addproject */ +/* Shared styles for signup, scrum, and project pages */ +/* Most styling now handled by Chakra UI components */ .register-body { - font-family: Arial, sans-serif; - margin: 0; - display: flex; - justify-content: center; - align-items: center; -} -.register-container { - background-color: #f0f0f0; - border-radius: 10px; - box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); - padding: 20px; - width: 100%; - max-width: 560px; - text-align: center; - margin-top: 3%; -} - -.register-header { - background-color: #3498db; - color: #fff; - border-radius: 10px; - padding: 10px; - text-align: center; - font-family:'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; - font-style: italic ; + font-family: 'Inter', sans-serif; + margin: 0; + display: flex; + justify-content: center; + align-items: center; + min-height: 100vh; + background: #f8fafc; } -.form-group { - margin: 10px 0; - text-align: left; -} - -.form-group label { - display: block; - margin-bottom: 5px; - color: #555; -} - -.form-group input[type="text"], -.form-group input[type="email"], -.form-group select { - width: 100%; - padding: 10px; - border: 1px solid #ccc; - border-radius: 5px; - outline: none; -} - -.form-group select { - background-color: #f9f9f9; - +.studetail { + width: 100%; } .form-group button { - background-color: #3498db; - color: #fff; - border: none; - border-radius: 5px; - padding: 10px 20px; - cursor: pointer; - height: 40px; + background-color: #3498db; + color: #fff; + border: none; + border-radius: 8px; + padding: 10px 20px; + cursor: pointer; + height: 40px; + font-weight: 600; + transition: all 0.2s; } .form-group button:hover { - background-color: #2587c8; + background-color: #2587c8; } .login-link { - text-decoration: none; - background-color:rgb(47, 203, 255); - color:#fff; - border: none; - border-radius: 5px; - padding: 10px 20px; - cursor: pointer; -} - -.studetail{ - width: 100%; + text-decoration: none; + background: linear-gradient(135deg, #6366f1, #4f46e5); + color: #fff; + border: none; + border-radius: 8px; + padding: 10px 20px; + cursor: pointer; + font-weight: 600; + display: inline-block; + transition: all 0.2s; +} + +.login-link:hover { + background: linear-gradient(135deg, #4f46e5, #4338ca); } diff --git a/client/src/collection/cerdentials/signup.js b/client/src/collection/cerdentials/signup.js index 13121956..c7f98d05 100644 --- a/client/src/collection/cerdentials/signup.js +++ b/client/src/collection/cerdentials/signup.js @@ -4,6 +4,8 @@ import React, { useState } from "react"; import { Link, useNavigate } from "react-router-dom"; import "../cerdentials/signup.css"; import { Navbars } from "../nav&foot/nav"; +import { Box, Input, Text, Button, VStack, HStack, Select, Radio, RadioGroup, Stack } from "@chakra-ui/react"; + const Signup = () => { const nav = useNavigate(); const [check, SetCheck] = useState(""); @@ -13,9 +15,12 @@ const Signup = () => { const [branch, Setbranch] = useState(""); const [email, SetEmail] = useState(""); const [num, snum] = useState(0); + const [loading, setLoading] = useState(false); const toast = useToast(); + const Handleclick = async () => { const emailRegex = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; + setLoading(true); try { if (emailRegex.test(email)) { const res = await axios.post(process.env.REACT_APP_database + "/student/" + email) @@ -27,19 +32,15 @@ const Signup = () => { const res = await axios.post(process.env.REACT_APP_database + "/signup/" + email + "/" + name + "/" + regd + "/" + year + "/" + branch + "/" + num) { if (res) { - toast({ title: "Register Successfully", status: 'success', position: "bottom-right", isClosable: true }) - setTimeout(() => { - window.location = '/login' - window.history.back(); - }, 1000); + toast({ title: "Register Successfully", status: 'success', position: "top-right", isClosable: true }); + setTimeout(() => { window.location = '/login'; window.history.back(); }, 1000); } else { - toast({ title: "Try again", status: "error", position: "bottom-left", isClosable: true }) + toast({ title: "Try again", status: "error", position: "bottom-left", isClosable: true }); } } } } - } else { SetCheck("Invalid Email"); @@ -47,104 +48,57 @@ const Signup = () => { } catch (err) { console.log(err); + } finally { + setLoading(false); } } + const Login = () => { if (sessionStorage.yoga === "Yoga@9899") { window.location = '/yoga'; } else { window.history.back(); - // window.location = '/login'; } } + return ( <> -
-
-
-

SIGNUP FORM

-
-
-
{check}
-
-
-
- - SetName(e.target.value.toUpperCase())} - /> -
+ + + Student Signup + + {check && ( + {check} + )} + + + + Full Name + SetName(e.target.value.toUpperCase())} /> + -
- - SetRegd(e.target.value.toUpperCase())} - /> -
+ + Register Number + SetRegd(e.target.value.toUpperCase())} /> + -
- -
- SetYear('1')} - /> - - SetYear('2')} - /> - - SetYear('3')} - /> - - SetYear('4')} - /> - -
-
+ + Year Of Studying + + + 1st + 2nd + 3rd + 4th + + + -
- - Setbranch(e.target.value)} placeholder="Choose one"> @@ -155,34 +109,22 @@ const Signup = () => { - -
- -
- - SetEmail(e.target.value)} - /> -
-
- - - Attend - -
-
+ + + + Email + SetEmail(e.target.value)} /> + -
-
+ + + + + + + ); } -export default Signup; \ No newline at end of file +export default Signup; diff --git a/client/src/collection/home/fivestreak.js b/client/src/collection/home/fivestreak.js index df109d51..dd759ae1 100644 --- a/client/src/collection/home/fivestreak.js +++ b/client/src/collection/home/fivestreak.js @@ -1,4 +1,4 @@ -import { Box, SimpleGrid, Table, TableCaption, Tbody, Td, Th, Thead, Tr, Text } from "@chakra-ui/react"; +import { Box, SimpleGrid, Text, Table, Thead, Tbody, Tr, Th, Td, Badge } from "@chakra-ui/react"; export const FiveStreak = ({ data }) => { const sortedByTechnologyAttendance = [...data].sort((a, b) => b.Num - a.Num).slice(0, 5); @@ -6,66 +6,76 @@ export const FiveStreak = ({ data }) => { return ( - - - Technology Attendance - - - - - - - - - - - - {sortedByTechnologyAttendance.map((x, index) => ( - - - - - - + + + + Technology Attendance + + +
Reg NoNameBranchYearStreak
{x.Reg_No}{x.Name}{x.Branch}{x.Year} - -
{parseInt(x.Num)}
- -
+ + + + + + + - ))} - - Top Five Members In Technology Attendance Streaks -
Reg NoNameBranchYearStreak
+ + + {sortedByTechnologyAttendance.map((x, index) => ( + + {x.Reg_No} + {x.Name} + {x.Branch} + + {x.Year} + + + + {parseInt(x.Num)} + + + + ))} + + +
- - Sadhana Attendance - - - - - - - - - - - - {sortedBySadhanaAttendance.map((x, index) => ( - - - - - - + + + Sadhana Attendance + + +
Reg NoNameBranchYearStreak
{x.Reg_No}{x.Name}{x.Branch}{x.Year} - -
{parseInt(x.MrngStreak)}
- -
+ + + + + + + - ))} - - Top Five Members In Sadhana Attendance Streaks -
Reg NoNameBranchYearStreak
+ + + {sortedBySadhanaAttendance.map((x, index) => ( + + {x.Reg_No} + {x.Name} + {x.Branch} + + {x.Year} + + + + {parseInt(x.MrngStreak)} + + + + ))} + + +
diff --git a/client/src/collection/home/home.css b/client/src/collection/home/home.css index ee80e9ba..b6c9ca8f 100644 --- a/client/src/collection/home/home.css +++ b/client/src/collection/home/home.css @@ -1,182 +1,218 @@ .home-container { - font-family: Arial, sans-serif; - padding: 20px; - margin-bottom: 20px; - + padding: 2rem 1.5rem; + max-width: 1200px; + margin: 0 auto; } .homename { - text-align: center; - background: linear-gradient(180deg, #100445, #ff01a2); - font-size: 80px; - font-family: poppins; - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; + text-align: center; + background: linear-gradient(135deg, #4f46e5, #d946ef); + font-size: 3.5rem; + font-weight: 800; + font-family: 'Inter', sans-serif; + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + letter-spacing: -0.03em; + margin-bottom: 0.5rem; +} + +.homename-sub { + text-align: center; + font-size: 1rem; + color: #64748b; + font-weight: 400; + margin-bottom: 2rem; } .top-5 { - font-size: 30px; - /* margin-top: 5%; */ - color: #007acc; - text-align: center; - margin-bottom: 20px; + font-size: 1.5rem; + font-weight: 700; + color: #4f46e5; + text-align: center; + margin-bottom: 1.5rem; } .studetail { - border-collapse: collapse; - max-width: 1210px; - margin: 0 auto; - background-color: #fff; - box-shadow: 0 6px 8px rgba(0, 0, 0, 0.1); - text-align: center; - - + border-collapse: collapse; + max-width: 1210px; + margin: 0 auto; + background-color: #fff; + box-shadow: 0 1px 3px rgba(0,0,0,0.04), 0 1px 2px -1px rgba(0,0,0,0.06); + text-align: center; + border-radius: 12px; + overflow: hidden; } .studetail td { - padding: 10px; - text-align: center; - + padding: 12px; + text-align: center; } - .fivestreak { - margin-top: 5%; - display: flex; - width: 100%; - justify-content: center; + margin-top: 2rem; + display: flex; + width: 100%; + justify-content: center; } .streakgrid { - /* margin-top: 5%; */ - /* display: flex; */ - width: 100%; - /* justify-content: space-around; */ + width: 100%; } - .streakdiv { - margin-top: 5%; - display: flex; - width: 100%; - justify-content: center; + margin-top: 2rem; + display: flex; + width: 100%; + justify-content: center; } .graphinput { - display: grid; - align-items: center; - justify-content: center; - width: 100%; + display: grid; + align-items: center; + justify-content: center; + width: 100%; } .graphdiv { - width: 100%; - + width: 100%; } .graphinput input { - height: 5vh; + height: 40px; + border: 1px solid #e2e8f0; + border-radius: 8px; + padding: 0 12px; + font-size: 0.875rem; + transition: border-color 0.2s; +} +.graphinput input:focus { + border-color: #818cf8; + box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1); + outline: none; } +.labelinput tr td input { + width: 20px; +} +.labelinput tr td { + width: 100%; + justify-content: center; +} - -.labelinput tr td input -{ - width: 20px; +.streak-text { + width: 100%; + height: 36px; + background: linear-gradient(90deg, #eef2ff, #e0e7ff); + border-radius: 6px; + color: #4338ca; + font-size: 0.8125rem; + font-weight: 600; + display: flex; + justify-content: flex-end; + align-items: center; + padding-right: 12px; +} + +.main-streak-text { + width: 100%; + height: 36px; + background: linear-gradient(135deg, #eef2ff, #e0e7ff); + border-radius: 6px; + color: #4338ca; + font-size: 0.875rem; + font-weight: 700; + display: flex; + justify-content: center; + align-items: center; + padding: 8px; +} + +.streak-value { + font-size: 1.125rem; + font-weight: 700; + color: #4f46e5; } -.labelinput tr td -{ - width: 100%; -justify-content: center; +img { + align-items: center; + max-width: 100%; + height: 70px; } +.boothack { + width: 100%; + padding: 2rem 0; + display: flex; + justify-content: center; + align-items: center; +} +.applications { + width: 100%; + display: flex; + justify-content: center; + padding: 0 1rem; +} +/* Streak graph card */ +.streak-card { + background: white; + border: 1px solid #e2e8f0; + border-radius: 12px; + box-shadow: 0 1px 3px rgba(0,0,0,0.04); + padding: 1.5rem; + margin: 1rem 0; +} +.streak-card-title { + font-size: 1.25rem; + font-weight: 600; + color: #1e293b; + margin-bottom: 1rem; +} -.streak-text { - width: 150%; - height: 5vh; - background-image: url("./streak.png"); - background-repeat: no-repeat; - background-size: 150% 100%; - color: black; - font-size: 15px; - display: flex; - justify-content:flex-end; - align-items: center; -} -.main-streak-text{ +@media (max-width: 700px) { + .studetail { + font-size: 0.75rem; width: 100%; - height: 5vh; - background-image: url("./streak.png"); - background-repeat: no-repeat; - object-fit: cover; - color: black; - background-size: 100% 100%; - font-size: 10px; - padding-top: 20px !important; - padding: 9px; - display: flex; - justify-content:center; - align-items: center; - font-weight: bold; -} + } -img { - align-items: center; - max-width: 100%; - height: 70px; -} + .graphdiv { + padding-left: 0; + margin-left: 0; + } -.boothack{ + .homename { + font-size: 2rem; + } + + .top-5 { + font-size: 1.25rem; + } + + img { + height: 50px; + width: 120px; + } + + .streak-text { + font-size: 0.6875rem; + } + + .streakgrid { width: 100%; - height: 30vh; - display: flex; - justify-content: center; - align-items: center; -} + } -@media (max-width: 700px) { - .studetail { - font-size: 12px; - width: 100%; - } - - .graphdiv { - padding-left: 0%; - margin-left: 0%; - } - - - .homename { - font-size: 50px; - } - - .top-5 { - font-size: 24px; - } - - img { - height: 50px; - width: 120px - } - - .streak-text { - font-size: 11px; - } - - .streakgrid { - width: 100%; - } - - .streakgrid table tbody { - background-color: white; - } - - - .studetail td { - padding: 2px; - } -} \ No newline at end of file + .streakgrid table tbody { + background-color: white; + } + + .studetail td { + padding: 4px; + } + + .home-container { + padding: 1rem 0.75rem; + } +} diff --git a/client/src/collection/home/homes.js b/client/src/collection/home/homes.js index 04013bd7..1263b7e4 100644 --- a/client/src/collection/home/homes.js +++ b/client/src/collection/home/homes.js @@ -7,9 +7,12 @@ import { FiveStreak } from "./fivestreak"; import { StreakGraph } from "./streakgraph.js"; import { Applications } from "../otheraplications/applications.js"; import { BootHack } from "../boot&hack/boot&hack.js"; +import { Box, Heading, Text, Container, Spinner, VStack } from "@chakra-ui/react"; + export const Home = () => { const [dat, sdat] = useState([]); const [tat, stat] = useState([]); + const [loading, setLoading] = useState(true); useEffect(() => { axios.post(process.env.REACT_APP_database + "/students") .then((result) => { @@ -21,22 +24,44 @@ export const Home = () => { stat(result.data) }) .catch((e)=>console.log(e)) + .finally(() => setLoading(false)) }, []) + + if (loading) { + return ( + <> + + + + Loading... + + + ) + } + return ( <> -
-
AST Admin
+ + AST Admin + ARKHA SODHARA TECH — SRKR CSE Department - - -
-
+ + + Leaderboard + + + + + + + + -
-
- -
+ + + + ) -} \ No newline at end of file +} diff --git a/client/src/collection/menu/menu.css b/client/src/collection/menu/menu.css index cd7de524..a74a02cd 100644 --- a/client/src/collection/menu/menu.css +++ b/client/src/collection/menu/menu.css @@ -1,35 +1,33 @@ .menu { - width: 100%; - min-height: 50vh; - display: flex; - justify-content: center; - align-items: center; - /* transform: scale(-100%,-100%); */ - margin-top: 5%; + width: 100%; + min-height: auto; + display: flex; + justify-content: center; + align-items: center; + padding: 1rem 0; } .menucard { - height: 200px; + height: 200px; } .menulist { - width: 40%; - /* margin: 0%; */ - height: 100%; - /* background-color: black; */ - display: flex; - justify-content: center; + width: 100%; + max-width: 900px; + height: 100%; + display: flex; + justify-content: center; } .menucard button { - border: none; - color: blue; + border: none; + color: blue; } @media (max-width: 768px) { - .menulist { - width: 100%; - display: grid; - justify-content: center; - } -} \ No newline at end of file + .menulist { + width: 100%; + display: grid; + justify-content: center; + } +} diff --git a/client/src/collection/nav&foot/nav.js b/client/src/collection/nav&foot/nav.js index f1ef0d0c..2571e7fe 100644 --- a/client/src/collection/nav&foot/nav.js +++ b/client/src/collection/nav&foot/nav.js @@ -4,32 +4,85 @@ import Container from 'react-bootstrap/Container'; import Nav from 'react-bootstrap/Nav'; import NavDropdown from 'react-bootstrap/NavDropdown'; import Navbar from 'react-bootstrap/Navbar'; -export const Navbars=()=> -{ - const Pin=()=> - { - sessionStorage.yoga=prompt("Enter pin"); - } - return( - <> - - - AST - - - - - - - - ) -} \ No newline at end of file +import { Box, IconButton, useColorModeValue } from "@chakra-ui/react"; +import { HamburgerIcon } from "@chakra-ui/icons"; + +const navStyles = { + navbar: { + background: 'rgba(255, 255, 255, 0.8)', + backdropFilter: 'blur(12px)', + WebkitBackdropFilter: 'blur(12px)', + borderBottom: '1px solid rgba(226, 232, 240, 0.8)', + boxShadow: '0 1px 3px rgba(0,0,0,0.04)', + position: 'sticky', + top: 0, + zIndex: 100, + }, + brand: { + fontWeight: 700, + fontSize: '1.25rem', + background: 'linear-gradient(135deg, #6366f1, #d946ef)', + WebkitBackgroundClip: 'text', + WebkitTextFillColor: 'transparent', + letterSpacing: '-0.02em', + }, + link: { + fontWeight: 500, + fontSize: '0.875rem', + color: '#475569', + transition: 'color 0.2s', + borderRadius: '6px', + padding: '0.5rem 0.75rem', + }, + dropdownItem: { + fontWeight: 500, + fontSize: '0.8125rem', + color: '#334155', + padding: '0.5rem 1rem', + transition: 'all 0.15s', + borderRadius: '6px', + }, +} + +export const Navbars=()=> { + return ( + <> + + + AST Admin + + + + + + + + + + ) +} diff --git a/client/src/collection/otheraplications/application.css b/client/src/collection/otheraplications/application.css index 1f24b251..854e2133 100644 --- a/client/src/collection/otheraplications/application.css +++ b/client/src/collection/otheraplications/application.css @@ -1,160 +1,185 @@ .appcontainer { - margin: 2%; - padding: 5% 20%; - overflow: hidden; - align-items: center; - justify-content: center; - height: 50vh; - position: relative; + width: 100%; + max-width: 1000px; + margin: 0 auto; + padding: 2rem; + overflow: hidden; + align-items: center; + justify-content: center; + position: relative; } -.card { - background-position: center; - background-size: contain; - object-fit: contain; - background-repeat: no-repeat; - - -} -.hover-items{ - display: none; -} -.hover-items:hover{ - display: block; -} - -/* Slider CSS */ - +/* Slider */ .wrapper { - width: 100%; - position: relative; + width: 100%; + position: relative; } .wrapper i { - top: 50%; - z-index: 9; - height: 50px; - width: 50px; - cursor: pointer; - font-size: 1.25rem; - position: absolute; - text-align: center; - line-height: 50px; - background: #fff; - border-radius: 50%; - box-shadow: 0 3px 6px rgba(0, 0, 0, 0.23); - transform: translateY(-50%); - transition: transform 0.1s linear; - - @media (max-width :460px){ - display: none; - } + top: 50%; + z-index: 9; + height: 44px; + width: 44px; + cursor: pointer; + position: absolute; + text-align: center; + line-height: 44px; + background: white; + border-radius: 50%; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12); + transform: translateY(-50%); + transition: transform 0.15s linear; + display: flex; + align-items: center; + justify-content: center; + color: #475569; + border: 1px solid #e2e8f0; +} + +.wrapper i:hover { + background: #f8fafc; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); } .wrapper i:active { - transform: translateY(-50%) scale(0.85); + transform: translateY(-50%) scale(0.9); } .wrapper i:first-child { - left: 1px; + left: -12px; } .wrapper i:last-child { - right: 1px; + right: -12px; } .wrapper .carousel { - display: grid; - grid-auto-flow: column; - grid-auto-columns: calc((100% / 3) - 102px); - overflow-x: auto; - scroll-snap-type: x mandatory; - gap: 62px; - border-radius: 8px; - scroll-behavior: smooth; - scrollbar-width: none; + display: grid; + grid-auto-flow: column; + grid-auto-columns: calc((100% / 3) - 24px); + overflow-x: auto; + scroll-snap-type: x mandatory; + gap: 24px; + border-radius: 12px; + scroll-behavior: smooth; + scrollbar-width: none; + padding: 8px 0; } .carousel::-webkit-scrollbar { - display: none; + display: none; } .carousel.no-transition { - scroll-behavior: auto; + scroll-behavior: auto; } .carousel.dragging { - scroll-snap-type: none; - scroll-behavior: auto; + scroll-snap-type: none; + scroll-behavior: auto; } .carousel.dragging .card { - cursor: grab; - user-select: none; + cursor: grab; + user-select: none; } .carousel :where(.card, .img) { - display: flex; - justify-content: center; - align-items: center; -} - -#left { - z-index: 9; + display: flex; + justify-content: center; + align-items: center; } .carousel .card { - scroll-snap-align: start; - height: 205px; - list-style: none; - background-color: white; - cursor: pointer; - padding-bottom: 15px; - flex-direction: column; - border-radius: 8px; - position: relative; - overflow: hidden; + scroll-snap-align: start; + height: 220px; + list-style: none; + background: white; + cursor: pointer; + flex-direction: column; + border-radius: 16px; + position: relative; + overflow: hidden; + border: 1px solid #e2e8f0; + box-shadow: 0 1px 3px rgba(0,0,0,0.04); + background-size: cover; + background-position: center; + background-repeat: no-repeat; + transition: all 0.25s ease; +} + +.carousel .card:hover { + transform: translateY(-4px); + box-shadow: 0 12px 24px rgba(0,0,0,0.08); + border-color: #c7d2fe; } .carousel .card:hover .overlay { - opacity: 1; + opacity: 1; } - - .carousel .card .overlay { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: linear-gradient(to top, rgba(0, 0, 0, 0.5), transparent); - display: flex; - padding: 10px; - flex-direction: column; - justify-content:end; - align-items: end; - opacity: 0; - transition: opacity 0.3s ease; - color: white; - text-align: center; -} - -.carousel .card h2, -.carousel .card span { - margin: 0; - padding: 5px; - text-shadow: black 1px 1px; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: linear-gradient(to top, rgba(15, 23, 42, 0.7), rgba(15, 23, 42, 0.1)); + display: flex; + flex-direction: column; + justify-content: flex-end; + align-items: center; + opacity: 0; + transition: opacity 0.3s ease; + padding: 1.5rem; +} + +.carousel .card .overlay h2 { + margin: 0; + padding: 0; + color: white; + font-size: 1.125rem; + font-weight: 700; + text-shadow: 0 1px 4px rgba(0,0,0,0.3); +} + +.carousel .card .overlay a { + color: white; + text-decoration: none; + font-size: 0.8125rem; + font-weight: 500; + margin-top: 8px; + padding: 6px 16px; + background: rgba(255,255,255,0.2); + border-radius: 20px; + backdrop-filter: blur(4px); + transition: all 0.2s; +} + +.carousel .card .overlay a:hover { + background: rgba(255,255,255,0.35); } @media screen and (max-width: 900px) { - .wrapper .carousel { - grid-auto-columns: calc((100% / 2) - 9px); - } + .wrapper .carousel { + grid-auto-columns: calc((100% / 2) - 12px); + } } @media screen and (max-width: 600px) { - .wrapper .carousel { - grid-auto-columns: 100%; - } + .appcontainer { + padding: 1rem; + } + + .wrapper .carousel { + grid-auto-columns: 100%; + } + + .wrapper i:first-child { + left: 4px; + } + + .wrapper i:last-child { + right: 4px; + } } diff --git a/client/src/hackathon/hackathonsidebar/hackathonsidebar.css b/client/src/hackathon/hackathonsidebar/hackathonsidebar.css index e9528217..694d238b 100644 --- a/client/src/hackathon/hackathonsidebar/hackathonsidebar.css +++ b/client/src/hackathon/hackathonsidebar/hackathonsidebar.css @@ -6,13 +6,16 @@ #sidebar { height: 100vh; + border-right: 1px solid #e2e8f0 !important; + background: white !important; + transition: all 0.2s ease; } .main-content { flex: 1; padding: 2rem; height: 100vh; - background-color: white; + background: #f8fafc; } .mati { @@ -28,11 +31,9 @@ .allmetirials { width: 100%; - /* height: 80vh; */ display: flex; justify-content: center; align-items: center; - } .allmeti { @@ -41,7 +42,8 @@ .file-inputs input, Select { - border: black 3px solid; + border: 1px solid #e2e8f0; + border-radius: 8px; } .matform { @@ -49,14 +51,32 @@ Select { height: 20vh; } +.modern-sidebar .ps-sidebar-container { + background: white !important; +} + +.modern-sidebar .ps-menu-button:hover { + background: rgba(99, 102, 241, 0.08) !important; + color: #4f46e5 !important; + border-radius: 8px !important; +} + +.modern-sidebar .ps-menu-button { + margin: 2px 8px !important; + border-radius: 8px !important; + transition: all 0.15s ease !important; +} + +.modern-sidebar .ps-sidebar-container { + padding-top: 8px; +} -@media (max-width:500px) { +@media (max-width: 500px) { #sidebar { position: fixed; } - .main-content { padding-left: 5rem; width: 100%; } -} \ No newline at end of file +} diff --git a/client/src/index.css b/client/src/index.css index ec2585e8..563d9bcc 100644 --- a/client/src/index.css +++ b/client/src/index.css @@ -1,13 +1,99 @@ +@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap'); + +*, *::before, *::after { + box-sizing: border-box; +} + body { margin: 0; - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', - 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', + font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; + line-height: 1.6; } code { - font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', - monospace; + font-family: 'JetBrains Mono', 'Fira Code', 'Courier New', monospace; +} + +:root { + --brand-50: #eef2ff; + --brand-100: #e0e7ff; + --brand-200: #c7d2fe; + --brand-300: #a5b4fc; + --brand-400: #818cf8; + --brand-500: #6366f1; + --brand-600: #4f46e5; + --brand-700: #4338ca; + --brand-800: #3730a3; + --brand-900: #312e81; + --accent-500: #d946ef; + --surface-50: #f8fafc; + --surface-100: #f1f5f9; + --surface-200: #e2e8f0; + --surface-300: #cbd5e1; + --surface-400: #94a3b8; + --surface-500: #64748b; + --surface-600: #475569; + --surface-700: #334155; + --surface-800: #1e293b; + --surface-900: #0f172a; + --radius-sm: 6px; + --radius-md: 8px; + --radius-lg: 12px; + --radius-xl: 16px; + --shadow-card: 0 1px 3px 0 rgb(0 0 0 / 0.04), 0 1px 2px -1px rgb(0 0 0 / 0.06); + --shadow-elevated: 0 4px 6px -1px rgb(0 0 0 / 0.07), 0 2px 4px -2px rgb(0 0 0 / 0.05); +} + +/* Scrollbar */ +::-webkit-scrollbar { + width: 6px; + height: 6px; +} +::-webkit-scrollbar-track { + background: transparent; +} +::-webkit-scrollbar-thumb { + background: var(--surface-200); + border-radius: 3px; +} +::-webkit-scrollbar-thumb:hover { + background: var(--surface-300); +} + +/* Smooth focus visible */ +:focus-visible { + outline: 2px solid var(--brand-400); + outline-offset: 2px; + border-radius: var(--radius-sm); +} + +/* Animations */ +@keyframes fadeIn { + from { opacity: 0; transform: translateY(8px); } + to { opacity: 1; transform: translateY(0); } +} +@keyframes slideUp { + from { opacity: 0; transform: translateY(20px); } + to { opacity: 1; transform: translateY(0); } +} +@keyframes scaleIn { + from { opacity: 0; transform: scale(0.95); } + to { opacity: 1; transform: scale(1); } +} +@keyframes shimmer { + 0% { background-position: -200% 0; } + 100% { background-position: 200% 0; } +} + +.animate-fade-in { + animation: fadeIn 0.4s ease-out; +} +.animate-slide-up { + animation: slideUp 0.5s ease-out; +} +.animate-scale-in { + animation: scaleIn 0.3s ease-out; } diff --git a/client/src/index.js b/client/src/index.js index 54dab1cc..320185c0 100644 --- a/client/src/index.js +++ b/client/src/index.js @@ -5,6 +5,7 @@ import { Provider } from 'react-redux'; import { PersistGate } from 'redux-persist/integration/react'; import App from './App'; import { persistor, store } from './collection/redux/store/configurestore'; +import theme from './theme'; import './index.css'; import reportWebVitals from './reportWebVitals'; @@ -12,7 +13,7 @@ const root = ReactDOM.createRoot(document.getElementById('root')); root.render( - + diff --git a/client/src/theme.js b/client/src/theme.js new file mode 100644 index 00000000..c12e7454 --- /dev/null +++ b/client/src/theme.js @@ -0,0 +1,226 @@ +import { extendTheme } from '@chakra-ui/react' + +const theme = extendTheme({ + colors: { + brand: { + 50: '#eef2ff', + 100: '#e0e7ff', + 200: '#c7d2fe', + 300: '#a5b4fc', + 400: '#818cf8', + 500: '#6366f1', + 600: '#4f46e5', + 700: '#4338ca', + 800: '#3730a3', + 900: '#312e81', + }, + accent: { + 50: '#fdf4ff', + 100: '#fae8ff', + 200: '#f5d0fe', + 300: '#f0abfc', + 400: '#e879f9', + 500: '#d946ef', + 600: '#c026d3', + 700: '#a21caf', + 800: '#86198f', + 900: '#701a75', + }, + surface: { + 50: '#f8fafc', + 100: '#f1f5f9', + 200: '#e2e8f0', + 300: '#cbd5e1', + 400: '#94a3b8', + 500: '#64748b', + 600: '#475569', + 700: '#334155', + 800: '#1e293b', + 900: '#0f172a', + }, + }, + fonts: { + heading: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif", + body: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif", + mono: "'JetBrains Mono', 'Fira Code', monospace", + }, + fontSizes: { + '2xs': '0.625rem', + xs: '0.75rem', + sm: '0.8125rem', + md: '0.875rem', + lg: '1rem', + xl: '1.125rem', + '2xl': '1.25rem', + '3xl': '1.5rem', + '4xl': '1.875rem', + '5xl': '2.25rem', + '6xl': '3rem', + '7xl': '3.75rem', + }, + radii: { + sm: '6px', + md: '8px', + lg: '12px', + xl: '16px', + '2xl': '20px', + }, + shadows: { + card: '0 1px 3px 0 rgb(0 0 0 / 0.04), 0 1px 2px -1px rgb(0 0 0 / 0.06)', + elevated: '0 4px 6px -1px rgb(0 0 0 / 0.07), 0 2px 4px -2px rgb(0 0 0 / 0.05)', + modal: '0 20px 25px -5px rgb(0 0 0 / 0.12), 0 8px 10px -6px rgb(0 0 0 / 0.06)', + glow: '0 0 0 3px rgba(99, 102, 241, 0.15)', + }, + styles: { + global: { + body: { + bg: 'surface.50', + color: 'surface.900', + fontSize: 'md', + lineHeight: '1.6', + WebkitFontSmoothing: 'antialiased', + }, + '*::selection': { + bg: 'brand.100', + color: 'brand.900', + }, + }, + }, + components: { + Button: { + baseStyle: { + fontWeight: 600, + borderRadius: 'md', + _focus: { boxShadow: 'glow' }, + }, + sizes: { + sm: { px: 3, py: 1.5, fontSize: 'sm' }, + md: { px: 4, py: 2, fontSize: 'sm' }, + lg: { px: 6, py: 3, fontSize: 'md' }, + }, + variants: { + solid: { + bg: 'brand.500', + color: 'white', + _hover: { bg: 'brand.600', _disabled: { bg: 'brand.300' } }, + _active: { bg: 'brand.700' }, + }, + ghost: { + color: 'surface.700', + _hover: { bg: 'surface.100' }, + _active: { bg: 'surface.200' }, + }, + outline: { + borderColor: 'surface.200', + color: 'surface.700', + _hover: { bg: 'surface.50', borderColor: 'brand.300' }, + }, + }, + defaultProps: { size: 'md', variant: 'solid' }, + }, + Input: { + baseStyle: { + field: { + borderRadius: 'md', + borderColor: 'surface.200', + _focus: { borderColor: 'brand.400', boxShadow: 'glow' }, + _placeholder: { color: 'surface.400' }, + }, + }, + sizes: { + md: { field: { px: 3, py: 2, fontSize: 'sm' } }, + }, + defaultProps: { size: 'md' }, + }, + Select: { + baseStyle: { + field: { + borderRadius: 'md', + borderColor: 'surface.200', + _focus: { borderColor: 'brand.400', boxShadow: 'glow' }, + }, + }, + }, + Table: { + baseStyle: { + th: { + fontWeight: 600, + fontSize: 'xs', + textTransform: 'uppercase', + letterSpacing: '0.05em', + color: 'surface.500', + borderBottom: '1px solid', + borderColor: 'surface.100', + }, + td: { + fontSize: 'sm', + borderBottom: '1px solid', + borderColor: 'surface.100', + }, + }, + }, + Modal: { + baseStyle: { + dialog: { + borderRadius: 'xl', + boxShadow: 'modal', + }, + header: { + fontWeight: 600, + fontSize: 'lg', + }, + }, + }, + Card: { + baseStyle: { + container: { + borderRadius: 'lg', + boxShadow: 'card', + bg: 'white', + border: '1px solid', + borderColor: 'surface.100', + }, + }, + }, + Badge: { + baseStyle: { + borderRadius: 'full', + px: 2, + py: 0.5, + fontSize: '2xs', + fontWeight: 600, + textTransform: 'uppercase', + letterSpacing: '0.05em', + }, + }, + Tabs: { + baseStyle: { + tab: { + fontWeight: 500, + fontSize: 'sm', + _selected: { + color: 'brand.600', + borderColor: 'brand.500', + }, + }, + }, + }, + Tooltip: { + baseStyle: { + borderRadius: 'md', + fontSize: 'xs', + px: 3, + py: 1.5, + }, + }, + Toast: { + defaultProps: { + position: 'top-right', + duration: 3000, + isClosable: true, + }, + }, + }, +}) + +export default theme From 4f3cf8ac10edc10129911f877f5b39837a6747fa Mon Sep 17 00:00:00 2001 From: Teja Date: Tue, 19 May 2026 00:41:21 +0530 Subject: [PATCH 4/4] Refactor navigation handling to use useNavigate hook for improved routing consistency --- .../bootcampsidebar/bootcampsidebar.js | 6 +- client/src/bootcamp/login/login.js | 4 +- client/src/collection/admin/admin.js | 278 +++++------------- client/src/collection/boot&hack/boot&hack.js | 8 +- client/src/collection/menu/menu.js | 80 +++-- .../hackathonsidebar/hackathonsidebar.js | 6 +- 6 files changed, 141 insertions(+), 241 deletions(-) diff --git a/client/src/bootcamp/bootcampsidebar/bootcampsidebar.js b/client/src/bootcamp/bootcampsidebar/bootcampsidebar.js index 9827a7d1..28ed955d 100644 --- a/client/src/bootcamp/bootcampsidebar/bootcampsidebar.js +++ b/client/src/bootcamp/bootcampsidebar/bootcampsidebar.js @@ -37,15 +37,15 @@ const SidebarContent = ({ collapsed, toggleSidebar, select }) => { >

Bootcamp

- } onClick={() => window.location.href = '/'}>Home - } onClick={() => window.location.href = '/bootcamp'}>House + } onClick={() => nav('/')}>Home + } onClick={() => nav('/bootcamp')}>House } onClick={() => { select(3); queryParams.set("page", "attendance"); nav({ search: queryParams.toString() }) }}>Attendance } onClick={() => { select(4); queryParams.set("page", "material"); nav({ search: queryParams.toString() }) }}>Materials } onClick={() => { select(5); queryParams.set("page", "score"); nav({ search: queryParams.toString() }) }}>Score } onClick={() => { select(6); queryParams.set("page", "tasks"); nav({ search: queryParams.toString() }) }}>Tasks } onClick={() => { select(7); queryParams.set("page", "students"); nav({ search: queryParams.toString() }) }}>Students Data } onClick={() => { select(8); queryParams.set("page", "others"); nav({ search: queryParams.toString() }) }}>Others - } onClick={() => window.location.href = '/hackathon'}>Hackathon + } onClick={() => nav('/hackathon')}>Hackathon } onClick={() => { dispatch({ type: 'BOOT', payload: { bootmail: null, bootpassword: null } }); window.location.reload(1000) }} >Log out diff --git a/client/src/bootcamp/login/login.js b/client/src/bootcamp/login/login.js index 30b6917b..d7047375 100644 --- a/client/src/bootcamp/login/login.js +++ b/client/src/bootcamp/login/login.js @@ -16,6 +16,7 @@ import CryptoAES from 'crypto-js/aes'; import * as React from 'react'; import { useState } from 'react'; import { useDispatch } from 'react-redux'; +import { useNavigate } from 'react-router-dom'; import { Actions } from '../../actions/actions'; @@ -24,6 +25,7 @@ const defaultTheme = createTheme(); export const LoginForm = () => { const [mail, setMail] = useState() const dispatch = useDispatch() + const nav = useNavigate() const toast = useToast() const [loading,setLoading] = useState(false) const [password, setPassword] = useState() @@ -36,7 +38,7 @@ export const LoginForm = () => { if (res?.data?.message) { dispatch({ type: 'BOOT', payload: { bootmail: res?.data?.data?.Gmail, bootpassword: CryptoAES.encrypt(res?.data?.data?.Password, res?.data?.data?.Gmail).toString() } }); toast({ title: res?.data?.message, status: 'success', position: 'top-right', isClosable: true }) - window.location.href = '/bootcamp' + nav('/bootcamp') } if (res?.data?.error) { toast({ title: res?.data?.error, status: 'error', position: 'bottom-right', isClosable: true }) diff --git a/client/src/collection/admin/admin.js b/client/src/collection/admin/admin.js index 9ecfe334..4cb2a5a7 100644 --- a/client/src/collection/admin/admin.js +++ b/client/src/collection/admin/admin.js @@ -1,169 +1,82 @@ import { useToast } from "@chakra-ui/react"; import axios from "axios"; -import "bootstrap/dist/css/bootstrap.min.css"; import CryptoAES from "crypto-js/aes"; import React, { useState } from "react"; import { useNavigate } from "react-router-dom"; -import "../admin/admin.css"; import { Navbars } from "../nav&foot/nav"; +import { Box, VStack, Button, Input, Text } from "@chakra-ui/react"; + export const Admin = () => { + const nav = useNavigate(); const [gmail, setgmail] = useState([]); const [password, setpassword] = useState([]); + const [loading, setLoading] = useState(false); const date = new Date(); const toast = useToast(); const Submit = async () => { + setLoading(true); try { - const responce = await axios.post( - process.env.REACT_APP_database + "/admincheck/" + gmail - ); - { - if (responce.data?.Password === password) { - if (responce.data.Dates !== date.toDateString()) { - const res1 = await axios.post( - process.env.REACT_APP_database + "/totaldays" - ); - { - if (res1.data) { - if (res1.data.Date !== date.toDateString()) { - let tdays = parseInt(res1.data.Days) + 1; - const res = await axios.post( - process.env.REACT_APP_database + - "/updateadmin/" + - gmail + - "/" + - date.toDateString() + - "/" + - tdays - ); - { - if (res) { - sessionStorage.gmail = gmail; - sessionStorage.password = CryptoAES.encrypt( - password, - gmail - ).toString(); - toast({ - title: "Login Success", - description: "Admin sucessfully logged in Today", - status: "success", - position: "top", - isClosable: true, - }); - setTimeout( - () => (window.location.href = "/attendance"), - 1000 - ); - } else { - toast({ - title: "Try again", - description: "Please login again", - status: "error", - position: "bottom-left", - isClosable: true, - }); - } - } - } else { - sessionStorage.gmail = gmail; - sessionStorage.password = CryptoAES.encrypt( - password, - gmail - ).toString(); - toast({ - title: "Login Success", - description: "Admin 2 sucessfully logged in Today", - status: "success", - position: "top", - isClosable: true, - }); - setTimeout( - () => (window.location.href = "/attendance"), - 1000 - ); - } + const responce = await axios.post(process.env.REACT_APP_database + "/admincheck/" + gmail); + if (responce.data?.Password === password) { + if (responce.data.Dates !== date.toDateString()) { + const res1 = await axios.post(process.env.REACT_APP_database + "/totaldays"); + if (res1.data) { + if (res1.data.Date !== date.toDateString()) { + let tdays = parseInt(res1.data.Days) + 1; + const res = await axios.post(process.env.REACT_APP_database + "/updateadmin/" + gmail + "/" + date.toDateString() + "/" + tdays); + if (res) { + sessionStorage.gmail = gmail; + sessionStorage.password = CryptoAES.encrypt(password, gmail).toString(); + toast({ title: "Login Success", description: "Admin successfully logged in Today", status: "success", position: "top", isClosable: true }); + setTimeout(() => nav("/attendance"), 1000); + } else { + toast({ title: "Try again", description: "Please login again", status: "error", position: "bottom-left", isClosable: true }); } + } else { + sessionStorage.gmail = gmail; + sessionStorage.password = CryptoAES.encrypt(password, gmail).toString(); + toast({ title: "Login Success", description: "Admin successfully logged in Today", status: "success", position: "top", isClosable: true }); + setTimeout(() => nav("/attendance"), 1000); } - } else { - sessionStorage.gmail = gmail; - sessionStorage.password = CryptoAES.encrypt( - password, - gmail - ).toString(); - sessionStorage.removeItem("yoga"); - toast({ - title: "Login Success", - description: "Admin sucessfully logged in again", - status: "success", - position: "top", - isClosable: true, - }); - setTimeout(() => (window.location.href = "/attendance"), 1000); } } else { - toast({ - title: "Please register as admin", - description: "Credentials unmatched", - status: "error", - position: "bottom-left", - isClosable: true, - }); + sessionStorage.gmail = gmail; + sessionStorage.password = CryptoAES.encrypt(password, gmail).toString(); + sessionStorage.removeItem("yoga"); + toast({ title: "Login Success", description: "Admin successfully logged in again", status: "success", position: "top", isClosable: true }); + setTimeout(() => nav("/attendance"), 1000); } + } else { + toast({ title: "Please register as admin", description: "Credentials unmatched", status: "error", position: "bottom-left", isClosable: true }); } } catch (e) { - toast({ - title: "Network Error", - description: e?.name, - status: "warning", - position: "bottom-left", - isClosable: true, - }); + toast({ title: "Network Error", description: e?.name, status: "warning", position: "bottom-left", isClosable: true }); + } finally { + setLoading(false); } }; const handelkeydown = (e) => { - if (e.key === "Enter") { - Submit(); - } + if (e.key === "Enter") Submit(); }; return ( <> -
-

Attendance

-
-
- - setgmail(e.target.value)} - /> -
-
- - setpassword(e.target.value)} - onKeyDown={(e) => handelkeydown(e)} - /> -
-
- -
-
-
+ + + Attendance Login + + Admin Gmail + setgmail(e.target.value)} /> + + + Password + setpassword(e.target.value)} onKeyDown={handelkeydown} /> + + + + ); }; @@ -172,86 +85,41 @@ export const Adminreg = () => { const nav = useNavigate(); const [gmail, setgmail] = useState([]); const [password, setpassword] = useState([]); + const [loading, setLoading] = useState(false); const toast = useToast(); const Submit = async () => { - await axios - .post( - process.env.REACT_APP_database + "/admincheck/" + gmail + "/" + password - ) + setLoading(true); + await axios.post(process.env.REACT_APP_database + "/admincheck/" + gmail + "/" + password) .then(async (res) => { if (res.data) { - toast({ - title: "Already Register", - status: "error", - position: "bottom-left", - isClosable: true, - }); + toast({ title: "Already Register", status: "error", position: "bottom-left", isClosable: true }); } else { - if ( - await axios.post( - process.env.REACT_APP_database + - "/adminregi/" + - gmail + - "/" + - password - ) - ) { - toast({ - title: "Sucessfully Registered", - status: "success", - position: "bottom-right", - isClosable: true, - }); + if (await axios.post(process.env.REACT_APP_database + "/adminregi/" + gmail + "/" + password)) { + toast({ title: "Successfully Registered", status: "success", position: "top-right", isClosable: true }); nav("/adminlogin"); } } }) - .catch((e) => - toast({ - title: e.message, - description: e.name, - status: "error", - position: "bottom-left", - isClosable: true, - }) - ); + .catch((e) => toast({ title: e.message, description: e.name, status: "error", position: "bottom-left", isClosable: true })) + .finally(() => setLoading(false)); }; return ( <> -
-

Admin Register

-
-
- - setgmail(e.target.value)} - /> -
-
- - setpassword(e.target.value)} - /> -
-
- -
-
-
+ + + + Admin Register + + Admin Gmail + setgmail(e.target.value)} /> + + + Password + setpassword(e.target.value)} /> + + + + ); }; diff --git a/client/src/collection/boot&hack/boot&hack.js b/client/src/collection/boot&hack/boot&hack.js index 29a3632f..fcf1c1e0 100644 --- a/client/src/collection/boot&hack/boot&hack.js +++ b/client/src/collection/boot&hack/boot&hack.js @@ -1,15 +1,17 @@ -import { Box, Button, Text } from "@chakra-ui/react"; +import { Box, Text } from "@chakra-ui/react"; +import { useNavigate } from "react-router-dom"; import './boot&hack.css'; export const BootHack = () => { + const nav = useNavigate(); return ( - window.location.href = 'bootcamp'}> + nav('/bootcamp')}> 🏕️ Bootcamp Training & Tasks - window.location.href = 'hackathon'}> + nav('/hackathon')}> 🏆 Hackathon Events & Scoring diff --git a/client/src/collection/menu/menu.js b/client/src/collection/menu/menu.js index 033fdc66..1af9946a 100644 --- a/client/src/collection/menu/menu.js +++ b/client/src/collection/menu/menu.js @@ -1,32 +1,60 @@ -import { Button, SimpleGrid } from "@chakra-ui/react" +import { Box, SimpleGrid, Text } from "@chakra-ui/react" +import { useNavigate } from "react-router-dom" import exam from './exam.jpeg' import "./menu.css" import team from './team.jpeg' import teamwork from './teamwork.jpeg' import console from './console.png' + +const menuItem = { + background: 'white', + borderRadius: '16px', + border: '1px solid', + borderColor: 'surface.100', + boxShadow: 'card', + transition: 'all 0.25s ease', + cursor: 'pointer', + overflow: 'hidden', + position: 'relative', +} + export const Menu = () => { - return ( -
-
- -
-
-
- -
Team Members
-
-
-
-
- -
AST console
-
-
-
-
- ) -} \ No newline at end of file + const nav = useNavigate() + const items = [ + { img: exam, label: 'Exam', link: 'https://asthack.me/exam/192.5264.27', external: true }, + { img: team, label: 'Team Members', link: 'https://asthack.me/exam/studentscore', external: true }, + { img: teamwork, label: 'Team Work', link: 'https://asthack.me/exam/teamwork', external: true }, + { img: console, label: 'AST Console', link: '/console', external: false }, + ] + return ( + + + {items.map((item, i) => ( + item.external ? window.open(item.link, '_blank') : nav(item.link)} + _hover={{ transform: 'translateY(-4px)', boxShadow: 'elevated', borderColor: 'brand.200' }} + className="animate-fade-in" + style={{ animationDelay: `${i * 0.1}s` }} + > + + + + {item.label} + + + + ))} + + + ) +} diff --git a/client/src/hackathon/hackathonsidebar/hackathonsidebar.js b/client/src/hackathon/hackathonsidebar/hackathonsidebar.js index 1bbf2ced..94c9ff23 100644 --- a/client/src/hackathon/hackathonsidebar/hackathonsidebar.js +++ b/client/src/hackathon/hackathonsidebar/hackathonsidebar.js @@ -39,8 +39,8 @@ const SidebarContent = ({ collapsed, toggleSidebar, select }) => { >

Hackathon

- } onClick={() => window.location.href = '/'}>Home - } onClick={() => window.location.href = '/hackathon'}>House + } onClick={() => nav('/')}>Home + } onClick={() => nav('/hackathon')}>House } onClick={() => { select(2); queryParams.set("page", "team"); nav({ search: queryParams.toString() }) }}>Team } onClick={() => { select(5); queryParams.set("page", "score"); nav({ search: queryParams.toString() }) }}>Score } onClick={() => { select(6); queryParams.set("page", "tasks"); nav({ search: queryParams.toString() }) }}>Tasks @@ -48,7 +48,7 @@ const SidebarContent = ({ collapsed, toggleSidebar, select }) => { } onClick={() => { select(7); queryParams.set("page", "problemstatements"); nav({ search: queryParams.toString() }) }}>Problem Statements } onClick={() => { select(8); queryParams.set("page", "timer"); nav({ search: queryParams.toString() }); }}>Timer Manager } onClick={() => { select(8); queryParams.set("page", "others"); nav({ search: queryParams.toString() }) }}>Others - } onClick={() => window.location.href = '/bootcamp'}>Bootcamp + } onClick={() => nav('/bootcamp')}>Bootcamp
} onClick={() => { dispatch({ type: 'BOOT', payload: { bootmail: null, bootpassword: null } }); window.location.reload(1000) }}>Log out