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

Merge branch 'followPages' into 'main'

following page, but does not refresh on delete

See merge request !41
parents 90aea8e6 8ef32873
No related branches found
No related tags found
1 merge request!41following page, but does not refresh on delete
Pipeline #39772 passed
export default async function Following() { import { BackHeader } from "@/components/back-header"
import { GlobalLayout } from "@/components/global-layout"
import { UserFollows } from "@/components/profile/components/user-follows"
import { Card } from "@/components/ui/card"
import { getCurrentUser } from "@/lib/session"
export default async function Following({ params }: { params: { username: string } }) {
const session = await getCurrentUser()
return ( return (
<div> <GlobalLayout
<h1>Following Page WIP</h1> mainContent={
</div> <Card className="w-full overflow-hidden ">
<div className="p-3">
<BackHeader>
<h1 className="font-bold">Following</h1>
</BackHeader>
</div>
<div className="px-5">
<UserFollows username={params.username} session={session} />
</div>
</Card>
}
/>
) )
} }
\ No newline at end of file
...@@ -3,14 +3,13 @@ import { getCurrentUser } from "@/lib/session" ...@@ -3,14 +3,13 @@ import { getCurrentUser } from "@/lib/session"
import { NextResponse } from "next/server" import { NextResponse } from "next/server"
import { z } from "zod" import { z } from "zod"
// get following or followers information
export async function GET(request: Request) { export async function GET(request: Request) {
const { searchParams } = new URL(request.url) const { searchParams } = new URL(request.url)
const userId = searchParams.get("userId") || undefined const username = searchParams.get("userId") || undefined
const type = searchParams.get("type") || undefined const type = searchParams.get("type") || undefined
const userIdSchema = z.string().cuid().optional() const userIdSchema = z.string().optional()
const zod = userIdSchema.safeParse(userId) const zod = userIdSchema.safeParse(username)
if (!zod.success) { if (!zod.success) {
return NextResponse.json(zod.error, { status: 400 }) return NextResponse.json(zod.error, { status: 400 })
...@@ -21,19 +20,29 @@ export async function GET(request: Request) { ...@@ -21,19 +20,29 @@ export async function GET(request: Request) {
const followers = await db.user const followers = await db.user
.findUnique({ .findUnique({
where: { where: {
id: userId, username,
},
})
.followers({
include: {
followers: true,
following: true,
}, },
}) })
.followers()
return NextResponse.json(followers, { status: 200 }) return NextResponse.json(followers, { status: 200 })
} else if (type === "following") { } else if (type === "following") {
const following = await db.user const following = await db.user
.findUnique({ .findUnique({
where: { where: {
id: userId, username,
},
})
.following({
include: {
followers: true,
following: true,
}, },
}) })
.following()
return NextResponse.json(following, { status: 200 }) return NextResponse.json(following, { status: 200 })
} }
...@@ -42,7 +51,6 @@ export async function GET(request: Request) { ...@@ -42,7 +51,6 @@ export async function GET(request: Request) {
} }
} }
// follow a user
export async function PUT(request: Request) { export async function PUT(request: Request) {
const session = await getCurrentUser() const session = await getCurrentUser()
const { userId } = await request.json() const { userId } = await request.json()
...@@ -84,7 +92,6 @@ export async function PUT(request: Request) { ...@@ -84,7 +92,6 @@ export async function PUT(request: Request) {
} }
} }
// unfollow a user
export async function DELETE(request: Request) { export async function DELETE(request: Request) {
const session = await getCurrentUser() const session = await getCurrentUser()
const { userId } = await request.json() const { userId } = await request.json()
......
...@@ -36,43 +36,48 @@ export const FollowButton = ({ ...@@ -36,43 +36,48 @@ export const FollowButton = ({
}, [router, followMutation.isSuccess, unfollowMutation.isSuccess]) }, [router, followMutation.isSuccess, unfollowMutation.isSuccess])
return ( return (
<Dialog open={open} onOpenChange={setOpen}> <div onClick={(e) => {
{isFollowing ? ( e.preventDefault()
<DialogTrigger asChild> e.stopPropagation()
<Button variant={`${isHovered ? "destructive" : "outline"}`} size="lg" }}>
className="w-24" <Dialog open={open} onOpenChange={setOpen}>
onMouseEnter={() => { {isFollowing ? (
setText("Unfollow") <DialogTrigger asChild >
setIsHovered(true) <Button variant={`${isHovered ? "destructive" : "outline"}`} size="lg"
}} className="w-24"
onMouseOut={() => { onMouseEnter={() => {
setText("Following") setText("Unfollow")
setIsHovered(false) setIsHovered(true)
}}> }}
{text} onMouseOut={() => {
setText("Following")
setIsHovered(false)
}}>
{text}
</Button>
</DialogTrigger>
) : (
<Button size="lg" onClick={() => followMutation.mutate({ userId })}>
Follow
</Button> </Button>
</DialogTrigger> )}
) : ( <DialogContent>
<Button size="lg" onClick={() => followMutation.mutate({ userId })}> <DialogHeader>
Follow <DialogTitle>Unfollow @{username}?</DialogTitle>
</Button> <DialogDescription>
)} You can still view their profile, unless their Gweets are protected.
<DialogContent> </DialogDescription>
<DialogHeader> </DialogHeader>
<DialogTitle>Unfollow @{username}?</DialogTitle> <DialogFooter>
<DialogDescription> <Button type="submit" onClick={() => unfollowMutation.mutate({ userId })} disabled={unfollowMutation.isLoading}>
You can still view their profile, unless their Gweets are protected. {unfollowMutation.isLoading && (
</DialogDescription> <Icons.spinner className="mr-2 h-4 w-4 animate-spin" />
</DialogHeader> )}
<DialogFooter> Unfollow
<Button type="submit" onClick={() => unfollowMutation.mutate({ userId })} disabled={unfollowMutation.isLoading}> </Button>
{unfollowMutation.isLoading && ( </DialogFooter>
<Icons.spinner className="mr-2 h-4 w-4 animate-spin" /> </DialogContent>
)} </Dialog>
Unfollow </div>
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
) )
} }
\ No newline at end of file
export const getFollows = async (id: string | undefined, type: string | undefined) => { export const getFollows = async (id: string | undefined, type: string | undefined) => {
try { try {
const data = await fetch(`/api/users/follow?type=${type}&user_id=${id}`) const data = await fetch(`/api/users/follow?type=${type}&userId=${id}`)
.then((result) => result.json()) .then((result) => result.json())
return data return data
......
"use client"
import LoadingItem from "@/components/loading-item"
import { TryAgain } from "@/components/try-again"
import { User } from "next-auth"
import { usePathname } from "next/navigation"
import { useGetFollows } from "../hooks/use-get-follows"
import { UserItem } from "./user-item"
export const UserFollows = ({ username, session }: { username: string, session: User | undefined }) => {
const pathValue = usePathname().split("/")[2] || ""
const {
data: following,
isLoading,
isError,
} = useGetFollows({
id: username,
type: pathValue,
})
if (isLoading) {
return (
<LoadingItem />
)
}
if (isError || !following) {
return (
<TryAgain />
)
}
if (following?.length === 0) {
if (session?.username === username) {
return (
<div className="m-6 flex justify-center">
<div className="font-bold">
<h1>You are not following anyone.</h1>
<p>When you do, it&apos;ll show up here.</p>
</div>
</div>
)
}
return (
<div className="m-6 flex justify-center">
<div className="font-bold">
<h1><span className="text-sky-500">@{username}</span> is not following anyone yet.</h1>
<p>When they do, it&apos;ll show up here.</p>
</div>
</div>
)
}
return (
<div className="space-y-5 flex flex-col">
{following?.map((user) => {
return <UserItem key={user?.id} user={user} sessionId={session?.id} />
})}
</div>
)
}
\ No newline at end of file
import { FollowButton } from "@/components/follow-button"
import { UserAvatar } from "@/components/user-avatar"
import Link from "next/link"
import { IUser } from "../types"
import { following } from "../utils/following"
export const UserItem = ({ user, sessionId }: { user: IUser, sessionId: string | undefined }) => {
const isFollowing = following({
user,
sessionUserId: sessionId ? sessionId : "",
})
return (
<Link
href={`/${user?.username}`}
className="flex flex-row flex-shrink gap-3 hover:bg-accent active:bg-accent rounded-lg p-3 items-center">
<UserAvatar
user={{ username: user.username, image: user.image || null }}
className="h-12 w-12 aspect-square"
/>
<div className="flex flex-col flex-shrink justify-center h-full w-full space-y-3 overflow-hidden">
<div className="flex justify-between">
<div className="whitespace-nowrap">
<h1 className="font-bold">{user.name}</h1>
<h1 className="text-sm text-sky-500">@{user.username}</h1>
</div>
<FollowButton
userId={user.id}
username={user.username ? user.username : ""}
isFollowing={isFollowing}
/>
</div>
{user.bio ? (<p className="truncate w-full">{user.bio}</p>) : <p>&nbsp;</p>}
</div>
</Link>
)
}
...@@ -7,12 +7,12 @@ export const Trend = ({ ranking = 1, title, gweets = 1 }: iTrendProps) => { ...@@ -7,12 +7,12 @@ export const Trend = ({ ranking = 1, title, gweets = 1 }: iTrendProps) => {
return ( return (
<Link <Link
href={`/search?query=${title.toLowerCase()}`} href={`/search?query=${title.toLowerCase()}`}
className="flex flex-col justify-between hover:bg-accent active:bg-accent rounded-lg p-1"> className="flex flex-col justify-between hover:bg-accent active:bg-accent rounded-lg p-1 overflow-hidden">
<div className="text-xs text-muted-foreground"> <div className="text-xs text-muted-foreground">
{ranking} · Trending {ranking} · Trending
</div> </div>
<div>#{title}</div> <div className="truncate">#{title}</div>
<div className="text-xs text-muted-foreground"> <div className="text-xs text-muted-foreground">
{gweets} {gweets === 1 ? "gweet" : "gweets"} {gweets} {gweets === 1 ? "gweet" : "gweets"}
</div> </div>
......
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