Skip to content
Snippets Groups Projects
Commit 53b9dffd authored by Yusuf Akgül's avatar Yusuf Akgül :hatching_chick:
Browse files

Merge branch 'GameList' into 'main'

Game list

See merge request !26
parents e355e504 0abff279
No related branches found
No related tags found
1 merge request!26Game list
Pipeline #36994 passed
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
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
import { db } from "@/lib/db";
import { getCurrentUser } from "@/lib/session";
import { revalidatePath } from "next/cache";
import { NextRequest, NextResponse } from "next/server";
export async function PUT(req: NextRequest) {
const user = await getCurrentUser();
if (!user) {
return NextResponse.json({ status: 401, message: 'Unauthorized' });
}
const userId = user.id;
const data = await req.json()
data.gameId = parseInt(data.gameId)
console.log(data);
console.log(userId);
try {
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);
return NextResponse.json({ status: 201, message: 'Game Hinzugefügt' })
} catch (error: any) {
return NextResponse.json({ status: 500, message: error.message })
}
}
\ No newline at end of file
"use client"
import { Post, Prisma } from "@prisma/client";
import { useRouter } from "next/navigation";
import { startTransition, useEffect, useState } from "react";
export default function AddGameToList(props: { userGameList: Number[], gameId: string }) {
const router = useRouter();
const gameId = props.gameId
let formData = { gameId: "", add: true }
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)
})
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()
}
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
)
}
......@@ -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
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
generator client {
provider = "prisma-client-js"
}
......@@ -16,21 +13,20 @@ model Account {
type String
provider String
providerAccountId String
refresh_token String? @db.Text
access_token String? @db.Text
refresh_token String?
access_token String?
expires_at Int?
token_type String?
scope String?
id_token String? @db.Text
id_token String?
session_state String?
createdAt DateTime @default(now()) @map(name: "created_at")
updatedAt DateTime @default(now()) @map(name: "updated_at")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @default(now()) @map("updated_at")
refresh_token_expires_in Int?
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([provider, providerAccountId])
@@map(name: "accounts")
@@map("accounts")
}
model Session {
......@@ -38,10 +34,9 @@ model Session {
sessionToken String @unique
userId String @unique
expires DateTime
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@map(name: "sessions")
@@map("sessions")
}
model User {
......@@ -52,20 +47,18 @@ model User {
emailVerified DateTime?
password String?
image String?
createdAt DateTime @default(now()) @map(name: "created_at")
updatedAt DateTime @default(now()) @map(name: "updated_at")
accounts Account[]
sessions Session[]
Post Post[]
Comment Comment[]
Like Like[]
followers Follows[] @relation("follower")
following Follows[] @relation("following")
@@map(name: "users")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @default(now()) @map("updated_at")
favGameList Int[]
accounts Account?
Comment Comment[]
following Follows[] @relation("following")
followers Follows[] @relation("follower")
Like Like[]
Post Post[]
sessions Session?
@@map("users")
}
model VerificationToken {
......@@ -74,61 +67,58 @@ model VerificationToken {
expires DateTime
@@unique([identifier, token])
@@map(name: "verification_tokens")
@@map("verification_tokens")
}
model Follows {
follower User @relation("following", fields: [followerId], references: [id])
followerId String
following User @relation("follower", fields: [followingId], references: [id])
followingId String
createdAt DateTime @default(now())
follower User @relation("following", fields: [followerId], references: [id])
following User @relation("follower", fields: [followingId], references: [id])
@@id([followerId, followingId])
@@map(name: "follows")
@@map("follows")
}
model Post {
id String @id @default(cuid())
createdAt DateTime @default(now()) @map(name: "created_at")
updatedAt DateTime @default(now()) @map(name: "updated_at")
id String @id @default(cuid())
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @default(now()) @map("updated_at")
userId String
content String
likeCount Int? @default(0)
published Boolean @default(false)
likeCount Int? @default(0)
published Boolean @default(false)
Comment Comment[]
Like Like[]
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
Comment Comment[]
Like Like[]
@@map(name: "posts")
@@map("posts")
}
model Like {
id String @id @default(cuid())
id String @id @default(cuid())
postId String
commentId String?
userId String
comment Comment? @relation(fields: [commentId], references: [id], onDelete: Cascade)
post Post @relation(fields: [postId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
post Post @relation(fields: [postId], references: [id], onDelete: Cascade)
comment Comment? @relation(fields: [commentId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@map(name: "likes")
@@map("likes")
}
model Comment {
id String @id @default(cuid())
createdAt DateTime @default(now()) @map(name: "created_at")
updatedAt DateTime @default(now()) @map(name: "updated_at")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @default(now()) @map("updated_at")
message String
likeCount Int? @default(0)
postId String
userId String
post Post @relation(fields: [postId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
Like Like[]
post Post @relation(fields: [postId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
Like Like[]
@@map(name: "comments")
@@map("comments")
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment