diff --git a/app/(content)/(gaming)/games/[gameid]/page.tsx b/app/(content)/(gaming)/games/[gameid]/page.tsx index 20d751b75a932a20817380767d01bd898f1dcb6b..65e4ba58f2a688ffccd15b19c7f588fe9e6d15f4 100644 --- a/app/(content)/(gaming)/games/[gameid]/page.tsx +++ b/app/(content)/(gaming)/games/[gameid]/page.tsx @@ -1,10 +1,13 @@ +import AddGameToList from "@/components/addGameToList"; import { AspectRatio } from "@/components/ui/aspect-ratio"; import { Button } from "@/components/ui/button"; import { Card } from "@/components/ui/card"; import { getGame } from "@/lib/igdb"; +import { getCurrentUser } from "@/lib/session"; import { formatDate } from "@/lib/utils"; import { IGame } from "@/types/igdb-types"; import Image from "next/image"; +import { db } from "@/lib/db"; // renders a single game detail page export default async function GameDetail({ params }: { params: { gameid: string } }) { @@ -12,6 +15,16 @@ export default async function GameDetail({ params }: { params: { gameid: string const date = formatDate(data[0].first_release_date * 1000) + const user = await getCurrentUser() + const fullUser = await db.user.findFirst({ + where: { + id: user?.id + } + }) + + + /* console.log(user) */ + const companies = data[0].involved_companies.map((company) => { if (company !== data[0].involved_companies[0]) { return `, ${company.company.name}` @@ -20,7 +33,9 @@ export default async function GameDetail({ params }: { params: { gameid: string }) return ( + <div className="main-content h-full"> + <Card className="w-full h-full overflow-hidden"> <div className="h-64 overflow-hidden"> <AspectRatio ratio={889 / 500}> @@ -93,6 +108,7 @@ export default async function GameDetail({ params }: { params: { gameid: string </div> </Card> </div> + <AddGameToList userGameList={fullUser?.favGameList!} gameId={params.gameid} /> </div > ) } \ No newline at end of file diff --git a/app/(content)/(user)/[userid]/page.tsx b/app/(content)/(user)/[userid]/page.tsx index d4b50066daf5a9f30224779a5ee4d38a42c9bbd4..e59fb23e2e2758881bf78a2d596074c269f577c3 100644 --- a/app/(content)/(user)/[userid]/page.tsx +++ b/app/(content)/(user)/[userid]/page.tsx @@ -1,8 +1,12 @@ +import GameItem from "@/components/game-item" import { AspectRatio } from "@/components/ui/aspect-ratio" import { Card } from "@/components/ui/card" import { Skeleton } from "@/components/ui/skeleton" import { UserAvatar } from "@/components/user-avatar" +import { db } from "@/lib/db" +import { getFavoriteGames } from "@/lib/igdb" import { getCurrentUser } from "@/lib/session" +import { IGame } from "@/types/igdb-types" import { redirect } from "next/navigation" export default async function User({ params }: { params: { userid: string } }) { @@ -11,6 +15,13 @@ export default async function User({ params }: { params: { userid: string } }) { if (user?.username !== params.userid) { redirect('/') } + const fullUser = await db.user.findFirst({ + where: { + id: user?.id + } + }) + + const favoritegames = await getFavoriteGames(fullUser?.favGameList!) return ( <div className="main-content h-full"> @@ -54,6 +65,19 @@ export default async function User({ params }: { params: { userid: string } }) { </div> </Card> </div> + + <Card className="w-full h-full overflow-hidden p-6 md:p-12" > + <h1 className="text-2xl font-bold pb-3">Your Favorite Games</h1> + <div className="grid grid-cols-1 ss:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5 gap-4 lg:gap-8 items-center"> + {favoritegames ? favoritegames.map((game: IGame) => ( + <GameItem id={game.id} name={game.name} cover={game.cover} key={game.id} /> + )) + : + <p>You have no favorites currently</p>} + </div> + </Card> </div > + + ) } \ No newline at end of file diff --git a/app/api/gameList/route.ts b/app/api/gameList/route.ts index 8c14bc22c5fd90324e949ac411176b0fd4c946db..0f7489ede768fe669546f0bfa207aee40da2daba 100644 --- a/app/api/gameList/route.ts +++ b/app/api/gameList/route.ts @@ -11,21 +11,46 @@ export async function PUT(req: NextRequest) { } const userId = user.id; - const content = await req.json() - - console.log(content); + const data = await req.json() + data.gameId = parseInt(data.gameId) + console.log(data); console.log(userId); try { - await db.user.update({ - where:{ - id: userId - }, - data: { - favGameList:{ - push: content.gameId - } - } - }) + if (data.add) { + console.log("add true") + await db.user.update({ + where: { + id: userId + }, + data: { + favGameList: { + push: data.gameId + } + } + }) + console.log("gameList updated") + } else { + const user = await db.user.findFirst({ + where: { + id: userId + }, + select: { + favGameList: true + }, + }); + + await db.user.update({ + where: { + id: userId + }, + data: { + favGameList: { + set: user?.favGameList.filter((id) => id !== data.gameId), + } + } + }) + } + const path = req.nextUrl.searchParams.get('path') || '/'; revalidatePath(path); diff --git a/components/addGameToList.tsx b/components/addGameToList.tsx index 74ed545b1c2b6593509445e36446b27c8db01b82..c40c4b9abdbe8f995f85a4fee5e60211024947ba 100644 --- a/components/addGameToList.tsx +++ b/components/addGameToList.tsx @@ -4,17 +4,35 @@ import { Post, Prisma } from "@prisma/client"; import { useRouter } from "next/navigation"; import { startTransition, useEffect, useState } from "react"; -export default function AddGameToList(props: { userid: string, gameId: string }) { +export default function AddGameToList(props: { userGameList: Number[], gameId: string }) { const router = useRouter(); const gameId = props.gameId - let formData = {gameId} + let formData = { gameId: "", add: true } - async function addGame(e: any) { + async function removeGame(e: any) { e.preventDefault() formData.gameId = gameId; + formData.add = false; + const response = await fetch('http://localhost:3000/api/gameList', { + method: 'PUT', + body: JSON.stringify(formData) + }) + startTransition(() => { + // Refresh the current route and fetch new data from the server without + // losing client-side browser or React state. + router.refresh(); + }); + return await response.json() + } + + async function addGame(e: any) { + e.preventDefault() + + formData.gameId = gameId; + formData.add = true; const response = await fetch('http://localhost:3000/api/gameList', { method: 'PUT', body: JSON.stringify(formData) @@ -28,9 +46,33 @@ export default function AddGameToList(props: { userid: string, gameId: string }) return await response.json() } + + let button = <div></div>; + try { + if (!props.userGameList.includes(parseFloat(props.gameId))) { + + button = ( + <form onSubmit={addGame}> + <button type="submit" className="mt-2 bg-gray-300 text-gray-800 px-4 py-2 rounded float-right"> + AddGame + </button> + </form> + ) + } else { + button = ( + <form onSubmit={removeGame}> + <button type="submit" className="mt-2 bg-gray-300 text-gray-800 px-4 py-2 rounded float-right"> + Remove Game + </button> + </form> + ) + } + } catch (error) { + + } + return ( - <button type="submit" className="mt-2 bg-gray-300 text-gray-800 px-4 py-2 rounded float-right"> - Post - </button> + button ) -} \ No newline at end of file +} + diff --git a/lib/igdb.ts b/lib/igdb.ts index a3f26bf32d53791fe2751bf12773973b19714016..d2b94af8234be79d80a1805e727e193856524575 100644 --- a/lib/igdb.ts +++ b/lib/igdb.ts @@ -99,4 +99,37 @@ export async function getGame(id: number): Promise<IGame[]> { }); return games +} + +export async function getFavoriteGames(gamelist: Number[]): Promise<IGame[]> { + const auth = await getToken(); + const url = new URL(`${IGDB_BASE_URL}/games`); + let gamelistString = gamelist.toString() + + console.log("ID STRING:", gamelistString) + + const response = await fetch(url, { + method: 'POST', + headers: { + 'Client-ID': CLIENT_ID, + 'Authorization': `Bearer ${auth.access_token}` + }, + body: + `fields name, cover.image_id; limit ${limit}; + where id = (${gamelistString}); + ` + }); + console.log(response) + if (!response.ok) { + + throw new Error(`Error fetching games: ${response.statusText}`); + } + + const games: IGame[] = await response.json() as IGame[]; + + games.forEach(game => { + game.cover.url = getImageURL(game.cover.image_id, 'cover_big'); + }); + + return games; } \ No newline at end of file