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 { AspectRatio } from "@/components/ui/aspect-ratio";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { Card } from "@/components/ui/card"; import { Card } from "@/components/ui/card";
import { getGame } from "@/lib/igdb"; import { getGame } from "@/lib/igdb";
import { getCurrentUser } from "@/lib/session";
import { formatDate } from "@/lib/utils"; import { formatDate } from "@/lib/utils";
import { IGame } from "@/types/igdb-types"; import { IGame } from "@/types/igdb-types";
import Image from "next/image"; import Image from "next/image";
import { db } from "@/lib/db";
// renders a single game detail page // renders a single game detail page
export default async function GameDetail({ params }: { params: { gameid: string } }) { export default async function GameDetail({ params }: { params: { gameid: string } }) {
...@@ -12,6 +15,16 @@ 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 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) => { const companies = data[0].involved_companies.map((company) => {
if (company !== data[0].involved_companies[0]) { if (company !== data[0].involved_companies[0]) {
return `, ${company.company.name}` return `, ${company.company.name}`
...@@ -20,7 +33,9 @@ export default async function GameDetail({ params }: { params: { gameid: string ...@@ -20,7 +33,9 @@ export default async function GameDetail({ params }: { params: { gameid: string
}) })
return ( return (
<div className="main-content h-full"> <div className="main-content h-full">
<Card className="w-full h-full overflow-hidden"> <Card className="w-full h-full overflow-hidden">
<div className="h-64 overflow-hidden"> <div className="h-64 overflow-hidden">
<AspectRatio ratio={889 / 500}> <AspectRatio ratio={889 / 500}>
...@@ -93,6 +108,7 @@ export default async function GameDetail({ params }: { params: { gameid: string ...@@ -93,6 +108,7 @@ export default async function GameDetail({ params }: { params: { gameid: string
</div> </div>
</Card> </Card>
</div> </div>
<AddGameToList userGameList={fullUser?.favGameList!} gameId={params.gameid} />
</div > </div >
) )
} }
\ No newline at end of file
import GameItem from "@/components/game-item"
import { AspectRatio } from "@/components/ui/aspect-ratio" import { AspectRatio } from "@/components/ui/aspect-ratio"
import { Card } from "@/components/ui/card" import { Card } from "@/components/ui/card"
import { Skeleton } from "@/components/ui/skeleton" import { Skeleton } from "@/components/ui/skeleton"
import { UserAvatar } from "@/components/user-avatar" import { UserAvatar } from "@/components/user-avatar"
import { db } from "@/lib/db"
import { getFavoriteGames } from "@/lib/igdb"
import { getCurrentUser } from "@/lib/session" import { getCurrentUser } from "@/lib/session"
import { IGame } from "@/types/igdb-types"
import { redirect } from "next/navigation" import { redirect } from "next/navigation"
export default async function User({ params }: { params: { userid: string } }) { export default async function User({ params }: { params: { userid: string } }) {
...@@ -11,6 +15,13 @@ 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) { if (user?.username !== params.userid) {
redirect('/') redirect('/')
} }
const fullUser = await db.user.findFirst({
where: {
id: user?.id
}
})
const favoritegames = await getFavoriteGames(fullUser?.favGameList!)
return ( return (
<div className="main-content h-full"> <div className="main-content h-full">
...@@ -54,6 +65,19 @@ export default async function User({ params }: { params: { userid: string } }) { ...@@ -54,6 +65,19 @@ export default async function User({ params }: { params: { userid: string } }) {
</div> </div>
</Card> </Card>
</div> </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 > </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[]> { ...@@ -99,4 +99,37 @@ export async function getGame(id: number): Promise<IGame[]> {
}); });
return games 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 { generator client {
provider = "prisma-client-js" provider = "prisma-client-js"
} }
...@@ -16,21 +13,20 @@ model Account { ...@@ -16,21 +13,20 @@ model Account {
type String type String
provider String provider String
providerAccountId String providerAccountId String
refresh_token String? @db.Text refresh_token String?
access_token String? @db.Text access_token String?
expires_at Int? expires_at Int?
token_type String? token_type String?
scope String? scope String?
id_token String? @db.Text id_token String?
session_state String? session_state String?
createdAt DateTime @default(now()) @map(name: "created_at") createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @default(now()) @map(name: "updated_at") updatedAt DateTime @default(now()) @map("updated_at")
refresh_token_expires_in Int? 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]) @@unique([provider, providerAccountId])
@@map(name: "accounts") @@map("accounts")
} }
model Session { model Session {
...@@ -38,10 +34,9 @@ model Session { ...@@ -38,10 +34,9 @@ model Session {
sessionToken String @unique sessionToken String @unique
userId String @unique userId String @unique
expires DateTime expires DateTime
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@map("sessions")
@@map(name: "sessions")
} }
model User { model User {
...@@ -52,20 +47,18 @@ model User { ...@@ -52,20 +47,18 @@ model User {
emailVerified DateTime? emailVerified DateTime?
password String? password String?
image String? image String?
createdAt DateTime @default(now()) @map(name: "created_at") createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @default(now()) @map(name: "updated_at") updatedAt DateTime @default(now()) @map("updated_at")
favGameList Int[]
accounts Account[] accounts Account?
sessions Session[] Comment Comment[]
following Follows[] @relation("following")
Post Post[] followers Follows[] @relation("follower")
Comment Comment[] Like Like[]
Like Like[] Post Post[]
sessions Session?
followers Follows[] @relation("follower")
following Follows[] @relation("following") @@map("users")
@@map(name: "users")
} }
model VerificationToken { model VerificationToken {
...@@ -74,61 +67,58 @@ model VerificationToken { ...@@ -74,61 +67,58 @@ model VerificationToken {
expires DateTime expires DateTime
@@unique([identifier, token]) @@unique([identifier, token])
@@map(name: "verification_tokens") @@map("verification_tokens")
} }
model Follows { model Follows {
follower User @relation("following", fields: [followerId], references: [id])
followerId String followerId String
following User @relation("follower", fields: [followingId], references: [id])
followingId String followingId String
createdAt DateTime @default(now()) createdAt DateTime @default(now())
follower User @relation("following", fields: [followerId], references: [id])
following User @relation("follower", fields: [followingId], references: [id])
@@id([followerId, followingId]) @@id([followerId, followingId])
@@map(name: "follows") @@map("follows")
} }
model Post { model Post {
id String @id @default(cuid()) id String @id @default(cuid())
createdAt DateTime @default(now()) @map(name: "created_at") createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @default(now()) @map(name: "updated_at") updatedAt DateTime @default(now()) @map("updated_at")
userId String userId String
content String content String
likeCount Int? @default(0) likeCount Int? @default(0)
published Boolean @default(false) 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) @@map("posts")
Comment Comment[]
Like Like[]
@@map(name: "posts")
} }
model Like { model Like {
id String @id @default(cuid()) id String @id @default(cuid())
postId String postId String
commentId String? commentId String?
userId 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) @@map("likes")
comment Comment? @relation(fields: [commentId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@map(name: "likes")
} }
model Comment { model Comment {
id String @id @default(cuid()) id String @id @default(cuid())
createdAt DateTime @default(now()) @map(name: "created_at") createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @default(now()) @map(name: "updated_at") updatedAt DateTime @default(now()) @map("updated_at")
message String message String
likeCount Int? @default(0) likeCount Int? @default(0)
postId String postId String
userId 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) @@map("comments")
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
Like Like[]
@@map(name: "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