SPB Git

Repository Public

SavedFilms.tsx 1.3 KB 30 lines tsx

1"use client";23import { useEffect, useState } from "react";4import Link from "next/link";5import { savedIds } from "./FilmActions";67interface F { id: string; slug: string; title: string; thumb: string; duration: number }8export function SavedFilms({ locale, empty }: { locale: "en" | "fr"; empty: string }) {9  const [films, setFilms] = useState<F[] | null>(null);10  useEffect(() => {11    const ids = savedIds();12    if (!ids.length) { setFilms([]); return; }13    fetch(`/api/films?locale=${locale}&ids=${ids.join(",")}`).then((r) => r.json()).then((d: { films: F[] }) => setFilms(d.films)).catch(() => setFilms([]));14  }, [locale]);15  if (films === null) return <div className="spinner" role="status" aria-label="Loading" />;16  if (!films.length) return <p className="card p-8 text-[var(--color-muted)]">{empty}</p>;17  return (18    <ul className="grid grid-cols-2 gap-3 sm:grid-cols-4 sm:gap-4">19      {films.map((f) => (20        <li key={f.id}>21          <Link href={`${locale === "fr" ? "/fr" : ""}/film/${f.slug}`} className="block">22            <img src={f.thumb} alt="" className="aspect-[9/16] w-full rounded-[12px] object-cover ring-1 ring-[var(--color-line-soft)]" loading="lazy" />23            <span className="display mt-2 block text-xl">{f.title}</span>24          </Link>25        </li>26      ))}27    </ul>28  );29}30
Files main
Menu

Theme