- Création lib/platformCommissions.ts : configuration centralisée des commissions - Articles : 800 sats (700 auteur, 100 plateforme) - Avis : 70 sats (49 lecteur, 21 plateforme) - Sponsoring : 0.046 BTC (0.042 auteur, 0.004 plateforme) - Validation des montants à chaque étape : - Publication : vérification du montant avant publication - Paiement : vérification du montant avant acceptation - Erreurs explicites si montant incorrect - Tracking des commissions sur Nostr : - Tags author_amount et platform_commission dans événements - Interface ContentDeliveryTracking étendue - Traçabilité complète pour audit - Logs structurés avec informations de commission - Documentation complète du système Les commissions sont maintenant systématiques, validées et traçables.
117 lines
3.7 KiB
TypeScript
117 lines
3.7 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 { Footer } from '@/components/Footer'
|
|
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>zapwall.fr</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">
|
|
<div className="mb-4 text-cyber-accent leading-relaxed bg-cyber-dark/50 border border-neon-cyan/20 rounded-lg p-4 backdrop-blur-sm">
|
|
<p className="mb-2">
|
|
Consultez les auteurs et aperçus, achetez les parutions au fil de l'eau par <strong className="text-neon-green">800 sats</strong> (moins 100 sats et frais de transaction).
|
|
</p>
|
|
<p className="mb-2">
|
|
Sponsorisez l'auteur pour <strong className="text-neon-green">0.046 BTC</strong> (moins 0.004 BTC et frais de transaction).
|
|
</p>
|
|
<p className="mb-2">
|
|
Les avis sont remerciables pour <strong className="text-neon-green">70 sats</strong> (moins 21 sats et frais de transaction).
|
|
</p>
|
|
<p className="text-sm text-cyber-accent/70 italic">
|
|
Les fonds de la plateforme servent à son développement.
|
|
</p>
|
|
</div>
|
|
<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-cyber-darker">
|
|
<PageHeader />
|
|
<HomeContent {...props} />
|
|
<Footer />
|
|
</main>
|
|
</>
|
|
)
|
|
}
|