diff --git a/backend/src/main.rs b/backend/src/main.rs
index 1e641af..69fae17 100644
--- a/backend/src/main.rs
+++ b/backend/src/main.rs
@@ -85,23 +85,51 @@ fn get_users(
#[get("/game/
")]
fn get_game(
_token: auth::Token,
- game_list: &rocket::State>,
+ game_list: &rocket::State>>,
title: &str,
) -> Option {
- game_list.iter().find(|g| g.title == title).cloned()
+ let games = game_list.lock().unwrap();
+ games.iter().find(|g| g.title == title).cloned()
+}
+
+#[post("/game", data = "")]
+fn add_game(
+ _token: auth::Token,
+ game_list: &rocket::State>>,
+ user_list: &rocket::State>>,
+ game: proto_utils::Proto,
+) -> Option {
+ let mut games = game_list.lock().unwrap();
+ let game = game.into_inner();
+
+ if games.iter().any(|g| g.title == game.title) {
+ return None;
+ }
+
+ games.push(game.clone());
+
+ let users = user_list.lock().unwrap();
+ save_state(&games, &users);
+
+ Some(game)
}
#[post("/opinion", data = "")]
fn add_opinion(
token: auth::Token,
-
user_list: &rocket::State>>,
- game_list: &rocket::State>,
+ game_list: &rocket::State>>,
req: proto_utils::Proto,
) -> Option {
let mut users = user_list.lock().unwrap();
+ let games = game_list.lock().unwrap();
let mut result = None;
+ // Validate game exists
+ if !games.iter().any(|g| g.title == req.game_title) {
+ return None;
+ }
+
if let Some(user) = users.iter_mut().find(|u| u.person.name == token.username) {
let req = req.into_inner();
let opinion = items::Opinion {
@@ -123,7 +151,7 @@ fn add_opinion(
}
if result.is_some() {
- save_state(game_list, &users);
+ save_state(&games, &users);
}
result
}
@@ -172,8 +200,11 @@ async fn main() -> Result<(), std::io::Error> {
rocket::build()
.manage(Mutex::new(user_list))
.manage(auth::AuthState::new())
- .manage(game_list)
- .mount("/api", routes![get_users, get_user, get_game, add_opinion])
+ .manage(Mutex::new(game_list))
+ .mount(
+ "/api",
+ routes![get_users, get_user, get_game, add_opinion, add_game],
+ )
.mount(
"/auth",
routes![auth::login, auth::logout, auth::get_auth_status],
diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx
index 2d9a9b8..ae27d2b 100644
--- a/frontend/src/App.tsx
+++ b/frontend/src/App.tsx
@@ -3,6 +3,7 @@ import { Person, PersonList as PersonListProto } from "../items";
import { Login } from "./Login";
import { PersonList } from "./PersonList";
import { PersonDetails } from "./PersonDetails";
+import { GameList } from "./GameList";
import { BrowserRouter, Routes, Route, Link } from "react-router-dom";
import "./App.css";
import { apiFetch } from "./api";
@@ -52,14 +53,28 @@ function App() {
}}
>
-
+
People List
+
+ Games
+
} />
+ } />
} />
diff --git a/frontend/src/GameList.tsx b/frontend/src/GameList.tsx
new file mode 100644
index 0000000..a5bd135
--- /dev/null
+++ b/frontend/src/GameList.tsx
@@ -0,0 +1,126 @@
+import { useState } from "react";
+import { Game, Source } from "../items";
+import { apiFetch } from "./api";
+
+export function GameList() {
+ const [title, setTitle] = useState("");
+ const [source, setSource] = useState(Source.STEAM);
+ const [multiplayer, setMultiplayer] = useState(false);
+ const [minPlayers, setMinPlayers] = useState(1);
+ const [maxPlayers, setMaxPlayers] = useState(1);
+ const [price, setPrice] = useState(0);
+ const [remoteId, setRemoteId] = useState(0);
+ const [message, setMessage] = useState("");
+
+ const handleSubmit = async (e: React.FormEvent) => {
+ e.preventDefault();
+ const game = {
+ title,
+ source,
+ multiplayer,
+ minPlayers,
+ maxPlayers,
+ price,
+ remoteId,
+ };
+
+ try {
+ const encoded = Game.encode(game).finish();
+ const res = await apiFetch("/api/game", {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/octet-stream",
+ },
+ body: encoded,
+ });
+
+ if (res.ok) {
+ setMessage("Game added successfully!");
+ setTitle("");
+ // Reset other fields if needed
+ } else {
+ setMessage("Failed to add game.");
+ }
+ } catch (err) {
+ console.error(err);
+ setMessage("Error adding game.");
+ }
+ };
+
+ return (
+
+
Add New Game
+ {message &&
{message}
}
+
+
+ );
+}
diff --git a/protobuf/items.proto b/protobuf/items.proto
index c4c68b7..49ffb1e 100644
--- a/protobuf/items.proto
+++ b/protobuf/items.proto
@@ -71,5 +71,6 @@ message AddOpinionRequest {
service MainService {
rpc GetGame(GameRequest) returns (Game);
+ rpc AddGame(Game) returns (Game);
rpc AddOpinion(AddOpinionRequest) returns (Person);
}
\ No newline at end of file