import React from 'react' import { motion } from 'framer-motion' import { useParams, useNavigate } from 'react-router-dom' import { ArrowLeftIcon, PlayIcon, CalendarIcon, UserIcon, FilmIcon, PlusIcon, CheckIcon, ExclamationTriangleIcon, LockClosedIcon } from '@heroicons/react/24/outline' import { StarIcon as StarIconSolid } from '@heroicons/react/24/solid' import { useAdult } from '../hooks/useApi' import { Tooltip } from '../components/MicroInteractions' class AdultDetailErrorBoundary extends React.Component< { children: React.ReactNode; navigate: (to: string) => void }, { hasError: boolean; error?: Error } > { constructor(props: any) { super(props) this.state = { hasError: false } } static getDerivedStateFromError(error: Error) { return { hasError: true, error } } componentDidCatch(error: Error, errorInfo: React.ErrorInfo) { console.error('AdultDetail error:', error, errorInfo) } render() { if (this.state.hasError) { return (

Content Error

{this.state.error?.message || 'Failed to load content details'}

) } return this.props.children } } export default function AdultDetail() { const { id } = useParams<{ id: string }>() const navigate = useNavigate() // Validate ID and handle invalid cases const contentId = id ? Number(id) : null const isValidId = contentId && !isNaN(contentId) && contentId > 0 // Early return for invalid ID if (!isValidId) { return (
🔒

Invalid Content ID

The content ID is invalid or missing.

) } const { data: adultContent, isLoading, error } = useAdult(contentId) if (isLoading) { return (
) } if (error || !adultContent) { return (
🔒

Content Not Found

The content you're looking for doesn't exist or has been removed.

) } const posterUrl = adultContent.poster_url || adultContent.screenshot_url ? ((adultContent.poster_url || adultContent.screenshot_url).startsWith('http') ? (adultContent.poster_url || adultContent.screenshot_url) : `${(import.meta as any).env?.VITE_API_URL?.replace('/api', '') || ''}${adultContent.poster_url || adultContent.screenshot_url}`) : null const backdropUrl = adultContent.backdrop_url ? (adultContent.backdrop_url.startsWith('http') ? adultContent.backdrop_url : `${(import.meta as any).env?.VITE_API_URL?.replace('/api', '') || ''}${adultContent.backdrop_url}`) : null const getPosterAspectRatio = () => { // Check for poster_aspect_ratio first, then fall back to 2/3 return adultContent.poster_aspect_ratio || 2/3 } const formatYear = (date?: string) => { if (!date) return 'Unknown' return new Date(date).getFullYear() } const formatDate = (date?: string) => { if (!date) return 'Unknown' return new Date(date).toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' }) } const formatRuntime = (minutes?: number) => { if (!minutes) return 'Unknown' const hours = Math.floor(minutes / 60) const mins = minutes % 60 return `${hours}h ${mins}m` } return (
{/* Hero Section - Compact */}
{backdropUrl ? ( <>
) : (
)} {/* Back Button */} navigate(-1)} className="absolute top-4 left-4 p-2 bg-black/50 dark:bg-black/70 backdrop-blur-sm rounded-lg text-white hover:bg-black/70 dark:hover:bg-black/80 transition-all duration-200" whileHover={{ scale: 1.05 }} whileTap={{ scale: 0.95 }} > {/* Play Button - Compact */}
{/* Main Content - Compact */}
{/* Poster and Basic Info - Compact */}
{posterUrl ? ( { console.error('Failed to load poster:', posterUrl, 'for adult content:', adultContent.title) // Set a fallback background const target = e.target as HTMLImageElement target.style.display = 'none' const parent = target.parentElement if (parent) { parent.className = 'w-full bg-gray-200 dark:bg-gray-800 rounded-lg flex items-center justify-center mb-4' parent.style.aspectRatio = getPosterAspectRatio().toString() const iconDiv = document.createElement('div') iconDiv.className = 'text-gray-400 dark:text-gray-600' iconDiv.innerHTML = '' parent.appendChild(iconDiv) } }} /> ) : (
)}

{adultContent.title}

{adultContent.watched && ( )}
{formatYear(adultContent.release_date)}
Adult Content
{adultContent.rating && (
{[...Array(5)].map((_, i) => ( ))}
{Number(adultContent.rating)?.toFixed(1)}
)}
Play Now Add to List
{/* Details - Compact */}

Description

{adultContent.overview || 'No description available for this content.'}

Details

Release Date

{formatDate(adultContent.release_date)}

Duration

{adultContent.runtime_minutes ? formatRuntime(adultContent.runtime_minutes) : 'Unknown'}

Rating

{adultContent.rating ? `${adultContent.rating}/10` : 'Not Rated'}

Source

{adultContent.source_name || 'Unknown'}

Cast & Actors

{adultContent.actors && adultContent.actors.length > 0 ? (
{adultContent.actors.map((actor: any) => ( navigate(`/actors/${actor.id}`)} className="bg-gray-50 dark:bg-gray-800 rounded-lg p-3 border border-gray-200 dark:border-gray-700 hover:shadow-lg transition-all cursor-pointer" >
{actor.thumbnail_path ? ( {actor.name} { console.error('Failed to load actor thumbnail:', actor.thumbnail_path, 'for actor:', actor.name) const target = e.target as HTMLImageElement target.style.display = 'none' const parent = target.parentElement if (parent) { parent.innerHTML = '
' } }} /> ) : (
)}

{actor.name}

{actor.metadata?.age && (

Age: {actor.metadata.age}

)}
))}
) : (

No actor information available for this content.

)}

Content Warning

Adult Content - 18+ Only

This content is intended for mature audiences only. Viewer discretion is advised.

) }