diff --git a/apps/frontend/components/home/featured-products.tsx b/apps/frontend/components/home/featured-products.tsx index 9a5865ca..5ee044e5 100644 --- a/apps/frontend/components/home/featured-products.tsx +++ b/apps/frontend/components/home/featured-products.tsx @@ -29,7 +29,7 @@ export function FeaturedProducts() {

- {t("common.featuredProductsTitle.title")} + {t("common.featuredProductsTitle.title")}

void; +} + +export default function MarketplaceFilters({ + onFilterChange, +}: MarketplaceFiltersProps) { + const t = useTranslations(); + const [showFilters, setShowFilters] = useState(true); + const [activeFilters, setActiveFilters] = useState([]); + + const [categoryFilter, setCategoryFilter] = useState("electronics"); + const [priceRange, setPriceRange] = useState<[number, number]>([970, 5000]); + const [conditionFilter, setConditionFilter] = useState(["new"]); + const [sellerRatingFilter, setSellerRatingFilter] = useState("4"); + const [postedWithinFilter, setPostedWithinFilter] = useState("24h"); + const [sortByFilter, setSortByFilter] = useState("price_low_high"); + + const updateActiveFilters = useCallback(() => { + const newActiveFilters = []; + if (categoryFilter) + newActiveFilters.push( + `Category: ${t(`commonMarketPlaceFilter.categories.${categoryFilter}`)}`, + ); + if (priceRange[0] > 0 || priceRange[1] < 5000) { + newActiveFilters.push(`Price: $${priceRange[0]}-$${priceRange[1]}`); + } + if (conditionFilter.includes("new")) newActiveFilters.push("New: Yes"); + if (sellerRatingFilter) + newActiveFilters.push(`Seller Rating: ${sellerRatingFilter}★ & Up`); + if (postedWithinFilter === "24h") + newActiveFilters.push("Posted Within: Last 24 Hours"); + if (sortByFilter === "price_low_high") + newActiveFilters.push("Sort By: Price: Low to High"); + + setActiveFilters(newActiveFilters); + }, [ + categoryFilter, + conditionFilter, + priceRange, + postedWithinFilter, + sellerRatingFilter, + sortByFilter, + t, + ]); + + useEffect(() => { + updateActiveFilters(); + if (onFilterChange) { + onFilterChange({ + category: categoryFilter, + priceRange, + condition: conditionFilter, + sellerRating: sellerRatingFilter, + postedWithin: postedWithinFilter, + sortBy: sortByFilter, + }); + } + }, [ + updateActiveFilters, + onFilterChange, + categoryFilter, + priceRange, + conditionFilter, + sellerRatingFilter, + postedWithinFilter, + sortByFilter, + ]); + + const toggleFilters = () => { + setShowFilters(!showFilters); + }; + + const clearAllFilters = () => { + setCategoryFilter(""); + setPriceRange([0, 5000]); + setConditionFilter([]); + setSellerRatingFilter(""); + setPostedWithinFilter(""); + setSortByFilter(""); + }; + + // Remove a specific filter + const removeFilter = (filterType: string) => { + switch (filterType) { + case "Category": + setCategoryFilter(""); + break; + case "Price": + setPriceRange([0, 5000]); + break; + case "New": + setConditionFilter(conditionFilter.filter((c) => c !== "new")); + break; + case "Seller Rating": + setSellerRatingFilter(""); + break; + case "Posted Within": + setPostedWithinFilter(""); + break; + case "Sort By": + setSortByFilter(""); + break; + } + }; + + return ( +
+ +
+
+

+ {t("commonMarketPlaceFilter.filters")} + {activeFilters.length > 0 && ( + + {activeFilters.length} + + )} +

+
+ +
+ + {showFilters && ( +
+
+ + +
+ +
+ +
+ + setPriceRange([values[0], values[1]]) + } + /> +
+
+ +
+ +
+
+ { + if (checked) { + setConditionFilter([...conditionFilter, "new"]); + } else { + setConditionFilter( + conditionFilter.filter((c) => c !== "new"), + ); + } + }} + /> + +
+
+ { + if (checked) { + setConditionFilter([...conditionFilter, "like-new"]); + } else { + setConditionFilter( + conditionFilter.filter((c) => c !== "like-new"), + ); + } + }} + /> + +
+
+ { + if (checked) { + setConditionFilter([...conditionFilter, "good"]); + } else { + setConditionFilter( + conditionFilter.filter((c) => c !== "good"), + ); + } + }} + /> + +
+
+ { + if (checked) { + setConditionFilter([...conditionFilter, "fair"]); + } else { + setConditionFilter( + conditionFilter.filter((c) => c !== "fair"), + ); + } + }} + /> + +
+
+
+ +
+ + +
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ +
+ + +
+ +
+ + +
+
+ )} +
+ {activeFilters.length > 0 && ( +
+
+ + {t("commonMarketPlaceFilter.activeFilters")}: + + + {activeFilters.map((filter, index) => ( + + {filter} + removeFilter(filter.split(":")[0].trim())} + /> + + ))} + + +
+
+ )} +
+ ); +} diff --git a/apps/frontend/components/products/product-list.tsx b/apps/frontend/components/products/product-list.tsx index 0212e437..d2396be3 100644 --- a/apps/frontend/components/products/product-list.tsx +++ b/apps/frontend/components/products/product-list.tsx @@ -17,6 +17,7 @@ import type { ProductImagesData, ProductsData, } from "@/lib/types/product"; +import MarketplaceFilters from "../marketplace/marketplace-filters"; export default function ProductList() { const t = useTranslations(); @@ -83,7 +84,9 @@ export default function ProductList() { <>

Marketplace

+ Showing 8 of 100 products
+
{loading ? ( diff --git a/apps/frontend/locales/en.ts b/apps/frontend/locales/en.ts index f58a4abf..ec7f78aa 100644 --- a/apps/frontend/locales/en.ts +++ b/apps/frontend/locales/en.ts @@ -635,6 +635,45 @@ export const en = { save: "Save changes", successMessage: "Your profile has been successfully updated.", }, + commonMarketPlaceFilter: { + // Filter UI elements + filters: "Filters", + hideFilters: "Hide Filters", + showFilters: "Show Filters", + category: "Category", + selectCategory: "Select category...", + priceRange: "Price Range (${min} - ${max})", + condition: "Condition", + sellerRating: "Seller Rating", + postedWithin: "Posted Within", + anyTime: "Any Time", + last24Hours: "Last 24 Hours", + last7Days: "Last 7 Days", + last30Days: "Last 30 Days", + sortBy: "Sort By", + mostRecent: "Most Recent", + priceLowHigh: "Price: Low to High", + priceHighLow: "Price: High to Low", + bestRating: "Best Rating", + activeFilters: "Active filters", + clearAll: "Clear all", + applyFilters: "Apply Filters", + + // Condition options + conditions: { + new: "New", + likeNew: "Like New", + good: "Good", + fair: "Fair", + }, + categories: { + electronics: "Electronics", + clothing: "Clothing", + homeAndGarden: "Home & Garden", + sports: "Sports & Outdoors", + }, + }, + // Add more sections as needed }; diff --git a/apps/frontend/locales/es.ts b/apps/frontend/locales/es.ts index e0644326..a0b498ab 100644 --- a/apps/frontend/locales/es.ts +++ b/apps/frontend/locales/es.ts @@ -640,6 +640,44 @@ export const es = { save: "Guardar cambios", successMessage: "Su perfil se ha actualizado correctamente.", }, + commonMarketPlaceFilter: { + // Filter UI elements + filters: "Filtros", + hideFilters: "Ocultar Filtros", + showFilters: "Mostrar Filtros", + category: "Categoría", + selectCategory: "Seleccionar categoría...", + priceRange: "Rango de Precio (${min} - ${max})", + condition: "Condición", + sellerRating: "Calificación del Vendedor", + postedWithin: "Publicado Dentro", + anyTime: "Cualquier Tiempo", + last24Hours: "Últimas 24 Horas", + last7Days: "Últimos 7 Días", + last30Days: "Últimos 30 Días", + sortBy: "Ordenar Por", + mostRecent: "Más Reciente", + priceLowHigh: "Precio: Bajo a Alto", + priceHighLow: "Precio: Alto a Bajo", + bestRating: "Mejor Calificación", + activeFilters: "Filtros activos", + clearAll: "Borrar todo", + applyFilters: "Aplicar Filtros", + + // Condition options + conditions: { + new: "Nuevo", + likeNew: "Como Nuevo", + good: "Bueno", + fair: "Regular", + }, + categories: { + electronics: "Electrónica", + clothing: "Ropa", + homeAndGarden: "Hogar y Jardín", + sports: "Deportes y Aire Libre", + }, + }, // Add more sections as needed };