diff --git a/vingo/database/users.go b/vingo/database/users.go index 136258c..e46a148 100644 --- a/vingo/database/users.go +++ b/vingo/database/users.go @@ -1,10 +1,10 @@ package database type User struct { + Id int `json:"id"` Username string `json:"username"` Admin bool `json:"admin"` Settings Settings `json:"settings"` - Id int `json:"id"` } var ( diff --git a/vinvoor/public/first-first-place-svgrepo-com.svg b/vinvoor/public/first_place.svg similarity index 100% rename from vinvoor/public/first-first-place-svgrepo-com.svg rename to vinvoor/public/first_place.svg diff --git a/vinvoor/public/second-svgrepo-com.svg b/vinvoor/public/second_place.svg similarity index 100% rename from vinvoor/public/second-svgrepo-com.svg rename to vinvoor/public/second_place.svg diff --git a/vinvoor/public/third-svgrepo-com.svg b/vinvoor/public/third_place.svg similarity index 100% rename from vinvoor/public/third-svgrepo-com.svg rename to vinvoor/public/third_place.svg diff --git a/vinvoor/src/App.tsx b/vinvoor/src/App.tsx index 8e766e0..8371a6c 100644 --- a/vinvoor/src/App.tsx +++ b/vinvoor/src/App.tsx @@ -1,20 +1,33 @@ -import { Container, CssBaseline } from "@mui/material"; -import { Outlet } from "react-router-dom"; +import { Container } from "@mui/material"; +import { useContext } from "react"; +import { Navigate, Outlet } from "react-router-dom"; +import { LoadingSkeleton } from "./components/LoadingSkeleton"; import { NavBar } from "./navbar/NavBar"; -import { ThemeProvider } from "./theme/ThemeProvider"; -import { UserProvider } from "./user/UserProvider"; +import { UserContext } from "./user/UserProvider"; +import { WelcomePage } from "./WelcomePage"; export const App = () => { + const { + userState: { user, loading }, + } = useContext(UserContext); + return ( - - - - - + <> + + + + {user !== undefined ? ( - - - - + ) : ( + <> + + + + )} + + + ); }; + +// TODO: Add link to the github repo diff --git a/vinvoor/src/WelcomePage.tsx b/vinvoor/src/WelcomePage.tsx new file mode 100644 index 0000000..c8cd2f7 --- /dev/null +++ b/vinvoor/src/WelcomePage.tsx @@ -0,0 +1,49 @@ +import { GitHub } from "@mui/icons-material"; +import { Box, Button, Typography } from "@mui/material"; +import { ShakerOutline } from "mdi-material-ui"; +import { TypographyG } from "./components/TypographyG"; +import { UnstyledLink } from "./components/UnstyledLink"; + +declare module "@mui/material/Button" { + interface ButtonPropsColorOverrides { + github: true; + } +} + +export const WelcomePage = () => { + const handleClick = () => { + window.location.replace("https://github.com/ZeusWPI/ZeSS"); + }; + + return ( + + Welcome to Vinvoor! + Log in to start scanning + + + + + + ); +}; diff --git a/vinvoor/src/leaderboard/LeaderboardTableToolbar.tsx b/vinvoor/src/leaderboard/LeaderboardTableToolbar.tsx index 4bd090f..44f9103 100644 --- a/vinvoor/src/leaderboard/LeaderboardTableToolbar.tsx +++ b/vinvoor/src/leaderboard/LeaderboardTableToolbar.tsx @@ -9,7 +9,9 @@ interface LeaderboardTableToolbarProps {} export const LeaderboardTableToolbar: FC< LeaderboardTableToolbarProps > = ({}) => { - const { user } = useContext(UserContext); + const { + userState: { user }, + } = useContext(UserContext); return ( diff --git a/vinvoor/src/main.tsx b/vinvoor/src/main.tsx index ea7dba5..8f070ec 100644 --- a/vinvoor/src/main.tsx +++ b/vinvoor/src/main.tsx @@ -2,6 +2,7 @@ import "@fontsource/roboto/300.css"; import "@fontsource/roboto/400.css"; import "@fontsource/roboto/500.css"; import "@fontsource/roboto/700.css"; +import { CssBaseline } from "@mui/material"; import React from "react"; import ReactDOM from "react-dom/client"; import { createBrowserRouter, RouterProvider } from "react-router-dom"; @@ -9,8 +10,10 @@ import { App } from "./App.tsx"; import { Cards } from "./cards/Cards.tsx"; import { ErrorPage } from "./errors/ErrorPage.tsx"; import { Leaderboard } from "./leaderboard/Leaderboard.tsx"; +import { ThemeProvider } from "./theme/ThemeProvider"; import { Login } from "./user/Login.tsx"; import { Logout } from "./user/Logout.tsx"; +import { UserProvider } from "./user/UserProvider.tsx"; const router = createBrowserRouter([ { @@ -18,10 +21,6 @@ const router = createBrowserRouter([ element: , errorElement: , children: [ - { - path: "login", - element: , - }, { path: "logout", element: , @@ -36,10 +35,21 @@ const router = createBrowserRouter([ }, ], }, + { + path: "/login", + element: , + errorElement: , + }, ]); ReactDOM.createRoot(document.getElementById("root")!).render( - + + + + + + + ); diff --git a/vinvoor/src/navbar/NavBar.tsx b/vinvoor/src/navbar/NavBar.tsx index 4608b3b..be65857 100644 --- a/vinvoor/src/navbar/NavBar.tsx +++ b/vinvoor/src/navbar/NavBar.tsx @@ -11,7 +11,9 @@ const pages = ["Cards", "Leaderboard"]; const settings = ["Logout"]; export const NavBar = () => { - const { user } = useContext(UserContext); + const { + userState: { user }, + } = useContext(UserContext); const screenSize = { mobile: { xs: "flex", md: "none" }, diff --git a/vinvoor/src/navbar/NavBarUserMenu.tsx b/vinvoor/src/navbar/NavBarUserMenu.tsx index 1eb6bd6..8d64df7 100644 --- a/vinvoor/src/navbar/NavBarUserMenu.tsx +++ b/vinvoor/src/navbar/NavBarUserMenu.tsx @@ -9,7 +9,9 @@ interface NavBarUserMenuProps { } export const NavBarUserMenu: FC = ({ settings }) => { - const { user } = useContext(UserContext); + const { + userState: { user }, + } = useContext(UserContext); const [anchorElUser, setAnchorElUser] = useState( undefined ); diff --git a/vinvoor/src/theme/theme.ts b/vinvoor/src/theme/theme.ts index 072d299..fca57c3 100644 --- a/vinvoor/src/theme/theme.ts +++ b/vinvoor/src/theme/theme.ts @@ -9,6 +9,9 @@ export const lightTheme = createTheme({ secondary: { main: "#002379", }, + github: { + main: "#FFF4F2", + }, }, }); @@ -21,6 +24,9 @@ export const darkTheme = createTheme({ secondary: { main: "#002379", }, + github: { + main: "#996860", + }, }, components: { MuiAppBar: { @@ -32,3 +38,13 @@ export const darkTheme = createTheme({ }, }, }); + +declare module "@mui/material/styles" { + interface Palette { + github: Palette["primary"]; + } + + interface PaletteOptions { + github?: PaletteOptions["primary"]; + } +} diff --git a/vinvoor/src/user/Login.tsx b/vinvoor/src/user/Login.tsx index a19456b..97276ee 100644 --- a/vinvoor/src/user/Login.tsx +++ b/vinvoor/src/user/Login.tsx @@ -4,7 +4,7 @@ export const Login = () => { const baseUrl = import.meta.env.VITE_BASE_URL; useEffect(() => { - window.location.href = `${baseUrl}/login`; + window.location.replace(`${baseUrl}/login`); }, []); return <>; diff --git a/vinvoor/src/user/Logout.tsx b/vinvoor/src/user/Logout.tsx index 9009a6d..f4b8222 100644 --- a/vinvoor/src/user/Logout.tsx +++ b/vinvoor/src/user/Logout.tsx @@ -4,7 +4,7 @@ export const Logout = () => { const baseUrl = import.meta.env.VITE_BASE_URL; useEffect(() => { - window.location.href = `${baseUrl}/logout`; + window.location.replace(`${baseUrl}/logout`); }, []); return <>; diff --git a/vinvoor/src/user/UserProvider.tsx b/vinvoor/src/user/UserProvider.tsx index 6f3a86f..7577470 100644 --- a/vinvoor/src/user/UserProvider.tsx +++ b/vinvoor/src/user/UserProvider.tsx @@ -15,33 +15,60 @@ interface UserProviderProps { children: ReactNode; } -interface UserContextProps { +interface UserState { user: User | undefined; - setUser: Dispatch>; + loading: boolean; + error: Error | undefined; } -export const UserContext = createContext({ +interface UserContextProps { + userState: UserState; + setUserState: Dispatch>; +} + +const defaultUserState: UserState = { user: undefined, - setUser: () => {}, + loading: true, + error: undefined, +}; + +export const UserContext = createContext({ + userState: defaultUserState, + setUserState: () => {}, }); export const UserProvider: FC = ({ children }) => { - const [user, setUser] = useState(undefined); + const [userState, setUserState] = useState(defaultUserState); useEffect(() => { const sessionId = Cookies.get("session_id"); if (!sessionId) { + setUserState({ + user: undefined, + loading: false, + error: new Error("No session ID"), + }); + return; } + let newUserState = { ...userState }; + fetchApi("user") - .then((data) => setUser(data)) - .catch(() => Cookies.remove("session_id")); + .then((data) => (newUserState.user = data)) + .catch((error) => { + Cookies.remove("session_id"); + newUserState.error = error; + }) + .finally(() => { + newUserState.loading = false; + setUserState(newUserState); + }); }, []); return ( - + {children} );