Nicolas Cantu 90ff8282f1 feat: Implémentation système de commissions systématique et incontournable
- 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.
2025-12-27 21:11:09 +01:00

110 lines
3.0 KiB
TypeScript

import Head from 'next/head'
import type { Article } from '@/types/nostr'
import type { ArticleFilters } from '@/components/ArticleFilters'
import type { NostrProfile } from '@/types/nostr'
import { ProfileHeader } from '@/components/ProfileHeader'
import { BackButton } from '@/components/ProfileBackButton'
import { UserProfile } from '@/components/UserProfile'
import { ProfileArticlesSection } from '@/components/ProfileArticlesSection'
interface ProfileViewProps {
currentPubkey: string
profile: NostrProfile | null
loadingProfile: boolean
searchQuery: string
setSearchQuery: (value: string) => void
filters: ArticleFilters
setFilters: (value: ArticleFilters) => void
articles: Article[]
allArticles: Article[]
loading: boolean
error: string | null
loadArticleContent: (id: string, pubkey: string) => Promise<Article | null>
selectedSeriesId?: string | undefined
onSelectSeries: (seriesId: string | undefined) => void
}
function ProfileLoading() {
return (
<div className="text-center py-12">
<p className="text-gray-500">Loading profile...</p>
</div>
)
}
function ProfileLayout(props: ProfileViewProps) {
const articleFiltersVisible = !props.loading && props.allArticles.length > 0
return (
<>
<ProfileHeaderSection
loadingProfile={props.loadingProfile}
profile={props.profile}
currentPubkey={props.currentPubkey}
articleCount={props.allArticles.length}
/>
<ProfileArticlesSection
searchQuery={props.searchQuery}
setSearchQuery={props.setSearchQuery}
filters={props.filters}
setFilters={props.setFilters}
articles={props.articles}
allArticles={props.allArticles}
loading={props.loading}
error={props.error}
loadArticleContent={props.loadArticleContent}
articleFiltersVisible={articleFiltersVisible}
currentPubkey={props.currentPubkey}
selectedSeriesId={props.selectedSeriesId}
onSelectSeries={props.onSelectSeries}
/>
</>
)
}
function ProfileHeaderSection({
loadingProfile,
profile,
currentPubkey,
articleCount,
}: {
loadingProfile: boolean
profile: NostrProfile | null
currentPubkey: string
articleCount: number
}) {
return (
<>
<BackButton />
{loadingProfile ? (
<ProfileLoading />
) : profile ? (
<UserProfile profile={profile} pubkey={currentPubkey} articleCount={articleCount} />
) : null}
</>
)
}
export function ProfileView(props: ProfileViewProps) {
return (
<>
<ProfileHead />
<main className="min-h-screen bg-gray-50">
<ProfileHeader />
<div className="max-w-4xl mx-auto px-4 py-8">
<ProfileLayout {...props} />
</div>
</main>
</>
)
}
function ProfileHead() {
return (
<Head>
<title>My Profile - zapwall.fr</title>
<meta name="description" content="View your profile and published articles" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
</Head>
)
}