summaryrefslogtreecommitdiffhomepage
path: root/react-frontend/src
diff options
context:
space:
mode:
Diffstat (limited to 'react-frontend/src')
-rw-r--r--react-frontend/src/App.tsx37
-rw-r--r--react-frontend/src/components/Layout.tsx46
-rw-r--r--react-frontend/src/index.css70
-rw-r--r--react-frontend/src/main.tsx1
-rw-r--r--react-frontend/src/pages/CloseWindow.tsx19
-rw-r--r--react-frontend/src/pages/Home.tsx10
-rw-r--r--react-frontend/src/routes/index.tsx40
7 files changed, 124 insertions, 99 deletions
diff --git a/react-frontend/src/App.tsx b/react-frontend/src/App.tsx
index b2ba1e4..92de410 100644
--- a/react-frontend/src/App.tsx
+++ b/react-frontend/src/App.tsx
@@ -1,36 +1,5 @@
-import { useState } from 'react'
-import reactLogo from './assets/react.svg'
-import viteLogo from '/vite.svg'
-import './App.css'
+import Routes from "./routes"
-function App() {
- const [count, setCount] = useState(0)
-
- return (
- <>
- <div>
- <a href="https://vitejs.dev" target="_blank">
- <img src={viteLogo} className="logo" alt="Vite logo" />
- </a>
- <a href="https://react.dev" target="_blank">
- <img src={reactLogo} className="logo react" alt="React logo" />
- </a>
- </div>
- <h1>Game Holster</h1>
- <h2>Temp Page</h2>
- <div className="card">
- <button onClick={() => setCount((count) => count + 1)}>
- count is {count}
- </button>
- <p>
- Edit <code>src/App.tsx</code> and save to test HMR
- </p>
- </div>
- <p className="read-the-docs">
- Click on the Vite and React logos to learn more
- </p>
- </>
- )
+export default function App() {
+ return (<Routes />);
}
-
-export default App
diff --git a/react-frontend/src/components/Layout.tsx b/react-frontend/src/components/Layout.tsx
new file mode 100644
index 0000000..8f834ef
--- /dev/null
+++ b/react-frontend/src/components/Layout.tsx
@@ -0,0 +1,46 @@
+import { Outlet } from "react-router-dom";
+import { useState } from "react";
+import { IconButton, Button, ButtonGroup } from 'rsuite';
+import { Icon } from '@rsuite/icons';
+import { FaUser } from "react-icons/fa6";
+import { FaGamepad } from "react-icons/fa";
+import { GiCowboyHolster } from "react-icons/gi";
+import { GrAdd } from "react-icons/gr";
+
+export type userData = { userData: { name: string } };
+
+ //{ userData.name ? <div className="flex items-end gap-2 pb-2"> <div className="text-xs"> Logged in as: </div> <div>{userData.name}</div> </div> : <a href="" onClick={loginLink} className="pb-2"> Login with Github </a> }
+
+
+export default function Layout({userData} : userData)
+{
+ const loginLink = () => {
+ window.open(`https://github.com/login/oauth/authorize?client_id=${import.meta.env.VITE_GITHUB_CLIENTID}`);
+ };
+
+
+ const loggedout_element = <IconButton onClick={loginLink} appearance="primary" color="green" icon={<Icon as={FaUser}/>}>Log In</IconButton>;
+ const loggedin_element = <ButtonGroup className="flex"><Button appearance="ghost" style={{width:"100%"}}>{userData.name}</Button><Button appearance="subtle" style={{paddingLeft:"1.4em", paddingRight:"1.4em"}}>Log Out</Button></ButtonGroup>;
+
+ return(
+ <>
+ <div className="w-screen h-screen flex border-none">
+ <div className="flex flex-col h-screen overflow-y-auto overflow-x-hidden w-72 bg-stone-100">
+ <div className="flex flex-col bg-stone-800">
+ <div className="m-4 mb-0 flex flex-col flex-grow">
+ { userData.name ? loggedin_element : loggedout_element }
+ </div>
+ </div>
+ <div className="border-green-500 p-2 mb-2 text-red-700 bg-stone-800 rounded-b-xl"><Icon as={GiCowboyHolster} style={{width:"100%", height:"100%"}}/></div>
+ <div className="flex flex-col px-4 gap-2">
+ <IconButton appearance="subtle" size="lg" icon={<Icon as={FaGamepad}/>}>Browse Games</IconButton>
+ <IconButton appearance="subtle" size="lg" icon={<Icon as={GrAdd}/>}>Upload Game</IconButton>
+ </div>
+ </div>
+ <div className="w-full">
+ <Outlet/>
+ </div>
+ </div>
+ </>
+ );
+}
diff --git a/react-frontend/src/index.css b/react-frontend/src/index.css
index 6119ad9..ac216f5 100644
--- a/react-frontend/src/index.css
+++ b/react-frontend/src/index.css
@@ -1,68 +1,8 @@
-:root {
- font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
- line-height: 1.5;
- font-weight: 400;
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
- color-scheme: light dark;
- color: rgba(255, 255, 255, 0.87);
- background-color: #242424;
-
- font-synthesis: none;
- text-rendering: optimizeLegibility;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
-}
-
-a {
- font-weight: 500;
- color: #646cff;
- text-decoration: inherit;
-}
-a:hover {
- color: #535bf2;
+* {
+ /*border: 1px solid red;*/
}
-body {
- margin: 0;
- display: flex;
- place-items: center;
- min-width: 320px;
- min-height: 100vh;
-}
-
-h1 {
- font-size: 3.2em;
- line-height: 1.1;
-}
-
-button {
- border-radius: 8px;
- border: 1px solid transparent;
- padding: 0.6em 1.2em;
- font-size: 1em;
- font-weight: 500;
- font-family: inherit;
- background-color: #1a1a1a;
- cursor: pointer;
- transition: border-color 0.25s;
-}
-button:hover {
- border-color: #646cff;
-}
-button:focus,
-button:focus-visible {
- outline: 4px auto -webkit-focus-ring-color;
-}
-
-@media (prefers-color-scheme: light) {
- :root {
- color: #213547;
- background-color: #ffffff;
- }
- a:hover {
- color: #747bff;
- }
- button {
- background-color: #f9f9f9;
- }
-}
diff --git a/react-frontend/src/main.tsx b/react-frontend/src/main.tsx
index 3d7150d..4ec8a7d 100644
--- a/react-frontend/src/main.tsx
+++ b/react-frontend/src/main.tsx
@@ -1,6 +1,7 @@
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.tsx'
+import 'rsuite/dist/rsuite-no-reset.min.css';
import './index.css'
ReactDOM.createRoot(document.getElementById('root')!).render(
diff --git a/react-frontend/src/pages/CloseWindow.tsx b/react-frontend/src/pages/CloseWindow.tsx
new file mode 100644
index 0000000..b92d77e
--- /dev/null
+++ b/react-frontend/src/pages/CloseWindow.tsx
@@ -0,0 +1,19 @@
+
+export default function CloseWindow () {
+
+ // trigger localStorage listener in other tabs.
+ // this forces react rerender where required.
+ localStorage.setItem("logged in trigger", String(Math.random()));
+ // close window once done
+ window.close();
+
+ // window can only be closed if it was opened by javascript.
+ // if the window was opened by a user then just redirect to
+ // the home page instead.
+ window.location.replace("/");
+
+ return(
+ <>
+ </>
+ );
+}
diff --git a/react-frontend/src/pages/Home.tsx b/react-frontend/src/pages/Home.tsx
new file mode 100644
index 0000000..2f15dd3
--- /dev/null
+++ b/react-frontend/src/pages/Home.tsx
@@ -0,0 +1,10 @@
+
+export default function Home() {
+ return(
+ <>
+ <div className="flex justify-center p-4">
+ <h1 className="font-title text-6xl">Welcome to Game Holster</h1>
+ </div>
+ </>
+ );
+}
diff --git a/react-frontend/src/routes/index.tsx b/react-frontend/src/routes/index.tsx
new file mode 100644
index 0000000..e22bcc4
--- /dev/null
+++ b/react-frontend/src/routes/index.tsx
@@ -0,0 +1,40 @@
+import { useState, useEffect } from "react";
+import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
+import Home from "../pages/Home";
+import Layout from "../components/Layout";
+import CloseWindow from "../pages/CloseWindow";
+
+export default function Index()
+{
+
+ const [userData, setUserData] = useState({ name: '' });
+ useEffect(() => {
+ const update_login_status = () => {
+ //localStorage.removeItem("logged in trigger");
+ const url = `${import.meta.env.VITE_API_TITLE}/api/v1/auth/data`;
+ try { fetch(url, {
+ credentials: "include"
+ }).then((response) => {
+ if(response.ok) {
+ return response.json();
+ }
+ //throw new Error("Network response was not ok.");
+ }).then((response) => response && setUserData(response.user_data)).catch((err) => { console.log(err); });}
+ catch(err) { console.log(err); }
+ };
+ window.addEventListener('storage', update_login_status );
+ update_login_status();
+ return () => { window.removeEventListener('storage', update_login_status); };
+ }, []);
+
+ return (<>
+ <Router>
+ <Routes>
+ <Route path="/" element = {<Layout userData={userData}/>}>
+ <Route index element={<Home />} />
+ <Route path="/closewindow" element={<CloseWindow />} />
+ </Route>
+ </Routes>
+ </Router>
+ </>);
+}