import { useEffect, useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { motion } from 'framer-motion'; import { marketplaceApi, type MarketplaceListResponse } from '../api/marketplace.js'; import { lessonsApi } from '../api/lessons.js'; import { ApiClientError } from '../api/client.js'; export function MarketplacePage() { const [data, setData] = useState({ rows: [], total: 0 }); const [q, setQ] = useState(''); const [curatedOnly, setCuratedOnly] = useState(false); const [busy, setBusy] = useState(false); const [error, setError] = useState(null); const navigate = useNavigate(); async function refresh() { setBusy(true); setError(null); try { const r = await marketplaceApi.list({ q: q.trim() || undefined, curated: curatedOnly ? true : undefined }); setData(r); } catch (e) { setError(e instanceof ApiClientError ? e.message : 'Kon marketplace niet laden.'); } finally { setBusy(false); } } useEffect(() => { refresh(); }, [curatedOnly]); async function subscribe(id: number) { try { await lessonsApi.subscribe(id); await refresh(); } catch (e) { alert(e instanceof ApiClientError ? e.message : 'Abonneren mislukt'); } } async function fork(id: number) { try { const f = await lessonsApi.fork(id); navigate(`/lessons/${f.id}`); } catch (e) { alert(e instanceof ApiClientError ? e.message : 'Forken mislukt'); } } return (

Marketplace 🛍️

Vind trainingen van andere gebruikers en officiële beheerderscontent.

setQ(e.target.value)} onKeyDown={(e) => e.key === 'Enter' && refresh()} />
{error &&

{error}

} {data.rows.length === 0 && !busy ? (
Geen lessen gevonden.
) : (
    {data.rows.map((l, i) => (
    {l.isCurated && ⭐ Curated} {l.isFork && 🍴 Fork}

    {l.name}

    {l.description ?? geen beschrijving}

    door {l.ownerDisplayName} {l.totalCards} kaarten · {l.subscribersCount} abonnees
    ))}
)}
); }