/** * Creators browse page (R007, R014). * * - Default sort: random (creator equity — no featured/highlighted creators) * - Genre filter pills from canonical taxonomy * - Type-to-narrow client-side name filter * - Sort toggle: Random | Alphabetical | Views * - Click row → /creators/{slug} */ import { useEffect, useState } from "react"; import { Link } from "react-router-dom"; import { fetchCreators, type CreatorBrowseItem, } from "../api/public-client"; const GENRES = [ "Bass music", "Drum & bass", "Dubstep", "Halftime", "House", "Techno", "IDM", "Glitch", "Downtempo", "Neuro", "Ambient", "Experimental", "Cinematic", ]; type SortMode = "random" | "alpha" | "views"; const SORT_OPTIONS: { value: SortMode; label: string }[] = [ { value: "random", label: "Random" }, { value: "alpha", label: "A–Z" }, { value: "views", label: "Views" }, ]; export default function CreatorsBrowse() { const [creators, setCreators] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [sort, setSort] = useState("random"); const [genreFilter, setGenreFilter] = useState(null); const [nameFilter, setNameFilter] = useState(""); useEffect(() => { let cancelled = false; setLoading(true); setError(null); void (async () => { try { const res = await fetchCreators({ sort, genre: genreFilter ?? undefined, limit: 200, }); if (!cancelled) setCreators(res.items); } catch (err) { if (!cancelled) { setError( err instanceof Error ? err.message : "Failed to load creators", ); } } finally { if (!cancelled) setLoading(false); } })(); return () => { cancelled = true; }; }, [sort, genreFilter]); // Client-side name filtering const displayed = nameFilter ? creators.filter((c) => c.name.toLowerCase().includes(nameFilter.toLowerCase()), ) : creators; return (

Creators

Discover creators and their technique libraries

{/* Controls row */}
{/* Sort toggle */}
{SORT_OPTIONS.map((opt) => ( ))}
{/* Name filter */} setNameFilter(e.target.value)} aria-label="Filter creators by name" />
{/* Genre pills */}
{GENRES.map((g) => ( ))}
{/* Content */} {loading ? (
Loading creators…
) : error ? (
Error: {error}
) : displayed.length === 0 ? (
{nameFilter ? `No creators matching "${nameFilter}"` : "No creators found."}
) : (
{displayed.map((creator) => ( {creator.name} {creator.genres?.map((g) => ( {g} ))} {creator.technique_count} technique{creator.technique_count !== 1 ? "s" : ""} · {creator.video_count} video{creator.video_count !== 1 ? "s" : ""} · {creator.view_count.toLocaleString()} views ))}
)}
); }