diff --git a/src/app/(investment)/deals/ShowFilter.tsx b/src/app/(investment)/deals/ShowFilter.tsx new file mode 100644 index 0000000..2930030 --- /dev/null +++ b/src/app/(investment)/deals/ShowFilter.tsx @@ -0,0 +1,53 @@ +import { Button } from "@/components/ui/button"; +import { FilterParams } from "@/lib/data/projectQuery"; + +export const ShowFilter = ({ filterParams, clearAll }: { filterParams: FilterParams; clearAll: () => void }) => { + const { searchTerm, tagFilter, projectStatusFilter, businessTypeFilter } = filterParams; + + if (!searchTerm && !tagFilter && !projectStatusFilter && !businessTypeFilter) { + return
; + } + + if (projectStatusFilter === "all" && businessTypeFilter === "all" && tagFilter === "all") { + return
; + } + + return ( +
+ {searchTerm && ( + + )} + + {tagFilter && tagFilter !== "all" && ( + + )} + + {projectStatusFilter && projectStatusFilter !== "all" && ( + + )} + + {businessTypeFilter && businessTypeFilter !== "all" && ( + + )} + + {/* {sortByTimeFilter && sortByTimeFilter !== "all" && ( + + )} */} + + {/* Clear All button */} + +
+ ); +}; diff --git a/src/app/(investment)/deals/page.tsx b/src/app/(investment)/deals/page.tsx index 0f0697b..0559c19 100644 --- a/src/app/(investment)/deals/page.tsx +++ b/src/app/(investment)/deals/page.tsx @@ -4,186 +4,84 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@ import { useEffect, useState } from "react"; import { Clock3Icon, UserIcon, UsersIcon } from "lucide-react"; import { Separator } from "@/components/ui/separator"; -import { ProjectCard } from "@/components/projectCard"; -import { getALlFundedStatusQuery, getAllBusinessTypeQuery } from "@/lib/data/dropdownQuery"; +import { getAllBusinessTypeQuery, getAllTagsQuery, getAllProjectStatusQuery } from "@/lib/data/dropdownQuery"; import { createSupabaseClient } from "@/lib/supabase/clientComponentClient"; import { useQuery } from "@supabase-cache-helpers/postgrest-react-query"; import { searchProjectsQuery, FilterParams, FilterProjectQueryParams } from "@/lib/data/projectQuery"; import { Input } from "@/components/ui/input"; +import { ProjectSection } from "@/components/ProjectSection"; +import { ShowFilter } from "./ShowFilter"; import { Button } from "@/components/ui/button"; -import Link from "next/link"; - -interface Project { - project_id: string; - project_name: string; - published_time: string; - project_short_description: string; - card_image_url: string; - project_status: { - value: string; - }; - min_investment: number; - total_investment: number; - target_investment: number; - investment_deadline: string; - tags: { - tag_name: string; - }[]; - business_type: { - value: string; - }; - business_location: string; -} - -const ProjectSection = ({ filteredProjects }: { filteredProjects: Project[] }) => { - interface Tags { - tag_name: string; - } - - if (!filteredProjects) { - return
No projects found!
; - } - - return ( -
-
-

Deals

-

The deals attracting the most interest right now

-
- - {/* Block for all the deals */} -
- {filteredProjects.map((item, index) => ( - - tag.tag_name)} - /> - - ))} -
-
- ); -}; - -const ShowFilter = ({ filterParams, clearAll }: { filterParams: FilterParams; clearAll: () => void }) => { - const { searchTerm, tagsFilter, projectStatusFilter, businessTypeFilter, sortByTimeFilter } = filterParams; - - if (!searchTerm && !tagsFilter && !projectStatusFilter && !businessTypeFilter && !sortByTimeFilter) { - return
; - } - - if ( - projectStatusFilter === "all" && - businessTypeFilter === "all" && - sortByTimeFilter === "all" && - (!tagsFilter || tagsFilter.length === 0) - ) { - return
; - } - - return ( -
- {searchTerm && ( - - )} - - {tagsFilter && - tagsFilter.map((tag: string) => ( - - ))} - - {projectStatusFilter && projectStatusFilter !== "all" && ( - - )} - - {businessTypeFilter && businessTypeFilter !== "all" && ( - - )} - - {sortByTimeFilter && sortByTimeFilter !== "all" && ( - - )} - - {/* Clear All button */} - -
- ); -}; export default function Deals() { const supabase = createSupabaseClient(); const [searchTerm, setSearchTerm] = useState(""); - const [searchTermVisual, setSearchTermVisual] = useState(""); - const [sortByTimeFilter, setSortByTimeFilter] = useState("all"); + const [searchTermVisual, setSearchTermVisual] = useState(""); // For the input field + // const [sortByTimeFilter, setSortByTimeFilter] = useState("all"); const [businessTypeFilter, setBusinessTypeFilter] = useState("all"); - const [tagFilter, setTagFilter] = useState([]); + const [tagFilter, setTagFilter] = useState("all"); const [projectStatusFilter, setProjectStatusFilter] = useState("all"); const [page, setPage] = useState(1); const [pageSize, setPageSize] = useState(4); const filterParams: FilterParams = { searchTerm, - tagsFilter: tagFilter, + tagFilter, projectStatusFilter, businessTypeFilter, - sortByTimeFilter, + // sortByTimeFilter, }; - const filterProjectQueryParams: FilterProjectQueryParams = { - searchTerm: "", - tagsFilter: [], - projectStatusFilter: "all", - businessTypeFilter: "all", - sortByTimeFilter: "all", + let filterProjectQueryParams: FilterProjectQueryParams = { + searchTerm, + tagFilter, + projectStatusFilter, + businessTypeFilter, + // sortByTimeFilter, page, pageSize, }; + const { data: tagData, isLoading: isLoadingTag, error: isTagError } = useQuery(getAllTagsQuery(supabase)); const { - data: projectStatus, - isLoading: isLoadingFunded, - error: fundedLoadingError, - } = useQuery(getALlFundedStatusQuery(supabase)); + data: projectStatusData, + isLoading: isLoadingprojectStatus, + error: isprojectStatusError, + } = useQuery(getAllProjectStatusQuery(supabase)); const { data: businessType, isLoading: isLoadingBusinessType, error: businessTypeLoadingError, } = useQuery(getAllBusinessTypeQuery(supabase)); - const { data: projects, isLoading: isLoadingProjects, error: projectsLoadingError, + refetch, } = useQuery(searchProjectsQuery(supabase, filterProjectQueryParams)); + const formattedProjects = + projects?.map((project) => ({ + id: project.project_id, + project_name: project.project_name, + short_description: project.project_short_description, + image_url: project.card_image_url, + join_date: new Date(project.published_time).toLocaleDateString(), + location: project.business_location, + tags: project.tags.map((tag) => tag.tag_name), + min_investment: project.min_investment || 0, + total_investor: project.total_investment || 0, + total_raise: project.total_investment || 0, + })) || []; + const clearAll = () => { setSearchTerm(""); - setTagFilter([]); + setSearchTermVisual(""); + setTagFilter("all"); setProjectStatusFilter("all"); setBusinessTypeFilter("all"); - setSortByTimeFilter("all"); + // setSortByTimeFilter("all"); }; const handlePageSizeChange = (value: number) => { @@ -191,9 +89,10 @@ export default function Deals() { setPage(1); }; - useEffect(() => { + const handleSearchClick = () => { setSearchTerm(searchTermVisual); - }, [searchTermVisual]); + refetch(); + }; return (
@@ -214,13 +113,17 @@ export default function Deals() { onChange={(e) => setSearchTermVisual(e.target.value)} onKeyDown={(e) => { if (e.key === "Enter") { - setSearchTerm(e.currentTarget.value); + handleSearchClick(); } }} /> + + {/* Posted At Filter */} - setSortByTimeFilter(value)}> @@ -231,10 +134,10 @@ export default function Deals() { This Week This Month - + */} {/* Business Type Filter */} - setBusinessTypeFilter(value)}> @@ -263,25 +166,25 @@ export default function Deals() { {/* Project Status Filter */} - setProjectStatusFilter(value)}> - {isLoadingFunded ? ( + {isLoadingprojectStatus ? ( Loading... - ) : fundedLoadingError ? ( + ) : isprojectStatusError ? ( No data available ) : ( <> All Statuses - {projectStatus && - projectStatus.map((status) => ( + {projectStatusData && + projectStatusData.map((status) => ( {status.value} @@ -290,21 +193,51 @@ export default function Deals() { )} + + {/* Tags Filter */} +
{/* Active Filters */} + - + {/* Project Cards Section */} {isLoadingProjects ? (
Loading...
) : projectsLoadingError ? ( -
Error loading projects.
- ) : projects ? ( - +
Error loading projects
) : ( -
No projects found!
+
+ +
)} {/* Pagination Controls */}
diff --git a/src/lib/data/dropdownQuery.ts b/src/lib/data/dropdownQuery.ts index 2216190..17ccd4c 100644 --- a/src/lib/data/dropdownQuery.ts +++ b/src/lib/data/dropdownQuery.ts @@ -12,4 +12,8 @@ function getAllBusinessTypeQuery(client: SupabaseClient) { return client.from("business_type").select("id, value, description"); } -export { getAllBusinessTypeQuery, getALlFundedStatusQuery, getAllTagsQuery }; +function getAllProjectStatusQuery(client: SupabaseClient) { + return client.from("project_status").select("id, value, description"); +} + +export { getAllBusinessTypeQuery, getALlFundedStatusQuery, getAllTagsQuery, getAllProjectStatusQuery }; diff --git a/src/lib/data/projectQuery.ts b/src/lib/data/projectQuery.ts index ce457b8..719f799 100644 --- a/src/lib/data/projectQuery.ts +++ b/src/lib/data/projectQuery.ts @@ -96,7 +96,7 @@ async function getProjectData(client: SupabaseClient, projectId: number) { export interface FilterParams { searchTerm?: string; - tagsFilter?: string[]; + tagFilter?: string; projectStatus?: string; projectStatusFilter?: string; businessTypeFilter?: string; @@ -112,8 +112,8 @@ function searchProjectsQuery( client: SupabaseClient, { searchTerm, - tagsFilter, - projectStatus, + tagFilter, + projectStatusFilter, businessTypeFilter, sortByTimeFilter, page = 1, @@ -121,7 +121,7 @@ function searchProjectsQuery( }: FilterProjectQueryParams ) { const start = (page - 1) * pageSize; - const end = start + pageSize; + const end = start + pageSize - 1; let query = client .from("project") @@ -132,8 +132,8 @@ function searchProjectsQuery( published_time, project_short_description, card_image_url, - ...project_status!inner ( - project_status:value + project_status!inner ( + value ), ...project_investment_detail!inner ( min_investment, @@ -154,42 +154,29 @@ function searchProjectsQuery( ) ` ) - .order("published_time", { ascending: false }) .range(start, end); - if (sortByTimeFilter === "all") { - sortByTimeFilter = undefined; + // if (sortByTimeFilter && sortByTimeFilter !== "all") { + // query = query.eq("published_time", sortByTimeFilter); + // } + + if (projectStatusFilter && projectStatusFilter !== "all") { + query = query.eq("project_status.value", projectStatusFilter); } - if (projectStatus === "all") { - projectStatus = undefined; + if (businessTypeFilter && businessTypeFilter !== "all") { + query = query.eq("business.business_type.value", businessTypeFilter); } - if (businessTypeFilter === "all") { - businessTypeFilter = undefined; - } - - if (tagsFilter?.length === 0) { - tagsFilter = undefined; + if (tagFilter && tagFilter !== "all") { + query = query.in("tags.tag_name", [tagFilter]); } if (searchTerm) { query = query.ilike("project_name", `%${searchTerm}%`); } - if (tagsFilter) { - query = query.in("project_tag.tag.value", tagsFilter); - } - - if (projectStatus) { - query = query.eq("project_status.value", projectStatus); - } - - if (businessTypeFilter) { - query = query.eq("business.business_type.value", businessTypeFilter); - } - - return query; + return query.order("published_time", { ascending: false }); } const getProjectByBusinessId = (client: SupabaseClient, businessIds: string[]) => {