import React, { useState, useEffect } from 'react'; import { Song } from '../types'; import { Heart, Share2, Play, Pause, MoreHorizontal, X, Copy, Wand2, MoreVertical, Download, Repeat, Video, Music, Link as LinkIcon, Sparkles, Globe, Lock, Trash2, Edit3, Layers } from 'lucide-react'; import { songsApi } from '../services/api'; import { useAuth } from '../context/AuthContext'; import { SongDropdownMenu } from './SongDropdownMenu'; import { ShareModal } from './ShareModal'; import { AlbumCover } from './AlbumCover'; interface RightSidebarProps { song: Song | null; onClose?: () => void; onOpenVideo?: () => void; onReuse?: (song: Song) => void; onSongUpdate?: (song: Song) => void; onNavigateToProfile?: (username: string) => void; onNavigateToSong?: (songId: string) => void; isLiked?: boolean; onToggleLike?: (song: Song) => void; onDelete?: (song: Song) => void; onAddToPlaylist?: (song: Song) => void; onPlay?: (song: Song) => void; isPlaying?: boolean; currentSong?: Song | null; } export const RightSidebar: React.FC = ({ song, onClose, onOpenVideo, onReuse, onSongUpdate, onNavigateToProfile, onNavigateToSong, isLiked, onToggleLike, onDelete, onAddToPlaylist, onPlay, isPlaying, currentSong }) => { const { token, user } = useAuth(); const [showMenu, setShowMenu] = useState(false); const [isOwner, setIsOwner] = useState(false); const [tagsExpanded, setTagsExpanded] = useState(false); const [shareModalOpen, setShareModalOpen] = useState(false); const [copiedStyle, setCopiedStyle] = useState(false); const [copiedLyrics, setCopiedLyrics] = useState(false); useEffect(() => { if (song) { setIsOwner(user?.id === song.userId); } }, [song, user]); const getSourceLabel = (url?: string) => { if (!url) return 'None'; try { const parsed = new URL(url, window.location.origin); const name = decodeURIComponent(parsed.pathname.split('/').pop() || url); return name.replace(/\.[^/.]+$/, '') || name; } catch { const parts = url.split('/'); const name = decodeURIComponent(parts[parts.length - 1] || url); return name.replace(/\.[^/.]+$/, '') || name; } }; const openSource = (url?: string) => { if (!url) return; const resolved = url.startsWith('http') ? url : `${window.location.origin}${url}`; window.open(resolved, '_blank'); }; if (!song) return (

Select a song to view details

); return (
{/* Header */}
Song Details
{/* Cover Art */}
onPlay?.(song)} > {song.coverUrl ? ( {song.title} { e.currentTarget.style.display = 'none'; }} /> ) : null} {!song.coverUrl && } {/* Overlay Gradient */}
{/* Play Button Overlay */}
{song.viewCount || 0}
{song.duration}
{/* Title & Artist Block */}

onNavigateToSong?.(song.id)} className="text-2xl font-bold text-zinc-900 dark:text-white leading-tight tracking-tight cursor-pointer hover:underline" > {song.title}

setShowMenu(false)} isOwner={isOwner} onCreateVideo={onOpenVideo} onReusePrompt={() => onReuse?.(song)} onDelete={() => onDelete?.(song)} onAddToPlaylist={() => onAddToPlaylist?.(song)} onShare={() => setShareModalOpen(true)} />
{song.creator ? song.creator[0].toUpperCase() : 'A'}
song.creator && onNavigateToProfile?.(song.creator)} className="text-sm font-semibold text-zinc-900 dark:text-white hover:underline cursor-pointer" > {song.creator || 'Anonymous'} Created {new Date(song.createdAt).toLocaleDateString()}
{/* Main Actions */}
{/* Icon Actions Row */}
} label={String(song.likeCount || 0)} active={isLiked} onClick={() => onToggleLike?.(song)} /> } onClick={() => setShareModalOpen(true)} />
{(song.generationParams?.referenceAudioUrl || song.generationParams?.sourceAudioUrl) && (
Sources
{song.generationParams?.referenceAudioUrl && (
Reference
{song.generationParams?.referenceAudioTitle || getSourceLabel(song.generationParams?.referenceAudioUrl)}
)} {song.generationParams?.sourceAudioUrl && (
Cover
{song.generationParams?.sourceAudioTitle || getSourceLabel(song.generationParams?.sourceAudioUrl)}
)}
)}
{/* Tags / Style */}

Style & Tags

setTagsExpanded(!tagsExpanded)} className={`flex flex-wrap gap-1.5 cursor-pointer relative ${!tagsExpanded ? 'max-h-[22px] overflow-hidden' : ''}`} > {Array.isArray(song.tags) && song.tags.length > 0 ? ( song.tags.map(tag => ( {tag} )) ) : ( song.style.split(',').map((tag, idx) => ( {tag.trim()} )) )} {!tagsExpanded && ( +more )}
{/* Lyrics Section */}

Lyrics

{song.lyrics ||
Instrumental
No lyrics generated
}
{song && ( setShareModalOpen(false)} song={song} /> )}
); }; const ActionButton: React.FC<{ icon: React.ReactNode; label?: string; active?: boolean; onClick?: () => void }> = ({ icon, label, active, onClick }) => ( );