fixes and architecture
This commit is contained in:
1 parent
ce98f270d5
commit
dd43fa04c1
104 files changed
+7098
-5198
No files matched your search
@@ -0,0 +1,70 @@
|
||||
"use client";
|
||||
import { useState, useMemo } from "react";
|
||||
import { useSearchParams } from "next/navigation";
|
||||
import { mockCourses } from "@/data/mockCourses";
|
||||
|
||||
function toggleItem(arr: string[], val: string): string[] {
|
||||
return arr.includes(val) ? arr.filter((x) => x !== val) : [...arr, val];
|
||||
}
|
||||
|
||||
export function useFilters() {
|
||||
const searchParams = useSearchParams();
|
||||
|
||||
const [search, setSearch] = useState(searchParams.get("q") ?? "");
|
||||
const [selectedCategories, setSelectedCategories] = useState<string[]>(() => {
|
||||
const cat = searchParams.get("cat");
|
||||
return cat ? [cat] : [];
|
||||
});
|
||||
const [selectedLevels, setSelectedLevels] = useState<string[]>([]);
|
||||
const [minRating, setMinRating] = useState<number | null>(null);
|
||||
const [maxPrice, setMaxPrice] = useState<number | null>(null);
|
||||
const [sort, setSort] = useState("popular");
|
||||
|
||||
const toggleCategory = (val: string) => setSelectedCategories((prev) => toggleItem(prev, val));
|
||||
const toggleLevel = (val: string) => setSelectedLevels((prev) => toggleItem(prev, val));
|
||||
const toggleRating = (r: number) => setMinRating((prev) => (prev === r ? null : r));
|
||||
const togglePrice = (p: number) => setMaxPrice((prev) => (prev === p ? null : p));
|
||||
|
||||
const activeFiltersCount =
|
||||
selectedCategories.length + selectedLevels.length + (minRating ? 1 : 0) + (maxPrice ? 1 : 0);
|
||||
|
||||
const clearAll = () => {
|
||||
setSearch("");
|
||||
setSelectedCategories([]);
|
||||
setSelectedLevels([]);
|
||||
setMinRating(null);
|
||||
setMaxPrice(null);
|
||||
};
|
||||
|
||||
const filtered = useMemo(() => {
|
||||
let list = [...mockCourses];
|
||||
if (search)
|
||||
list = list.filter(
|
||||
(c) =>
|
||||
c.title.toLowerCase().includes(search.toLowerCase()) ||
|
||||
c.subtitle.toLowerCase().includes(search.toLowerCase()),
|
||||
);
|
||||
if (selectedCategories.length) list = list.filter((c) => selectedCategories.includes(c.category));
|
||||
if (selectedLevels.length) list = list.filter((c) => selectedLevels.includes(c.level));
|
||||
if (minRating) list = list.filter((c) => c.rating >= minRating);
|
||||
if (maxPrice) list = list.filter((c) => c.price <= maxPrice);
|
||||
switch (sort) {
|
||||
case "rating": list.sort((a, b) => b.rating - a.rating); break;
|
||||
case "price_lo": list.sort((a, b) => a.price - b.price); break;
|
||||
case "price_hi": list.sort((a, b) => b.price - a.price); break;
|
||||
case "newest": list.sort((a, b) => (b.badge === "Nuevo" ? 1 : 0) - (a.badge === "Nuevo" ? 1 : 0)); break;
|
||||
default: list.sort((a, b) => b.studentsCount - a.studentsCount);
|
||||
}
|
||||
return list;
|
||||
}, [search, selectedCategories, selectedLevels, minRating, maxPrice, sort]);
|
||||
|
||||
return {
|
||||
search, setSearch,
|
||||
selectedCategories, toggleCategory,
|
||||
selectedLevels, toggleLevel,
|
||||
minRating, toggleRating,
|
||||
maxPrice, togglePrice,
|
||||
sort, setSort,
|
||||
activeFiltersCount, clearAll, filtered,
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user