From 49c64cc65f2956aa72c5de10c7b32903445777ea Mon Sep 17 00:00:00 2001 From: JonasSchweigler Date: Wed, 3 Jan 2024 22:15:23 +0100 Subject: [PATCH 1/6] added new navbar design and added news section --- .eslintrc | 16 +- apps/web/jsconfig.json | 8 +- apps/web/src/App.jsx | 42 ++-- apps/web/src/components/navbar.jsx | 44 ++-- apps/web/src/index.css | 5 +- apps/web/src/main.jsx | 21 +- apps/web/src/pages/about.jsx | 36 ++-- apps/web/src/pages/app.jsx | 179 +++++++++------- apps/web/src/pages/home.jsx | 38 +--- apps/web/src/pages/leaderboard.jsx | 16 +- apps/web/src/pages/login.jsx | 229 ++++++++++---------- apps/web/src/pages/news.jsx | 20 ++ apps/web/src/pages/register.jsx | 292 +++++++++++++------------- apps/web/src/pages/verify.jsx | 184 ++++++++-------- apps/web/src/pages/whoami.jsx | 172 ++++++++------- apps/web/src/{ => styles}/App.css | 249 +++++++++------------- apps/web/src/styles/logo.styles.css | 25 +++ apps/web/src/styles/navbar.styles.css | 47 +++++ 18 files changed, 850 insertions(+), 773 deletions(-) create mode 100644 apps/web/src/pages/news.jsx rename apps/web/src/{ => styles}/App.css (64%) create mode 100644 apps/web/src/styles/logo.styles.css create mode 100644 apps/web/src/styles/navbar.styles.css diff --git a/.eslintrc b/.eslintrc index 21c32ce..bb6e01b 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,9 +1,9 @@ { - "extends": ["@bravo68web"], - "rules": { - "sonarjs/cognitive-complexity": "off", - "unicorn/no-array-reduce": "off", - "unicorn/filename-case": "off", - "@typescript-eslint/no-empty-interface": "off" - } -} \ No newline at end of file + "extends": ["@bravo68web"], + "rules": { + "sonarjs/cognitive-complexity": "off", + "unicorn/no-array-reduce": "off", + "unicorn/filename-case": "off", + "@typescript-eslint/no-empty-interface": "off" + } +} diff --git a/apps/web/jsconfig.json b/apps/web/jsconfig.json index 4120155..a224293 100644 --- a/apps/web/jsconfig.json +++ b/apps/web/jsconfig.json @@ -1,5 +1,5 @@ { - "compilerOptions": { - "jsx": "react-jsx" - } -} \ No newline at end of file + "compilerOptions": { + "jsx": "react-jsx" + } +} diff --git a/apps/web/src/App.jsx b/apps/web/src/App.jsx index 16826fe..f6c2116 100644 --- a/apps/web/src/App.jsx +++ b/apps/web/src/App.jsx @@ -1,27 +1,29 @@ // App.js -import { Routes, Route } from 'react-router-dom'; -import Home from './pages/home'; -import Player from './pages/app'; -import Login from './pages/login'; -import Register from './pages/register'; -import Verify from './pages/verify'; -import About from './pages/about'; -import Leaderboard from './pages/leaderboard'; -import WhoAmI from './pages/whoami'; +import { Routes, Route } from "react-router-dom"; +import Home from "./pages/home"; +import Player from "./pages/app"; +import Login from "./pages/login"; +import Register from "./pages/register"; +import Verify from "./pages/verify"; +import About from "./pages/about"; +import Leaderboard from "./pages/leaderboard"; +import WhoAmI from "./pages/whoami"; +import News from "./pages/news"; const App = () => { - return ( + return ( - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> - ); + ); }; -export default App; \ No newline at end of file +export default App; diff --git a/apps/web/src/components/navbar.jsx b/apps/web/src/components/navbar.jsx index e2ef2cb..c6a6adb 100644 --- a/apps/web/src/components/navbar.jsx +++ b/apps/web/src/components/navbar.jsx @@ -1,23 +1,31 @@ import { Link } from "react-router-dom"; -import { Component } from 'react' -export default class Navbar extends Component { - render() { - return ( -
-
-
- Home - About - App - Login - Register - Verify Account - Leaderboard - Whoami +import "../styles/navbar.styles.css"; + +export default function Navbar(props) { + return ( +
+
+
+
+ About + News + Whoami +
+ + ee logo + +
+ App + Leaderboard
+ {/* Login + Register */} + {/* Verify Account */}
+ +

{props.pageTitle}

- ) - } -} \ No newline at end of file +
+ ); +} diff --git a/apps/web/src/index.css b/apps/web/src/index.css index 56e4f04..4dc4c72 100644 --- a/apps/web/src/index.css +++ b/apps/web/src/index.css @@ -8,7 +8,6 @@ src: url("/MinecraftBold.woff2"); } - :root { font-family: "MinecraftBold", sans-serif; line-height: 1.5; @@ -35,10 +34,10 @@ a:hover { body { margin: 0; - display: flex; + /* display: flex; place-items: center; min-width: 320px; - min-height: 100vh; + min-height: 100vh; */ } h1 { diff --git a/apps/web/src/main.jsx b/apps/web/src/main.jsx index 62ed430..69eadfc 100644 --- a/apps/web/src/main.jsx +++ b/apps/web/src/main.jsx @@ -1,14 +1,15 @@ -import React from 'react' -import ReactDOM from 'react-dom/client' -import App from './App.jsx' -import { BrowserRouter } from 'react-router-dom'; -import './index.css' +import React from "react"; +import ReactDOM from "react-dom/client"; +import App from "./App.jsx"; +import { BrowserRouter } from "react-router-dom"; +import "./index.css"; +import "./styles/logo.styles.css"; -const root = ReactDOM.createRoot(document.getElementById('root')); +const root = ReactDOM.createRoot(document.getElementById("root")); root.render( - - - + + + -); \ No newline at end of file +); diff --git a/apps/web/src/pages/about.jsx b/apps/web/src/pages/about.jsx index e5ae496..4354596 100644 --- a/apps/web/src/pages/about.jsx +++ b/apps/web/src/pages/about.jsx @@ -1,24 +1,20 @@ -import '../App.css' -import 'react-toastify/dist/ReactToastify.css'; -import Navbar from '../components/navbar'; +import "react-toastify/dist/ReactToastify.css"; +import Navbar from "../components/navbar"; function Home() { - return ( - <> - -
- ee logo -
-

rcsCTF24

- -
-

Guides

- -
- - ) + return ( + <> + + + + ); } -export default Home +export default Home; diff --git a/apps/web/src/pages/app.jsx b/apps/web/src/pages/app.jsx index 86da67e..d9484ed 100644 --- a/apps/web/src/pages/app.jsx +++ b/apps/web/src/pages/app.jsx @@ -1,84 +1,111 @@ -import '../App.css' -import 'react-toastify/dist/ReactToastify.css'; -import Navbar from '../components/navbar'; -import { useEffect, useState } from 'react'; -import Machines from "../components/machine" -import Challenge from '../components/challenge'; -import { ToastContainer } from 'react-toastify'; -import apiClient from '../libs/api.client'; +import "react-toastify/dist/ReactToastify.css"; +import Navbar from "../components/navbar"; +import { useEffect, useState } from "react"; +import Machines from "../components/machine"; +import Challenge from "../components/challenge"; +import { ToastContainer } from "react-toastify"; +import apiClient from "../libs/api.client"; function Player() { - const token = localStorage.getItem('token'); - const [machines, setMachines] = useState([]); - const [currentExpandedMachine, setCurrentExpandedMachine] = useState(1); - const [currentChallenge, setCurrentChallenge] = useState([currentExpandedMachine,-1]); + const token = localStorage.getItem("token"); + const [machines, setMachines] = useState([]); + const [currentExpandedMachine, setCurrentExpandedMachine] = useState(1); + const [currentChallenge, setCurrentChallenge] = useState([ + currentExpandedMachine, + -1, + ]); - useEffect(() => { - if(!token) return window.location.href = '/login'; + useEffect(() => { + if (!token) return (window.location.href = "/login"); - apiClient.get("/challenge/progress", { - headers: { - "Authorization": "Bearer " + token, - } - }).then(res => { - if(!Array.isArray(res.data)) return window.location.href = '/login' - if(res.data.message === 'Invalid token') return window.location.href = '/login'; - setMachines(res.data); - }) - - },[token]) + apiClient + .get("/challenge/progress", { + headers: { + Authorization: "Bearer " + token, + }, + }) + .then((res) => { + if (!Array.isArray(res.data)) return (window.location.href = "/login"); + if (res.data.message === "Invalid token") + return (window.location.href = "/login"); + setMachines(res.data); + }); + }, [token]); - return ( - <> - -
-
-
-

Machines

-
- {machines.map((machine, index) => ( - - ))} -
-
-
-
-
- {currentChallenge[0] > -1 && currentChallenge[1] > -1 && } -
-
+ return ( + <> + +
+
+
+

Machines

+
+ {machines.map((machine, index) => ( + + ))}
- - - ) +
+
+
+
+ {currentChallenge[0] > -1 && currentChallenge[1] > -1 && ( + + )} +
+
+
+ + + ); } -export default Player +export default Player; diff --git a/apps/web/src/pages/home.jsx b/apps/web/src/pages/home.jsx index bad0465..3cda7da 100644 --- a/apps/web/src/pages/home.jsx +++ b/apps/web/src/pages/home.jsx @@ -1,31 +1,15 @@ -import '../App.css' -import 'react-toastify/dist/ReactToastify.css'; -import { Link } from "react-router-dom"; +import "../styles/App.css"; +import "react-toastify/dist/ReactToastify.css"; +// import { Link } from "react-router-dom"; +import Navbar from "../components/navbar"; function Home() { - return ( - <> -
- ee logo -
-

Welcome to eeCTF

- -
-

- Actions -

-
- About - App - Login - Register - Verify Account - Leaderboard - Whoami -
-
- - ) + return ( +
+ +

hello

+
+ ); } -export default Home +export default Home; diff --git a/apps/web/src/pages/leaderboard.jsx b/apps/web/src/pages/leaderboard.jsx index 8847fda..6a4b29d 100644 --- a/apps/web/src/pages/leaderboard.jsx +++ b/apps/web/src/pages/leaderboard.jsx @@ -1,7 +1,6 @@ -import "../App.css"; import "react-toastify/dist/ReactToastify.css"; import { useEffect, useState } from "react"; -import apiClient from '../libs/api.client'; +import apiClient from "../libs/api.client"; import Navbar from "../components/navbar"; function Leaderboard() { @@ -16,10 +15,11 @@ function Leaderboard() { .get("/stats/leaderboard", { headers: { Authorization: "Bearer " + token, - } + }, }) .then((response) => { - if(!Array.isArray(response.data)) return window.location.href = '/login' + if (!Array.isArray(response.data)) + return (window.location.href = "/login"); setLeaderboard(response.data); }) .catch(() => { @@ -29,12 +29,8 @@ function Leaderboard() { return ( <> - -
- ee logo -
-

Leaderboard

-
+ +
diff --git a/apps/web/src/pages/login.jsx b/apps/web/src/pages/login.jsx index 56e5644..c9fc918 100644 --- a/apps/web/src/pages/login.jsx +++ b/apps/web/src/pages/login.jsx @@ -1,126 +1,127 @@ -import { useState } from 'react' -import apiClient from '../libs/api.client'; -import { ToastContainer, toast } from 'react-toastify'; +import { useState } from "react"; +import apiClient from "../libs/api.client"; +import { ToastContainer, toast } from "react-toastify"; import { Link } from "react-router-dom"; -import '../App.css' -import 'react-toastify/dist/ReactToastify.css'; -import Navbar from '../components/navbar'; +import "react-toastify/dist/ReactToastify.css"; +import Navbar from "../components/navbar"; function Home() { - const [email, setEmail] = useState('') - const [password, setPassword] = useState('') + const [email, setEmail] = useState(""); + const [password, setPassword] = useState(""); - let token = localStorage.getItem('token'); + let token = localStorage.getItem("token"); - const handleSubmit = (event) => { - event.preventDefault(); - - apiClient.post("/user/login", { - email, - password - }, { - headers: { - "Content-Type": "application/json" - } - }) - .then((response) => { - if (response.data.message === 'Login successful') { - token = response.data.token; - localStorage.setItem('token', token); - toast.success('Login Successful!', { - position: "bottom-right", - autoClose: 3000, - hideProgressBar: true, - closeOnClick: true, - draggable: true, - }); - setTimeout(() => { - window.location.href = '/app'; - }, 3000); - } else { - toast.error('Login Failed!', { - position: "bottom-right", - autoClose: 3000, - hideProgressBar: true, - closeOnClick: true, - draggable: true, - }); - } - }) - .catch(() => { - toast.error('Login Failed!', { - position: "bottom-right", - autoClose: 3000, - hideProgressBar: true, - closeOnClick: true, - draggable: true, - }); - }); - } + const handleSubmit = (event) => { + event.preventDefault(); - return ( - <> - -
- ee logo -
-

Login Portal

-
-

Sign In

-
-
-
- -
-
- setEmail(event.target.value)} - placeholder="Enter your email" - /> -
+ apiClient + .post( + "/user/login", + { + email, + password, + }, + { + headers: { + "Content-Type": "application/json", + }, + } + ) + .then((response) => { + if (response.data.message === "Login successful") { + token = response.data.token; + localStorage.setItem("token", token); + toast.success("Login Successful!", { + position: "bottom-right", + autoClose: 3000, + hideProgressBar: true, + closeOnClick: true, + draggable: true, + }); + setTimeout(() => { + window.location.href = "/app"; + }, 3000); + } else { + toast.error("Login Failed!", { + position: "bottom-right", + autoClose: 3000, + hideProgressBar: true, + closeOnClick: true, + draggable: true, + }); + } + }) + .catch(() => { + toast.error("Login Failed!", { + position: "bottom-right", + autoClose: 3000, + hideProgressBar: true, + closeOnClick: true, + draggable: true, + }); + }); + }; + + return ( + <> + +
+

Sign In

+ +
+
+ +
+
+ setEmail(event.target.value)} + placeholder='Enter your email' + /> +
+
+
+
+
-
-
- -
-
- + setPassword(event.target.value)} - placeholder="Enter your password" - /> -
+ type='password' + id='password' + value={password} + onChange={(event) => setPassword(event.target.value)} + placeholder='Enter your password' + />
- - -
-

- Don't have a account, register from here. -

- - - ) +
+ + +
+

+ Don't have a account, register from{" "} + here. +

+ + + ); } -export default Home +export default Home; diff --git a/apps/web/src/pages/news.jsx b/apps/web/src/pages/news.jsx new file mode 100644 index 0000000..c17837f --- /dev/null +++ b/apps/web/src/pages/news.jsx @@ -0,0 +1,20 @@ +import "react-toastify/dist/ReactToastify.css"; +import Navbar from "../components/navbar"; + +function News() { + return ( + <> + + {/* */} + + ); +} + +export default News; diff --git a/apps/web/src/pages/register.jsx b/apps/web/src/pages/register.jsx index 45c6cbf..f7811f3 100644 --- a/apps/web/src/pages/register.jsx +++ b/apps/web/src/pages/register.jsx @@ -1,154 +1,158 @@ -import { useState } from 'react' -import apiClient from '../libs/api.client'; -import { ToastContainer, toast } from 'react-toastify'; +import { useState } from "react"; +import apiClient from "../libs/api.client"; +import { ToastContainer, toast } from "react-toastify"; import { Link } from "react-router-dom"; -import '../App.css' -import 'react-toastify/dist/ReactToastify.css'; +import "react-toastify/dist/ReactToastify.css"; function Home() { - const [email, setEmail] = useState('') - const [password, setPassword] = useState('') - const [firstName, setFirstName] = useState('') - const [lastName, setLastName] = useState('') + const [email, setEmail] = useState(""); + const [password, setPassword] = useState(""); + const [firstName, setFirstName] = useState(""); + const [lastName, setLastName] = useState(""); - const handleSubmit = (event) => { - event.preventDefault() - - apiClient.post("/user/register", { - email, - password, - firstName, - lastName - }, { - headers: { - "Content-Type": "application/json" - } - }) - .then((response) => { - if (response.data.email === email) { - toast.success('Register Successful!', { - position: "bottom-right", - autoClose: 3000, - hideProgressBar: true, - closeOnClick: true, - draggable: true, - }); - setTimeout(() => { - window.location.href = '/verify'; - }, 3000); - } else { - toast.error('Register Failed!', { - position: "bottom-right", - autoClose: 3000, - hideProgressBar: true, - closeOnClick: true, - draggable: true, - }); - } - }) - .catch(() => { - toast.error('Register Failed!', { - position: "bottom-right", - autoClose: 3000, - hideProgressBar: true, - closeOnClick: true, - draggable: true, - }); - }); - } + const handleSubmit = (event) => { + event.preventDefault(); - return ( - <> -
- React logo + apiClient + .post( + "/user/register", + { + email, + password, + firstName, + lastName, + }, + { + headers: { + "Content-Type": "application/json", + }, + } + ) + .then((response) => { + if (response.data.email === email) { + toast.success("Register Successful!", { + position: "bottom-right", + autoClose: 3000, + hideProgressBar: true, + closeOnClick: true, + draggable: true, + }); + setTimeout(() => { + window.location.href = "/verify"; + }, 3000); + } else { + toast.error("Register Failed!", { + position: "bottom-right", + autoClose: 3000, + hideProgressBar: true, + closeOnClick: true, + draggable: true, + }); + } + }) + .catch(() => { + toast.error("Register Failed!", { + position: "bottom-right", + autoClose: 3000, + hideProgressBar: true, + closeOnClick: true, + draggable: true, + }); + }); + }; + + return ( + <> +
+ React logo +
+

Login Portal

+
+

Sign In

+
+
+
+ +
+
+ setEmail(event.target.value)} + placeholder='Enter your email' + /> +
+
+
+
+ +
+
+ setPassword(event.target.value)} + placeholder='Enter your password' + /> +
+
+
+
+ +
+
+ setFirstName(event.target.value)} + placeholder='Enter your firstName' + /> +
+
+
+
+
-

Login Portal

-
-

Sign In

- -
-
- -
-
- setEmail(event.target.value)} - placeholder="Enter your email" - /> -
-
-
-
- -
-
- setPassword(event.target.value)} - placeholder="Enter your password" - /> -
-
-
-
- -
-
- setFirstName(event.target.value)} - placeholder="Enter your firstName" - /> -
-
-
-
- -
-
- setLastName(event.target.value)} - placeholder="Enter your lastName" - /> -
-
- - +
+ setLastName(event.target.value)} + placeholder='Enter your lastName' + />
-

- Already have a account? Login from here. -

- - - ) +
+ + +
+

+ Already have a account? Login from here. +

+ + + ); } -export default Home +export default Home; diff --git a/apps/web/src/pages/verify.jsx b/apps/web/src/pages/verify.jsx index ee2d168..3b02903 100644 --- a/apps/web/src/pages/verify.jsx +++ b/apps/web/src/pages/verify.jsx @@ -1,98 +1,102 @@ -import { useState } from 'react' -import apiClient from '../libs/api.client'; -import { ToastContainer, toast } from 'react-toastify'; +import { useState } from "react"; +import apiClient from "../libs/api.client"; +import { ToastContainer, toast } from "react-toastify"; -import '../App.css' -import 'react-toastify/dist/ReactToastify.css'; +import "react-toastify/dist/ReactToastify.css"; function Home() { - const [otp, setOtp] = useState('') + const [otp, setOtp] = useState(""); - const handleSubmit = (event) => { - event.preventDefault() - - apiClient.post("/user/verify", { - otp - }, { - headers: { - "Content-Type": "application/json" - } - }) - .then((response) => { - if (response.data.message === 'User verified successfully') { - toast.success('Email Verified!', { - position: "bottom-right", - autoClose: 3000, - hideProgressBar: true, - closeOnClick: true, - draggable: true, - }); - setTimeout(() => { - window.location.href = '/login'; - }, 3000); - } else { - toast.error('Email Verification Failed!', { - position: "bottom-right", - autoClose: 3000, - hideProgressBar: true, - closeOnClick: true, - draggable: true, - }); - } - }) - .catch(() => { - toast.error('Email Verification Failed!', { - position: "bottom-right", - autoClose: 3000, - hideProgressBar: true, - closeOnClick: true, - draggable: true, - }); - }); - } + const handleSubmit = (event) => { + event.preventDefault(); - return ( - <> -
- ee logo -
-

Auth Portal

-
-

Verify Email

-
-
-
- -
-
- setOtp(event.target.value)} - placeholder="EC-XXXXXX" - /> -
+ apiClient + .post( + "/user/verify", + { + otp, + }, + { + headers: { + "Content-Type": "application/json", + }, + } + ) + .then((response) => { + if (response.data.message === "User verified successfully") { + toast.success("Email Verified!", { + position: "bottom-right", + autoClose: 3000, + hideProgressBar: true, + closeOnClick: true, + draggable: true, + }); + setTimeout(() => { + window.location.href = "/login"; + }, 3000); + } else { + toast.error("Email Verification Failed!", { + position: "bottom-right", + autoClose: 3000, + hideProgressBar: true, + closeOnClick: true, + draggable: true, + }); + } + }) + .catch(() => { + toast.error("Email Verification Failed!", { + position: "bottom-right", + autoClose: 3000, + hideProgressBar: true, + closeOnClick: true, + draggable: true, + }); + }); + }; + + return ( + <> +
+ ee logo +
+

Auth Portal

+
+

Verify Email

+ +
+
+ +
+
+ setOtp(event.target.value)} + placeholder='EC-XXXXXX' + />
- - -
- - - ) +
+ + +
+ + + ); } -export default Home +export default Home; diff --git a/apps/web/src/pages/whoami.jsx b/apps/web/src/pages/whoami.jsx index 9e9e70c..43f7db1 100644 --- a/apps/web/src/pages/whoami.jsx +++ b/apps/web/src/pages/whoami.jsx @@ -1,94 +1,106 @@ -import '../App.css' -import 'react-toastify/dist/ReactToastify.css'; -import { useState, useEffect } from 'react'; -import apiClient from '../libs/api.client'; +import "../styles/App.css"; +import "react-toastify/dist/ReactToastify.css"; +import { useState, useEffect } from "react"; +import apiClient from "../libs/api.client"; import Navbar from "../components/navbar"; function WhoAmI() { - const [userWhoami, setUserWhoami] = useState(null); - const [teamWhoami, setTeamWhoami] = useState(null); - const [teamStats, setTeamStats] = useState(null); + const [userWhoami, setUserWhoami] = useState(null); + const [teamWhoami, setTeamWhoami] = useState(null); + const [teamStats, setTeamStats] = useState(null); - useEffect(() => { - const token = localStorage.getItem('token'); + useEffect(() => { + const token = localStorage.getItem("token"); - if(!token) return window.location.href = '/login'; + if (!token) return (window.location.href = "/login"); - apiClient.get("/user/whoami", { - headers: { - "Authorization": "Bearer " + token, - } - }).then(res => { - if(res.data.error) return window.location.href = '/login' + apiClient + .get("/user/whoami", { + headers: { + Authorization: "Bearer " + token, + }, + }) + .then((res) => { + if (res.data.error) return (window.location.href = "/login"); - if(res.data.message === 'Invalid token') return window.location.href = '/login'; - setUserWhoami(res.data); - }) + if (res.data.message === "Invalid token") + return (window.location.href = "/login"); + setUserWhoami(res.data); + }); - apiClient.get("/team/whoami", { - headers: { - "Authorization": "Bearer " + token, - } - }).then(res => { - if(res.data.error) return window.location.href = '/login' + apiClient + .get("/team/whoami", { + headers: { + Authorization: "Bearer " + token, + }, + }) + .then((res) => { + if (res.data.error) return (window.location.href = "/login"); - if(res.data.message === 'Invalid token') return window.location.href = '/login'; - setTeamWhoami(res.data); - }) + if (res.data.message === "Invalid token") + return (window.location.href = "/login"); + setTeamWhoami(res.data); + }); - apiClient.get(import.meta.env.VITE_API_URL + "/stats/team", { - headers: { - "Authorization": "Bearer " + token, - } - }).then(res => { - if(res.data.error) return window.location.href = '/login' - if(res.data.message === 'Invalid token') return window.location.href = '/login'; - setTeamStats(res.data); - }) - }, []) + apiClient + .get(import.meta.env.VITE_API_URL + "/stats/team", { + headers: { + Authorization: "Bearer " + token, + }, + }) + .then((res) => { + if (res.data.error) return (window.location.href = "/login"); + if (res.data.message === "Invalid token") + return (window.location.href = "/login"); + setTeamStats(res.data); + }); + }, []); - return ( - <> - -
- ee logo -
-

Who Am I ?

-
-
-

$ User

- ID: {userWhoami?.id}
- Name: {userWhoami?.first_name} {userWhoami?.last_name}
-
-
-

$ Team

- ID: {teamWhoami?.id}
- Name: {teamWhoami?.name}
-
-
-

$ Stats

-
- - - - - - - - - {teamStats?.submissions?.map((stat, index) => ( - - - - - - ))} - -
MachineChallengeFlag
{stat.machine_name}{stat.challenge_name}{stat.submited_flag}
+ return ( + <> + +
+
+

$ User

+ ID: {userWhoami?.id} +
+ Name:{" "} + + {userWhoami?.first_name} {userWhoami?.last_name} + +
-
- - ) +
+

$ Team

+ ID: {teamWhoami?.id} +
+ Name: {teamWhoami?.name} +
+
+
+

$ Stats

+ + + + + + + + + + {teamStats?.submissions?.map((stat, index) => ( + + + + + + ))} + +
MachineChallengeFlag
{stat.machine_name}{stat.challenge_name}{stat.submited_flag}
+
+
+ + ); } -export default WhoAmI +export default WhoAmI; diff --git a/apps/web/src/App.css b/apps/web/src/styles/App.css similarity index 64% rename from apps/web/src/App.css rename to apps/web/src/styles/App.css index d669090..71a8bd3 100644 --- a/apps/web/src/App.css +++ b/apps/web/src/styles/App.css @@ -5,29 +5,6 @@ text-align: center; } -.logo { - height: 6em; - padding: 1.5em; - will-change: filter; - transition: filter 300ms; - --r: 10px; /* control the radius of the circles */ - padding: calc(2 * var(--r)); - filter: grayscale(.4); - background: - radial-gradient(var(--r),#0000 98%,#fff) round - calc(-1.5 * var(--r)) calc(-1.5 * var(--r)) / calc(3 * var(--r)) calc(3 * var(--r)), - linear-gradient(#fff 0 0) no-repeat - 50% / calc(100% - 3 * var(--r)) calc(100% - 3 * var(--r)); - -} - -.logo:hover { - filter: drop-shadow(0 0 2em #646cffaa); -} -.logo.react:hover { - filter: drop-shadow(0 0 2em #61dafbaa); -} - @keyframes logo-spin { from { transform: rotate(0deg); @@ -54,10 +31,8 @@ .login-card { max-width: 30em; margin: 0 auto; - } - .form-control { display: block; width: 100%; @@ -69,10 +44,11 @@ background-clip: padding-box; border: 1px solid #ced4da; border-radius: 0.25em; - transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; - font-family: ; + transition: + border-color 0.15s ease-in-out, + box-shadow 0.15s ease-in-out; margin: 20px; - + /* add pixlated border */ clip-path: polygon( 0px calc(100% - 9px), @@ -99,8 +75,7 @@ 3px 6px, 3px 9px, 0px 9px - ); - + ); } .player-component { @@ -128,48 +103,22 @@ height: 100%; display: flex; flex-direction: column; - -} - -.actions { - display: flex; - flex-direction: column; - justify-content: space-between; - align-items: center; - padding: 1em; - } -@keyframes slide-in-bck-center{0%{transform:translateZ(600px);opacity:0}100%{transform:translateZ(0);opacity:1}} - - - - -.action-title { - font-size: 1.5em; - font-weight: bold; -} - -.action-card { - width: 100%; - height: 100%; - display: flex; - flex-direction: row; - gap: 1em; - align-items: center; - justify-content: center; - -} -@media (max-width: 600px) { - .action-card { - flex-direction: column; - +@keyframes slide-in-bck-center { + 0% { + transform: translateZ(600px); + opacity: 0; + } + 100% { + transform: translateZ(0); + opacity: 1; } } .player-mlists { -padding: 2em; -margin: 10%; + padding: 2em; + margin: 10%; } .player-machine-title { @@ -188,72 +137,75 @@ margin: 10%; } .btn { - border: #646cff 5px solid ; + border: #646cff 5px solid; color: #0000; --g: no-repeat linear-gradient(#5793f2 0 0) 0 0; background: var(--g), var(--g); background-size: 0 80%; - -webkit-background-clip: padding-box,text; - background-clip: padding-box,text; + -webkit-background-clip: padding-box, text; + background-clip: padding-box, text; -webkit-box-decoration-break: clone; - box-decoration-break: clone; - animation: - t 1.2s .5s both, + box-decoration-break: clone; + animation: + t 1.2s 0.5s both, b 1.2s 1.3s both; - /* This adds pixilated border */ - clip-path: polygon( - 0px calc(100% - 9px), - 3px calc(100% - 9px), - 3px calc(100% - 6px), - 6px calc(100% - 3px), - 9px calc(100% - 3px), - 9px 100%, - calc(100% - 9px) 100%, - calc(100% - 9px) calc(100% - 3px), - calc(100% - 6px) calc(100% - 3px), - calc(100% - 3px) calc(100% - 6px), - calc(100% - 3px) calc(100% - 9px), - 100% calc(100% - 9px), - 100% 9px, - calc(100% - 3px) 9px, - calc(100% - 3px) 6px, - calc(100% - 6px) 3px, - calc(100% - 9px) 3px, - calc(100% - 9px) 0px, - 9px 0px, - 9px 3px, - 6px 3px, - 3px 6px, - 3px 9px, - 0px 9px - ); + /* This adds pixilated border */ + clip-path: polygon( + 0px calc(100% - 9px), + 3px calc(100% - 9px), + 3px calc(100% - 6px), + 6px calc(100% - 3px), + 9px calc(100% - 3px), + 9px 100%, + calc(100% - 9px) 100%, + calc(100% - 9px) calc(100% - 3px), + calc(100% - 6px) calc(100% - 3px), + calc(100% - 3px) calc(100% - 6px), + calc(100% - 3px) calc(100% - 9px), + 100% calc(100% - 9px), + 100% 9px, + calc(100% - 3px) 9px, + calc(100% - 3px) 6px, + calc(100% - 6px) 3px, + calc(100% - 9px) 3px, + calc(100% - 9px) 0px, + 9px 0px, + 9px 3px, + 6px 3px, + 3px 6px, + 3px 9px, + 0px 9px + ); } -@keyframes t{ - to {background-size:150% 100%} +@keyframes t { + to { + background-size: 150% 100%; + } } @keyframes b { - to {background-position:-200% 0,0 0} + to { + background-position: + -200% 0, + 0 0; + } } -.forminput{ -width: 90%; -border-radius:0.5em; -padding: 0.5em; -font-family: Minecraft; -font-size: 0.7em; +.forminput { + width: 90%; + border-radius: 0.5em; + padding: 0.5em; + font-family: Minecraft; + font-size: 0.7em; } - - -.home-head{ +.home-head { animation: slide-in-bck-center 1000ms normal; } /* This is challenge section components */ /* This gives pixilated borders to website */ -.player-component{ - +.player-component { clip-path: polygon( 0px calc(100% - 15px), 5px calc(100% - 15px), @@ -282,39 +234,39 @@ font-size: 0.7em; ); } -.player-machine-detail{ +.player-machine-detail { padding: 1em; } -.player-challenge-button{ -margin: 10px; -clip-path: polygon( - 0px calc(100% - 6px), - 2px calc(100% - 6px), - 2px calc(100% - 4px), - 4px calc(100% - 2px), - 6px calc(100% - 2px), - 6px 100%, - calc(100% - 6px) 100%, - calc(100% - 6px) calc(100% - 2px), - calc(100% - 4px) calc(100% - 2px), - calc(100% - 2px) calc(100% - 4px), - calc(100% - 2px) calc(100% - 6px), - 100% calc(100% - 6px), - 100% 6px, - calc(100% - 2px) 6px, - calc(100% - 2px) 4px, - calc(100% - 4px) 2px, - calc(100% - 6px) 2px, - calc(100% - 6px) 0px, - 6px 0px, - 6px 2px, - 4px 2px, - 2px 4px, - 2px 6px, - 0px 6px -); +.player-challenge-button { + margin: 10px; + clip-path: polygon( + 0px calc(100% - 6px), + 2px calc(100% - 6px), + 2px calc(100% - 4px), + 4px calc(100% - 2px), + 6px calc(100% - 2px), + 6px 100%, + calc(100% - 6px) 100%, + calc(100% - 6px) calc(100% - 2px), + calc(100% - 4px) calc(100% - 2px), + calc(100% - 2px) calc(100% - 4px), + calc(100% - 2px) calc(100% - 6px), + 100% calc(100% - 6px), + 100% 6px, + calc(100% - 2px) 6px, + calc(100% - 2px) 4px, + calc(100% - 4px) 2px, + calc(100% - 6px) 2px, + calc(100% - 6px) 0px, + 6px 0px, + 6px 2px, + 4px 2px, + 2px 4px, + 2px 6px, + 0px 6px + ); } -.player-challenge-compl-button{ +.player-challenge-compl-button { margin: 5px; border: #646cff 1px solid; clip-path: polygon( @@ -341,13 +293,13 @@ clip-path: polygon( ); } -.who-card{ +.who-card { padding: 10px; display: flex; flex-direction: column; row-gap: 2em; } -.user-wrapper{ +.user-wrapper { padding: 1em; border: #ccc 5px solid; clip-path: polygon( @@ -376,9 +328,8 @@ clip-path: polygon( 3px 9px, 0px 9px ); - ); } -.team-wrapper{ +.team-wrapper { padding: 1em; border: #ccc 5px solid; clip-path: polygon( @@ -408,7 +359,7 @@ clip-path: polygon( 0px 9px ); } -.stats-wrapper{ +.stats-wrapper { padding: 1em; border: #ccc 5px solid; clip-path: polygon( @@ -437,4 +388,4 @@ clip-path: polygon( 3px 9px, 0px 9px ); -} \ No newline at end of file +} diff --git a/apps/web/src/styles/logo.styles.css b/apps/web/src/styles/logo.styles.css new file mode 100644 index 0000000..0deca91 --- /dev/null +++ b/apps/web/src/styles/logo.styles.css @@ -0,0 +1,25 @@ +.logo { + height: 6em; + padding: 1.5em; + will-change: filter; + transition: filter 300ms; + --r: 10px; /* control the radius of the circles */ + padding: calc(2 * var(--r)); + filter: grayscale(0.4); + border-radius: 100%; + cursor: pointer; + object-position: -1px 2px; + font-size: 0.7em; + /* background: + radial-gradient(var(--r), #0000 98%, #fff) round calc(-1.5 * var(--r)) + calc(-1.5 * var(--r)) / calc(3 * var(--r)) calc(3 * var(--r)), + linear-gradient(#fff 0 0) no-repeat 50% / calc(100% - 3 * var(--r)) + calc(100% - 3 * var(--r)); */ +} + +.logo:hover { + filter: drop-shadow(0 0 2em #646cffaa); +} +.logo .react:hover { + filter: drop-shadow(0 0 2em #61dafbaa); +} diff --git a/apps/web/src/styles/navbar.styles.css b/apps/web/src/styles/navbar.styles.css new file mode 100644 index 0000000..8ab072e --- /dev/null +++ b/apps/web/src/styles/navbar.styles.css @@ -0,0 +1,47 @@ +.actions { + display: flex; + flex-direction: column; + justify-content: space-between; + align-items: center; + padding: 1em; +} + +.actions a { + font-size: 1.3em; + font-weight: bold; +} + +.action-card { + width: 100%; + display: flex; + flex-direction: row; + align-items: center; +} + +.action-card .right { + width: 100%; + height: 100%; + display: flex; + flex-direction: row; + flex: 1; + gap: 1em; + align-items: center; + justify-content: space-evenly; +} + +.action-card .left { + width: 100%; + height: 100%; + display: flex; + flex-direction: row; + flex: 1; + gap: 1em; + align-items: center; + justify-content: space-evenly; +} + +@media (max-width: 600px) { + .action-card { + flex-direction: column; + } +} From 1adbbd479e0be573ff6d8ce3ef66387625949a48 Mon Sep 17 00:00:00 2001 From: JonasSchweigler Date: Wed, 3 Jan 2024 22:43:44 +0100 Subject: [PATCH 2/6] added new who am i layout --- apps/web/src/index.css | 3 +- apps/web/src/pages/app.jsx | 2 +- apps/web/src/pages/whoami.jsx | 36 +++++---- apps/web/src/styles/App.css | 97 ----------------------- apps/web/src/styles/whoami.styles.css | 108 ++++++++++++++++++++++++++ 5 files changed, 131 insertions(+), 115 deletions(-) create mode 100644 apps/web/src/styles/whoami.styles.css diff --git a/apps/web/src/index.css b/apps/web/src/index.css index 4dc4c72..24b4493 100644 --- a/apps/web/src/index.css +++ b/apps/web/src/index.css @@ -15,7 +15,8 @@ color-scheme: light dark; color: rgba(255, 255, 255, 0.87); - background-color: #242424; + /* background-color: #242424; */ + background-color: #0e0e0e; font-synthesis: none; text-rendering: optimizeLegibility; diff --git a/apps/web/src/pages/app.jsx b/apps/web/src/pages/app.jsx index d9484ed..d96b783 100644 --- a/apps/web/src/pages/app.jsx +++ b/apps/web/src/pages/app.jsx @@ -34,7 +34,7 @@ function Player() { return ( <> - + {/* */}
diff --git a/apps/web/src/pages/whoami.jsx b/apps/web/src/pages/whoami.jsx index 43f7db1..983c92b 100644 --- a/apps/web/src/pages/whoami.jsx +++ b/apps/web/src/pages/whoami.jsx @@ -4,6 +4,8 @@ import { useState, useEffect } from "react"; import apiClient from "../libs/api.client"; import Navbar from "../components/navbar"; +import "../styles/whoami.styles.css"; + function WhoAmI() { const [userWhoami, setUserWhoami] = useState(null); const [teamWhoami, setTeamWhoami] = useState(null); @@ -60,22 +62,24 @@ function WhoAmI() { <>
-
-

$ User

- ID: {userWhoami?.id} -
- Name:{" "} - - {userWhoami?.first_name} {userWhoami?.last_name} - -
-
-
-

$ Team

- ID: {teamWhoami?.id} -
- Name: {teamWhoami?.name} -
+
+
+

$ User

+ ID: {userWhoami?.id} +
+ Name:{" "} + + {userWhoami?.first_name} {userWhoami?.last_name} + +
+
+
+

$ Team

+ ID: {teamWhoami?.id} +
+ Name: {teamWhoami?.name} +
+

$ Stats

diff --git a/apps/web/src/styles/App.css b/apps/web/src/styles/App.css index 71a8bd3..e62c4d9 100644 --- a/apps/web/src/styles/App.css +++ b/apps/web/src/styles/App.css @@ -292,100 +292,3 @@ 0px 4px ); } - -.who-card { - padding: 10px; - display: flex; - flex-direction: column; - row-gap: 2em; -} -.user-wrapper { - padding: 1em; - border: #ccc 5px solid; - clip-path: polygon( - 0px calc(100% - 9px), - 3px calc(100% - 9px), - 3px calc(100% - 6px), - 6px calc(100% - 3px), - 9px calc(100% - 3px), - 9px 100%, - calc(100% - 9px) 100%, - calc(100% - 9px) calc(100% - 3px), - calc(100% - 6px) calc(100% - 3px), - calc(100% - 3px) calc(100% - 6px), - calc(100% - 3px) calc(100% - 9px), - 100% calc(100% - 9px), - 100% 9px, - calc(100% - 3px) 9px, - calc(100% - 3px) 6px, - calc(100% - 6px) 3px, - calc(100% - 9px) 3px, - calc(100% - 9px) 0px, - 9px 0px, - 9px 3px, - 6px 3px, - 3px 6px, - 3px 9px, - 0px 9px - ); -} -.team-wrapper { - padding: 1em; - border: #ccc 5px solid; - clip-path: polygon( - 0px calc(100% - 9px), - 3px calc(100% - 9px), - 3px calc(100% - 6px), - 6px calc(100% - 3px), - 9px calc(100% - 3px), - 9px 100%, - calc(100% - 9px) 100%, - calc(100% - 9px) calc(100% - 3px), - calc(100% - 6px) calc(100% - 3px), - calc(100% - 3px) calc(100% - 6px), - calc(100% - 3px) calc(100% - 9px), - 100% calc(100% - 9px), - 100% 9px, - calc(100% - 3px) 9px, - calc(100% - 3px) 6px, - calc(100% - 6px) 3px, - calc(100% - 9px) 3px, - calc(100% - 9px) 0px, - 9px 0px, - 9px 3px, - 6px 3px, - 3px 6px, - 3px 9px, - 0px 9px - ); -} -.stats-wrapper { - padding: 1em; - border: #ccc 5px solid; - clip-path: polygon( - 0px calc(100% - 9px), - 3px calc(100% - 9px), - 3px calc(100% - 6px), - 6px calc(100% - 3px), - 9px calc(100% - 3px), - 9px 100%, - calc(100% - 9px) 100%, - calc(100% - 9px) calc(100% - 3px), - calc(100% - 6px) calc(100% - 3px), - calc(100% - 3px) calc(100% - 6px), - calc(100% - 3px) calc(100% - 9px), - 100% calc(100% - 9px), - 100% 9px, - calc(100% - 3px) 9px, - calc(100% - 3px) 6px, - calc(100% - 6px) 3px, - calc(100% - 9px) 3px, - calc(100% - 9px) 0px, - 9px 0px, - 9px 3px, - 6px 3px, - 3px 6px, - 3px 9px, - 0px 9px - ); -} diff --git a/apps/web/src/styles/whoami.styles.css b/apps/web/src/styles/whoami.styles.css new file mode 100644 index 0000000..b906c07 --- /dev/null +++ b/apps/web/src/styles/whoami.styles.css @@ -0,0 +1,108 @@ +.who-card { + padding: 10px; + display: flex; + flex-direction: column; + gap: 2em; + display: grid; + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); +} + +.who-wrapper { + display: grid; + gap: 2em; +} + +.user-wrapper { + padding: 1em; + border: #ccc 5px solid; + clip-path: polygon( + 0px calc(100% - 9px), + 3px calc(100% - 9px), + 3px calc(100% - 6px), + 6px calc(100% - 3px), + 9px calc(100% - 3px), + 9px 100%, + calc(100% - 9px) 100%, + calc(100% - 9px) calc(100% - 3px), + calc(100% - 6px) calc(100% - 3px), + calc(100% - 3px) calc(100% - 6px), + calc(100% - 3px) calc(100% - 9px), + 100% calc(100% - 9px), + 100% 9px, + calc(100% - 3px) 9px, + calc(100% - 3px) 6px, + calc(100% - 6px) 3px, + calc(100% - 9px) 3px, + calc(100% - 9px) 0px, + 9px 0px, + 9px 3px, + 6px 3px, + 3px 6px, + 3px 9px, + 0px 9px + ); +} + +.team-wrapper { + padding: 1em; + border: #ccc 5px solid; + clip-path: polygon( + 0px calc(100% - 9px), + 3px calc(100% - 9px), + 3px calc(100% - 6px), + 6px calc(100% - 3px), + 9px calc(100% - 3px), + 9px 100%, + calc(100% - 9px) 100%, + calc(100% - 9px) calc(100% - 3px), + calc(100% - 6px) calc(100% - 3px), + calc(100% - 3px) calc(100% - 6px), + calc(100% - 3px) calc(100% - 9px), + 100% calc(100% - 9px), + 100% 9px, + calc(100% - 3px) 9px, + calc(100% - 3px) 6px, + calc(100% - 6px) 3px, + calc(100% - 9px) 3px, + calc(100% - 9px) 0px, + 9px 0px, + 9px 3px, + 6px 3px, + 3px 6px, + 3px 9px, + 0px 9px + ); +} + +.stats-wrapper { + display: flex; + flex-direction: column; + padding: 1em; + border: #ccc 5px solid; + clip-path: polygon( + 0px calc(100% - 9px), + 3px calc(100% - 9px), + 3px calc(100% - 6px), + 6px calc(100% - 3px), + 9px calc(100% - 3px), + 9px 100%, + calc(100% - 9px) 100%, + calc(100% - 9px) calc(100% - 3px), + calc(100% - 6px) calc(100% - 3px), + calc(100% - 3px) calc(100% - 6px), + calc(100% - 3px) calc(100% - 9px), + 100% calc(100% - 9px), + 100% 9px, + calc(100% - 3px) 9px, + calc(100% - 3px) 6px, + calc(100% - 6px) 3px, + calc(100% - 9px) 3px, + calc(100% - 9px) 0px, + 9px 0px, + 9px 3px, + 6px 3px, + 3px 6px, + 3px 9px, + 0px 9px + ); +} From a90d5eb1e9e12b4e395ae52a6db6bbf9640c3dfc Mon Sep 17 00:00:00 2001 From: JonasSchweigler Date: Wed, 3 Jan 2024 22:52:42 +0100 Subject: [PATCH 3/6] changed redirect to home when auth invalid --- apps/web/src/pages/about.jsx | 2 +- apps/web/src/pages/app.jsx | 6 +++--- apps/web/src/pages/leaderboard.jsx | 5 ++--- apps/web/src/pages/news.jsx | 2 +- apps/web/src/pages/verify.jsx | 2 +- apps/web/src/pages/whoami.jsx | 14 +++++++------- apps/web/src/styles/App.css | 7 +++++++ apps/web/src/styles/navbar.styles.css | 7 ------- 8 files changed, 22 insertions(+), 23 deletions(-) diff --git a/apps/web/src/pages/about.jsx b/apps/web/src/pages/about.jsx index 4354596..aa84d6f 100644 --- a/apps/web/src/pages/about.jsx +++ b/apps/web/src/pages/about.jsx @@ -4,7 +4,7 @@ import Navbar from "../components/navbar"; function Home() { return ( <> - +

Guides

diff --git a/apps/web/src/pages/app.jsx b/apps/web/src/pages/app.jsx index d96b783..ed66f12 100644 --- a/apps/web/src/pages/app.jsx +++ b/apps/web/src/pages/app.jsx @@ -16,7 +16,7 @@ function Player() { ]); useEffect(() => { - if (!token) return (window.location.href = "/login"); + if (!token) return (window.location.href = "/"); apiClient .get("/challenge/progress", { @@ -25,9 +25,9 @@ function Player() { }, }) .then((res) => { - if (!Array.isArray(res.data)) return (window.location.href = "/login"); + if (!Array.isArray(res.data)) return (window.location.href = "/"); if (res.data.message === "Invalid token") - return (window.location.href = "/login"); + return (window.location.href = "/"); setMachines(res.data); }); }, [token]); diff --git a/apps/web/src/pages/leaderboard.jsx b/apps/web/src/pages/leaderboard.jsx index 6a4b29d..1e9dd03 100644 --- a/apps/web/src/pages/leaderboard.jsx +++ b/apps/web/src/pages/leaderboard.jsx @@ -9,7 +9,7 @@ function Leaderboard() { useEffect(() => { const token = localStorage.getItem("token"); - if (!token) return (window.location.href = "/login"); + if (!token) return (window.location.href = "/"); apiClient .get("/stats/leaderboard", { @@ -18,8 +18,7 @@ function Leaderboard() { }, }) .then((response) => { - if (!Array.isArray(response.data)) - return (window.location.href = "/login"); + if (!Array.isArray(response.data)) return (window.location.href = "/"); setLeaderboard(response.data); }) .catch(() => { diff --git a/apps/web/src/pages/news.jsx b/apps/web/src/pages/news.jsx index c17837f..4f781e7 100644 --- a/apps/web/src/pages/news.jsx +++ b/apps/web/src/pages/news.jsx @@ -4,7 +4,7 @@ import Navbar from "../components/navbar"; function News() { return ( <> - + {/*

News

diff --git a/apps/web/src/pages/verify.jsx b/apps/web/src/pages/verify.jsx index 3b02903..ad2d342 100644 --- a/apps/web/src/pages/verify.jsx +++ b/apps/web/src/pages/verify.jsx @@ -32,7 +32,7 @@ function Home() { draggable: true, }); setTimeout(() => { - window.location.href = "/login"; + window.location.href = "/"; }, 3000); } else { toast.error("Email Verification Failed!", { diff --git a/apps/web/src/pages/whoami.jsx b/apps/web/src/pages/whoami.jsx index 983c92b..0b54d77 100644 --- a/apps/web/src/pages/whoami.jsx +++ b/apps/web/src/pages/whoami.jsx @@ -14,7 +14,7 @@ function WhoAmI() { useEffect(() => { const token = localStorage.getItem("token"); - if (!token) return (window.location.href = "/login"); + if (!token) return (window.location.href = "/"); apiClient .get("/user/whoami", { @@ -23,10 +23,10 @@ function WhoAmI() { }, }) .then((res) => { - if (res.data.error) return (window.location.href = "/login"); + if (res.data.error) return (window.location.href = "/"); if (res.data.message === "Invalid token") - return (window.location.href = "/login"); + return (window.location.href = "/"); setUserWhoami(res.data); }); @@ -37,10 +37,10 @@ function WhoAmI() { }, }) .then((res) => { - if (res.data.error) return (window.location.href = "/login"); + if (res.data.error) return (window.location.href = "/"); if (res.data.message === "Invalid token") - return (window.location.href = "/login"); + return (window.location.href = "/"); setTeamWhoami(res.data); }); @@ -51,9 +51,9 @@ function WhoAmI() { }, }) .then((res) => { - if (res.data.error) return (window.location.href = "/login"); + if (res.data.error) return (window.location.href = "/"); if (res.data.message === "Invalid token") - return (window.location.href = "/login"); + return (window.location.href = "/"); setTeamStats(res.data); }); }, []); diff --git a/apps/web/src/styles/App.css b/apps/web/src/styles/App.css index e62c4d9..a2828bb 100644 --- a/apps/web/src/styles/App.css +++ b/apps/web/src/styles/App.css @@ -20,6 +20,13 @@ } } +.action-card { + width: 100%; + display: flex; + flex-direction: row; + align-items: center; +} + .card { padding: 2em; } diff --git a/apps/web/src/styles/navbar.styles.css b/apps/web/src/styles/navbar.styles.css index 8ab072e..8d2ea9b 100644 --- a/apps/web/src/styles/navbar.styles.css +++ b/apps/web/src/styles/navbar.styles.css @@ -11,13 +11,6 @@ font-weight: bold; } -.action-card { - width: 100%; - display: flex; - flex-direction: row; - align-items: center; -} - .action-card .right { width: 100%; height: 100%; From 51d06878358acc097ab18389d3cd8140840be994 Mon Sep 17 00:00:00 2001 From: JonasSchweigler Date: Wed, 3 Jan 2024 23:09:59 +0100 Subject: [PATCH 4/6] added user state in home route --- apps/web/src/components/cards/login-card.tsx | 0 .../src/components/cards/register-card.tsx | 0 apps/web/src/pages/home.jsx | 23 ++++++++++++++++++- 3 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 apps/web/src/components/cards/login-card.tsx create mode 100644 apps/web/src/components/cards/register-card.tsx diff --git a/apps/web/src/components/cards/login-card.tsx b/apps/web/src/components/cards/login-card.tsx new file mode 100644 index 0000000..e69de29 diff --git a/apps/web/src/components/cards/register-card.tsx b/apps/web/src/components/cards/register-card.tsx new file mode 100644 index 0000000..e69de29 diff --git a/apps/web/src/pages/home.jsx b/apps/web/src/pages/home.jsx index 3cda7da..88cdd05 100644 --- a/apps/web/src/pages/home.jsx +++ b/apps/web/src/pages/home.jsx @@ -1,9 +1,30 @@ import "../styles/App.css"; import "react-toastify/dist/ReactToastify.css"; -// import { Link } from "react-router-dom"; +import apiClient from "../libs/api.client"; import Navbar from "../components/navbar"; +import { useEffect, useState } from "react"; function Home() { + const [user, setUser] = useState(null); + useEffect(() => { + const token = localStorage.getItem("token"); + + if (!token) return; + + apiClient + .get("/user/whoami", { + headers: { + Authorization: "Bearer " + token, + }, + }) + .then((res) => { + if (res.data.error) return; + + if (res.data.message === "Invalid token") return; + setUser(res.data); + }); + }, []); + return (
From fd5a8c19ed103175b8b60fd4d15693c89bbaa353 Mon Sep 17 00:00:00 2001 From: JonasSchweigler Date: Wed, 3 Jan 2024 23:13:13 +0100 Subject: [PATCH 5/6] added player name in greeting --- apps/web/src/pages/home.jsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/web/src/pages/home.jsx b/apps/web/src/pages/home.jsx index 88cdd05..75c0f4f 100644 --- a/apps/web/src/pages/home.jsx +++ b/apps/web/src/pages/home.jsx @@ -27,7 +27,11 @@ function Home() { return (
- +

hello

); From e7ceb596ca6859f71d029bd49a2c3d6865ab8cb6 Mon Sep 17 00:00:00 2001 From: JonasSchweigler Date: Wed, 3 Jan 2024 23:30:48 +0100 Subject: [PATCH 6/6] added base cards for auth in home --- apps/web/src/components/cards/login-card.tsx | 108 ++++++++++++++ .../src/components/cards/register-card.tsx | 140 ++++++++++++++++++ apps/web/src/pages/home.jsx | 22 ++- apps/web/src/styles/home.styles.css | 9 ++ 4 files changed, 277 insertions(+), 2 deletions(-) create mode 100644 apps/web/src/styles/home.styles.css diff --git a/apps/web/src/components/cards/login-card.tsx b/apps/web/src/components/cards/login-card.tsx index e69de29..f0a260c 100644 --- a/apps/web/src/components/cards/login-card.tsx +++ b/apps/web/src/components/cards/login-card.tsx @@ -0,0 +1,108 @@ +import { useState } from "react"; +import apiClient from "../../libs/api.client"; +import { toast } from "react-toastify"; +import { Link } from "react-router-dom"; + +export const LoginCard = () => { + const [email, setEmail] = useState(""); + const [password, setPassword] = useState(""); + + let token = localStorage.getItem("token"); + + const handleSubmit = (event) => { + event.preventDefault(); + + apiClient + .post( + "/user/login", + { + email, + password, + }, + { + headers: { + "Content-Type": "application/json", + }, + } + ) + .then((response) => { + if (response.data.message === "Login successful") { + token = response.data.token; + localStorage.setItem("token", token); + toast.success("Login Successful!", { + position: "bottom-right", + autoClose: 3000, + hideProgressBar: true, + closeOnClick: true, + draggable: true, + }); + setTimeout(() => { + window.location.href = "/app"; + }, 3000); + } else { + toast.error("Login Failed!", { + position: "bottom-right", + autoClose: 3000, + hideProgressBar: true, + closeOnClick: true, + draggable: true, + }); + } + }) + .catch(() => { + toast.error("Login Failed!", { + position: "bottom-right", + autoClose: 3000, + hideProgressBar: true, + closeOnClick: true, + draggable: true, + }); + }); + }; + return ( +
+
+

Sign In

+
+
+
+ +
+
+ setEmail(event.target.value)} + placeholder='Enter your email' + /> +
+
+
+
+ +
+
+ setPassword(event.target.value)} + placeholder='Enter your password' + /> +
+
+ +
+
+

+ Don't have a account, register from{" "} + here. +

+
+ ); +}; diff --git a/apps/web/src/components/cards/register-card.tsx b/apps/web/src/components/cards/register-card.tsx index e69de29..a59268b 100644 --- a/apps/web/src/components/cards/register-card.tsx +++ b/apps/web/src/components/cards/register-card.tsx @@ -0,0 +1,140 @@ +import { useState } from "react"; +import { ToastContainer, toast } from "react-toastify"; +import { Link } from "react-router-dom"; + +import "react-toastify/dist/ReactToastify.css"; +import apiClient from "../../libs/api.client"; + +export const RegisterCard = () => { + const [email, setEmail] = useState(""); + const [password, setPassword] = useState(""); + const [firstName, setFirstName] = useState(""); + const [lastName, setLastName] = useState(""); + + const handleSubmit = (event) => { + event.preventDefault(); + + apiClient + .post( + "/user/register", + { + email, + password, + firstName, + lastName, + }, + { + headers: { + "Content-Type": "application/json", + }, + } + ) + .then((response) => { + if (response.data.email === email) { + toast.success("Register Successful!", { + position: "bottom-right", + autoClose: 3000, + hideProgressBar: true, + closeOnClick: true, + draggable: true, + }); + setTimeout(() => { + window.location.href = "/verify"; + }, 3000); + } else { + toast.error("Register Failed!", { + position: "bottom-right", + autoClose: 3000, + hideProgressBar: true, + closeOnClick: true, + draggable: true, + }); + } + }) + .catch(() => { + toast.error("Register Failed!", { + position: "bottom-right", + autoClose: 3000, + hideProgressBar: true, + closeOnClick: true, + draggable: true, + }); + }); + }; + + return ( +
+
+

Sign In

+
+
+
+ +
+
+ setEmail(event.target.value)} + placeholder='Enter your email' + /> +
+
+
+
+ +
+
+ setPassword(event.target.value)} + placeholder='Enter your password' + /> +
+
+
+
+ +
+
+ setFirstName(event.target.value)} + placeholder='Enter your firstName' + /> +
+
+
+
+ +
+
+ setLastName(event.target.value)} + placeholder='Enter your lastName' + /> +
+
+ +
+
+

+ Already have a account? Login from here. +

+
+ ); +}; diff --git a/apps/web/src/pages/home.jsx b/apps/web/src/pages/home.jsx index 75c0f4f..55d0d6b 100644 --- a/apps/web/src/pages/home.jsx +++ b/apps/web/src/pages/home.jsx @@ -1,8 +1,10 @@ -import "../styles/App.css"; +import "../styles/home.styles.css"; import "react-toastify/dist/ReactToastify.css"; import apiClient from "../libs/api.client"; import Navbar from "../components/navbar"; import { useEffect, useState } from "react"; +import { LoginCard } from "../components/cards/login-card"; +import { RegisterCard } from "../components/cards/register-card"; function Home() { const [user, setUser] = useState(null); @@ -32,7 +34,23 @@ function Home() { user ? "Welcome back, " + user.last_name : "Welcome to eeCTF" } /> -

hello

+
+ {user === null ? ( +
+ + +
+ ) : ( +
+
+ {/*

+ You are currently in {user.team_name} team. Your team has{" "} + {user.team_score} points. +

*/} +
+
+ )} +
); } diff --git a/apps/web/src/styles/home.styles.css b/apps/web/src/styles/home.styles.css new file mode 100644 index 0000000..f857508 --- /dev/null +++ b/apps/web/src/styles/home.styles.css @@ -0,0 +1,9 @@ +.auht-grid { + display: flex; + flex-direction: row; + gap: 3rem; + align-items: center; + justify-content: center; + width: 100%; + margin: auto; +}