feat(dashboard): subscriptions section

This commit is contained in:
2026-05-21 00:39:36 +02:00
parent 6a65c5cf96
commit 9fdadca529

View File

@@ -3,7 +3,8 @@ import { Link, useNavigate } from 'react-router-dom';
import { motion } from 'framer-motion'; import { motion } from 'framer-motion';
import { statsApi, type Overview } from '../api/stats.js'; import { statsApi, type Overview } from '../api/stats.js';
import { sessionsApi } from '../api/sessions.js'; import { sessionsApi } from '../api/sessions.js';
import type { SessionRow } from '@flashcard/shared'; import { lessonsApi } from '../api/lessons.js';
import type { SessionRow, SubscriptionEntry } from '@flashcard/shared';
import { useLessons } from '../stores/lessonsStore.js'; import { useLessons } from '../stores/lessonsStore.js';
import { formatDuration, formatDate } from '../lib/format.js'; import { formatDuration, formatDate } from '../lib/format.js';
@@ -11,6 +12,7 @@ export function DashboardPage() {
const { tree, refresh } = useLessons(); const { tree, refresh } = useLessons();
const [ov, setOv] = useState<Overview | null>(null); const [ov, setOv] = useState<Overview | null>(null);
const [active, setActive] = useState<SessionRow | null>(null); const [active, setActive] = useState<SessionRow | null>(null);
const [subs, setSubs] = useState<SubscriptionEntry[]>([]);
const navigate = useNavigate(); const navigate = useNavigate();
useEffect(() => { useEffect(() => {
@@ -22,6 +24,8 @@ export function DashboardPage() {
sessionsApi.active().then(setActive).catch(() => {}); sessionsApi.active().then(setActive).catch(() => {});
}, []); }, []);
useEffect(() => { lessonsApi.mySubscriptions().then(setSubs).catch(() => {}); }, []);
return ( return (
<div className="space-y-8"> <div className="space-y-8">
<header> <header>
@@ -118,6 +122,23 @@ export function DashboardPage() {
)} )}
</section> </section>
{subs.length > 0 && (
<section>
<h2 className="mb-3 font-display text-xl font-bold">Geabonneerde lessen</h2>
<ul className="grid gap-3 sm:grid-cols-2">
{subs.map((s) => (
<li key={s.lessonId} className="surface flex items-center justify-between gap-3 p-4">
<div className="min-w-0">
<div className="truncate font-semibold">{s.name}</div>
<div className="text-xs text-slate-500">door {s.ownerDisplayName}</div>
</div>
<Link to={`/practice/${s.lessonId}/setup`} className="btn-success shrink-0 px-4 py-2">Oefenen </Link>
</li>
))}
</ul>
</section>
)}
{ov?.recentSessions && ov.recentSessions.length > 0 && ( {ov?.recentSessions && ov.recentSessions.length > 0 && (
<section> <section>
<h2 className="mb-3 font-display text-xl font-bold">Recente sessies</h2> <h2 className="mb-3 font-display text-xl font-bold">Recente sessies</h2>