diff --git a/components/saved-games/saved-games-grid.tsx b/components/saved-games/saved-games-grid.tsx new file mode 100644 index 0000000..2ea5a7d --- /dev/null +++ b/components/saved-games/saved-games-grid.tsx @@ -0,0 +1,133 @@ +"use client" + +import { useState, useEffect } from "react" +import Image from "next/image" +import Link from "next/link" +import { Bookmark, Loader2, X, Gamepad2 } from "lucide-react" +import { motion, AnimatePresence } from "motion/react" + +interface SavedGame { + id: string + gameId: string + createdAt: string + gameTitle: string + gameHeaderImage: string | null + gameCapsuleImage: string | null + gameSteamAppId: number | null +} + +export function SavedGamesGrid() { + const [games, setGames] = useState([]) + const [isLoading, setIsLoading] = useState(true) + const [removingId, setRemovingId] = useState(null) + + useEffect(() => { + async function fetchSaved() { + try { + const res = await fetch("/api/user/me/saved-games") + if (res.ok) { + setGames(await res.json()) + } + } catch (err) { + console.error("Failed to fetch saved games:", err) + } finally { + setIsLoading(false) + } + } + + fetchSaved() + }, []) + + const removeGame = async (id: string, gameId: string) => { + setRemovingId(id) + try { + const res = await fetch(`/api/user/me/saved-games/${gameId}`, { + method: "DELETE", + }) + if (res.ok) { + setGames((prev) => prev.filter((g) => g.id !== id)) + } + } catch (err) { + console.error("Failed to remove saved game:", err) + } finally { + setRemovingId(null) + } + } + + if (isLoading) { + return ( +
+ +
+ ) + } + + if (games.length === 0) { + return ( +
+ +

No saved games yet

+

+ Save games from their detail pages to see them here +

+
+ ) + } + + return ( +
+ + {games.map((game) => ( + + + {game.gameHeaderImage ? ( + {game.gameTitle} + ) : ( +
+ +
+ )} +
+

+ {game.gameTitle} +

+

+ Saved {new Date(game.createdAt).toLocaleDateString()} +

+
+ + + +
+ ))} +
+
+ ) +}