"use client" import { useState, useEffect, useRef, useCallback } from "react" import Image from "next/image" import { Button } from "@/components/ui/button" import { Badge } from "@/components/ui/badge" import Link from "next/link" import { ArrowLeft, Instagram, ExternalLink, Loader2, DollarSign } from "lucide-react" import { useArtist } from "@/hooks/use-artist-data" interface ArtistPortfolioProps { artistId: string } export function ArtistPortfolio({ artistId }: ArtistPortfolioProps) { const [selectedCategory, setSelectedCategory] = useState("All") const [selectedImage, setSelectedImage] = useState(null) const [scrollY, setScrollY] = useState(0) // Fetch artist data from API const { data: artist, isLoading, error } = useArtist(artistId) // keep a reference to the last focused thumbnail so we can return focus on modal close const lastFocusedRef = useRef(null) const closeButtonRef = useRef(null) useEffect(() => { const handleScroll = () => setScrollY(window.scrollY) window.addEventListener("scroll", handleScroll) return () => window.removeEventListener("scroll", handleScroll) }, []) // Derived lists (safe when `artist` is undefined during initial renders) const portfolioImages = artist?.portfolioImages || [] // Get unique categories from tags const allTags = portfolioImages.flatMap(img => img.tags) const categories = ["All", ...Array.from(new Set(allTags))] const filteredPortfolio = selectedCategory === "All" ? portfolioImages : portfolioImages.filter(img => img.tags.includes(selectedCategory)) // keyboard navigation for modal (kept as hooks so they run in same order every render) const goToIndex = useCallback( (index: number) => { const item = filteredPortfolio[index] if (item) setSelectedImage(item.id) }, [filteredPortfolio], ) useEffect(() => { if (!selectedImage) return const handleKey = (e: KeyboardEvent) => { if (e.key === "Escape") { setSelectedImage(null) } else if (e.key === "ArrowRight") { const currentIndex = filteredPortfolio.findIndex((p) => p.id === selectedImage) const nextIndex = (currentIndex + 1) % filteredPortfolio.length goToIndex(nextIndex) } else if (e.key === "ArrowLeft") { const currentIndex = filteredPortfolio.findIndex((p) => p.id === selectedImage) const prevIndex = (currentIndex - 1 + filteredPortfolio.length) % filteredPortfolio.length goToIndex(prevIndex) } } document.addEventListener("keydown", handleKey) // move focus to close button for keyboard users setTimeout(() => closeButtonRef.current?.focus(), 0) return () => { document.removeEventListener("keydown", handleKey) } }, [selectedImage, filteredPortfolio, goToIndex]) const openImageFromElement = (id: string, el: HTMLElement | null) => { if (el) lastFocusedRef.current = el setSelectedImage(id) } const closeModal = () => { setSelectedImage(null) // return focus to last focused thumbnail setTimeout(() => lastFocusedRef.current?.focus(), 0) } const currentIndex = selectedImage ? filteredPortfolio.findIndex((p) => p.id === selectedImage) : -1 const currentItem = selectedImage ? filteredPortfolio.find((p) => p.id === selectedImage) : null // Loading state if (isLoading) { return (
) } // Error state if (error) { return (

Failed to load artist

Please try again later

) } // Artist not found if (!artist) { return (

Artist not found

) } // Get profile image const profileImage = portfolioImages.find(img => img.tags.includes('profile'))?.url || portfolioImages[0]?.url || "/placeholder.svg" return (
{/* Back Button */}
{/* Hero Section with Split Screen */}
{/* Left Side - Artist Image */}
{artist.name}
{artist.isActive ? "Available" : "Unavailable"}
{/* Right Side - Artist Info */}

{artist.name}

{artist.specialties.join(", ")}

{artist.bio}

{artist.instagramHandle && ( )} {artist.hourlyRate && (
Starting at ${artist.hourlyRate}/hr
)}

Specializes in:

{artist.specialties.map((style) => ( {style} ))}
{/* Curved Border */}
{/* Portfolio Section with Split Screen Layout */}
{/* Left Side - Portfolio Grid */}
{filteredPortfolio.length === 0 ? (

No portfolio images available

) : (
{filteredPortfolio.map((item) => (
{ openImageFromElement(item.id, (e.currentTarget as HTMLElement) || null) }} onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault() openImageFromElement(item.id, e.currentTarget as HTMLElement) } }} >
{item.caption
{item.caption &&

{item.caption}

}
))}
)}
{/* Right Side - Sticky Header and Info */}

Featured Work

{filteredPortfolio.length}

Explore the portfolio of {artist.name} showcasing their expertise in{" "} {artist.specialties.join(", ")}. Each piece represents a unique collaboration between artist and client.

{/* Category Filter */} {categories.length > 1 && (

Filter by Style

{categories.map((category) => { const count = category === "All" ? portfolioImages.length : portfolioImages.filter(img => img.tags.includes(category)).length return ( ) })}
)} {/* Quick Stats */}
{portfolioImages.length}
Pieces
{artist.isActive ? "Active" : "Inactive"}
Status
{/* Contact Section */}

Ready to Get Started?

Book a consultation with {artist.name} to discuss your next tattoo. We can help plan the design and schedule the session.

{artist.specialties.length}+
Specialties
{portfolioImages.length}
Portfolio Pieces
{artist.hourlyRate ? `$${artist.hourlyRate}` : "Contact"}
Starting Rate
{/* Image Modal / Lightbox */} {selectedImage && currentItem && (
closeModal()} >
e.stopPropagation()} > {/* Prev */}
{currentItem.caption
{/* Next */}
)}
) }