mirror of
https://github.com/Sosokker/B2D-Ventures.git
synced 2025-12-20 14:34:05 +01:00
feat: follow button
This commit is contained in:
parent
67a1fe0f7f
commit
fa24222760
@ -2,24 +2,22 @@
|
|||||||
|
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
|
|
||||||
import { useState, useEffect } from "react";
|
import { useState } from "react";
|
||||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
|
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
|
||||||
import { ShareIcon, StarIcon } from "lucide-react";
|
import { ShareIcon, StarIcon } from "lucide-react";
|
||||||
import { redirect } from "next/navigation";
|
import { deleteFollow, insertFollow } from "@/lib/data/followQuery";
|
||||||
import useSession from "@/lib/supabase/useSession";
|
|
||||||
import toast from "react-hot-toast";
|
import toast from "react-hot-toast";
|
||||||
|
import { createSupabaseClient } from "@/lib/supabase/clientComponentClient";
|
||||||
|
|
||||||
const FollowShareButtons = () => {
|
interface FollowShareButtons {
|
||||||
const { session, loading } = useSession();
|
isFollow: boolean;
|
||||||
const user = session?.user;
|
userId: string;
|
||||||
const [sessionLoaded, setSessionLoaded] = useState(false);
|
projectId: number;
|
||||||
const [isFollow, setIsFollow] = useState(false);
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
const FollowShareButtons = ({ isFollow, userId, projectId }: FollowShareButtons) => {
|
||||||
if (!loading) {
|
const supabase = createSupabaseClient();
|
||||||
setSessionLoaded(true);
|
const [isFollowState, setIsFollowState] = useState<boolean>(isFollow);
|
||||||
}
|
|
||||||
}, [loading]);
|
|
||||||
|
|
||||||
const handleShare = () => {
|
const handleShare = () => {
|
||||||
const currentUrl = window.location.href;
|
const currentUrl = window.location.href;
|
||||||
@ -29,11 +27,23 @@ const FollowShareButtons = () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const handleFollow = () => {
|
const handleFollow = async () => {
|
||||||
if (user) {
|
if (!isFollowState) {
|
||||||
setIsFollow((prevState) => !prevState);
|
const error = await insertFollow(supabase, userId, projectId);
|
||||||
|
if (error) {
|
||||||
|
toast.error("Error occur!");
|
||||||
} else {
|
} else {
|
||||||
redirect("/login");
|
toast.success("You have followed the project!", { icon: "❤️" });
|
||||||
|
setIsFollowState(true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
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 = () => {
|
|||||||
<TooltipProvider>
|
<TooltipProvider>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<StarIcon id="follow" fill={isFollow ? "#FFFF00" : "#fff"} strokeWidth={2} />
|
<StarIcon id="follow" fill={isFollowState ? "#fcb30e" : "#fff"} strokeWidth={2} />
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
<TooltipContent>
|
<TooltipContent>
|
||||||
<p>Follow NVIDIA</p>
|
<p>Follow NVIDIA</p>
|
||||||
|
|||||||
@ -17,6 +17,7 @@ import { getDealList } from "@/app/api/dealApi";
|
|||||||
import { sumByKey, toPercentage } from "@/lib/utils";
|
import { sumByKey, toPercentage } from "@/lib/utils";
|
||||||
import { redirect } from "next/navigation";
|
import { redirect } from "next/navigation";
|
||||||
import { isOwnerOfProject } from "./query";
|
import { isOwnerOfProject } from "./query";
|
||||||
|
import { getFollow } from "@/lib/data/followQuery";
|
||||||
import remarkGfm from "remark-gfm";
|
import remarkGfm from "remark-gfm";
|
||||||
|
|
||||||
const PHOTO_MATERIAL_ID = 2;
|
const PHOTO_MATERIAL_ID = 2;
|
||||||
@ -25,13 +26,12 @@ export default async function ProjectDealPage({ params }: { params: { id: number
|
|||||||
const supabase = createSupabaseClient();
|
const supabase = createSupabaseClient();
|
||||||
const { data: projectData, error: projectDataError } = await getProjectData(supabase, params.id);
|
const { data: projectData, error: projectDataError } = await getProjectData(supabase, params.id);
|
||||||
const { data: user, error: userError } = await supabase.auth.getUser();
|
const { data: user, error: userError } = await supabase.auth.getUser();
|
||||||
|
|
||||||
const { data: projectMaterial, error: projectMaterialError } = await supabase
|
const { data: projectMaterial, error: projectMaterialError } = await supabase
|
||||||
.from("project_material")
|
.from("project_material")
|
||||||
.select("material_url")
|
.select("material_url")
|
||||||
.eq("project_id", params.id)
|
.eq("project_id", params.id)
|
||||||
.eq("material_type_id", PHOTO_MATERIAL_ID);
|
.eq("material_type_id", PHOTO_MATERIAL_ID);
|
||||||
// console.log(projectMaterial);
|
|
||||||
if (projectMaterialError) {
|
if (projectMaterialError) {
|
||||||
console.error("Error while fetching project material" + projectMaterialError);
|
console.error("Error while fetching project material" + projectMaterialError);
|
||||||
}
|
}
|
||||||
@ -43,9 +43,9 @@ export default async function ProjectDealPage({ params }: { params: { id: number
|
|||||||
return (
|
return (
|
||||||
<div className="container max-w-screen-xl my-5">
|
<div className="container max-w-screen-xl my-5">
|
||||||
<p className="text-red-600">Error fetching data. Please try again.</p>
|
<p className="text-red-600">Error fetching data. Please try again.</p>
|
||||||
<Button className="mt-4" onClick={() => window.location.reload()}>
|
<Link href={`/deals/${params.id}`} className="mt-4">
|
||||||
Refresh
|
<Button className="mt-4">Refresh</Button>
|
||||||
</Button>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -54,12 +54,32 @@ export default async function ProjectDealPage({ params }: { params: { id: number
|
|||||||
return (
|
return (
|
||||||
<div className="container max-w-screen-xl my-5">
|
<div className="container max-w-screen-xl my-5">
|
||||||
<p className="text-red-600">Error fetching data. Please try again.</p>
|
<p className="text-red-600">Error fetching data. Please try again.</p>
|
||||||
<Button className="mt-4" onClick={() => window.location.reload()}>
|
<Link href={`/deals/${params.id}`} className="mt-4">
|
||||||
Refresh
|
<Button className="mt-4">Refresh</Button>
|
||||||
</Button>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
const { data: follow, error: followError } = await getFollow(supabase, user!.user.id, params.id);
|
||||||
|
|
||||||
|
if (followError) {
|
||||||
|
return (
|
||||||
|
<div className="flex items-center justify-center h-screen">
|
||||||
|
<div className="container max-w-screen-xl text-center">
|
||||||
|
<p className="text-red-600">Error fetching data. Please try again.</p>
|
||||||
|
<p className="text-red-600">{followError.message}</p>
|
||||||
|
<Link href={`/deals/${params.id}`}>
|
||||||
|
<Button className="mt-4">Refresh</Button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let isFollow = false;
|
||||||
|
if (follow) {
|
||||||
|
isFollow = true;
|
||||||
|
}
|
||||||
|
|
||||||
const isOwner = await isOwnerOfProject(supabase, params.id, user.user?.id);
|
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" }];
|
: [{ src: "/boiler1.jpg", alt: "Default Boiler Image" }];
|
||||||
|
|
||||||
// console.log(carouselData);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="container max-w-screen-xl my-5">
|
<div className="container max-w-screen-xl my-5">
|
||||||
<div className="flex flex-col gap-y-10">
|
<div className="flex flex-col gap-y-10">
|
||||||
@ -92,7 +110,7 @@ export default async function ProjectDealPage({ params }: { params: { id: number
|
|||||||
<Image src="/logo.svg" alt="logo" width={50} height={50} className="sm:scale-75" />
|
<Image src="/logo.svg" alt="logo" width={50} height={50} className="sm:scale-75" />
|
||||||
<h1 className="mt-3 font-bold text-lg md:text-3xl">{projectData?.project_name}</h1>
|
<h1 className="mt-3 font-bold text-lg md:text-3xl">{projectData?.project_name}</h1>
|
||||||
</span>
|
</span>
|
||||||
<FollowShareButtons />
|
<FollowShareButtons isFollow={isFollow} userId={user!.user.id} projectId={params.id} />
|
||||||
</div>
|
</div>
|
||||||
{/* end of pack */}
|
{/* end of pack */}
|
||||||
<p className="mt-2 sm:text-sm">{projectData?.project_short_description}</p>
|
<p className="mt-2 sm:text-sm">{projectData?.project_short_description}</p>
|
||||||
|
|||||||
29
src/lib/data/followQuery.ts
Normal file
29
src/lib/data/followQuery.ts
Normal file
@ -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;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user