186 lines
5.4 KiB
JavaScript
186 lines
5.4 KiB
JavaScript
import React, { useState, useEffect, useCallback } from 'react'
|
||
import { usePage } from '@inertiajs/react'
|
||
import ProfileHero from '../../Components/Profile/ProfileHero'
|
||
import ProfileStatsRow from '../../Components/Profile/ProfileStatsRow'
|
||
import ProfileTabs from '../../Components/Profile/ProfileTabs'
|
||
import TabArtworks from '../../Components/Profile/tabs/TabArtworks'
|
||
import TabAbout from '../../Components/Profile/tabs/TabAbout'
|
||
import TabStats from '../../Components/Profile/tabs/TabStats'
|
||
import TabFavourites from '../../Components/Profile/tabs/TabFavourites'
|
||
import TabCollections from '../../Components/Profile/tabs/TabCollections'
|
||
import TabActivity from '../../Components/Profile/tabs/TabActivity'
|
||
import TabPosts from '../../Components/Profile/tabs/TabPosts'
|
||
import TabStories from '../../Components/Profile/tabs/TabStories'
|
||
|
||
const VALID_TABS = ['artworks', 'stories', 'posts', 'collections', 'about', 'stats', 'favourites', 'activity']
|
||
|
||
function getInitialTab() {
|
||
try {
|
||
const sp = new URLSearchParams(window.location.search)
|
||
const t = sp.get('tab')
|
||
return VALID_TABS.includes(t) ? t : 'artworks'
|
||
} catch {
|
||
return 'artworks'
|
||
}
|
||
}
|
||
|
||
/**
|
||
* ProfileShow – Inertia page for /@username
|
||
*
|
||
* Props injected by ProfileController::renderUserProfile()
|
||
*/
|
||
export default function ProfileShow() {
|
||
const { props } = usePage()
|
||
|
||
const {
|
||
user,
|
||
profile,
|
||
artworks,
|
||
featuredArtworks,
|
||
favourites,
|
||
stats,
|
||
socialLinks,
|
||
followerCount,
|
||
recentFollowers,
|
||
viewerIsFollowing,
|
||
heroBgUrl,
|
||
profileComments,
|
||
creatorStories,
|
||
countryName,
|
||
isOwner,
|
||
auth,
|
||
} = props
|
||
|
||
const [activeTab, setActiveTab] = useState(getInitialTab)
|
||
|
||
const handleTabChange = useCallback((tab) => {
|
||
if (!VALID_TABS.includes(tab)) return
|
||
setActiveTab(tab)
|
||
|
||
// Update URL query param without full navigation
|
||
try {
|
||
const url = new URL(window.location.href)
|
||
if (tab === 'artworks') {
|
||
url.searchParams.delete('tab')
|
||
} else {
|
||
url.searchParams.set('tab', tab)
|
||
}
|
||
window.history.pushState({}, '', url.toString())
|
||
} catch (_) {}
|
||
}, [])
|
||
|
||
// Handle browser back/forward
|
||
useEffect(() => {
|
||
const onPop = () => setActiveTab(getInitialTab())
|
||
window.addEventListener('popstate', onPop)
|
||
return () => window.removeEventListener('popstate', onPop)
|
||
}, [])
|
||
|
||
const isLoggedIn = !!(auth?.user)
|
||
|
||
// Normalise artwork list (SSR may send cursor-paginated object)
|
||
const artworkList = Array.isArray(artworks)
|
||
? artworks
|
||
: (artworks?.data ?? [])
|
||
const artworkNextCursor = artworks?.next_cursor ?? null
|
||
|
||
// Normalise social links (may be object keyed by platform, or array)
|
||
const socialLinksObj = Array.isArray(socialLinks)
|
||
? socialLinks.reduce((acc, l) => { acc[l.platform] = l; return acc }, {})
|
||
: (socialLinks ?? {})
|
||
|
||
return (
|
||
<div className="min-h-screen pb-16">
|
||
{/* Hero section */}
|
||
<ProfileHero
|
||
user={user}
|
||
profile={profile}
|
||
isOwner={isOwner}
|
||
viewerIsFollowing={viewerIsFollowing}
|
||
followerCount={followerCount}
|
||
heroBgUrl={heroBgUrl}
|
||
countryName={countryName}
|
||
/>
|
||
|
||
{/* Stats pills row */}
|
||
<ProfileStatsRow
|
||
stats={stats}
|
||
followerCount={followerCount}
|
||
onTabChange={handleTabChange}
|
||
/>
|
||
|
||
{/* Sticky tabs */}
|
||
<ProfileTabs
|
||
activeTab={activeTab}
|
||
onTabChange={handleTabChange}
|
||
/>
|
||
|
||
{/* Tab content area */}
|
||
<div className={activeTab === 'artworks' ? 'w-full px-4 md:px-6' : 'max-w-6xl mx-auto px-4'}>
|
||
{activeTab === 'artworks' && (
|
||
<TabArtworks
|
||
artworks={{ data: artworkList, next_cursor: artworkNextCursor }}
|
||
featuredArtworks={featuredArtworks}
|
||
username={user.username || user.name}
|
||
isActive
|
||
/>
|
||
)}
|
||
{activeTab === 'posts' && (
|
||
<TabPosts
|
||
username={user.username || user.name}
|
||
isOwner={isOwner}
|
||
authUser={auth?.user ?? null}
|
||
user={user}
|
||
profile={profile}
|
||
stats={stats}
|
||
followerCount={followerCount}
|
||
recentFollowers={recentFollowers}
|
||
socialLinks={socialLinksObj}
|
||
countryName={countryName}
|
||
onTabChange={handleTabChange}
|
||
/>
|
||
)}
|
||
{activeTab === 'stories' && (
|
||
<TabStories
|
||
stories={creatorStories}
|
||
username={user.username || user.name}
|
||
/>
|
||
)}
|
||
{activeTab === 'collections' && (
|
||
<TabCollections collections={[]} />
|
||
)}
|
||
{activeTab === 'about' && (
|
||
<TabAbout
|
||
user={user}
|
||
profile={profile}
|
||
socialLinks={socialLinksObj}
|
||
countryName={countryName}
|
||
followerCount={followerCount}
|
||
/>
|
||
)}
|
||
{activeTab === 'stats' && (
|
||
<TabStats
|
||
stats={stats}
|
||
followerCount={followerCount}
|
||
/>
|
||
)}
|
||
{activeTab === 'favourites' && (
|
||
<TabFavourites
|
||
favourites={favourites}
|
||
isOwner={isOwner}
|
||
username={user.username || user.name}
|
||
/>
|
||
)}
|
||
{activeTab === 'activity' && (
|
||
<TabActivity
|
||
profileComments={profileComments}
|
||
user={user}
|
||
isOwner={isOwner}
|
||
isLoggedIn={isLoggedIn}
|
||
/>
|
||
)}
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|