102 lines
3.0 KiB
TypeScript

import { useState, useEffect } from "react";
import { Person, PersonList as PersonListProto } from "../items";
import { Login } from "./Login";
import { PersonList } from "./PersonList";
import { PersonDetails } from "./PersonDetails";
import { GameList } from "./GameList";
import { GameFilter } from "./GameFilter";
import { GameDetails } from "./GameDetails";
import { ShaderBackground } from "./ShaderBackground";
import { BrowserRouter, Routes, Route, Link } from "react-router-dom";
import "./App.css";
import { apiFetch } from "./api";
function App() {
const [people, setPeople] = useState<Person[]>([]);
const [token, setToken] = useState<string>(
localStorage.getItem("token") || ""
);
const [theme, setTheme] = useState<string>("default");
const [isShaderTheme, setIsShaderTheme] = useState(false);
useEffect(() => {
if (theme !== "default") {
document.body.classList.add("shader-theme");
setIsShaderTheme(true);
} else {
document.body.classList.remove("shader-theme");
setIsShaderTheme(false);
}
}, [theme]);
const fetchPeople = () => {
if (!token) return;
apiFetch("/api")
.then((res) => res.arrayBuffer())
.then((buffer) => {
const list = PersonListProto.decode(new Uint8Array(buffer));
setPeople(list.person);
})
.catch((err) => console.error("Failed to fetch people:", err));
};
useEffect(() => {
fetchPeople();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [token]);
const handleLogin = (newToken: string) => {
setToken(newToken);
localStorage.setItem("token", newToken);
};
const handleLogout = () => {
setToken("");
setPeople([]);
localStorage.removeItem("token");
};
if (!token) {
return <Login onLogin={handleLogin} />;
}
return (
<BrowserRouter>
<div className="card">
<div className="navbar">
<div className="nav-links">
<Link to="/" className="nav-link">
People List
</Link>
<Link to="/games" className="nav-link">
Games
</Link>
<Link to="/filter" className="nav-link">
Filter
</Link>
</div>
<button onClick={handleLogout} className="btn-secondary">
Logout
</button>
<select value={theme} onChange={(e) => setTheme(e.target.value)}>
<option value="default">Default Theme</option>
<option value="blackhole">Blackhole Theme</option>
<option value="star">Star Theme</option>
</select>
</div>
{isShaderTheme && <ShaderBackground theme= {theme} />}
<Routes>
<Route path="/" element={<PersonList people={people} />} />
<Route path="/games" element={<GameList />} />
<Route path="/filter" element={<GameFilter />} />
<Route path="/person/:name" element={<PersonDetails />} />
<Route path="/game/:title" element={<GameDetails />} />
</Routes>
</div>
</BrowserRouter>
);
}
export default App;