- **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.
133 lines
3.6 KiB
TypeScript
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>
|
|
</>
|
|
)
|
|
}
|