Nicolas Cantu 3000872dbc refactoring
- **Motivations :** Assurer passage du lint strict et clarifier la logique paiements/publications.

- **Root causes :** Fonctions trop longues, promesses non gérées et typages WebLN/Nostr incomplets.

- **Correctifs :** Refactor PaymentModal (handlers void), extraction helpers articlePublisher, simplification polling sponsoring/zap, corrections curly et awaits.

- **Evolutions :** Nouveau module articlePublisherHelpers pour présentation/aiguillage contenu privé.

- **Page affectées :** components/PaymentModal.tsx, lib/articlePublisher.ts, lib/articlePublisherHelpers.ts, lib/paymentPolling.ts, lib/sponsoring.ts, lib/nostrZapVerification.ts et dépendances liées.
2025-12-22 17:56:00 +01:00

103 lines
3.0 KiB
TypeScript

import Head from 'next/head'
import type { Article } from '@/types/nostr'
import { ArticleFiltersComponent, type ArticleFilters } from '@/components/ArticleFilters'
import { CategoryTabs } from '@/components/CategoryTabs'
import { SearchBar } from '@/components/SearchBar'
import { ArticlesList } from '@/components/ArticlesList'
import { PageHeader } from '@/components/PageHeader'
import type { Dispatch, SetStateAction } from 'react'
interface HomeViewProps {
searchQuery: string
setSearchQuery: Dispatch<SetStateAction<string>>
selectedCategory: ArticleFilters['category']
setSelectedCategory: Dispatch<SetStateAction<ArticleFilters['category']>>
filters: ArticleFilters
setFilters: Dispatch<SetStateAction<ArticleFilters>>
articles: Article[]
allArticles: Article[]
loading: boolean
error: string | null
onUnlock: (article: Article) => void
unlockedArticles: Set<string>
}
function HomeHead() {
return (
<Head>
<title>zapwall4Science - Science Fiction & Scientific Research</title>
<meta
name="description"
content="Plateforme de publication d'articles scientifiques et de science-fiction avec sponsoring et rémunération des avis"
/>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="/favicon.ico" />
</Head>
)
}
function ArticlesHero({
searchQuery,
setSearchQuery,
selectedCategory,
setSelectedCategory,
}: Pick<HomeViewProps, 'searchQuery' | 'setSearchQuery' | 'selectedCategory' | 'setSelectedCategory'>) {
return (
<div className="mb-8">
<h2 className="text-3xl font-bold mb-4">Articles</h2>
<p className="text-gray-600 mb-4">Lisez les aperçus gratuitement, débloquez le contenu complet avec {800} sats</p>
<CategoryTabs selectedCategory={selectedCategory} onCategoryChange={setSelectedCategory} />
<div className="mb-4">
<SearchBar value={searchQuery} onChange={setSearchQuery} />
</div>
</div>
)
}
function HomeContent({
searchQuery,
setSearchQuery,
selectedCategory,
setSelectedCategory,
filters,
setFilters,
articles,
allArticles,
loading,
error,
onUnlock,
unlockedArticles,
}: HomeViewProps) {
const shouldShowFilters = !loading && allArticles.length > 0
const articlesListProps = { articles, allArticles, loading, error, onUnlock, unlockedArticles }
return (
<div className="max-w-4xl mx-auto px-4 py-8">
<ArticlesHero
searchQuery={searchQuery}
setSearchQuery={setSearchQuery}
selectedCategory={selectedCategory}
setSelectedCategory={setSelectedCategory}
/>
{shouldShowFilters && (
<ArticleFiltersComponent filters={filters} onFiltersChange={setFilters} articles={allArticles} />
)}
<ArticlesList {...articlesListProps} />
</div>
)
}
export function HomeView(props: HomeViewProps) {
return (
<>
<HomeHead />
<main className="min-h-screen bg-gray-50">
<PageHeader />
<HomeContent {...props} />
</main>
</>
)
}