From fa24222760b5788c3b42ce9d1c3f5bd4c0d5ab02 Mon Sep 17 00:00:00 2001 From: Sosokker Date: Sun, 10 Nov 2024 17:06:16 +0700 Subject: [PATCH] feat: follow button --- .../deals/[id]/followShareButton.tsx | 46 +++++++++++-------- src/app/(investment)/deals/[id]/page.tsx | 40 +++++++++++----- src/lib/data/followQuery.ts | 29 ++++++++++++ 3 files changed, 86 insertions(+), 29 deletions(-) create mode 100644 src/lib/data/followQuery.ts diff --git a/src/app/(investment)/deals/[id]/followShareButton.tsx b/src/app/(investment)/deals/[id]/followShareButton.tsx index 9242b98..5c69cd4 100644 --- a/src/app/(investment)/deals/[id]/followShareButton.tsx +++ b/src/app/(investment)/deals/[id]/followShareButton.tsx @@ -2,24 +2,22 @@ /* eslint-disable */ -import { useState, useEffect } from "react"; +import { useState } from "react"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"; import { ShareIcon, StarIcon } from "lucide-react"; -import { redirect } from "next/navigation"; -import useSession from "@/lib/supabase/useSession"; +import { deleteFollow, insertFollow } from "@/lib/data/followQuery"; import toast from "react-hot-toast"; +import { createSupabaseClient } from "@/lib/supabase/clientComponentClient"; -const FollowShareButtons = () => { - const { session, loading } = useSession(); - const user = session?.user; - const [sessionLoaded, setSessionLoaded] = useState(false); - const [isFollow, setIsFollow] = useState(false); +interface FollowShareButtons { + isFollow: boolean; + userId: string; + projectId: number; +} - useEffect(() => { - if (!loading) { - setSessionLoaded(true); - } - }, [loading]); +const FollowShareButtons = ({ isFollow, userId, projectId }: FollowShareButtons) => { + const supabase = createSupabaseClient(); + const [isFollowState, setIsFollowState] = useState(isFollow); const handleShare = () => { const currentUrl = window.location.href; @@ -29,11 +27,23 @@ const FollowShareButtons = () => { }); } }; - const handleFollow = () => { - if (user) { - setIsFollow((prevState) => !prevState); + const handleFollow = async () => { + if (!isFollowState) { + const error = await insertFollow(supabase, userId, projectId); + if (error) { + toast.error("Error occur!"); + } else { + toast.success("You have followed the project!", { icon: "❤️" }); + setIsFollowState(true); + } } else { - redirect("/login"); + const error = await deleteFollow(supabase, userId, projectId); + if (error) { + toast.error("Error occur!"); + } else { + toast.success("You have unfollowed the project!", { icon: "💔" }); + setIsFollowState(false); + } } }; @@ -43,7 +53,7 @@ const FollowShareButtons = () => { - +

Follow NVIDIA

diff --git a/src/app/(investment)/deals/[id]/page.tsx b/src/app/(investment)/deals/[id]/page.tsx index f6d8280..c86a41e 100644 --- a/src/app/(investment)/deals/[id]/page.tsx +++ b/src/app/(investment)/deals/[id]/page.tsx @@ -17,6 +17,7 @@ import { getDealList } from "@/app/api/dealApi"; import { sumByKey, toPercentage } from "@/lib/utils"; import { redirect } from "next/navigation"; import { isOwnerOfProject } from "./query"; +import { getFollow } from "@/lib/data/followQuery"; import remarkGfm from "remark-gfm"; const PHOTO_MATERIAL_ID = 2; @@ -25,13 +26,12 @@ export default async function ProjectDealPage({ params }: { params: { id: number const supabase = createSupabaseClient(); const { data: projectData, error: projectDataError } = await getProjectData(supabase, params.id); const { data: user, error: userError } = await supabase.auth.getUser(); - const { data: projectMaterial, error: projectMaterialError } = await supabase .from("project_material") .select("material_url") .eq("project_id", params.id) .eq("material_type_id", PHOTO_MATERIAL_ID); - // console.log(projectMaterial); + if (projectMaterialError) { console.error("Error while fetching project material" + projectMaterialError); } @@ -43,9 +43,9 @@ export default async function ProjectDealPage({ params }: { params: { id: number return (

Error fetching data. Please try again.

- + + +
); } @@ -54,12 +54,32 @@ export default async function ProjectDealPage({ params }: { params: { id: number return (

Error fetching data. Please try again.

- + + +
); } + const { data: follow, error: followError } = await getFollow(supabase, user!.user.id, params.id); + + if (followError) { + return ( +
+
+

Error fetching data. Please try again.

+

{followError.message}

+ + + +
+
+ ); + } + + let isFollow = false; + if (follow) { + isFollow = true; + } const isOwner = await isOwnerOfProject(supabase, params.id, user.user?.id); @@ -80,8 +100,6 @@ export default async function ProjectDealPage({ params }: { params: { id: number ) : [{ src: "/boiler1.jpg", alt: "Default Boiler Image" }]; - // console.log(carouselData); - return (
@@ -92,7 +110,7 @@ export default async function ProjectDealPage({ params }: { params: { id: number logo

{projectData?.project_name}

- +
{/* end of pack */}

{projectData?.project_short_description}

diff --git a/src/lib/data/followQuery.ts b/src/lib/data/followQuery.ts new file mode 100644 index 0000000..63f2e95 --- /dev/null +++ b/src/lib/data/followQuery.ts @@ -0,0 +1,29 @@ +import { SupabaseClient } from "@supabase/supabase-js"; + +export function getFollow(client: SupabaseClient, user_id: string, project_id: number) { + return client + .from("follow") + .select("id, project_id, user_id, created_at") + .eq("user_id", user_id) + .eq("project_id", project_id) + .maybeSingle(); +} + +export async function insertFollow(client: SupabaseClient, user_id: string, project_id: number) { + const { error } = await client.from("follow").insert({ user_id, project_id }).select(); + + if (error) { + return error; + } + + return null; +} + +export async function deleteFollow(client: SupabaseClient, user_id: string, project_id: number) { + const { error } = await client.from("follow").delete().eq("user_id", user_id).eq("project_id", project_id); + + if (error) { + return error; + } + return null; +}