mirror of
https://github.com/myronblair/kino-app
synced 2026-07-29 14:02:50 -05:00
auto-commit for df4b0748-985b-4592-8c48-1e56102f3613
This commit is contained in:
@@ -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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user