110 lines
3.0 KiB
TypeScript
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 - zapwall4Science</title>
|
|
<meta name="description" content="View your profile and published articles" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
</Head>
|
|
)
|
|
}
|