64 lines
2.8 KiB
TypeScript
64 lines
2.8 KiB
TypeScript
|
|
"use client";
|
||
|
|
import useSWR from "swr";
|
||
|
|
import { useEffect, useMemo, useState } from "react";
|
||
|
|
import HorizontalCardScroller from "@/app/components/HorizontalCardScroller";
|
||
|
|
|
||
|
|
const fetcher = (url: string) => fetch(url).then((r) => r.json());
|
||
|
|
|
||
|
|
export default function PartnerScroller() {
|
||
|
|
const { data: catData } = useSWR<{ categories: any[] }>("/api/partner-categories", fetcher);
|
||
|
|
const categories = catData?.categories ?? [];
|
||
|
|
const defaultCatId = categories[0]?.id || "";
|
||
|
|
const [selectedId, setSelectedId] = useState<string>(defaultCatId);
|
||
|
|
|
||
|
|
useEffect(() => {
|
||
|
|
if (!selectedId) {
|
||
|
|
let id = "";
|
||
|
|
try {
|
||
|
|
id = (window as any).__partnerCategoryId || localStorage.getItem("selectedPartnerCategoryId") || "";
|
||
|
|
} catch {}
|
||
|
|
if (!id) id = defaultCatId;
|
||
|
|
if (id) setSelectedId(id);
|
||
|
|
}
|
||
|
|
}, [defaultCatId, selectedId]);
|
||
|
|
|
||
|
|
// Listen to HeroBanner selection events
|
||
|
|
useEffect(() => {
|
||
|
|
// initialize from global if present
|
||
|
|
try {
|
||
|
|
const initial = (window as any).__partnerCategoryId;
|
||
|
|
const stored = localStorage.getItem("selectedPartnerCategoryId");
|
||
|
|
if (initial) setSelectedId(initial);
|
||
|
|
else if (stored) setSelectedId(stored);
|
||
|
|
} catch {}
|
||
|
|
const handler = (e: Event) => {
|
||
|
|
const ce = e as CustomEvent<{ id: string }>;
|
||
|
|
if (ce?.detail?.id) setSelectedId(ce.detail.id);
|
||
|
|
};
|
||
|
|
window.addEventListener("partnerCategorySelect", handler as EventListener);
|
||
|
|
return () => window.removeEventListener("partnerCategorySelect", handler as EventListener);
|
||
|
|
}, []);
|
||
|
|
|
||
|
|
const partnersQuery = useMemo(() => (selectedId ? `/api/partners?categoryId=${encodeURIComponent(selectedId)}` : "/api/partners"), [selectedId]);
|
||
|
|
const { data: partnersData } = useSWR<{ partners: any[] }>(partnersQuery, fetcher);
|
||
|
|
const partners = partnersData?.partners ?? [];
|
||
|
|
|
||
|
|
// Fallback to approved partner requests if no partners
|
||
|
|
const { data: reqData } = useSWR<{ items: any[] }>(partners.length === 0 ? "/api/partner-shops" : null, fetcher);
|
||
|
|
const activeCategoryName = useMemo(() => categories.find((c: any) => c.id === selectedId)?.name, [categories, selectedId]);
|
||
|
|
const fallbackItems = useMemo(() => {
|
||
|
|
if (!reqData?.items) return [] as any[];
|
||
|
|
const filtered = activeCategoryName ? reqData.items.filter((it: any) => it.category === activeCategoryName) : reqData.items;
|
||
|
|
return filtered.map((s: any) => ({ id: s.id, region: s.region, name: s.name, address: s.address, image: s.imageUrl || "/sample.jpg" }));
|
||
|
|
}, [reqData, activeCategoryName]);
|
||
|
|
|
||
|
|
const items = partners.length > 0
|
||
|
|
? partners.map((p: any) => ({ id: p.id, region: p.address ? String(p.address).split(" ")[0] : p.category, name: p.name, address: p.address || "", image: p.imageUrl || "/sample.jpg" }))
|
||
|
|
: fallbackItems;
|
||
|
|
|
||
|
|
if (items.length === 0) return null;
|
||
|
|
return <HorizontalCardScroller items={items} />;
|
||
|
|
}
|
||
|
|
|
||
|
|
|