818 lines
28 KiB
JavaScript
818 lines
28 KiB
JavaScript
"use client";
|
|
import { useEffect, useMemo, useState } from "react";
|
|
import { useSearchParams } from "next/navigation";
|
|
import Filter from "../../Filter/Filter";
|
|
import {
|
|
allItemApi,
|
|
FeaturedSectionApi,
|
|
getCustomFieldsApi,
|
|
getParentCategoriesApi,
|
|
getSeoSettingsApi,
|
|
} from "@/utils/api";
|
|
import ProductCard from "@/components/Common/ProductCard";
|
|
import {
|
|
Select,
|
|
SelectContent,
|
|
SelectGroup,
|
|
SelectItem,
|
|
SelectTrigger,
|
|
SelectValue,
|
|
} from "@/components/ui/select";
|
|
import { TbTransferVertical } from "react-icons/tb";
|
|
import ProductHorizontalCard from "@/components/Common/ProductHorizontalCard";
|
|
import ProductCardSkeleton from "@/components/Common/ProductCardSkeleton";
|
|
import ProductHorizontalCardSkeleton from "@/components/Common/ProductHorizontalCardSkeleton";
|
|
import NoData from "@/components/EmptyStates/NoData";
|
|
import { IoGrid } from "react-icons/io5";
|
|
import { CiGrid2H } from "react-icons/ci";
|
|
import { Badge } from "@/components/ui/badge";
|
|
import { IoIosCloseCircle } from "react-icons/io";
|
|
import BreadCrumb from "@/components/BreadCrumb/BreadCrumb";
|
|
import Layout from "@/components/Layout/Layout";
|
|
import { Button } from "@/components/ui/button";
|
|
import { useDispatch, useSelector } from "react-redux";
|
|
import {
|
|
BreadcrumbPathData,
|
|
setBreadcrumbPath,
|
|
} from "@/redux/reducer/breadCrumbSlice";
|
|
import { seoData, t } from "@/utils";
|
|
import { getSelectedLocation } from "@/redux/reducer/globalStateSlice";
|
|
import { generateKeywords } from "@/utils/generateKeywords";
|
|
|
|
const Ads = () => {
|
|
const dispatch = useDispatch();
|
|
const searchParams = useSearchParams();
|
|
const newSearchParams = new URLSearchParams(searchParams);
|
|
const BreadcrumbPath = useSelector(BreadcrumbPathData);
|
|
|
|
const [view, setView] = useState("grid");
|
|
const [advertisements, setAdvertisements] = useState({
|
|
data: [],
|
|
currentPage: 1,
|
|
hasMore: false,
|
|
isLoading: false,
|
|
isLoadMore: false,
|
|
});
|
|
const [featuredTitle, setFeaturedTitle] = useState("");
|
|
|
|
const selectedLocation = useSelector(getSelectedLocation);
|
|
|
|
const query = searchParams.get("query") || "";
|
|
const slug = searchParams.get("category") || "";
|
|
const country = searchParams.get("country") || "";
|
|
const state = searchParams.get("state") || "";
|
|
const city = searchParams.get("city") || "";
|
|
const area = searchParams.get("area") || "";
|
|
const areaId = Number(searchParams.get("areaId")) || "";
|
|
const lat = Number(searchParams.get("lat"));
|
|
const lng = Number(searchParams.get("lng"));
|
|
const min_price = searchParams.get("min_price")
|
|
? Number(searchParams.get("min_price"))
|
|
: "";
|
|
const max_price = searchParams.get("max_price")
|
|
? Number(searchParams.get("max_price"))
|
|
: "";
|
|
const date_posted = searchParams.get("date_posted") || "";
|
|
const km_range = searchParams.get("km_range") || "";
|
|
const sortBy = searchParams.get("sort_by") || "new-to-old";
|
|
const langCode = searchParams.get("lang");
|
|
const featured_section = searchParams.get("featured_section") || "";
|
|
|
|
const isMinPrice =
|
|
min_price !== "" &&
|
|
min_price !== null &&
|
|
min_price !== undefined &&
|
|
min_price >= 0;
|
|
|
|
const knownParams = [
|
|
"country",
|
|
"state",
|
|
"city",
|
|
"area",
|
|
"areaId",
|
|
"lat",
|
|
"lng",
|
|
"min_price",
|
|
"max_price",
|
|
"date_posted",
|
|
"km_range",
|
|
"sort_by",
|
|
"category",
|
|
"query",
|
|
"lang",
|
|
"featured_section",
|
|
];
|
|
|
|
const title = useMemo(() => {
|
|
if (BreadcrumbPath.length === 2) {
|
|
return BreadcrumbPath[1]?.name;
|
|
}
|
|
|
|
if (BreadcrumbPath.length > 2) {
|
|
const last = BreadcrumbPath[BreadcrumbPath.length - 1]?.name;
|
|
const secondLast = BreadcrumbPath[BreadcrumbPath.length - 2]?.name;
|
|
return `${last} ${t("in")} ${secondLast}`;
|
|
}
|
|
|
|
return t("ads");
|
|
}, [BreadcrumbPath, t]);
|
|
|
|
const category =
|
|
BreadcrumbPath.length > 1 &&
|
|
BreadcrumbPath[BreadcrumbPath.length - 1]?.name;
|
|
|
|
const [customFields, setCustomFields] = useState([]);
|
|
|
|
const initialExtraDetails = useMemo(() => {
|
|
const temprorayExtraDet = {};
|
|
Array.from(searchParams.entries() || []).forEach(([key, value]) => {
|
|
if (!knownParams?.includes(key)) {
|
|
temprorayExtraDet[key] = value?.includes(",")
|
|
? value?.split(",")
|
|
: value;
|
|
}
|
|
});
|
|
return temprorayExtraDet;
|
|
}, [
|
|
JSON.stringify(
|
|
Array.from(searchParams.entries()).filter(
|
|
([key]) => !knownParams.includes(key)
|
|
)
|
|
),
|
|
]);
|
|
|
|
const [extraDetails, setExtraDetails] = useState(initialExtraDetails);
|
|
|
|
// Count active filters
|
|
const getActiveFilterCount = () => {
|
|
let count = 0;
|
|
|
|
// Location filter
|
|
if (country || state || city || areaId) count++;
|
|
|
|
// KM Range filter
|
|
if (km_range) count++;
|
|
|
|
if (category) count++;
|
|
|
|
if (featured_section) count++;
|
|
|
|
// Query filter
|
|
if (query) count++;
|
|
|
|
// Date Posted filter
|
|
if (date_posted) count++;
|
|
|
|
// Price Range filter
|
|
if (isMinPrice && max_price) count++;
|
|
|
|
// Extra Details filters
|
|
if (initialExtraDetails && Object.keys(initialExtraDetails).length > 0) {
|
|
count += Object.keys(initialExtraDetails).length;
|
|
}
|
|
|
|
return count;
|
|
};
|
|
|
|
const activeFilterCount = getActiveFilterCount();
|
|
|
|
useEffect(() => {
|
|
const fetchFeaturedSectionData = async () => {
|
|
try {
|
|
const response = await FeaturedSectionApi.getFeaturedSections({
|
|
slug: featured_section,
|
|
});
|
|
|
|
if (response?.data?.error === false) {
|
|
setFeaturedTitle(
|
|
response?.data?.data?.[0]?.translated_name ||
|
|
response?.data?.data?.[0]?.title
|
|
);
|
|
} else {
|
|
console.error(response?.data?.message);
|
|
}
|
|
} catch (error) {
|
|
console.error("Error:", error);
|
|
}
|
|
};
|
|
if (featured_section) {
|
|
fetchFeaturedSectionData();
|
|
}
|
|
}, [langCode, featured_section]);
|
|
|
|
useEffect(() => {
|
|
if (slug) {
|
|
constructBreadcrumbPath();
|
|
} else {
|
|
dispatch(
|
|
setBreadcrumbPath([
|
|
{
|
|
name: t("allCategories"),
|
|
key: "all-categories",
|
|
slug: "/ads",
|
|
isAllCategories: true,
|
|
},
|
|
])
|
|
);
|
|
setCustomFields([]);
|
|
setExtraDetails({});
|
|
const fetchSeoSettings = async () => {
|
|
const res = await getSeoSettingsApi.getSeoSettings({
|
|
page: "ad-listing",
|
|
});
|
|
const data = res.data.data[0];
|
|
const title =
|
|
data?.translated_title ||
|
|
data?.title ||
|
|
process.env.NEXT_PUBLIC_META_TITLE;
|
|
const description =
|
|
data?.translated_description ||
|
|
process.env.NEXT_PUBLIC_META_DESCRIPTION;
|
|
const keywords =
|
|
data?.translated_keywords || process.env.NEXT_PUBLIC_META_kEYWORDS;
|
|
const image = data?.image || "";
|
|
const canonicalUrl = process.env.NEXT_PUBLIC_WEB_URL;
|
|
seoData({ title, description, keywords, image, canonicalUrl });
|
|
};
|
|
fetchSeoSettings();
|
|
}
|
|
}, [slug, langCode]);
|
|
|
|
const getCustomFieldsData = async (categoryIds) => {
|
|
try {
|
|
const res = await getCustomFieldsApi.getCustomFields({
|
|
category_ids: categoryIds,
|
|
filter: true,
|
|
});
|
|
const data = res?.data?.data;
|
|
setCustomFields(data);
|
|
const isShowCustomfieldFilter =
|
|
data.length > 0 &&
|
|
data.some(
|
|
(field) =>
|
|
field.type === "checkbox" ||
|
|
field.type === "radio" ||
|
|
field.type === "dropdown"
|
|
);
|
|
|
|
if (isShowCustomfieldFilter) {
|
|
const initialExtraDetails = {};
|
|
data.forEach((field) => {
|
|
const value = searchParams.get(field.id);
|
|
if (value) {
|
|
initialExtraDetails[field.id] =
|
|
field.type === "checkbox" ? value.split(",") : value;
|
|
}
|
|
});
|
|
setExtraDetails(initialExtraDetails);
|
|
} else {
|
|
setExtraDetails({});
|
|
}
|
|
} catch (error) {
|
|
console.log(error);
|
|
}
|
|
};
|
|
|
|
const constructBreadcrumbPath = async () => {
|
|
try {
|
|
const res = await getParentCategoriesApi.getPaymentCategories({
|
|
slug,
|
|
tree: 0,
|
|
});
|
|
const data = res?.data?.data || [];
|
|
const selectedCategory = data?.at(-1);
|
|
if (selectedCategory) {
|
|
seoData({
|
|
title:
|
|
selectedCategory?.translated_name || process.env.NEXT_PUBLIC_META_TITLE,
|
|
description:
|
|
selectedCategory?.translated_description ||
|
|
process.env.NEXT_PUBLIC_META_DESCRIPTION,
|
|
keywords:
|
|
generateKeywords(selectedCategory?.translated_description) ||
|
|
process.env.NEXT_PUBLIC_META_kEYWORDS,
|
|
image: selectedCategory?.image,
|
|
canonicalUrl: `${process.env.NEXT_PUBLIC_WEB_URL}?category=${selectedCategory?.slug}&lang=${langCode}`,
|
|
});
|
|
}
|
|
const breadcrumbArray = [
|
|
{
|
|
name: t("allCategories"),
|
|
key: "all-categories",
|
|
slug: "/ads",
|
|
isAllCategories: true,
|
|
},
|
|
...data.map((item) => ({
|
|
name: item.translated_name,
|
|
key: item.slug,
|
|
slug: `/ads?category=${item.slug}`,
|
|
})),
|
|
];
|
|
dispatch(setBreadcrumbPath(breadcrumbArray));
|
|
const categoryIds = data.map((category) => category.id).join(",");
|
|
await getCustomFieldsData(categoryIds);
|
|
} catch (error) {
|
|
console.log(error);
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
getSingleCatItem(1);
|
|
}, [
|
|
lat,
|
|
lng,
|
|
areaId,
|
|
city,
|
|
state,
|
|
country,
|
|
min_price,
|
|
max_price,
|
|
date_posted,
|
|
km_range,
|
|
sortBy,
|
|
initialExtraDetails,
|
|
slug,
|
|
query,
|
|
langCode,
|
|
featured_section,
|
|
]);
|
|
|
|
const getSingleCatItem = async (page) => {
|
|
try {
|
|
const parameters = { page, limit: 12 };
|
|
if (sortBy) parameters.sort_by = sortBy;
|
|
if (isMinPrice) parameters.min_price = min_price;
|
|
if (max_price) parameters.max_price = max_price;
|
|
if (date_posted) parameters.posted_since = date_posted;
|
|
if (slug) parameters.category_slug = slug;
|
|
if (extraDetails) parameters.custom_fields = extraDetails;
|
|
if (featured_section) parameters.featured_section_slug = featured_section;
|
|
|
|
if (Number(km_range) > 0) {
|
|
parameters.latitude = lat;
|
|
parameters.longitude = lng;
|
|
parameters.radius = km_range;
|
|
} else {
|
|
if (areaId) {
|
|
parameters.area_id = areaId;
|
|
} else if (city) {
|
|
parameters.city = city;
|
|
} else if (state) {
|
|
parameters.state = state;
|
|
} else if (country) {
|
|
parameters.country = country;
|
|
}
|
|
}
|
|
if (query) {
|
|
parameters.search = query;
|
|
}
|
|
page === 1
|
|
? setAdvertisements((prev) => ({ ...prev, isLoading: true }))
|
|
: setAdvertisements((prev) => ({ ...prev, isLoadMore: true }));
|
|
|
|
const res = await allItemApi.getItems(parameters);
|
|
const data = res?.data;
|
|
|
|
if (data.error === false) {
|
|
page > 1
|
|
? setAdvertisements((prev) => ({
|
|
...prev,
|
|
data: [...prev.data, ...data?.data?.data],
|
|
currentPage: data?.data?.current_page,
|
|
hasMore: data?.data?.last_page > data?.data?.current_page,
|
|
}))
|
|
: setAdvertisements((prev) => ({
|
|
...prev,
|
|
data: data?.data?.data,
|
|
currentPage: data?.data?.current_page,
|
|
hasMore: data?.data?.last_page > data?.data?.current_page,
|
|
}));
|
|
}
|
|
} catch (error) {
|
|
console.log(error);
|
|
} finally {
|
|
setAdvertisements((prev) => ({
|
|
...prev,
|
|
isLoading: false,
|
|
isLoadMore: false,
|
|
}));
|
|
}
|
|
};
|
|
|
|
const handleProdLoadMore = async () => {
|
|
setAdvertisements((prev) => ({ ...prev, isLoadMore: true }));
|
|
await getSingleCatItem(advertisements.currentPage + 1);
|
|
};
|
|
|
|
const handleSortBy = (value) => {
|
|
newSearchParams.set("sort_by", value);
|
|
window.history.pushState(null, "", `/ads?${newSearchParams.toString()}`);
|
|
};
|
|
|
|
const handleLike = (id) => {
|
|
const updatedItems = advertisements.data.map((item) => {
|
|
if (item.id === id) {
|
|
return { ...item, is_liked: !item.is_liked };
|
|
}
|
|
return item;
|
|
});
|
|
setAdvertisements((prev) => ({ ...prev, data: updatedItems }));
|
|
};
|
|
|
|
const handleClearLocation = () => {
|
|
newSearchParams.delete("country");
|
|
newSearchParams.delete("state");
|
|
newSearchParams.delete("city");
|
|
newSearchParams.delete("area");
|
|
newSearchParams.delete("areaId");
|
|
newSearchParams.delete("lat");
|
|
newSearchParams.delete("lng");
|
|
newSearchParams.delete("km_range");
|
|
window.history.pushState(null, "", `/ads?${newSearchParams.toString()}`);
|
|
};
|
|
|
|
const handleClearRange = () => {
|
|
newSearchParams.delete("km_range");
|
|
window.history.pushState(null, "", `/ads?${newSearchParams.toString()}`);
|
|
};
|
|
|
|
const handleClearDatePosted = () => {
|
|
newSearchParams.delete("date_posted");
|
|
window.history.pushState(null, "", `/ads?${newSearchParams.toString()}`);
|
|
};
|
|
|
|
const handleClearBudget = () => {
|
|
newSearchParams.delete("min_price");
|
|
newSearchParams.delete("max_price");
|
|
window.history.pushState(null, "", `/ads?${newSearchParams.toString()}`);
|
|
};
|
|
|
|
const handleClearFeaturedSection = () => {
|
|
newSearchParams.delete("featured_section");
|
|
window.history.pushState(null, "", `/ads?${newSearchParams.toString()}`);
|
|
};
|
|
|
|
const handleClearCategory = () => {
|
|
newSearchParams.delete("category");
|
|
Object.keys(extraDetails || {})?.forEach((key) => {
|
|
newSearchParams.delete(key);
|
|
});
|
|
window.history.pushState(null, "", `/ads?${newSearchParams.toString()}`);
|
|
};
|
|
|
|
const handleClearExtraDetail = (keyToRemove) => {
|
|
const updatedExtraDetails = { ...extraDetails };
|
|
delete updatedExtraDetails[keyToRemove];
|
|
setExtraDetails(updatedExtraDetails);
|
|
|
|
newSearchParams.delete(keyToRemove);
|
|
window.history.pushState(null, "", `/ads?${newSearchParams.toString()}`);
|
|
};
|
|
|
|
const handleClearAll = () => {
|
|
newSearchParams.delete("country");
|
|
newSearchParams.delete("state");
|
|
newSearchParams.delete("city");
|
|
newSearchParams.delete("area");
|
|
newSearchParams.delete("areaId");
|
|
newSearchParams.delete("lat");
|
|
newSearchParams.delete("lng");
|
|
newSearchParams.delete("km_range");
|
|
newSearchParams.delete("date_posted");
|
|
newSearchParams.delete("min_price");
|
|
newSearchParams.delete("max_price");
|
|
newSearchParams.delete("category");
|
|
newSearchParams.delete("query");
|
|
newSearchParams.delete("featured_section");
|
|
Object.keys(initialExtraDetails || {})?.forEach((key) => {
|
|
newSearchParams.delete(key);
|
|
});
|
|
setExtraDetails({});
|
|
window.history.pushState(null, "", `/ads?${newSearchParams.toString()}`);
|
|
};
|
|
|
|
const handleClearQuery = () => {
|
|
newSearchParams.delete("query");
|
|
window.history.pushState(null, "", `/ads?${newSearchParams.toString()}`);
|
|
};
|
|
|
|
const postedSince =
|
|
date_posted === "all-time"
|
|
? t("allTime")
|
|
: date_posted === "today"
|
|
? t("today")
|
|
: date_posted === "within-1-week"
|
|
? t("within1Week")
|
|
: date_posted === "within-2-week"
|
|
? t("within2Weeks")
|
|
: date_posted === "within-1-month"
|
|
? t("within1Month")
|
|
: date_posted === "within-3-month"
|
|
? t("within3Months")
|
|
: "";
|
|
|
|
return (
|
|
<Layout>
|
|
<BreadCrumb />
|
|
<div className="container mt-8">
|
|
<div className="flex flex-col">
|
|
<h1 className="text-2xl font-semibold mb-6">{title}</h1>
|
|
<div className="grid grid-cols-1 lg:grid-cols-12 gap-8">
|
|
<div className="xl:col-span-3 lg:col-span-4 col-span-1">
|
|
<Filter
|
|
customFields={customFields}
|
|
extraDetails={extraDetails}
|
|
setExtraDetails={setExtraDetails}
|
|
newSearchParams={newSearchParams}
|
|
country={country}
|
|
state={state}
|
|
city={city}
|
|
area={area}
|
|
/>
|
|
</div>
|
|
<div className="xl:col-span-9 lg:col-span-8 col-span-1 flex flex-col gap-5">
|
|
<div className="flex justify-between items-center">
|
|
<div>
|
|
<div className="flex flex-col md:flex-row items-start md:items-center gap-2">
|
|
<div className="flex gap-2 items-center whitespace-nowrap">
|
|
<TbTransferVertical />
|
|
{t("sortBy")}
|
|
</div>
|
|
<Select value={sortBy} onValueChange={handleSortBy}>
|
|
<SelectTrigger className="max-w-[180px] font-semibold">
|
|
<SelectValue
|
|
placeholder={t("sortBy")}
|
|
className="font-semibold"
|
|
/>
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
<SelectGroup className="font-semibold">
|
|
<SelectItem value="new-to-old">
|
|
{t("newestToOldest")}
|
|
</SelectItem>
|
|
<SelectItem value="old-to-new">
|
|
{t("oldestToNewest")}
|
|
</SelectItem>
|
|
<SelectItem value="price-high-to-low">
|
|
{t("priceHighToLow")}
|
|
</SelectItem>
|
|
<SelectItem value="price-low-to-high">
|
|
{t("priceLowToHigh")}
|
|
</SelectItem>
|
|
<SelectItem value="popular_items">
|
|
{t("popular")}
|
|
</SelectItem>
|
|
</SelectGroup>
|
|
</SelectContent>
|
|
</Select>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="flex items-center gap-1">
|
|
<button
|
|
onClick={() => setView("list")}
|
|
className={`text-muted-foreground p-3 rounded-full ${view === "list" ? "bg-primary text-white" : ""
|
|
}`}
|
|
>
|
|
<CiGrid2H size={22} />
|
|
</button>
|
|
<button
|
|
onClick={() => setView("grid")}
|
|
className={` text-muted-foreground p-3 rounded-full ${view === "grid" ? "bg-primary text-white" : ""
|
|
}`}
|
|
>
|
|
<IoGrid size={22} />
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="flex items-center justify-between gap-2">
|
|
<div className="flex gap-2 flex-wrap">
|
|
{category && (
|
|
<Badge
|
|
variant="outline"
|
|
className="px-4 text-base font-normal py-2 rounded-full flex items-center gap-2 bg-muted"
|
|
>
|
|
<span>
|
|
{t("category")}: {category}
|
|
</span>
|
|
<IoIosCloseCircle
|
|
size={22}
|
|
className="cursor-pointer "
|
|
onClick={handleClearCategory}
|
|
/>
|
|
</Badge>
|
|
)}
|
|
|
|
{query && (
|
|
<Badge
|
|
variant="outline"
|
|
className="px-4 text-base font-normal py-2 rounded-full flex items-center gap-2 bg-muted"
|
|
>
|
|
<span>
|
|
{t("search")}: {query}
|
|
</span>
|
|
<IoIosCloseCircle
|
|
size={22}
|
|
className="cursor-pointer "
|
|
onClick={handleClearQuery}
|
|
/>
|
|
</Badge>
|
|
)}
|
|
|
|
{(country || state || city || area) && (
|
|
<Badge
|
|
variant="outline"
|
|
className="px-4 text-base font-normal py-2 rounded-full flex items-center gap-2 bg-muted"
|
|
>
|
|
<span>
|
|
{t("location")}:{" "}
|
|
{selectedLocation?.translated_name ||
|
|
selectedLocation?.name}
|
|
</span>
|
|
<IoIosCloseCircle
|
|
size={22}
|
|
className="cursor-pointer "
|
|
onClick={handleClearLocation}
|
|
/>
|
|
</Badge>
|
|
)}
|
|
{Number(km_range) > 0 && (
|
|
<Badge
|
|
variant="outline"
|
|
className="px-4 text-base font-normal py-2 rounded-full flex items-center gap-2 bg-muted"
|
|
>
|
|
<span>
|
|
{t("nearByRange")}: {km_range} KM
|
|
</span>
|
|
<IoIosCloseCircle
|
|
size={22}
|
|
className="cursor-pointer "
|
|
onClick={handleClearRange}
|
|
/>
|
|
</Badge>
|
|
)}
|
|
|
|
{date_posted && (
|
|
<Badge
|
|
variant="outline"
|
|
className="px-4 text-base font-normal py-2 rounded-full flex items-center gap-2 bg-muted"
|
|
>
|
|
<span>
|
|
{t("datePosted")}: {postedSince}
|
|
</span>
|
|
<IoIosCloseCircle
|
|
size={22}
|
|
className="cursor-pointer "
|
|
onClick={handleClearDatePosted}
|
|
/>
|
|
</Badge>
|
|
)}
|
|
|
|
{isMinPrice && max_price && (
|
|
<Badge
|
|
variant="outline"
|
|
className="px-4 text-base font-normal py-2 rounded-full flex items-center gap-2 bg-muted"
|
|
>
|
|
<span>
|
|
{t("budget")}: {min_price}-{max_price}
|
|
</span>
|
|
<IoIosCloseCircle
|
|
size={22}
|
|
className="cursor-pointer "
|
|
onClick={handleClearBudget}
|
|
/>
|
|
</Badge>
|
|
)}
|
|
|
|
{featured_section && (
|
|
<Badge
|
|
variant="outline"
|
|
className="px-4 text-base font-normal py-2 rounded-full flex items-center gap-2 bg-muted"
|
|
>
|
|
<span>
|
|
{t("featuredSection")}: {featuredTitle}
|
|
</span>
|
|
<IoIosCloseCircle
|
|
size={22}
|
|
className="cursor-pointer "
|
|
onClick={handleClearFeaturedSection}
|
|
/>
|
|
</Badge>
|
|
)}
|
|
{initialExtraDetails &&
|
|
Object.entries(initialExtraDetails || {}).map(
|
|
([key, value]) => {
|
|
const field = customFields.find(
|
|
(f) => f.id.toString() === key.toString()
|
|
);
|
|
|
|
const fieldName = field?.translated_name || field?.name;
|
|
|
|
// Function to get translated value
|
|
const getTranslatedValue = (val) => {
|
|
if (!field?.values || !field?.translated_value)
|
|
return val;
|
|
const idx = field.values.indexOf(val);
|
|
return idx !== -1 ? field.translated_value[idx] : val;
|
|
};
|
|
|
|
const displayValue = Array.isArray(value)
|
|
? value.map((v) => getTranslatedValue(v)).join(", ")
|
|
: getTranslatedValue(value);
|
|
|
|
return (
|
|
<Badge
|
|
key={key}
|
|
variant="outline"
|
|
className="px-4 text-base font-normal py-2 rounded-full flex items-center gap-2 bg-muted"
|
|
>
|
|
<span>
|
|
{fieldName}: {displayValue}
|
|
</span>
|
|
<IoIosCloseCircle
|
|
size={22}
|
|
className="cursor-pointer"
|
|
onClick={() => handleClearExtraDetail(key)}
|
|
/>
|
|
</Badge>
|
|
);
|
|
}
|
|
)}
|
|
</div>
|
|
{activeFilterCount > 1 && (
|
|
<button
|
|
className="text-primary whitespace-nowrap"
|
|
onClick={handleClearAll}
|
|
>
|
|
{t("clearAll")}
|
|
</button>
|
|
)}
|
|
</div>
|
|
|
|
<div className="grid grid-cols-12 gap-4">
|
|
{advertisements?.isLoading ? (
|
|
Array.from({ length: 12 }).map((_, index) =>
|
|
view === "list" ? (
|
|
<div className="col-span-12" key={index}>
|
|
<ProductHorizontalCardSkeleton />
|
|
</div>
|
|
) : (
|
|
<div
|
|
key={index}
|
|
className="col-span-12 sm:col-span-6 xl:col-span-4"
|
|
>
|
|
<ProductCardSkeleton />
|
|
</div>
|
|
)
|
|
)
|
|
) : advertisements.data && advertisements.data.length > 0 ? (
|
|
advertisements.data?.map((item, index) =>
|
|
view === "list" ? (
|
|
<div className="col-span-12" key={index}>
|
|
<ProductHorizontalCard
|
|
item={item}
|
|
handleLike={handleLike}
|
|
/>
|
|
</div>
|
|
) : (
|
|
<div
|
|
className="col-span-12 sm:col-span-6 xl:col-span-4"
|
|
key={index}
|
|
>
|
|
<ProductCard item={item} handleLike={handleLike} />
|
|
</div>
|
|
)
|
|
)
|
|
) : (
|
|
<div className="col-span-12">
|
|
<NoData name={t("ads")} />
|
|
</div>
|
|
)}
|
|
</div>
|
|
{advertisements.data &&
|
|
advertisements.data.length > 0 &&
|
|
advertisements.hasMore && (
|
|
<div className="text-center mt-6">
|
|
<Button
|
|
variant="outline"
|
|
className="text-sm sm:text-base text-primary w-[256px]"
|
|
disabled={
|
|
advertisements.isLoading || advertisements.isLoadMore
|
|
}
|
|
onClick={handleProdLoadMore}
|
|
>
|
|
{advertisements.isLoadMore ? t("loading") : t("loadMore")}
|
|
</Button>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</Layout>
|
|
);
|
|
};
|
|
|
|
export default Ads;
|