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.css b/apps/web/src/App.css
deleted file mode 100644
index d669090..0000000
--- a/apps/web/src/App.css
+++ /dev/null
@@ -1,440 +0,0 @@
-#root {
- max-width: 1280px;
- margin: 0 auto;
- padding: 2rem;
- 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);
- }
- to {
- transform: rotate(360deg);
- }
-}
-
-@media (prefers-reduced-motion: no-preference) {
- a:nth-of-type(2) .logo {
- animation: logo-spin infinite 20s linear;
- }
-}
-
-.card {
- padding: 2em;
-}
-
-.read-the-docs {
- color: #888;
-}
-
-.login-card {
- max-width: 30em;
- margin: 0 auto;
-
-}
-
-
-.form-control {
- display: block;
- width: 100%;
- padding: 0.5em;
- font-size: 1em;
- line-height: 1.5;
- color: #495057;
- background-color: #cec4c4;
- 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: ;
- margin: 20px;
-
- /* add pixlated 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
- );
-
-}
-
-.player-component {
- margin: auto;
- border: 10px solid #ccc;
- height: 700px;
- width: 1200px;
- /* width: 100%;
- height: 100%; */
- display: flex;
-}
-
-.player-machine-section {
- width: 100%;
- height: 100%;
- max-width: 300px;
- display: flex;
- border: 1px solid #ccc;
- flex-direction: column;
- overflow-y: scroll;
-}
-
-.player-challenge-detail-section {
- width: 100%;
- 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;
-
- }
-}
-
-.player-mlists {
-padding: 2em;
-margin: 10%;
-}
-
-.player-machine-title {
- position: sticky;
- top: 0;
-}
-
-.leaderboard-wrapper {
- width: 100%;
- height: 100%;
- display: flex;
- flex-direction: column;
- gap: 1em;
- align-items: center;
- justify-content: center;
-}
-
-.btn {
- 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-box-decoration-break: clone;
- box-decoration-break: clone;
- animation:
- t 1.2s .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
- );
-}
-@keyframes t{
- to {background-size:150% 100%}
-}
-@keyframes b {
- to {background-position:-200% 0,0 0}
-}
-
-.forminput{
-width: 90%;
-border-radius:0.5em;
-padding: 0.5em;
-font-family: Minecraft;
-font-size: 0.7em;
-}
-
-
-
-.home-head{
- animation: slide-in-bck-center 1000ms normal;
-}
-
-/* This is challenge section components */
-
-/* This gives pixilated borders to website */
-.player-component{
-
- clip-path: polygon(
- 0px calc(100% - 15px),
- 5px calc(100% - 15px),
- 5px calc(100% - 10px),
- 10px calc(100% - 5px),
- 15px calc(100% - 5px),
- 15px 100%,
- calc(100% - 15px) 100%,
- calc(100% - 15px) calc(100% - 5px),
- calc(100% - 10px) calc(100% - 5px),
- calc(100% - 5px) calc(100% - 10px),
- calc(100% - 5px) calc(100% - 15px),
- 100% calc(100% - 15px),
- 100% 15px,
- calc(100% - 5px) 15px,
- calc(100% - 5px) 10px,
- calc(100% - 10px) 5px,
- calc(100% - 15px) 5px,
- calc(100% - 15px) 0px,
- 15px 0px,
- 15px 5px,
- 10px 5px,
- 5px 10px,
- 5px 15px,
- 0px 15px
- );
-}
-
-.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-compl-button{
- margin: 5px;
- border: #646cff 1px solid;
- clip-path: polygon(
- 0px calc(100% - 4px),
- 2px calc(100% - 4px),
- 2px calc(100% - 2px),
- 4px calc(100% - 2px),
- 4px 100%,
- calc(100% - 4px) 100%,
- calc(100% - 4px) calc(100% - 2px),
- calc(100% - 2px) calc(100% - 2px),
- calc(100% - 2px) calc(100% - 4px),
- 100% calc(100% - 4px),
- 100% 4px,
- calc(100% - 2px) 4px,
- calc(100% - 2px) 2px,
- calc(100% - 4px) 2px,
- calc(100% - 4px) 0px,
- 4px 0px,
- 4px 2px,
- 2px 2px,
- 2px 4px,
- 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
- );
-}
\ No newline at end of file
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/cards/login-card.tsx b/apps/web/src/components/cards/login-card.tsx
new file mode 100644
index 0000000..f0a260c
--- /dev/null
+++ 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 (
+
+
+
+ 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
new file mode 100644
index 0000000..a59268b
--- /dev/null
+++ 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 (
+
+
+
+ Already have a account? Login from here.
+
+
+ );
+};
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
+
+
+

+
+
+ 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..24b4493 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;
@@ -16,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;
@@ -35,10 +35,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 6e50321..c51690e 100644
--- a/apps/web/src/pages/about.jsx
+++ b/apps/web/src/pages/about.jsx
@@ -1,18 +1,14 @@
-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";
import { url } from '../libs/api.client';
+
function Home() {
- return (
- <>
-
-
-

-
-
rcsCTF24
-
-
+ 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..ed66f12 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 = "/");
- 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 = "/");
+ if (res.data.message === "Invalid token")
+ return (window.location.href = "/");
+ 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..55d0d6b 100644
--- a/apps/web/src/pages/home.jsx
+++ b/apps/web/src/pages/home.jsx
@@ -1,31 +1,58 @@
-import '../App.css'
-import 'react-toastify/dist/ReactToastify.css';
-import { Link } from "react-router-dom";
+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() {
- return (
- <>
-
-

-
-
Welcome to eeCTF
-
-
-
- Actions
-
-
-
About
-
App
-
Login
-
Register
-
Verify Account
-
Leaderboard
-
Whoami
+ 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 (
+
+
+
+ {user === null ? (
+
+
+
+
+ ) : (
+
+
+ {/*
+ You are currently in {user.team_name} team. Your team has{" "}
+ {user.team_score} points.
+
*/}
-
- >
- )
+
+ )}
+
+
+ );
}
-export default Home
+export default Home;
diff --git a/apps/web/src/pages/leaderboard.jsx b/apps/web/src/pages/leaderboard.jsx
index 8847fda..1e9dd03 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() {
@@ -10,16 +9,16 @@ 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", {
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 = "/");
setLeaderboard(response.data);
})
.catch(() => {
@@ -29,12 +28,8 @@ function Leaderboard() {
return (
<>
-
-
-

-
-
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 (
- <>
-
-
-

-
- Login Portal
-