/** * Home / landing page. * * Prominent search bar with 300ms debounced typeahead (top 5 results after 2+ chars), * navigation cards for Topics and Creators, and a "Recently Added" section. */ import { IconTopics, IconCreators } from "../components/CategoryIcons"; import SearchAutocomplete from "../components/SearchAutocomplete"; import TagList from "../components/TagList"; import { useEffect, useState } from "react"; import { Link, useNavigate } from "react-router-dom"; import { useDocumentTitle } from "../hooks/useDocumentTitle"; import { fetchTechniques, fetchTopics, fetchRandomTechnique, fetchStats, fetchPopularSearches, type TechniqueListItem, type StatsResponse, type PopularSearchItem, } from "../api/public-client"; export default function Home() { useDocumentTitle("Chrysopedia — Production Knowledge, Distilled"); const [featured, setFeatured] = useState(null); const [recent, setRecent] = useState([]); const [recentLoading, setRecentLoading] = useState(true); const [popularTopics, setPopularTopics] = useState<{name: string; count: number}[]>([]); const [randomLoading, setRandomLoading] = useState(false); const [randomError, setRandomError] = useState(false); const [stats, setStats] = useState(null); const [trending, setTrending] = useState(null); const navigate = useNavigate(); const handleRandomTechnique = async () => { setRandomLoading(true); setRandomError(false); try { const { slug } = await fetchRandomTechnique(); navigate(`/techniques/${slug}`); } catch { setRandomError(true); setTimeout(() => setRandomError(false), 2000); } finally { setRandomLoading(false); } }; // Load featured technique (random) useEffect(() => { let cancelled = false; void (async () => { try { const res = await fetchTechniques({ sort: "random", limit: 1 }); if (!cancelled && res.items.length > 0) setFeatured(res.items[0] ?? null); } catch { // silently ignore — optional section } })(); return () => { cancelled = true; }; }, []); // Load recently added techniques useEffect(() => { let cancelled = false; void (async () => { try { const res = await fetchTechniques({ sort: "recent", limit: 6 }); if (!cancelled) setRecent(res.items); } catch { // silently ignore — not critical } finally { if (!cancelled) setRecentLoading(false); } })(); return () => { cancelled = true; }; }, []); // Load popular topics useEffect(() => { let cancelled = false; void (async () => { try { const categories = await fetchTopics(); const all = categories.flatMap((cat) => cat.sub_topics.map((st) => ({ name: st.name, count: st.technique_count })) ); all.sort((a, b) => b.count - a.count); if (!cancelled) setPopularTopics(all.slice(0, 8)); } catch { // optional section — silently ignore } })(); return () => { cancelled = true; }; }, []); // Load stats useEffect(() => { let cancelled = false; void (async () => { try { const data = await fetchStats(); if (!cancelled) setStats(data); } catch { // optional section — silently ignore } })(); return () => { cancelled = true; }; }, []); // Load trending searches useEffect(() => { let cancelled = false; void (async () => { try { const data = await fetchPopularSearches(); if (!cancelled && data.items.length > 0) { setTrending(data.items); } } catch { // optional section — silently ignore } })(); return () => { cancelled = true; }; }, []); return (
{/* Hero search */}

Production Knowledge, Distilled

Search techniques, key moments, and creators

navigate(`/search?q=${encodeURIComponent(q)}`)} />

Real music production techniques extracted from creator tutorials. Skip the 4-hour videos — find the insight you need in seconds.

1

Creators Share Techniques

Real producers and sound designers publish in-depth tutorials

2

AI Extracts Key Moments

We distill hours of video into structured, searchable knowledge

3

You Find Answers Fast

Search by topic, technique, or creator — get straight to the insight

Start Exploring {popularTopics.length > 0 && (

Popular Topics

{popularTopics.map((topic) => ( {topic.name} ))}
)}
{/* Navigation cards */}

Topics

Browse techniques organized by category and sub-topic

Creators

Discover creators and their technique libraries

{/* Stats scorecard */} {stats && (
{stats.technique_count} Articles
{stats.creator_count} Creators
)} {/* Trending Searches */} {trending && trending.length > 0 && (

Trending Searches

{trending.map((item, i) => ( {item.query} ))}
)} {/* Random technique discovery */}
{/* Featured Technique Spotlight */} {featured && (

Featured Technique

{featured.title} {featured.summary && (

{featured.summary}

)}
{featured.topic_category && ( {featured.topic_category} )} {featured.topic_tags && featured.topic_tags.length > 0 && ( )} {featured.key_moment_count > 0 && ( {featured.key_moment_count} moment{featured.key_moment_count !== 1 ? "s" : ""} )}
{featured.creator_name && ( by {featured.creator_name} )}
)} {/* Recently Added */}

Recently Added

{recentLoading ? (
Loading…
) : recent.length === 0 ? (
No techniques yet.
) : (
{recent .filter((t) => t.id !== featured?.id) .slice(0, 4) .map((t, i) => ( {t.title} {t.topic_category} {t.topic_tags && t.topic_tags.length > 0 && ( )} {t.summary && ( {t.summary.length > 150 ? `${t.summary.slice(0, 150)}…` : t.summary} )} {t.creator_name || ''} {t.created_at && ( {new Date(t.created_at).toLocaleDateString('en-US', { month: 'short', day: 'numeric' })} )} ))}
)}
); }