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

Merge branch 'profile' into 'main'

Profile

See merge request !38
parents 730e3738 95b938d3
No related branches found
No related tags found
1 merge request!38Profile
Pipeline #39781 passed
Showing
with 189 additions and 404 deletions
import { GlobalLayout } from "@/components/global-layout"
export default async function SearchPage() {
return (
<GlobalLayout
mainContent={
<>
Search Page
</>
}
sideContent={
<>
</>
}
/>
)
}
\ No newline at end of file
import { GlobalLayout } from "@/components/global-layout"
import { UserAvatar } from "@/components/user-avatar"
import { db } from "@/lib/db"
import { User } from "@prisma/client"
import Link from "next/link"
export default async function UserFollowers({ params }: { params: { userid: string } }) {
const fullUser = await db.user.findFirst({
where: {
username: params.userid
},
include: {
following: true,
followers: true
}
})
const followers = await db.user.findMany({
where: {
following: {
every: {
followerId: { not: undefined }
}
},
followers: {
every: {
followingId: fullUser?.id
}
}
}
})
return (
<GlobalLayout
mainContent={
<div className="flex flex-col w-full">
{followers?.map((follower: User) => (
<div className="flex items-center space-y-6" key={follower.id}>
<Link href={`/${follower.username}`} className="flex flex-row">
<UserAvatar
user={{ username: follower.username, image: follower.image }}
className="h-10 w-10"
/>
<div className="flex flex-col ml-3">
<span className="font-bold">{follower.name}</span>
<span className="text-sky-500 text-sm">@{follower.username}</span>
</div>
</Link>
<div className="ml-auto">
{/* Followbutton */}
</div>
</div>
))}
</div>
}
/>
)
}
\ No newline at end of file
export default async function Likes() {
return (
<div>
<h1>Likes Page WIP</h1>
</div>
)
}
\ No newline at end of file
import FollowButton from "@/components/following-button"
import GameItem from "@/components/game-item"
import { GlobalLayout } from "@/components/global-layout"
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 } }) {
const user = await getCurrentUser()
const sessionUser = await db.user.findFirst({
where: {
id: user?.id
},
include: {
following: true,
followers: true
}
})
const fullUser = await db.user.findFirst({
where: {
username: params.userid
},
include: {
following: true,
followers: true
}
})
if (!fullUser) {
redirect('/home')
}
let favoritegames = undefined
let playingGames = undefined
let finishedGames = undefined
let planningGames = undefined
if (fullUser?.favGameList?.length !== 0 && fullUser?.favGameList?.length != undefined) {
favoritegames = await getFavoriteGames(fullUser?.favGameList!)
}
if (fullUser?.playingGameList?.length !== 0) {
playingGames = await getFavoriteGames(fullUser?.playingGameList!)
}
if (fullUser?.finishedGameList?.length !== 0) {
finishedGames = await getFavoriteGames(fullUser?.finishedGameList!)
}
if (fullUser?.planningGameList?.length !== 0) {
planningGames = await getFavoriteGames(fullUser?.planningGameList!)
}
return (
<GlobalLayout
mainContent={
<div className="space-y-6 w-full">
<Card className="overflow-hidden">
<div className="h-64 overflow-hidden">
<AspectRatio ratio={889 / 500} className="bg-slate-600 dark:bg-slate-400">
{/* profile banner */}
{/* <Image
src={ }
alt={ }
fill
priority
className="object-center" /> */}
</AspectRatio>
</div>
<div className="p-6 md:p-12 ss:flex">
<UserAvatar
user={{ username: fullUser.username, image: fullUser.image || null }}
className="h-52 w-52 -mt-36"
/>
<div className="ml-6 md:ml-12 space-y-3">
<h1 className="text-2xl font-bold">{fullUser.name}</h1>
<h1 className="text-md text-sky-500">@{fullUser.username}</h1>
{/* <h1 className="pt-3">{fullUser.bio}</h1> */}
</div>
<div className="flex justify-start ml-6 md:ml-12 space-y-3">
<FollowButton user={sessionUser!} followingId={fullUser?.id!} />
</div>
</div>
<div className="px-6 md:px-12">
{/* <div className="border-b border-gray-400 dark:border-gray-200" /> */}
{/* gweets */}
</div>
</Card >
<Card className="overflow-hidden p-6 md:p-12" >
<h1 className="text-2xl font-bold pb-3">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>No favorites currently...</p>}
</div>
</Card>
<Card className="overflow-hidden p-6 md:p-12" >
<h1 className="text-2xl font-bold pb-3">Currently playing</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">
{playingGames ? playingGames.map((game: IGame) => (
<GameItem id={game.id} name={game.name} cover={game.cover} key={game.id} />
))
:
<p>Currently not playing any games...</p>}
</div>
</Card>
<Card className="overflow-hidden p-6 md:p-12" >
<h1 className="text-2xl font-bold pb-3">Planning to play</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">
{planningGames ? planningGames.map((game: IGame) => (
<GameItem id={game.id} name={game.name} cover={game.cover} key={game.id} />
))
:
<p>Currently not planning to play any games...</p>}
</div>
</Card>
<Card className="overflow-hidden p-6 md:p-12" >
<h1 className="text-2xl font-bold pb-3">Finished 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">
{finishedGames ? finishedGames.map((game: IGame) => (
<GameItem id={game.id} name={game.name} cover={game.cover} key={game.id} />
))
:
<p>No finished games...</p>}
</div>
</Card>
</div>
}
sideContent={
<Card className="p-6 grid items-start gap-2 bg-secondary">
<h1>Media</h1>
<div className="grid grid-cols-1 gap-4">
{Array.from({ length: 2 }, (_, i) => i + 1).map((i) => {
return (
<Skeleton key={i} className="aspect-[264/374] bg-gray-300" />
)
})}
</div>
</Card>
}
/>
)
}
\ No newline at end of file
import { UserGames } from "@/components/profile/components/user-games"
import { TabsContent } from "@/components/ui/tabs"
export default async function Games({ params }: { params: { username: string } }) {
return (
<TabsContent value="games">
<UserGames username={params.username} />
</TabsContent>
)
}
\ No newline at end of file
import { GlobalLayout } from "@/components/global-layout"
import { ProfileNavbar } from "@/components/profile/components/profile-navbar"
import { ProfileSideContent } from "@/components/profile/components/profile-side-content"
import { ProfileUserInfo } from "@/components/profile/components/profile-user-info"
import { Card } from "@/components/ui/card"
import { UserNotFound } from "@/components/user-not-found"
import getURL from "@/lib/utils"
// export const dynamic = 'force-dynamic'
// export const fetchCache = 'force-no-store'
export default async function ProfileLayout({
params,
children,
}: {
params: { username: string }
children: React.ReactNode
}) {
const user = await fetch(getURL(`/api/users/${params.username}`)).then((result) => result.json())
return (
<GlobalLayout
mainContent={
<Card className="overflow-hidden h-full w-full">
{!user ?
<UserNotFound />
:
<>
<ProfileUserInfo user={user} />
<ProfileNavbar param={params.username}>
{children}
</ProfileNavbar>
</>
}
</Card>
}
sideContent={<ProfileSideContent />}
/>
)
}
\ No newline at end of file
import { UserGweets } from "@/components/profile/components/user-gweets"
import { TabsContent } from "@/components/ui/tabs"
import { getCurrentUser } from "@/lib/session"
export default async function Likes({ params }: { params: { username: string } }) {
const session = await getCurrentUser()
return (
<TabsContent value="likes">
<UserGweets username={params.username} sessionname={session?.username as string} />
</TabsContent>
)
}
\ No newline at end of file
import { UserGweets } from "@/components/profile/components/user-gweets"
import { TabsContent } from "@/components/ui/tabs"
import { getCurrentUser } from "@/lib/session"
export default async function Media({ params }: { params: { username: string } }) {
const session = await getCurrentUser()
return (
<TabsContent value="media">
<UserGweets username={params.username} sessionname={session?.username as string} />
</TabsContent>
)
}
\ No newline at end of file
import { UserGweets } from "@/components/profile/components/user-gweets"
import { TabsContent } from "@/components/ui/tabs"
import { getCurrentUser } from "@/lib/session"
export default async function Gweets({ params }: { params: { username: string } }) {
const session = await getCurrentUser()
return (
<TabsContent value="gweets">
<UserGweets username={params.username} sessionname={session?.username as string} />
</TabsContent>
)
}
\ No newline at end of file
export default function CommunitiesPage() {
export default async function Following() {
return (
<div>
<h1>Community WIP</h1>
<h1>Following Page WIP</h1>
</div>
)
}
\ No newline at end of file
......@@ -3,12 +3,11 @@ import { Sidebar } from "@/components/nav-sidebar"
import { dashboardConfig } from "@/lib/config/dashboard"
import { getCurrentUser } from "@/lib/session"
interface DashboardLayoutProps {
children?: React.ReactNode
}
export default async function ContentLayout({
children,
}: DashboardLayoutProps) {
}: {
children: React.ReactNode
}) {
const user = await getCurrentUser()
return (
......
import { db } from "@/lib/db"
import { getCurrentUser } from "@/lib/session"
import { revalidatePath } from "next/cache"
import { NextRequest, NextResponse } from "next/server"
export async function GET(req: NextRequest) {
const sessionUser = await getCurrentUser()
if (!sessionUser) {
return NextResponse.json({ status: 401, message: 'Unauthorized' })
}
let follows = undefined
try {
follows = await db.follows.findMany({
where: {
followerId: sessionUser.id
}
})
} catch (error) {
console.log("error", error)
}
return NextResponse.json({ status: 200, message: "fetched follows", follows })
}
export async function PUT(req: NextRequest) {
const sessionUser = await getCurrentUser()
const data = await req.json()
if (!sessionUser) {
return NextResponse.json({ status: 401, message: 'Unauthorized' })
}
try {
const dbUser = await db.user.findFirst({
where: {
id: sessionUser.id
}
})
const follow = await db.follows.findFirst({
where: {
followerId: sessionUser.id,
followingId: data.followingId
}
})
console.log("follow", follow)
if (follow) {
// User is already following, so unfollow
console.log("delete follow")
const delfollow = await db.follows.delete({
where: {
followerId_followingId: {
followerId: sessionUser.id,
followingId: data.followingId
}
}
})
console.log("del follow:", delfollow)
} else {
// User is not following, so follow
console.log("create follow")
await db.follows.create({
data: {
followerId: sessionUser.id,
followingId: data.followingId
},
})
}
} catch (error) {
console.log("err", error)
}
const path = req.nextUrl.searchParams.get('path') || '/'
revalidatePath(path)
return NextResponse.json({ status: 200, message: 'Follow handled' })
}
\ No newline at end of file
......@@ -37,7 +37,7 @@ export async function GET(req: NextRequest) {
sortby ? sortby : undefined,
order ? order : undefined
)
return NextResponse.json(games)
return NextResponse.json(games, { status: 200 })
} catch (error) {
return NextResponse.json(error, { status: 500 })
}
......
......@@ -3,7 +3,6 @@ import { z } from "zod"
import { db } from "@/lib/db"
// get a single gweet
export async function GET(request: Request, { params }: { params: { id: string } }) {
const { id } = params
......@@ -12,12 +11,10 @@ export async function GET(request: Request, { params }: { params: { id: string }
const zod = gweetIdSchema.safeParse(id)
if (!zod.success) {
return NextResponse.json(
{
message: "Invalid request body",
error: zod.error.formErrors,
}, { status: 400 },
)
return NextResponse.json({
message: "Invalid request body",
error: zod.error.formErrors,
}, { status: 400 })
}
try {
......@@ -96,20 +93,16 @@ export async function GET(request: Request, { params }: { params: { id: string }
})
if (!gweet) {
return NextResponse.json(
{
message: "Gweet not found",
}, { status: 404 },
)
return NextResponse.json({
message: "Gweet not found",
}, { status: 404 })
}
return NextResponse.json(gweet, { status: 200 })
} catch (error) {
return NextResponse.json(
{
message: "Something went wrong",
error,
}, { status: 500 },
)
return NextResponse.json({
message: "Something went wrong",
error,
}, { status: 500 })
}
}
\ No newline at end of file
......@@ -3,7 +3,6 @@ import { z } from "zod"
import { db } from "@/lib/db"
// get likes from user
export async function GET(request: Request) {
const { searchParams } = new URL(request.url)
const user_id = searchParams.get("user_id") || undefined
......@@ -41,16 +40,13 @@ export async function GET(request: Request) {
return NextResponse.json(gweets, { status: 200 })
} catch (error: any) {
return NextResponse.json(
{
message: "Something went wrong",
error: error.message,
}, { status: error.errorCode || 500 },
)
return NextResponse.json({
message: "Something went wrong",
error: error.message,
}, { status: error.errorCode || 500 })
}
}
// like and dislike
export async function POST(request: Request) {
const { gweet_id, user_id } = await request.json()
......@@ -64,12 +60,10 @@ export async function POST(request: Request) {
const zod = likeSchema.safeParse({ gweet_id, user_id })
if (!zod.success) {
return NextResponse.json(
{
message: "Invalid request body",
error: zod.error.formErrors,
}, { status: 400 },
)
return NextResponse.json({
message: "Invalid request body",
error: zod.error.formErrors,
}, { status: 400 })
}
try {
......@@ -87,7 +81,7 @@ export async function POST(request: Request) {
},
})
return NextResponse.json({ message: "Gweet unliked" })
return NextResponse.json({ message: "Gweet unliked" }, { status: 200 })
} else {
await db.like.create({
data: {
......@@ -96,12 +90,12 @@ export async function POST(request: Request) {
},
})
return NextResponse.json({ message: "Gweet liked" })
return NextResponse.json({ message: "Gweet liked" }, { status: 201 })
}
} catch (error: any) {
return NextResponse.json({
message: "Something went wrong",
error: error.message,
})
}, { status: 500 })
}
}
\ No newline at end of file
......@@ -16,12 +16,10 @@ export async function POST(request: Request) {
const zod = regweetSchema.safeParse({ gweet_id, user_id })
if (!zod.success) {
return NextResponse.json(
{
message: "Invalid request body",
error: zod.error.formErrors,
}, { status: 400 },
)
return NextResponse.json({
message: "Invalid request body",
error: zod.error.formErrors,
}, { status: 400 })
}
try {
......@@ -39,7 +37,7 @@ export async function POST(request: Request) {
},
})
return NextResponse.json({ message: "Deleted gweet regweet" })
return NextResponse.json({ message: "Deleted gweet regweet" }, { status: 200 })
} else {
await db.regweet.create({
data: {
......@@ -48,7 +46,7 @@ export async function POST(request: Request) {
},
})
return NextResponse.json({ message: "Gweet regweeted" })
return NextResponse.json({ message: "Gweet regweeted" }, { status: 201 })
}
} catch (error: any) {
return NextResponse.json({ error: error.message }, { status: 500 })
......
......@@ -4,7 +4,6 @@ import { z } from "zod"
import { db } from "@/lib/db"
import { utapi } from "uploadthing/server"
// get gweets
export async function GET(request: Request) {
const { searchParams } = new URL(request.url)
......@@ -30,9 +29,9 @@ export async function GET(request: Request) {
// if (gweet && gweet.replyToGweetId) thread = await fetchThread(gweet.replyToGweetId)
// }
// // logic correct TODO
// // logic correct TODO get all gweets above comment
// const prevId = thread.length < 4 ? undefined : thread[thread.length - 1].id
// return NextResponse.json({ gweets: thread, prevId })
// return NextResponse.json({ gweets: thread, prevId }, { status: 200 })
// }
const gweets = await db.gweet.findMany({
......@@ -53,20 +52,35 @@ export async function GET(request: Request) {
}),
...(type === "user_gweets" && {
authorId: id,
author: {
username: id,
},
}),
...(type === "user_replies" && {
authorId: id,
author: {
username: id,
},
NOT: {
replyToGweetId: null,
},
}),
...(type === "user_media" && {
author: {
username: id,
},
media: {
some: {},
},
}),
...(type === "user_likes" && {
likes: {
some: {
userId: id,
user: {
username: id,
},
},
},
}),
......@@ -113,13 +127,12 @@ export async function GET(request: Request) {
const nextId = gweets.length < take ? undefined : gweets[gweets.length - 1].id
return NextResponse.json({ gweets, nextId })
return NextResponse.json({ gweets, nextId }, { status: 200 })
} catch (error) {
return NextResponse.error()
return NextResponse.json(error, { status: 500 })
}
}
// create gweet
export async function POST(request: Request) {
const { gweet, fileprops } = await request.json()
......@@ -144,12 +157,10 @@ export async function POST(request: Request) {
)
if (!zodGweet.success) {
return NextResponse.json(
{
message: "Invalid request body",
error: zodGweet.error.formErrors,
}, { status: 400 },
)
return NextResponse.json({
message: "Invalid request body",
error: zodGweet.error.formErrors,
}, { status: 400 })
}
try {
......@@ -174,12 +185,10 @@ export async function POST(request: Request) {
const zodMedia = mediaSchema.safeParse(mediaArray)
if (!zodMedia.success) {
return NextResponse.json(
{
message: "Invalid media body",
error: zodMedia.error.formErrors,
}, { status: 400 },
)
return NextResponse.json({
message: "Invalid media body",
error: zodMedia.error.formErrors,
}, { status: 400 })
}
await db.media.createMany({
......@@ -187,18 +196,15 @@ export async function POST(request: Request) {
})
}
return NextResponse.json(created_gweet, { status: 200 })
return NextResponse.json(created_gweet, { status: 201 })
} catch (error: any) {
return NextResponse.json(
{
message: "Something went wrong",
error: error.message,
}, { status: error.errorCode || 500 },
)
return NextResponse.json({
message: "Something went wrong",
error: error.message,
}, { status: error.errorCode || 500 })
}
}
// delete gweet
export async function DELETE(request: Request) {
const { searchParams } = new URL(request.url)
const id = searchParams.get("id") as string
......@@ -232,14 +238,12 @@ export async function DELETE(request: Request) {
},
})
return NextResponse.json({ message: "Gweet deleted successfully", })
return NextResponse.json({ message: "Gweet deleted" }, { status: 200 })
} catch (error: any) {
return NextResponse.json(
{
message: "Something went wrong",
error: error.message,
}, { status: error.errorCode || 500 },
)
return NextResponse.json({
message: "Something went wrong",
error: error.message,
}, { status: error.errorCode || 500 })
}
}
......
......@@ -57,18 +57,8 @@ export async function POST(request: Request) {
}
}
return NextResponse.json(
{
message: "Hashtag(s) created",
},
{ status: 200 },
)
return NextResponse.json({ message: "Hashtag(s) created", }, { status: 201 })
} catch (error: any) {
return NextResponse.json(
{
error: error.message,
},
{ status: 500 },
)
return NextResponse.json({ error: error.message, }, { status: 500 },)
}
}
\ No newline at end of file
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