219 lines
4.7 KiB
TypeScript
219 lines
4.7 KiB
TypeScript
// Auto-generated from design document
|
|
// Generated: 2025-12-18T15:56:41
|
|
|
|
import type {
|
|
Album, Artist, Genre, Playlist, Song, User
|
|
} from './types';
|
|
|
|
// =============================================================================
|
|
// COMPONENT PROPS
|
|
// =============================================================================
|
|
|
|
/**
|
|
* Global audio player with full controls
|
|
*/
|
|
export interface AudioPlayerProps {
|
|
currentSong?: Song;
|
|
queue?: Song[];
|
|
autoplay?: boolean; // default: False
|
|
onPlay?: (payload: { songId: string }) => void;
|
|
onPause?: (payload: void) => void;
|
|
onSeek?: (payload: { time: number }) => void;
|
|
onVolumeChange?: (payload: { volume: number }) => void;
|
|
onNext?: (payload: void) => void;
|
|
onPrevious?: (payload: void) => void;
|
|
onShuffle?: (payload: void) => void;
|
|
onRepeat?: (payload: void) => void;
|
|
}
|
|
|
|
/**
|
|
* Play/pause/seek controls
|
|
*/
|
|
export interface PlayerControlsProps {
|
|
isPlaying: boolean;
|
|
currentTime: number;
|
|
duration: number;
|
|
onPlay?: (payload: void) => void;
|
|
onPause?: (payload: void) => void;
|
|
onSeek?: (payload: { time: number }) => void;
|
|
}
|
|
|
|
/**
|
|
* Song display card with play button
|
|
*/
|
|
export interface SongCardProps {
|
|
song: Song;
|
|
showArtist?: boolean; // default: True
|
|
showAlbum?: boolean; // default: False
|
|
onPlay?: (payload: { songId: string }) => void;
|
|
onAddToPlaylist?: (payload: { songId: string }) => void;
|
|
}
|
|
|
|
/**
|
|
* Album display card
|
|
*/
|
|
export interface AlbumCardProps {
|
|
album: Album;
|
|
showArtist?: boolean; // default: True
|
|
onClick?: (payload: { albumId: string }) => void;
|
|
}
|
|
|
|
/**
|
|
* Artist preview card
|
|
*/
|
|
export interface ArtistCardProps {
|
|
artist: Artist;
|
|
onClick?: (payload: { artistId: string }) => void;
|
|
}
|
|
|
|
/**
|
|
* Playlist preview card
|
|
*/
|
|
export interface PlaylistCardProps {
|
|
playlist: Playlist;
|
|
onClick?: (payload: { playlistId: string }) => void;
|
|
}
|
|
|
|
/**
|
|
* Song upload form with file input
|
|
*/
|
|
export interface UploadFormProps {
|
|
albums: Album[];
|
|
genres: Genre[];
|
|
onUpload?: (payload: { file: File, metadata: Record<string, unknown> }) => void;
|
|
onCancel?: (payload: void) => void;
|
|
}
|
|
|
|
/**
|
|
* Audio waveform visualization
|
|
*/
|
|
export interface WaveformDisplayProps {
|
|
audioUrl: string;
|
|
waveformData?: number[];
|
|
currentTime?: number;
|
|
onSeek?: (payload: { time: number }) => void;
|
|
}
|
|
|
|
/**
|
|
* Genre tag display
|
|
*/
|
|
export interface GenreBadgeProps {
|
|
genre: Genre;
|
|
clickable?: boolean; // default: True
|
|
onClick?: (payload: { genreSlug: string }) => void;
|
|
}
|
|
|
|
/**
|
|
* List of songs with track numbers
|
|
*/
|
|
export interface TrackListProps {
|
|
songs: Song[];
|
|
showTrackNumber?: boolean; // default: True
|
|
reorderable?: boolean; // default: False
|
|
onPlay?: (payload: { songId: string }) => void;
|
|
onReorder?: (payload: { songIds: string[] }) => void;
|
|
}
|
|
|
|
/**
|
|
* Artist profile header with cover image
|
|
*/
|
|
export interface ArtistHeaderProps {
|
|
artist: Artist;
|
|
}
|
|
|
|
/**
|
|
* Album detail header with cover art
|
|
*/
|
|
export interface AlbumHeaderProps {
|
|
album: Album;
|
|
artist: Artist;
|
|
onPlayAll?: (payload: void) => void;
|
|
}
|
|
|
|
/**
|
|
* Playlist header with cover and controls
|
|
*/
|
|
export interface PlaylistHeaderProps {
|
|
playlist: Playlist;
|
|
isOwner?: boolean; // default: False
|
|
onPlayAll?: (payload: void) => void;
|
|
onEdit?: (payload: void) => void;
|
|
onDelete?: (payload: void) => void;
|
|
}
|
|
|
|
/**
|
|
* Social media links display
|
|
*/
|
|
export interface SocialLinksProps {
|
|
links: Record<string, unknown>;
|
|
}
|
|
|
|
/**
|
|
* Auth form mode type
|
|
*/
|
|
export type AuthFormMode = 'login' | 'register' | 'forgot';
|
|
|
|
/**
|
|
* Reusable authentication form
|
|
*/
|
|
export interface AuthFormProps {
|
|
mode: AuthFormMode;
|
|
onSubmit?: (payload: Record<string, unknown>) => void;
|
|
}
|
|
|
|
/**
|
|
* Search input with autocomplete
|
|
*/
|
|
export interface SearchBarProps {
|
|
placeholder?: string; // default: Search songs, artists, albums...
|
|
onSearch?: (payload: { query: string }) => void;
|
|
}
|
|
|
|
/**
|
|
* Search results with filters
|
|
*/
|
|
export interface SearchResultsProps {
|
|
results: Record<string, unknown>;
|
|
}
|
|
|
|
/**
|
|
* Modal for creating new playlist
|
|
*/
|
|
export interface CreatePlaylistModalProps {
|
|
isOpen: boolean;
|
|
onCreate?: (payload: { name: string, description: string, isPublic: boolean }) => void;
|
|
onClose?: (payload: void) => void;
|
|
}
|
|
|
|
/**
|
|
* User profile edit form
|
|
*/
|
|
export interface ProfileFormProps {
|
|
user: User;
|
|
onSave?: (payload: { name: string, avatarUrl: string }) => void;
|
|
}
|
|
|
|
/**
|
|
* Avatar image upload component
|
|
*/
|
|
export interface AvatarUploadProps {
|
|
currentAvatarUrl?: string;
|
|
onUpload?: (payload: { file: File }) => void;
|
|
}
|
|
|
|
/**
|
|
* Section title with optional action
|
|
*/
|
|
export interface SectionHeaderProps {
|
|
title: string;
|
|
actionLabel?: string;
|
|
onActionClick?: (payload: void) => void;
|
|
}
|
|
|
|
/**
|
|
* Genre browse page header
|
|
*/
|
|
export interface GenreHeaderProps {
|
|
genre: Genre;
|
|
}
|