From 03de0736920efe5c0ef2435e4115be81819361c2 Mon Sep 17 00:00:00 2001 From: code002lover Date: Thu, 4 Dec 2025 20:30:21 +0100 Subject: [PATCH] feat: Add API to retrieve authentication status and display user game opinions with colored borders in the game list. --- frontend/src/GameList.tsx | 71 ++++++++++++++++++++++++---------- frontend/src/PersonDetails.tsx | 42 +++++--------------- frontend/src/api.ts | 23 +++++++++++ 3 files changed, 83 insertions(+), 53 deletions(-) diff --git a/frontend/src/GameList.tsx b/frontend/src/GameList.tsx index f4aba16..3caddcd 100644 --- a/frontend/src/GameList.tsx +++ b/frontend/src/GameList.tsx @@ -1,7 +1,13 @@ import { useState, useEffect } from "react"; -import { Game, Source, GameList as GameListProto } from "../items"; +import { + Game, + Source, + GameList as GameListProto, + Person as PersonProto, + Opinion, +} from "../items"; import { Link } from "react-router-dom"; -import { apiFetch } from "./api"; +import { apiFetch, get_auth_status } from "./api"; import { GameImage } from "./GameImage"; export function GameList() { @@ -14,6 +20,7 @@ export function GameList() { const [remoteId, setRemoteId] = useState(0); const [message, setMessage] = useState(""); const [isSubmitting, setIsSubmitting] = useState(false); + const [opinions, setOpinions] = useState([]); const fetchGames = () => { apiFetch("/api/games") @@ -29,6 +36,22 @@ export function GameList() { .catch(console.error); }; + useEffect(() => { + get_auth_status().then((user) => { + apiFetch(`/api/${user?.username}`) + .then((res) => res.arrayBuffer()) + .then((buffer) => { + try { + const person = PersonProto.decode(new Uint8Array(buffer)); + const opinions = person.opinion; + setOpinions(opinions); + } catch (e) { + console.error("Failed to decode games:", e); + } + }); + }); + }, []); + useEffect(() => { fetchGames(); }, []); @@ -365,7 +388,7 @@ export function GameList() {
- +

Existing Games

    - {games.map((game) => ( - - {game.title} - - - ))} + {games.map((game) => { + const opinion = opinions.find((op) => op.title === game.title); + return ( + + {game.title} + + + ); + })}
diff --git a/frontend/src/PersonDetails.tsx b/frontend/src/PersonDetails.tsx index ce67ffc..7e48124 100644 --- a/frontend/src/PersonDetails.tsx +++ b/frontend/src/PersonDetails.tsx @@ -1,14 +1,7 @@ import { useState, useEffect } from "react"; import { Link, useParams } from "react-router-dom"; -import { - Person, - AddOpinionRequest, - Game, - GameList, - AuthStatusRequest, - AuthStatusResponse, -} from "../items"; -import { apiFetch } from "./api"; +import { Person, AddOpinionRequest, Game, GameList } from "../items"; +import { apiFetch, get_auth_status } from "./api"; import { GameImage } from "./GameImage"; export const PersonDetails = () => { @@ -20,31 +13,14 @@ export const PersonDetails = () => { const [currentUser, setCurrentUser] = useState(""); useEffect(() => { - const token = localStorage.getItem("token"); - if (token) { - const req = AuthStatusRequest.create({ token }); - const buffer = AuthStatusRequest.encode(req).finish(); - - apiFetch("/auth/get_auth_status", { - method: "POST", - headers: { - "Content-Type": "application/octet-stream", - }, - body: buffer, - }) - .then((res) => res.arrayBuffer()) - .then((buffer) => { - try { - const response = AuthStatusResponse.decode(new Uint8Array(buffer)); - if (response.authenticated) { - setCurrentUser(response.username); - } - } catch (e) { - console.error("Failed to decode auth status:", e); - } - }) - .catch(console.error); + async function fetchUser() { + const token = localStorage.getItem("token"); + if (token) { + const authStatus = await get_auth_status(); + setCurrentUser(authStatus?.username || ""); + } } + fetchUser(); }, []); useEffect(() => { diff --git a/frontend/src/api.ts b/frontend/src/api.ts index 545c1c3..1e06bd7 100644 --- a/frontend/src/api.ts +++ b/frontend/src/api.ts @@ -1,3 +1,5 @@ +import { AuthStatusRequest, AuthStatusResponse } from "../items"; + export const apiFetch = async ( url: string, options: RequestInit = {} @@ -26,3 +28,24 @@ export const apiFetch = async ( return response; }; + +export const get_auth_status = async (): Promise => { + const token = localStorage.getItem("token") as string; + const req = AuthStatusRequest.create({ token }); + const req_buffer = AuthStatusRequest.encode(req).finish(); + const response = await apiFetch("/auth/get_auth_status", { + method: "POST", + headers: { + "Content-Type": "application/octet-stream", + }, + body: req_buffer, + }); + const buffer = await response.arrayBuffer(); + try { + const response = AuthStatusResponse.decode(new Uint8Array(buffer)); + return response; + } catch (e) { + console.error("Failed to decode auth status:", e); + return null; + } +};