diff options
Diffstat (limited to 'react-frontend/src')
| -rw-r--r-- | react-frontend/src/App.tsx | 37 | ||||
| -rw-r--r-- | react-frontend/src/components/Layout.tsx | 46 | ||||
| -rw-r--r-- | react-frontend/src/index.css | 70 | ||||
| -rw-r--r-- | react-frontend/src/main.tsx | 1 | ||||
| -rw-r--r-- | react-frontend/src/pages/CloseWindow.tsx | 19 | ||||
| -rw-r--r-- | react-frontend/src/pages/Home.tsx | 10 | ||||
| -rw-r--r-- | react-frontend/src/routes/index.tsx | 40 |
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> + </>); +} |
