import { useRouter } from 'next/router' import Head from 'next/head' import { useEffect, useState } from 'react' import { getSeriesById } from '@/lib/seriesQueries' import { getSeriesAggregates } from '@/lib/seriesAggregation' import { getArticlesBySeries } from '@/lib/articleQueries' import type { Series, Article } from '@/types/nostr' import { SeriesStats } from '@/components/SeriesStats' import { ArticleCard } from '@/components/ArticleCard' import { t } from '@/lib/i18n' import Image from 'next/image' import { ArticleReviews } from '@/components/ArticleReviews' import { useNostrAuth } from '@/hooks/useNostrAuth' import Link from 'next/link' function SeriesHeader({ series }: { series: Series }): React.ReactElement { return (
{series.coverUrl && (
{series.title}
)}

{series.title}

{series.description}

{t('category.science-fiction')}: {series.category === 'science-fiction' ? t('category.science-fiction') : t('category.scientific-research')}

{series.preview && (

{series.preview}

)}
) } export default function SeriesPage(): React.ReactElement | null { const router = useRouter() const { id } = router.query const seriesId = getSeriesIdFromQuery(id) const data = useSeriesPageData(seriesId ?? '') if (!seriesId) { return null } return } function getSeriesIdFromQuery(id: unknown): string | null { return typeof id === 'string' && id.trim() ? id : null } function SeriesPageView({ series, articles, aggregates, loading, error, }: { series: Series | null articles: Article[] aggregates: { sponsoring: number; purchases: number; reviewTips: number } | null loading: boolean error: string | null }): React.ReactElement { return ( <> Série - zapwall.fr
{series ? : null}
) } function SeriesPageStatus({ loading, error }: { loading: boolean; error: string | null }): React.ReactElement | null { if (loading) { return

{t('common.loading')}

} if (error) { return

{error}

} return null } function SeriesPageContent({ series, articles, aggregates, }: { series: Series articles: Article[] aggregates: { sponsoring: number; purchases: number; reviewTips: number } | null }): React.ReactElement { return ( <> ) } function SeriesActions({ series }: { series: Series }): React.ReactElement | null { const { pubkey } = useNostrAuth() // Only show "Create Publication" button if user is the author if (!pubkey || pubkey !== series.pubkey) { return null } return (
{t('series.createPublication')}
) } function SeriesPublications({ articles }: { articles: Article[] }): React.ReactElement { if (articles.length === 0) { return

Aucune publication pour cette série.

} return (

{t('series.publications')}

{articles.map((a) => (
{}} />
))}
) } type SeriesAggregates = { sponsoring: number; purchases: number; reviewTips: number } type SeriesPageData = { series: Series | null articles: Article[] aggregates: SeriesAggregates | null loading: boolean error: string | null } function useSeriesPageData(seriesId: string): SeriesPageData { const [series, setSeries] = useState(null) const [articles, setArticles] = useState([]) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) const [aggregates, setAggregates] = useState(null) useEffect(() => { if (!seriesId) { return } const load = async (): Promise => { setLoading(true) setError(null) try { // First try cache (should be very fast) const s = await getSeriesById(seriesId, 2000) if (!s) { setError('Série introuvable') setLoading(false) return } setSeries(s) // Load aggregates and articles in parallel const [agg, seriesArticles] = await Promise.all([ getSeriesAggregates({ authorPubkey: s.pubkey, seriesId: s.id }), getArticlesBySeries(s.id), ]) setAggregates(agg) setArticles(seriesArticles) } catch (e) { setError(e instanceof Error ? e.message : 'Erreur lors du chargement de la série') } finally { setLoading(false) } } void load() }, [seriesId]) return { series, articles, aggregates, loading, error } }