From 0abff279d778af1b65f8029cc37e6e7b570b5152 Mon Sep 17 00:00:00 2001
From: "DESKTOP-9FO96TP\\hehexd" <davidjakszta@outlook.de>
Date: Thu, 8 Jun 2023 04:48:50 +0200
Subject: [PATCH] addFasvorite

---
 .../(gaming)/games/[gameid]/page.tsx          | 16 ++++++
 app/(content)/(user)/[userid]/page.tsx        | 24 ++++++++
 app/api/gameList/route.ts                     | 51 ++++++++++++-----
 components/addGameToList.tsx                  | 56 ++++++++++++++++---
 lib/igdb.ts                                   | 33 +++++++++++
 5 files changed, 160 insertions(+), 20 deletions(-)

diff --git a/app/(content)/(gaming)/games/[gameid]/page.tsx b/app/(content)/(gaming)/games/[gameid]/page.tsx
index 20d751b..65e4ba5 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 d4b5006..e59fb23 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 8c14bc2..0f7489e 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 74ed545..c40c4b9 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 a3f26bf..d2b94af 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
-- 
GitLab