Initial commit

This commit is contained in:
2026-10-05 20:38:28 +02:00
commit 60a68b420e
107 changed files with 21716 additions and 0 deletions

View File

@@ -0,0 +1,59 @@
import { useQuery } from "@tanstack/react-query";
import { Play, RefreshCw } from "lucide-react";
import { tracksApi } from "../lib/api";
import { useAuth } from "../store/auth";
import { usePlayer } from "../store/player";
import { TrackRow } from "../components/TrackRow";
export function Home() {
const { user } = useAuth();
const playQueue = usePlayer((s) => s.playQueue);
const { data, isLoading, isFetching, refetch } = useQuery({
queryKey: ["random-tracks"],
queryFn: () => tracksApi.random(25),
});
const items = data ?? [];
return (
<div className="mx-auto max-w-5xl animate-fade-in">
<div className="mb-6 flex flex-wrap items-end justify-between gap-3">
<div>
<h1 className="text-2xl font-bold tracking-tight text-white">
Привет{user?.displayName ? `, ${user.displayName}` : ""} 👋
</h1>
<p className="mt-1 text-sm text-zinc-500">
Случайные рекомендации из общей библиотеки. Персональные рекомендации появятся позже.
</p>
</div>
<div className="flex gap-2">
<button className="btn-ghost" onClick={() => refetch()} disabled={isFetching}>
<RefreshCw size={15} className={isFetching ? "animate-spin" : ""} />
Обновить
</button>
<button
className="btn-primary"
onClick={() => items.length && playQueue(items, 0)}
disabled={!items.length}
>
<Play size={15} /> Играть всё
</button>
</div>
</div>
{isLoading ? (
<p className="text-sm text-zinc-500">Загрузка рекомендаций...</p>
) : items.length === 0 ? (
<div className="card p-8 text-center text-sm text-zinc-500">
В библиотеке пока нет одобренных треков. Загрузите музыку на вкладке «Добавить».
</div>
) : (
<div className="card p-2">
{items.map((track, i) => (
<TrackRow key={track.id} track={track} list={items} index={i} />
))}
</div>
)}
</div>
);
}