"use client"; import Link from "next/link"; import { useEffect, useState } from "react"; import { browserFetch } from "../lib/api"; export type MapHomeMakerListItem = { id: string; slug: string; name: string; city: string; province: string; imageUrl: string; distance: string; rating: string; reviewCount: number; satisfaction: string; tags: string[]; }; type FavoritesResponse = { makers: Array<{ id: string; slug: string }>; }; function loginForCurrentPage() { const currentPath = `${window.location.pathname}${window.location.search}`; window.location.assign(`/login?returnTo=${encodeURIComponent(currentPath)}`); } export function MapHomeMakerList({ makers }: { makers: MapHomeMakerListItem[] }) { const [favoriteSlugs, setFavoriteSlugs] = useState>(new Set()); const [favoriteIds, setFavoriteIds] = useState>(new Set()); const [loadingSlug, setLoadingSlug] = useState(""); const [needsLogin, setNeedsLogin] = useState(false); useEffect(() => { let active = true; async function loadFavorites() { try { const response = await browserFetch("/favorites"); if (!active) { return; } setFavoriteSlugs(new Set(response.makers.map((maker) => maker.slug))); setFavoriteIds(new Set(response.makers.map((maker) => maker.id))); setNeedsLogin(false); } catch (error) { const apiError = error as Error & { status?: number }; if (active && (apiError.status === 401 || apiError.status === 403 || apiError.message.includes("Authentication"))) { setNeedsLogin(true); } } } void loadFavorites(); return () => { active = false; }; }, []); async function toggleFavorite(maker: MapHomeMakerListItem) { if (needsLogin) { loginForCurrentPage(); return; } const isFavorite = favoriteSlugs.has(maker.slug) || favoriteIds.has(maker.id); setLoadingSlug(maker.slug); try { await browserFetch<{ favorited: boolean }>(`/favorites/makers/${encodeURIComponent(maker.slug)}`, { method: isFavorite ? "DELETE" : "POST" }); setFavoriteSlugs((current) => { const next = new Set(current); if (isFavorite) { next.delete(maker.slug); } else { next.add(maker.slug); } return next; }); setFavoriteIds((current) => { const next = new Set(current); if (isFavorite) { next.delete(maker.id); } else { next.add(maker.id); } return next; }); } catch (error) { const apiError = error as Error & { status?: number }; if (apiError.status === 401 || apiError.status === 403 || apiError.message.includes("Authentication")) { loginForCurrentPage(); } } finally { setLoadingSlug(""); } } if (makers.length === 0) { return (
No encontramos makers con esa busqueda. Prueba otra categoria o abre la vista completa de descubrir.
); } return (
{makers.map((maker) => { const isFavorite = favoriteSlugs.has(maker.slug) || favoriteIds.has(maker.id); return (
{maker.name} {maker.distance}
{maker.name.slice(0, 2).toUpperCase()}
{maker.name}
{maker.city}, {maker.province}
* {maker.rating} ({maker.reviewCount}) | {maker.satisfaction}
{maker.tags.map((tag) => ( {tag} ))}
); })}
); }