auto-commit for df4b0748-985b-4592-8c48-1e56102f3613

This commit is contained in:
emergent-agent-e1
2026-04-29 14:49:07 +00:00
parent 7673090279
commit 356aa13063
30 changed files with 2809 additions and 244 deletions
+83
View File
@@ -0,0 +1,83 @@
import { useEffect, useState, useCallback } from "react";
import { useNavigate } from "react-router-dom";
import api from "../lib/api";
import Hero from "../components/Hero";
import Row from "../components/Row";
import MovieDetailModal from "../components/MovieDetailModal";
export default function Browse() {
const nav = useNavigate();
const [featured, setFeatured] = useState(null);
const [movies, setMovies] = useState([]);
const [genres, setGenres] = useState([]);
const [continueWatching, setContinueWatching] = useState([]);
const [watchlist, setWatchlist] = useState([]);
const [selected, setSelected] = useState(null);
const [progressMap, setProgressMap] = useState({});
const load = useCallback(async () => {
const [{ data: f }, { data: ms }, { data: gs }, { data: cw }, { data: wl }] = await Promise.all([
api.get("/movies/featured").catch(() => ({ data: null })),
api.get("/movies"),
api.get("/movies/genres"),
api.get("/progress/continue").catch(() => ({ data: [] })),
api.get("/watchlist").catch(() => ({ data: [] })),
]);
setFeatured(f);
setMovies(ms);
setGenres(gs);
setContinueWatching(cw);
setWatchlist(wl);
const map = {};
for (const m of cw) map[m.id] = m.progress;
setProgressMap(map);
}, []);
useEffect(() => { load(); }, [load]);
const handlePlay = (m) => nav(`/watch/${m.id}`);
const handleMore = (m) => setSelected(m);
const handleAddList = async (m) => {
try { await api.post(`/watchlist/${m.id}`); load(); } catch {}
};
const byGenre = (g) => movies.filter((m) => m.genres?.includes(g));
const trending = movies.slice(0, 10);
const newReleases = [...movies].sort((a, b) => b.year - a.year).slice(0, 12);
return (
<div className="min-h-screen bg-[#050505]" data-testid="browse-page">
{featured && (
<Hero
movie={featured}
onPlay={handlePlay}
onMore={handleMore}
onAddList={handleAddList}
/>
)}
<div className="-mt-20 relative z-10 pb-24">
{continueWatching.length > 0 && (
<Row title="Continue Watching" movies={continueWatching} onCardClick={handleMore} progressMap={progressMap} />
)}
<Row title="Trending Now" movies={trending} onCardClick={handleMore} progressMap={progressMap} />
<Row title="New Releases" movies={newReleases} onCardClick={handleMore} progressMap={progressMap} />
{watchlist.length > 0 && (
<Row title="My List" movies={watchlist} onCardClick={handleMore} progressMap={progressMap} />
)}
{genres.slice(0, 6).map((g) => {
const list = byGenre(g);
if (!list.length) return null;
return <Row key={g} title={g} movies={list} onCardClick={handleMore} progressMap={progressMap} />;
})}
</div>
<MovieDetailModal
movie={selected}
open={!!selected}
onClose={() => setSelected(null)}
onWatchlistChange={load}
/>
</div>
);
}