import React, { useState, useCallback } from 'react' import ArtworkCard from '../../gallery/ArtworkCard' const SORT_OPTIONS = [ { value: 'latest', label: 'Latest' }, { value: 'trending', label: 'Trending' }, { value: 'rising', label: 'Rising' }, { value: 'views', label: 'Most Viewed' }, { value: 'favs', label: 'Most Favourited' }, ] function ArtworkSkeleton() { return (
) } function EmptyState({ username }) { return (

No artworks yet

@{username} hasn't uploaded anything yet.

) } /** * Featured artworks horizontal scroll strip. */ function FeaturedStrip({ featuredArtworks }) { if (!featuredArtworks?.length) return null return (

Featured

{featuredArtworks.map((art) => (
{art.name}

{art.name}

{art.label && (

{art.label}

)}
))}
) } function slugify(str) { return (str || '').toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '') } /** * TabArtworks * Features: sort selector, featured strip, masonry-style artwork grid, * skeleton loading, empty state, load-more pagination. */ export default function TabArtworks({ artworks, featuredArtworks, username, isActive }) { const [sort, setSort] = useState('latest') const [items, setItems] = useState(artworks?.data ?? artworks ?? []) const [nextCursor, setNextCursor] = useState(artworks?.next_cursor ?? null) const [loadingMore, setLoadingMore] = useState(false) const [isInitialLoad] = useState(false) // data SSR-loaded const handleSort = async (newSort) => { setSort(newSort) setItems([]) try { const res = await fetch(`/api/profile/${encodeURIComponent(username)}/artworks?sort=${newSort}`, { headers: { Accept: 'application/json' }, }) if (res.ok) { const data = await res.json() setItems(data.data ?? data) setNextCursor(data.next_cursor ?? null) } } catch (_) {} } const loadMore = async () => { if (!nextCursor || loadingMore) return setLoadingMore(true) try { const res = await fetch( `/api/profile/${encodeURIComponent(username)}/artworks?sort=${sort}&cursor=${encodeURIComponent(nextCursor)}`, { headers: { Accept: 'application/json' } } ) if (res.ok) { const data = await res.json() setItems((prev) => [...prev, ...(data.data ?? data)]) setNextCursor(data.next_cursor ?? null) } } catch (_) {} setLoadingMore(false) } return (
{/* Featured strip */} {/* Sort bar */}
Sort
{SORT_OPTIONS.map((opt) => ( ))}
{/* Grid */} {isInitialLoad ? (
{Array.from({ length: 8 }).map((_, i) => )}
) : items.length === 0 ? (
) : ( <>
{items.map((art, i) => ( ))} {loadingMore && Array.from({ length: 4 }).map((_, i) => )}
{/* Load more */} {nextCursor && (
)} )}
) }