import { useState, useContext } from 'react' import { motion } from 'framer-motion' import { useNavigate } from 'react-router-dom' import { Play, Plus, Eye, Lock, AlertTriangle, Star, Heart, Circle, CheckCircle2 } from 'lucide-react' import { useAdults } from '../hooks/useApi' import { Tooltip } from '../components/MicroInteractions' import { ViewContext } from '../components/Layout' // Import from alternative frontend import { MediaListView } from '../../../frontend/components/MediaListView' import { MediaDetailView } from '../../../frontend/components/MediaDetailView' interface PaginatedResponse { items: T[] pagination: { total: number per_page: number current_page: number last_page: number } available_filters?: { sources?: string[] genres?: string[] years?: string[] } } interface AdultContent { id: number title: string overview?: string poster_url?: string poster_aspect_ratio?: number backdrop_url?: string screenshot_url?: string release_date?: string rating?: number runtime_minutes?: number watched?: boolean source_name?: string genre?: string studio?: string cast?: string[] director?: string year?: number } export default function Adult() { // Get view context from Layout const viewContext = useContext(ViewContext) // Extract values from context or use defaults const viewMode = viewContext?.viewMode || 'grid' const gridColumns = viewContext?.gridColumns || 5 const coverSize = viewContext?.coverSize || 200 const PaginationComp = viewContext?.PaginationComponent const FiltersComp = viewContext?.FiltersComponent // Load preferences from localStorage const getStoredPreferences = () => { const stored = localStorage.getItem('adultPreferences') return stored ? JSON.parse(stored) : {} } const [searchTerm, setSearchTerm] = useState('') const [selectedGenre, setSelectedGenre] = useState('') const [selectedYear, setSelectedYear] = useState('') const [selectedSource, setSelectedSource] = useState('') const [currentPage, setCurrentPage] = useState(1) const navigate = useNavigate() const [itemsPerPage, setItemsPerPage] = useState(() => getStoredPreferences().itemsPerPage || 20) // Save preferences to localStorage const savePreferences = (updates: any) => { const preferences = { itemsPerPage, ...updates } localStorage.setItem('adultPreferences', JSON.stringify(preferences)) } // Fetch adult content const { data: adultData, isLoading, error } = useAdults({ search: searchTerm || undefined, genre: selectedGenre || undefined, year: selectedYear ? parseInt(selectedYear) : undefined, source: selectedSource || undefined, page: currentPage, per_page: itemsPerPage }) as { data?: PaginatedResponse; isLoading: boolean; error: any } const adultContent = adultData?.items || [] const pagination = adultData?.pagination const availableFilters = adultData?.available_filters || {} const availableSources = availableFilters.sources || ['XBVR', 'Stash', 'Other'] // Convert adult content to MediaItem format for MediaListView const mediaItems = adultContent.map(content => ({ id: content.id.toString(), title: content.title || 'Untitled Adult Content', type: 'adult' as const, coverUrl: content.poster_url || content.screenshot_url || '', rating: Number(content.rating) || 0, status: 'completed' as const, releaseYear: content.year || (content.release_date ? new Date(content.release_date).getFullYear() : new Date().getFullYear()), addedAt: new Date().toISOString(), favorite: false, platform: content.source_name || 'Unknown', description: content.overview || '', genres: content.genre ? [content.genre] : [] })) // State for MediaListView const [selectedId, setSelectedId] = useState(null) const [multiSelectedIds, setMultiSelectedIds] = useState>(new Set()) const [detailItem, setDetailItem] = useState(null) const handleSelect = (item: any) => { setSelectedId(item.id) setDetailItem(item) } const handleToggleSelect = (id: string) => { const newSelected = new Set(multiSelectedIds) if (newSelected.has(id)) { newSelected.delete(id) } else { newSelected.add(id) } setMultiSelectedIds(newSelected) } // Pagination handlers const handlePageChange = (page: number) => { setCurrentPage(page) } const handleItemsPerPageChange = (newItemsPerPage: number) => { setItemsPerPage(newItemsPerPage) setCurrentPage(1) savePreferences({ itemsPerPage: newItemsPerPage }) } const handleContentClick = (content: AdultContent) => { navigate(`/adult/${content.id}`) } // Filter handlers const handleFiltersChange = (filters: any) => { setSelectedSource(filters.source || '') setSelectedGenre(filters.genre || '') setSelectedYear(filters.year || '') setCurrentPage(1) } const handleSearch = (term: string) => { setSearchTerm(term) setCurrentPage(1) } // Mock genres for adult content const genres = [ 'All', 'Action', 'Adventure', 'Comedy', 'Drama', 'Fantasy', 'Horror', 'Mystery', 'Romance', 'Sci-Fi', 'Thriller', 'Other' ] // Mock years const currentYear = new Date().getFullYear() const years = ['All', ...Array.from({ length: 10 }, (_, i) => (currentYear - i).toString())] // Prepare filter data for FiltersComponent const filterState = { search: searchTerm, source: selectedSource, genre: selectedGenre, year: selectedYear } const filterOptions = { sources: availableSources || [], genres: availableFilters.genres || genres.slice(1), years: availableFilters.years || years.slice(1) } // Helper function to get grid classes based on column count const getGridClass = (columns: number) => { const columnClasses = { 2: 'grid-cols-1 md:grid-cols-2', 3: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3', 4: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4', 5: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5', 6: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-6', 7: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-7', 8: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-8' } return columnClasses[columns as keyof typeof columnClasses] || columnClasses[5] } const formatYear = (date?: string) => { if (!date) return 'Unknown' return new Date(date).getFullYear() } const renderRating = (rating?: number | string) => { const numericRating = typeof rating === 'string' ? parseFloat(rating) : rating if (!numericRating || typeof numericRating !== 'number' || isNaN(numericRating)) return null return (
{[...Array(5)].map((_, i) => ( ))} {numericRating.toFixed(1)}
) } if (isLoading) { return (
{[...Array(8)].map((_, i) => (
))}
) } if (error) { return (

Content Error

Failed to load adult content. Please try again later.

) } return (
{/* Filters Component */} {FiltersComp && ( )} {/* Content Grid/List/Cover */} {adultContent.length === 0 ? (

No Content Found

Try adjusting your search or filters to find what you're looking for.

) : viewMode === 'list' ? ( // Use MediaListView for list mode with sideview
{detailItem && (
setDetailItem(null)} onEdit={(item) => console.log('Edit item:', item)} onToggleFavorite={(id, isFav) => console.log('Toggle favorite:', id, isFav)} onSelectRelated={(item) => setDetailItem(item)} onSelectPerson={(name, id) => console.log('Select person:', name, id)} onViewAll={(type, id) => console.log('View all:', type, id)} onToggleSelect={(id, isSelected) => console.log('Toggle select:', id, isSelected)} />
)}
) : viewMode === 'cover' ? ( // Cover View (Shelf-style) - use dynamic cover size
{adultContent.map((content: AdultContent) => (
{(() => { const aspectRatio = content.poster_aspect_ratio || 1.5; const height = coverSize / aspectRatio; return (
{content.poster_url ? ( {content.title} ) : (
)} {/* Shelf effect - bottom shadow */}
{/* Hover overlay */}
{content.watched && (
)}
); })()}
))}
) : ( {adultContent.map((content: AdultContent, index: number) => ( handleContentClick(content)} className="group cursor-pointer" > {/* Grid View */}
{content.poster_url || content.screenshot_url ? ( {content.title} ) : (
)} {/* Overlay */}
{content.watched && ( )}

{content.title}

{content.source_name && (
{content.source_name}
)} {content.rating && renderRating(content.rating)}
))}
)} {/* Pagination Component */} {PaginationComp && pagination && pagination.last_page > 1 && ( )}
) }