import React, { useState, useEffect, useCallback } from 'react' import { usePage } from '@inertiajs/react' import ProfileHero from '../../components/profile/ProfileHero' import ProfileTabs from '../../components/profile/ProfileTabs' import TabArtworks from '../../components/profile/tabs/TabArtworks' import TabAchievements from '../../components/profile/tabs/TabAchievements' 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 = ['posts', 'artworks', 'stories', 'achievements', 'collections', 'about', 'stats', 'favourites', 'activity'] function getInitialTab(initialTab = 'posts') { if (typeof window === 'undefined') { return VALID_TABS.includes(initialTab) ? initialTab : 'posts' } try { const pathname = window.location.pathname.replace(/\/+$/, '') const segments = pathname.split('/').filter(Boolean) const lastSegment = segments.at(-1) if (VALID_TABS.includes(lastSegment)) { return lastSegment } } catch { return VALID_TABS.includes(initialTab) ? initialTab : 'posts' } return VALID_TABS.includes(initialTab) ? initialTab : 'posts' } /** * 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, followContext, followAnalytics, suggestedUsers, viewerIsFollowing, heroBgUrl, profileComments, creatorStories, collections, achievements, leaderboardRank, countryName, isOwner, auth, initialTab, profileUrl, galleryUrl, collectionCreateUrl, collectionReorderUrl, collectionsFeaturedUrl, collectionFeatureLimit, profileTabUrls, } = props const [activeTab, setActiveTab] = useState(() => getInitialTab(initialTab)) const handleTabChange = useCallback((tab) => { if (!VALID_TABS.includes(tab)) return setActiveTab(tab) try { const currentUrl = new URL(window.location.href) const targetBase = profileTabUrls?.[tab] || `${profileUrl || `${window.location.origin}`}/${tab}` const nextUrl = new URL(targetBase, window.location.origin) const sharedPostId = currentUrl.searchParams.get('post') if (sharedPostId) { nextUrl.searchParams.set('post', sharedPostId) } window.history.pushState({}, '', nextUrl.toString()) } catch (_) {} }, [profileTabUrls, profileUrl]) useEffect(() => { const onPop = () => setActiveTab(getInitialTab(initialTab)) window.addEventListener('popstate', onPop) return () => window.removeEventListener('popstate', onPop) }, [initialTab]) 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 const favouriteList = Array.isArray(favourites) ? favourites : (favourites?.data ?? []) const favouriteNextCursor = favourites?.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 ?? {}) const contentShellClassName = activeTab === 'artworks' ? 'w-full px-4 md:px-6' : activeTab === 'posts' ? 'mx-auto max-w-7xl px-4 md:px-6' : 'max-w-6xl mx-auto px-4' return (