From 45ff12f1a63ef5061626ae45f7ed5e7fd25bed2b Mon Sep 17 00:00:00 2001 From: Mehul Date: Thu, 7 Nov 2024 14:39:14 -0500 Subject: [PATCH 01/14] rebase --- .../(community)/explore-community/page.tsx | 252 +++++++++++++++++- 1 file changed, 247 insertions(+), 5 deletions(-) diff --git a/src/app/(community)/explore-community/page.tsx b/src/app/(community)/explore-community/page.tsx index 4583406..fe20604 100644 --- a/src/app/(community)/explore-community/page.tsx +++ b/src/app/(community)/explore-community/page.tsx @@ -1,7 +1,249 @@ -import React from "react"; +"use client"; +import React, { useState, useEffect, useMemo } from "react"; +import { useSession } from "@supabase/auth-helpers-react"; +import { supabase } from "../../../utils/supabase"; +import { toast } from "sonner"; +import Pagination from "../../../components/Pagination"; +import Loading from "../../../components/loading"; +import { HeartIcon } from "@heroicons/react/solid"; +import { useUserDetails } from "../../../hooks/useUserDetails"; +import Link from "next/link"; +import { motion } from "framer-motion"; +import { CalendarIcon, MapPinIcon } from "lucide-react"; -function page() { - return
page
; -} +const Page: React.FC = () => { + // Define types + interface Community { + id: string; + community_name: string; + community_description: string; + community_location: string; + community_category: string; + community_members_count: number; + community_likes: number; + community_image: string; + community_creation_date: string; + } -export default page; + // State hooks + const [loading, setLoading] = useState(true); + const [communities, setCommunities] = useState([]); + const [currentPage, setCurrentPage] = useState(1); + const [itemsPerPage, setItemsPerPage] = useState(9); + const [likedCommunities, setLikedCommunities] = useState<{ [key: string]: boolean }>({}); + const [searchTerm, setSearchTerm] = useState(""); + const [category, setCategory] = useState(""); + const [sortByLikes, setSortByLikes] = useState(""); + const session = useSession(); + const { user } = useUserDetails(); + + useEffect(() => { + async function fetchCommunities() { + const { data, error } = await supabase.from("communities").select("*"); + if (error) { + console.error("Error fetching communities:", error); + toast.error("Failed to load communities. Please try again later."); + } else { + setCommunities(data); + } + setLoading(false); + } + + fetchCommunities(); + }, []); + + const handleLikeToggle = async (communityId: string) => { + if (!user) { + toast.error("You must be logged in to like a community."); + return; + } + + const useremail = user.email; + const { data: likedData, error: checkError } = await supabase + .from("community_likes") + .select("community_id") + .eq("community_id", communityId) + .eq("useremail", useremail); + + if (checkError) { + console.error("Error checking likes:", checkError); + return; + } + + const isLiked = likedData.length > 0; + + let communityData; + const { data: fetchedCommunityData, error: fetchError } = await supabase + .from("communities") + .select("community_likes") + .eq("id", communityId) + .single(); + + if (fetchError) { + console.error("Error fetching community likes:", fetchError); + return; + } + + communityData = fetchedCommunityData; + + if (isLiked) { + const { error: unlikeError } = await supabase + .from("community_likes") + .delete() + .eq("community_id", communityId) + .eq("useremail", useremail); + + if (unlikeError) { + console.error("Error unliking community:", unlikeError); + return; + } + + const newLikesCount = communityData.community_likes - 1; + await supabase + .from("communities") + .update({ community_likes: newLikesCount }) + .eq("id", communityId); + + setLikedCommunities((prev) => ({ + ...prev, + [communityId]: false, + })); + } else { + const { error: likeError } = await supabase + .from("community_likes") + .insert({ community_id: communityId, useremail }); + + if (likeError) { + console.error("Error liking community:", likeError); + return; + } + + const newLikesCount = communityData.community_likes + 1; + await supabase + .from("communities") + .update({ community_likes: newLikesCount }) + .eq("id", communityId); + + setLikedCommunities((prev) => ({ + ...prev, + [communityId]: true, + })); + } + }; + + // Filtering and sorting communities + const filteredAndSortedCommunities = useMemo(() => { + return communities + .filter((community) => { + const matchesCategory = category ? community.community_category === category : true; + const matchesSearchTerm = + community.community_name.toLowerCase().includes(searchTerm.toLowerCase()) || + community.community_location.toLowerCase().includes(searchTerm.toLowerCase()); + return matchesCategory && matchesSearchTerm; + }) + .sort((a, b) => { + if (sortByLikes === "high") { + return b.community_likes - a.community_likes; + } else if (sortByLikes === "low") { + return a.community_likes - b.community_likes; + } + return 0; + }); + }, [communities, searchTerm, category, sortByLikes]); + + const indexOfLastItem = currentPage * itemsPerPage; + const indexOfFirstItem = indexOfLastItem - itemsPerPage; + const currentCommunities = filteredAndSortedCommunities.slice(indexOfFirstItem, indexOfLastItem); + + const totalPages = Math.ceil(filteredAndSortedCommunities.length / itemsPerPage); + + if (loading) { + return ; + } + + return ( + <> +
+
+
+
+ setSearchTerm(e.target.value)} + /> + + +
+
+ +
+ {currentCommunities.map((community) => ( + + {community.community_name} +

{community.community_name}

+

{community.community_description}

+
+
+ handleLikeToggle(community.id)} + /> + {community.community_likes} Likes +
+ + View Community + +
+
+ ))} +
+ +
+ setCurrentPage(page)} + /> +
+
+
+ + ); +}; + +export default Page; From 76f82746ec7042d6bd5b112514aca2808a2915d1 Mon Sep 17 00:00:00 2001 From: Mehul Date: Thu, 7 Nov 2024 14:57:15 -0500 Subject: [PATCH 02/14] added search icon --- .../(community)/explore-community/page.tsx | 45 +++++++++++++------ 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/src/app/(community)/explore-community/page.tsx b/src/app/(community)/explore-community/page.tsx index fe20604..6daca36 100644 --- a/src/app/(community)/explore-community/page.tsx +++ b/src/app/(community)/explore-community/page.tsx @@ -10,6 +10,7 @@ import { useUserDetails } from "../../../hooks/useUserDetails"; import Link from "next/link"; import { motion } from "framer-motion"; import { CalendarIcon, MapPinIcon } from "lucide-react"; +import { SearchIcon } from '@heroicons/react/solid'; // Import the search icon const Page: React.FC = () => { // Define types @@ -131,6 +132,11 @@ const Page: React.FC = () => { } }; + const handleSearchClick = () => { + // Perform search action here + console.log("Search clicked!"); + }; + // Filtering and sorting communities const filteredAndSortedCommunities = useMemo(() => { return communities @@ -168,36 +174,47 @@ const Page: React.FC = () => { loading ? `px-0` : `px-4` }`} > +
+ Explore Communities +
-
+
- setSearchTerm(e.target.value)} - /> - setSearchTerm(e.target.value)} + /> + {/* Clickable Search Icon */} +
+
+
+ - setSortByLikes(e.target.value)} - > + > - +
From aa822f4e55a4cb0847d12444c14294c29cbb4da8 Mon Sep 17 00:00:00 2001 From: Mehul Date: Thu, 7 Nov 2024 15:19:47 -0500 Subject: [PATCH 03/14] remove likes --- .../(community)/explore-community/page.tsx | 362 ++++++++++-------- 1 file changed, 199 insertions(+), 163 deletions(-) diff --git a/src/app/(community)/explore-community/page.tsx b/src/app/(community)/explore-community/page.tsx index 6daca36..4086c4d 100644 --- a/src/app/(community)/explore-community/page.tsx +++ b/src/app/(community)/explore-community/page.tsx @@ -5,11 +5,9 @@ import { supabase } from "../../../utils/supabase"; import { toast } from "sonner"; import Pagination from "../../../components/Pagination"; import Loading from "../../../components/loading"; -import { HeartIcon } from "@heroicons/react/solid"; import { useUserDetails } from "../../../hooks/useUserDetails"; import Link from "next/link"; import { motion } from "framer-motion"; -import { CalendarIcon, MapPinIcon } from "lucide-react"; import { SearchIcon } from '@heroicons/react/solid'; // Import the search icon const Page: React.FC = () => { @@ -21,7 +19,6 @@ const Page: React.FC = () => { community_location: string; community_category: string; community_members_count: number; - community_likes: number; community_image: string; community_creation_date: string; } @@ -31,10 +28,18 @@ const Page: React.FC = () => { const [communities, setCommunities] = useState([]); const [currentPage, setCurrentPage] = useState(1); const [itemsPerPage, setItemsPerPage] = useState(9); - const [likedCommunities, setLikedCommunities] = useState<{ [key: string]: boolean }>({}); const [searchTerm, setSearchTerm] = useState(""); const [category, setCategory] = useState(""); const [sortByLikes, setSortByLikes] = useState(""); + const [showAddCommunityForm, setShowAddCommunityForm] = useState(false); // To toggle the form visibility + const [newCommunity, setNewCommunity] = useState({ + community_name: "", + community_description: "", + community_location: "", + community_category: "", + community_image: "", + }); + const session = useSession(); const { user } = useUserDetails(); @@ -45,7 +50,7 @@ const Page: React.FC = () => { console.error("Error fetching communities:", error); toast.error("Failed to load communities. Please try again later."); } else { - setCommunities(data); + setCommunities(data || []); // Set default to empty array if data is null } setLoading(false); } @@ -53,91 +58,53 @@ const Page: React.FC = () => { fetchCommunities(); }, []); - const handleLikeToggle = async (communityId: string) => { - if (!user) { - toast.error("You must be logged in to like a community."); - return; - } - - const useremail = user.email; - const { data: likedData, error: checkError } = await supabase - .from("community_likes") - .select("community_id") - .eq("community_id", communityId) - .eq("useremail", useremail); + const handleSearchClick = () => { + // Perform search action here + console.log("Search clicked!"); + }; - if (checkError) { - console.error("Error checking likes:", checkError); - return; - } + const handleFormSubmit = async (e: React.FormEvent) => { + e.preventDefault(); - const isLiked = likedData.length > 0; + const { community_name, community_description, community_location, community_category, community_image } = newCommunity; - let communityData; - const { data: fetchedCommunityData, error: fetchError } = await supabase + const { data, error } = await supabase .from("communities") - .select("community_likes") - .eq("id", communityId) - .single(); - - if (fetchError) { - console.error("Error fetching community likes:", fetchError); - return; - } - - communityData = fetchedCommunityData; - - if (isLiked) { - const { error: unlikeError } = await supabase - .from("community_likes") - .delete() - .eq("community_id", communityId) - .eq("useremail", useremail); - - if (unlikeError) { - console.error("Error unliking community:", unlikeError); - return; - } + .insert([ + { + community_name, + community_description, + community_location, + community_category, + community_image, + community_members_count: 0, // Initialize with 0 members + community_creation_date: new Date().toISOString(), + }, + ]); - const newLikesCount = communityData.community_likes - 1; - await supabase - .from("communities") - .update({ community_likes: newLikesCount }) - .eq("id", communityId); - - setLikedCommunities((prev) => ({ - ...prev, - [communityId]: false, - })); + if (error) { + toast.error("Failed to create community."); + console.error("Error creating community:", error); } else { - const { error: likeError } = await supabase - .from("community_likes") - .insert({ community_id: communityId, useremail }); + toast.success("Community created successfully!"); + setShowAddCommunityForm(false); // Hide form after submission + setNewCommunity({ + community_name: "", + community_description: "", + community_location: "", + community_category: "", + community_image: "", + }); - if (likeError) { - console.error("Error liking community:", likeError); - return; + // Ensure that `data` is an array before updating the state + if (Array.isArray(data)) { + setCommunities((prev) => [...prev, ...data]); + } else { + console.error("Data returned is not an array:", data); } - - const newLikesCount = communityData.community_likes + 1; - await supabase - .from("communities") - .update({ community_likes: newLikesCount }) - .eq("id", communityId); - - setLikedCommunities((prev) => ({ - ...prev, - [communityId]: true, - })); } }; - const handleSearchClick = () => { - // Perform search action here - console.log("Search clicked!"); - }; - - // Filtering and sorting communities const filteredAndSortedCommunities = useMemo(() => { return communities .filter((community) => { @@ -149,9 +116,9 @@ const Page: React.FC = () => { }) .sort((a, b) => { if (sortByLikes === "high") { - return b.community_likes - a.community_likes; + return b.community_members_count - a.community_members_count; // Sorting based on members count } else if (sortByLikes === "low") { - return a.community_likes - b.community_likes; + return a.community_members_count - b.community_members_count; } return 0; }); @@ -168,98 +135,167 @@ const Page: React.FC = () => { } return ( - <> -
-
+
+
Explore Communities -
-
-
-
+
+ +
+
+
- setSearchTerm(e.target.value)} - /> - {/* Clickable Search Icon */} -
+ setSearchTerm(e.target.value)} + /> + {/* Clickable Search Icon */} +
+ +
+ + +
- - + +
+ {currentCommunities.map((community) => ( + + {community.community_name} +

{community.community_name}

+

{community.community_description}

+
+ + View Community + +
+
+ ))} +
+ +
+ setCurrentPage(page)} + />
-
- {currentCommunities.map((community) => ( - - {community.community_name} -

{community.community_name}

-

{community.community_description}

-
-
- handleLikeToggle(community.id)} + {/* Add Community Form Modal */} + {showAddCommunityForm && ( +
+
+

Add New Community

+
+
+ + setNewCommunity({ ...newCommunity, community_name: e.target.value })} + required /> - {community.community_likes} Likes
- - View Community - -
- - ))} -
- -
- setCurrentPage(page)} - /> -
-
+
+ +