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

133 lines
3.6 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 { SearchBar } from '@/components/SearchBar'
import { ArticleFiltersComponent } from '@/components/ArticleFilters'
import { ArticlesSummary } from '@/components/ProfileArticlesSummary'
import { UserArticles } from '@/components/UserArticles'
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>
}
function ProfileLoading() {
return (
<div className="text-center py-12">
<p className="text-gray-500">Loading profile...</p>
</div>
)
}
function ProfileArticlesSection({
searchQuery,
setSearchQuery,
filters,
setFilters,
articles,
allArticles,
loading,
error,
loadArticleContent,
articleFiltersVisible,
}: Pick<
ProfileViewProps,
'searchQuery' | 'setSearchQuery' | 'filters' | 'setFilters' | 'articles' | 'allArticles' | 'loading' | 'error' | 'loadArticleContent'
> & {
articleFiltersVisible: boolean
}) {
return (
<>
<div className="mb-6">
<h2 className="text-2xl font-bold mb-4">My Articles</h2>
<div className="mb-4">
<SearchBar value={searchQuery} onChange={setSearchQuery} placeholder="Search my articles..." />
</div>
{articleFiltersVisible && (
<ArticleFiltersComponent filters={filters} onFiltersChange={setFilters} articles={allArticles} />
)}
</div>
<ArticlesSummary visibleCount={articles.length} total={allArticles.length} />
<UserArticles
articles={articles}
loading={loading}
error={error}
onLoadContent={loadArticleContent}
showEmptyMessage
/>
</>
)
}
function ProfileLayout({
currentPubkey,
profile,
loadingProfile,
searchQuery,
setSearchQuery,
filters,
setFilters,
articles,
allArticles,
loading,
error,
loadArticleContent,
}: ProfileViewProps) {
const articleFiltersVisible = !loading && allArticles.length > 0
return (
<>
<BackButton />
{loadingProfile ? (
<ProfileLoading />
) : profile ? (
<UserProfile profile={profile} pubkey={currentPubkey} articleCount={allArticles.length} />
) : null}
<ProfileArticlesSection
searchQuery={searchQuery}
setSearchQuery={setSearchQuery}
filters={filters}
setFilters={setFilters}
articles={articles}
allArticles={allArticles}
loading={loading}
error={error}
loadArticleContent={loadArticleContent}
articleFiltersVisible={articleFiltersVisible}
/>
</>
)
}
export function ProfileView(props: ProfileViewProps) {
return (
<>
<Head>
<title>My Profile - zapwall4Science</title>
<meta name="description" content="View your profile and published articles" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
</Head>
<main className="min-h-screen bg-gray-50">
<ProfileHeader />
<div className="max-w-4xl mx-auto px-4 py-8">
<ProfileLayout {...props} />
</div>
</main>
</>
)
}