diff --git a/app/(apidocs)/apidocs/page.tsx b/app/(apidocs)/apidocs/page.tsx index 6992e2d6a785ca2370d71c9d6625e38df94a3642..dcd107ba20f624834e55009f077da0fcfb710cdc 100644 --- a/app/(apidocs)/apidocs/page.tsx +++ b/app/(apidocs)/apidocs/page.tsx @@ -3,6 +3,7 @@ import ReactSwagger from './react-swagger' export default async function IndexPage() { const spec = await getApiDocs() + return ( <section className="container"> <ReactSwagger spec={spec} /> diff --git a/app/(content)/(user)/[username]/(profile)/layout.tsx b/app/(content)/(user)/[username]/(profile)/layout.tsx index f79ac51af8414f111f180c3ba913c54d01be8dbe..66445626fecee51e6e8507d795affad6ec202d46 100644 --- a/app/(content)/(user)/[username]/(profile)/layout.tsx +++ b/app/(content)/(user)/[username]/(profile)/layout.tsx @@ -2,6 +2,7 @@ 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 { IUser } from "@/components/profile/types" import { Card } from "@/components/ui/card" import { UserNotFound } from "@/components/user-not-found" import getURL from "@/lib/utils" @@ -16,7 +17,7 @@ export default async function ProfileLayout({ params: { username: string } children: React.ReactNode }) { - const user = await fetch(getURL(`/api/users/${params.username}`)).then((result) => result.json()) + const user: IUser = await fetch(getURL(`/api/users/${params.username}`)).then((result) => result.json()) return ( <GlobalLayout @@ -34,7 +35,7 @@ export default async function ProfileLayout({ } </Card> } - sideContent={<ProfileSideContent />} + sideContent={<ProfileSideContent user={user} />} /> ) } \ No newline at end of file diff --git a/app/api/users/[username]/route.ts b/app/api/users/[username]/route.ts index e089b9b7276365c1e9cc1d0131039894fc72fe11..4e90df12e820bf1795c81e43e1eb12ad385cdf15 100644 --- a/app/api/users/[username]/route.ts +++ b/app/api/users/[username]/route.ts @@ -33,6 +33,16 @@ export async function GET(request: Request, context: { params: { username: strin followers: true, following: true, + gweets: { + select: { + id: true, + media: true, + }, + orderBy: { + createdAt: "desc", + }, + }, + _count: { select: { followers: true, diff --git a/components/create-gweet/hooks/use-create-gweet.ts b/components/create-gweet/hooks/use-create-gweet.ts index 545aeeb262a2b41c71099897c114994dfea6f4eb..fde0e2321f1fa1e8d626687d4ef68b6a6eca2b91 100644 --- a/components/create-gweet/hooks/use-create-gweet.ts +++ b/components/create-gweet/hooks/use-create-gweet.ts @@ -33,7 +33,7 @@ export const useCreateGweet = () => { queryClient.invalidateQueries(["hashtags"]) }, onError: (error) => { - console.log("error", error) + if (process.env.NODE_ENV === "development") console.log(error) }, }, ) diff --git a/components/gweets/api/get-gweet.ts b/components/gweets/api/get-gweet.ts index 8b36271cd8afe7b31ebb6d159c7d1b67c5e7457e..6c60829b1e207cae8a773b3f1a777ca233ff291e 100644 --- a/components/gweets/api/get-gweet.ts +++ b/components/gweets/api/get-gweet.ts @@ -1,8 +1,11 @@ export default async function getGweet(id: string | undefined) { try { - const data = await fetch(`/api/gweets/${id}`).then((result) => result.json()) + const data = await fetch(`/api/gweets/${id}`) + if (!data.ok) { + throw new Error('Network response was not ok') + } - return data + return data.json() } catch (error: any) { return error.response.data } diff --git a/components/gweets/api/get-gweets.ts b/components/gweets/api/get-gweets.ts index 18bb683b6712058c19a5750f18a7b33ab3d56235..59b937a8a04a9228008fca464974809efd42a5fa 100644 --- a/components/gweets/api/get-gweets.ts +++ b/components/gweets/api/get-gweets.ts @@ -11,9 +11,12 @@ export const getGweets = async ({ }) => { try { const url = `/api/gweets?cursor=${pageParam}&limit=${limit}${type ? `&type=${type}` : ""}${id ? `&id=${id}` : ""}` - const data = await fetch(url).then((result) => result.json()) + const data = await fetch(url) + if (!data.ok) { + throw new Error('Network response was not ok') + } - return data + return data.json() } catch (error: any) { return error.response.data } diff --git a/components/gweets/components/delete-gweet-modal.tsx b/components/gweets/components/delete-gweet-modal.tsx index 67996349a2559ece51dbcad3bc2bc916945e3619..b7fd3459fe7166a189af34ac720dcf916c03c044 100644 --- a/components/gweets/components/delete-gweet-modal.tsx +++ b/components/gweets/components/delete-gweet-modal.tsx @@ -15,14 +15,27 @@ import { DialogTitle, DialogTrigger, } from "@/components/ui/dialog" -import { useRouter } from "next/navigation" +import { usePathname, useRouter } from "next/navigation" export const DeleteGweetModal = ({ gweet, props, forwardedRef }: { gweet: IGweet, props: any, forwardedRef: any }) => { const { triggerChildren, onSelect, onOpenChange, ...itemProps } = props const { isLoading, mutate, isSuccess } = useDeleteGweet() + const pathname = usePathname() + const isDetail = pathname?.split("/")[2] || "" + const router = useRouter() - if (isSuccess) router.push("/home") + if (isSuccess) { + onOpenChange(false) + + setTimeout(() => { + if (isDetail === "status") { + router.push("/home") + } else { + router.refresh() + } + }, 150) + } return ( <Dialog onOpenChange={onOpenChange}> diff --git a/components/gweets/components/gweet-details.tsx b/components/gweets/components/gweet-details.tsx index 110c6f0c33996dca685d26eaf3c1f2319557368a..bdc93b742c7405aa7bc8dcba11c35cae1b321456 100644 --- a/components/gweets/components/gweet-details.tsx +++ b/components/gweets/components/gweet-details.tsx @@ -29,10 +29,6 @@ export const GweetDetails = () => { return <TryAgain /> } - if (!isLoading && !isError && !gweet) { - return <>Not Found!</> - } - return ( <div> {/* TODO needs handling of all gweets above and under the gweet */} diff --git a/components/gweets/components/gweet.tsx b/components/gweets/components/gweet.tsx index 40f1f27eb695af5deea42ebd913e2f55b40c8c4b..4136f5c3c414a200348706ad8ac25fac95c12ff6 100644 --- a/components/gweets/components/gweet.tsx +++ b/components/gweets/components/gweet.tsx @@ -34,6 +34,7 @@ export const Gweet = ({ gweet }: { gweet: IGweet }) => { <div className="flex flex-row h-auto w-full"> <Link href={`/${gweet.author.username}`} + className="h-fit" onClick={(e) => { e.stopPropagation() }}> diff --git a/components/gweets/hooks/use-delete-gweet.ts b/components/gweets/hooks/use-delete-gweet.ts index 198d9924bf0cf975f017d9ca208472ca25f17373..0ff3a6962b8b4a2e2575210291790e75ff27978a 100644 --- a/components/gweets/hooks/use-delete-gweet.ts +++ b/components/gweets/hooks/use-delete-gweet.ts @@ -12,7 +12,7 @@ export const useDeleteGweet = () => { queryClient.invalidateQueries(["gweets"]) }, onError: (error) => { - console.log(error) + if (process.env.NODE_ENV === "development") console.log(error) }, }) } \ No newline at end of file diff --git a/components/gweets/hooks/use-like.ts b/components/gweets/hooks/use-like.ts index f0ab5591dd8e0e7b8c39a9b3e7c139fbd461a56b..c7159c01194259be7155a8f197f7dd73c5841abf 100644 --- a/components/gweets/hooks/use-like.ts +++ b/components/gweets/hooks/use-like.ts @@ -23,8 +23,8 @@ export const useLike = ({ queryClient.invalidateQueries(["users", gweetAuthorId]) }, onError: () => { - console.log("error") + if (process.env.NODE_ENV === "development") console.log("error") }, }, ) -} +} \ No newline at end of file diff --git a/components/gweets/hooks/use-regweet.ts b/components/gweets/hooks/use-regweet.ts index 82b5ef8468bc099f4f5d6280a464486142d22637..7181c4d0a375caa0467de477eb4c9b82ad1d5c9e 100644 --- a/components/gweets/hooks/use-regweet.ts +++ b/components/gweets/hooks/use-regweet.ts @@ -16,11 +16,9 @@ export const useRegweet = () => { QueryClient.invalidateQueries(["users"]) }, - onError: (error: any) => { - console.log(error) + onError: (error) => { + if (process.env.NODE_ENV === "development") console.log(error) }, - - onSettled: () => { }, }, ) } \ No newline at end of file diff --git a/components/profile/api/get-follows.ts b/components/profile/api/get-follows.ts index bfb15781fd8e6246ab3bfba6b138e3c2c20680da..42144039686aa88c7d39c7759ad73ef7f0d09049 100644 --- a/components/profile/api/get-follows.ts +++ b/components/profile/api/get-follows.ts @@ -1,9 +1,11 @@ export const getFollows = async (id: string | undefined, type: string | undefined) => { try { const data = await fetch(`/api/users/follow?type=${type}&userId=${id}`) - .then((result) => result.json()) + if (!data.ok) { + throw new Error('Network response was not ok') + } - return data + return data.json() } catch (error: any) { return error.message } diff --git a/components/profile/api/get-users.ts b/components/profile/api/get-users.ts index 5456b72d31a767f8a14246df0635d68ad20fdc21..b4f6009b6a981520d8208a82e82a41a2c1ec7990 100644 --- a/components/profile/api/get-users.ts +++ b/components/profile/api/get-users.ts @@ -1,9 +1,11 @@ export const getUsers = async (id?: string) => { try { const data = await fetch(`/api/users${id ? `?id=${id}` : ""}`) - .then((result) => result.json()) + if (!data.ok) { + throw new Error('Network response was not ok') + } - return data + return data.json() } catch (error: any) { return error.response.data } diff --git a/components/profile/api/update-profile.ts b/components/profile/api/update-profile.ts index 861e2c8125f87632faf323aee9d929a97e6f4ecb..31540051d7affc6643639d4f5eaca831ac99fffb 100644 --- a/components/profile/api/update-profile.ts +++ b/components/profile/api/update-profile.ts @@ -21,7 +21,7 @@ export const updateProfile = async ({ if (profile.image.file) { [imagefileprops] = await uploadFiles({ files: [profile.image.file], endpoint: 'imageUploader' }) } - console.log('bannerfileprops', profile.banner.removed) + const data = await fetch(`/api/users/${userId}`, { method: 'PUT', body: JSON.stringify({ diff --git a/components/profile/components/profile-side-content.tsx b/components/profile/components/profile-side-content.tsx index 71a6930e034e207cc622e51cb3ef9318e54e4ea1..b273d8ade513a3ed6cfc26381a78f6139f387fac 100644 --- a/components/profile/components/profile-side-content.tsx +++ b/components/profile/components/profile-side-content.tsx @@ -1,23 +1,36 @@ -import { Trends } from "@/components/trends/components/trends" import { Card } from "@/components/ui/card" -import { Skeleton } from "@/components/ui/skeleton" import { getCurrentUser } from "@/lib/session" +import Image from "next/image" +import { IUser } from "../types" import { Connect } from "./connect" -export const ProfileSideContent = async () => { +export const ProfileSideContent = async ({ user }: { user: IUser }) => { const session = await getCurrentUser() + const arrayOfUserMedia = user.gweets.slice(0, 4) + .flatMap((gweet) => gweet.media.slice(0, 4).map((media) => ({ id: gweet.id, url: media.url }))) + .slice(0, 4) return ( <div className="space-y-6"> - <Card className="p-6 bg-secondary"> - <div className="grid grid-cols-2 gap-3"> - {Array.from({ length: 4 }, (_, i) => i + 1).map((i) => { - return ( - <Skeleton key={i} className="aspect-[1/1] bg-gray-300" /> - ) - })} - </div> - </Card> + {arrayOfUserMedia.length > 0 && + <Card className="p-6 bg-secondary"> + <div className={`grid object-cover ${arrayOfUserMedia.length === 1 ? "grid-cols-1" + : arrayOfUserMedia.length === 2 ? "grid-cols-2 gap-3" + : arrayOfUserMedia.length === 3 || 4 ? "grid-cols-2 grid-rows-2 gap-3" + : "" + }`} + > + {arrayOfUserMedia.map(({ id, url }, i) => { + const isFirstImage = arrayOfUserMedia.length === 3 && i === 0 + return ( + <Card key={id} className={`relative overflow-hidden ${isFirstImage ? "col-span-2 aspect-[2/1]" : "aspect-square"}`}> + <Image src={url} alt="gweet media" fill className="object-cover rounded-lg" /> + </Card> + ) + })} + </div> + </Card> + } <Card className="p-6 bg-secondary"> <Connect session={session} /> diff --git a/components/profile/hooks/use-follow.ts b/components/profile/hooks/use-follow.ts index 0d9073a9931857ffba1152d497d7af1f7ee52ff0..447bfe9c7d2f53cf4d970e587750ef598e1d88a5 100644 --- a/components/profile/hooks/use-follow.ts +++ b/components/profile/hooks/use-follow.ts @@ -19,11 +19,11 @@ export const useFollow = (type: "follow" | "unfollow") => { { onSuccess: () => { - console.log("success") + if (process.env.NODE_ENV === "development") console.log("success") }, - onError: () => { - console.log("error") + onError: (error) => { + if (process.env.NODE_ENV === "development") console.log(error) }, onSettled: ({ userId }) => { diff --git a/components/profile/hooks/use-update-profile.ts b/components/profile/hooks/use-update-profile.ts index 4f3804edd55decd57cb9183571aaabf9415633eb..df79ee6ea97692e17fd6cf537c48cd89a6c2a279 100644 --- a/components/profile/hooks/use-update-profile.ts +++ b/components/profile/hooks/use-update-profile.ts @@ -19,11 +19,11 @@ export const useUpdateProfile = () => { { onSuccess: () => { - console.log("success") + if (process.env.NODE_ENV === "development") console.log("success") }, onError: (error) => { - console.log(error) + if (process.env.NODE_ENV === "development") console.log(error) }, onSettled: ({ userId }) => { diff --git a/components/trends/api/get-hashtags.ts b/components/trends/api/get-hashtags.ts index d70c90a99b03115ffcf346eae8adf0ccfcf63867..493f8f5659a52beb0e3831e86564b6040f02a46d 100644 --- a/components/trends/api/get-hashtags.ts +++ b/components/trends/api/get-hashtags.ts @@ -1,7 +1,11 @@ export const getHashtags = async () => { try { - const data = await fetch(`/api/hashtags`).then((result) => result.json()) - return data + const data = await fetch(`/api/hashtags`) + if (!data.ok) { + throw new Error('Network response was not ok') + } + + return data.json() } catch (error: any) { return error.response.data } diff --git a/components/try-again.tsx b/components/try-again.tsx index 218a1b6f0e6358c277cda3ad5e79b6af29f64aad..13ef547000805e2f4d1f255807df177b3901423f 100644 --- a/components/try-again.tsx +++ b/components/try-again.tsx @@ -1,14 +1,14 @@ import { useRouter } from "next/navigation" +import { Button } from "./ui/button" export const TryAgain = () => { const router = useRouter() return ( - <div className="flex flex-col items-center gap-1.2 p-4"> - <h2 className="text-tertiary text-center">Something went wrong. Try reloading.</h2> - <button onClick={() => router.refresh} className="px-4 py-2 rounded-full bg-primary text-light font-medium flex items-center gap-1"> - <span>Retry</span> - </button> + <div className="flex flex-col items-center p-6 space-y-3"> + <h1 className="text-tertiary text-center">Huh. Couldn't find what you were looking for.</h1> + <h1 className="text-tertiary text-center pb-3">Let's go back to the homepage.</h1> + <Button size="lg" onClick={() => router.push("/home")}>Home</Button> </div> ) } \ No newline at end of file