![]() Server : Apache/2 System : Linux server-15-235-50-60 5.15.0-164-generic #174-Ubuntu SMP Fri Nov 14 20:25:16 UTC 2025 x86_64 User : gositeme ( 1004) PHP Version : 8.2.29 Disable Function : exec,system,passthru,shell_exec,proc_close,proc_open,dl,popen,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname Directory : /home/gositeme/domains/soundstudiopro.com/private_html/ |
<?php
// Enable error reporting for debugging
error_reporting(E_ALL);
ini_set('display_errors', 1);
session_start();
// ALWAYS check if user is logged in - no exceptions
if (!isset($_SESSION['user_id'])) {
header('Location: /auth/login.php');
exit;
}
// Include database configuration
require_once 'config/database.php';
// Include shared music creation modal
include_once 'includes/create_music_modal.php';
$user = getUserById($_SESSION['user_id']);
$user_name = $user['name'] ?? 'User';
$credits = $_SESSION['credits'] ?? 5;
// Get user stats
$pdo = getDBConnection();
$stmt = $pdo->prepare("
SELECT
COUNT(*) as total_tracks,
COUNT(CASE WHEN status = 'complete' THEN 1 END) as completed_tracks,
COUNT(CASE WHEN status = 'processing' THEN 1 END) as processing_tracks,
COUNT(CASE WHEN status = 'failed' THEN 1 END) as failed_tracks,
AVG(CASE WHEN status = 'complete' THEN duration END) as avg_duration,
SUM(CASE WHEN status = 'complete' THEN duration END) as total_duration
FROM music_tracks
WHERE user_id = ?
");
$stmt->execute([$_SESSION['user_id']]);
$user_stats = $stmt->fetch();
// Get user's music tracks with enhanced data and variations
$status_filter = $_GET['status'] ?? 'all';
$sort_filter = $_GET['sort'] ?? 'latest';
// Build WHERE clause for status filtering
$where_clause = "WHERE mt.user_id = ?";
$params = [$_SESSION['user_id']];
if ($status_filter !== 'all') {
$where_clause .= " AND mt.status = ?";
$params[] = $status_filter;
}
// Build ORDER BY clause for sorting
$order_clause = "ORDER BY ";
switch ($sort_filter) {
case 'oldest':
$order_clause .= "mt.created_at ASC";
break;
case 'popular':
$order_clause = "LEFT JOIN (SELECT track_id, COUNT(*) as like_count FROM track_likes GROUP BY track_id) likes ON mt.id = likes.track_id ORDER BY likes.like_count DESC, mt.created_at DESC";
break;
case 'most-played':
$order_clause = "LEFT JOIN (SELECT track_id, COUNT(*) as play_count FROM track_plays GROUP BY track_id) plays ON mt.id = plays.track_id ORDER BY plays.play_count DESC, mt.created_at DESC";
break;
case 'latest':
default:
$order_clause .= "mt.created_at DESC";
break;
}
// Get tracks
$stmt = $pdo->prepare("
SELECT
mt.*,
COALESCE(vars.variation_count, 0) as variation_count,
CASE
WHEN mt.created_at >= DATE_SUB(NOW(), INTERVAL 1 HOUR) THEN '🔥 Hot'
WHEN mt.created_at >= DATE_SUB(NOW(), INTERVAL 24 HOUR) THEN '⭐ New'
ELSE ''
END as badge
FROM music_tracks mt
LEFT JOIN (
SELECT track_id, COUNT(*) as variation_count
FROM audio_variations
GROUP BY track_id
) vars ON mt.id = vars.track_id
$where_clause
$order_clause
");
$stmt->execute($params);
$user_tracks = $stmt->fetchAll();
// Get variations for each track
$tracks_with_variations = [];
foreach ($user_tracks as $track) {
$track['variations'] = [];
if ($track['variation_count'] > 0) {
$stmt = $pdo->prepare("
SELECT
variation_index,
audio_url,
duration,
title,
tags,
image_url,
source_audio_url,
created_at
FROM audio_variations
WHERE track_id = ?
ORDER BY variation_index ASC
");
$stmt->execute([$track['id']]);
$track['variations'] = $stmt->fetchAll();
}
$tracks_with_variations[] = $track;
}
include 'includes/header.php';
?>
<div class="main-content">
<style>
body {
padding-bottom: 120px; /* Space for global player */
}
/* Hero Section Styling */
.hero {
background: linear-gradient(135deg, rgba(102, 126, 234, 0.1), rgba(118, 75, 162, 0.1));
padding: 4rem 0 3rem;
position: relative;
overflow: hidden;
}
.hero .container {
display: flex;
align-items: center;
justify-content: space-between;
min-height: 250px;
}
.hero-content {
flex: 1;
max-width: 600px;
}
.hero-badge {
display: inline-flex;
align-items: center;
gap: 0.5rem;
background: rgba(102, 126, 234, 0.2);
color: #667eea;
padding: 0.8rem 1.5rem;
border-radius: 25px;
font-size: 1rem;
font-weight: 600;
margin-bottom: 2rem;
border: 1px solid rgba(102, 126, 234, 0.3);
}
.hero-title {
font-size: 3rem;
font-weight: 800;
margin-bottom: 1.5rem;
background: linear-gradient(135deg, #667eea, #764ba2);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
line-height: 1.2;
}
.hero-subtitle {
font-size: 1.1rem;
color: #a0aec0;
line-height: 1.6;
margin-bottom: 2rem;
}
.hero-visual {
flex: 1;
max-width: 400px;
height: 250px;
position: relative;
}
/* Floating Notes Animation */
.floating-elements {
position: relative;
height: 100%;
width: 100%;
}
.floating-note {
position: absolute;
font-size: 2.5rem;
color: rgba(102, 126, 234, 0.4);
animation: float 8s ease-in-out infinite;
user-select: none;
pointer-events: none;
}
.floating-note:nth-child(1) {
top: 20%;
left: 10%;
animation-delay: 0s;
font-size: 3rem;
}
.floating-note:nth-child(2) {
top: 60%;
right: 15%;
animation-delay: 1.6s;
font-size: 2.5rem;
}
.floating-note:nth-child(3) {
bottom: 30%;
left: 20%;
animation-delay: 3.2s;
font-size: 2.8rem;
}
.floating-note:nth-child(4) {
top: 40%;
right: 30%;
animation-delay: 4.8s;
font-size: 2.2rem;
}
.floating-note:nth-child(5) {
bottom: 60%;
left: 50%;
animation-delay: 6.4s;
font-size: 2.6rem;
}
@keyframes float {
0%, 100% {
transform: translateY(0px) rotate(0deg);
opacity: 0.4;
}
25% {
transform: translateY(-15px) rotate(5deg);
opacity: 0.7;
}
50% {
transform: translateY(-25px) rotate(10deg);
opacity: 1;
}
75% {
transform: translateY(-15px) rotate(5deg);
opacity: 0.7;
}
}
/* Stats Grid */
.stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 1.5rem;
margin: 2rem 0;
}
.stat-card {
background: linear-gradient(135deg,
rgba(0, 0, 0, 0.4) 0%,
rgba(15, 15, 25, 0.6) 100%);
border: 1px solid rgba(102, 126, 234, 0.2);
border-radius: 16px;
padding: 1.5rem;
text-align: center;
transition: all 0.3s ease;
backdrop-filter: blur(10px);
}
.stat-card:hover {
border-color: rgba(102, 126, 234, 0.5);
transform: translateY(-5px);
box-shadow: 0 10px 30px rgba(102, 126, 234, 0.2);
}
.stat-value {
font-size: 2rem;
font-weight: 900;
color: #667eea;
margin-bottom: 0.5rem;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
}
.stat-label {
font-size: 0.9rem;
color: #a0aec0;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 1px;
}
/* Filter Controls */
.filter-controls {
background: linear-gradient(135deg,
rgba(0, 0, 0, 0.4) 0%,
rgba(15, 15, 25, 0.6) 100%);
border: 1px solid rgba(102, 126, 234, 0.2);
border-radius: 16px;
padding: 1.5rem;
margin: 2rem 0;
backdrop-filter: blur(10px);
}
.filter-row {
display: flex;
gap: 1rem;
align-items: center;
flex-wrap: wrap;
}
.filter-group {
display: flex;
align-items: center;
gap: 0.5rem;
}
.filter-label {
font-size: 0.9rem;
font-weight: 600;
color: #a0aec0;
text-transform: uppercase;
letter-spacing: 1px;
}
.filter-select {
background: rgba(255, 255, 255, 0.1);
border: 1px solid rgba(102, 126, 234, 0.3);
color: white;
padding: 0.5rem 1rem;
border-radius: 8px;
font-size: 0.9rem;
transition: all 0.3s ease;
}
.filter-select:focus {
outline: none;
border-color: #667eea;
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
}
/* Premium Track Cards */
.track-card {
background: linear-gradient(135deg,
rgba(0, 0, 0, 0.6) 0%,
rgba(15, 15, 25, 0.8) 100%);
border: 1px solid rgba(102, 126, 234, 0.2);
border-radius: 20px;
margin-bottom: 2rem;
position: relative;
overflow: hidden;
transition: all 0.4s ease;
backdrop-filter: blur(20px);
box-shadow:
0 8px 32px rgba(0, 0, 0, 0.3),
0 2px 16px rgba(102, 126, 234, 0.1),
inset 0 1px 0 rgba(255, 255, 255, 0.1);
}
.track-card::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 2px;
background: linear-gradient(90deg,
transparent 0%,
#667eea 25%,
#764ba2 50%,
#667eea 75%,
transparent 100%);
opacity: 0;
transition: opacity 0.3s ease;
}
.track-card:hover {
transform: translateY(-8px) scale(1.02);
border-color: rgba(102, 126, 234, 0.5);
box-shadow:
0 20px 60px rgba(0, 0, 0, 0.4),
0 8px 40px rgba(102, 126, 234, 0.3),
inset 0 1px 0 rgba(255, 255, 255, 0.2);
}
.track-card:hover::before {
opacity: 1;
}
/* Track Header */
.track-header {
padding: 1.5rem 1.5rem 1rem;
background: linear-gradient(135deg,
rgba(102, 126, 234, 0.1) 0%,
rgba(118, 75, 162, 0.05) 100%);
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
position: relative;
}
.track-title {
font-size: 1.6rem;
font-weight: 800;
margin-bottom: 1rem;
background: linear-gradient(135deg, #e2e8f0, #f7fafc);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
line-height: 1.3;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.track-badge {
display: inline-block;
background: linear-gradient(135deg, #f59e0b, #d97706);
color: white;
padding: 0.3rem 0.8rem;
border-radius: 12px;
font-size: 0.7rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.5px;
margin-bottom: 1rem;
box-shadow: 0 2px 8px rgba(245, 158, 11, 0.3);
}
/* Track Prompt */
.track-prompt {
padding: 1rem 1.5rem;
background: linear-gradient(135deg,
rgba(0, 0, 0, 0.3) 0%,
rgba(15, 15, 25, 0.4) 100%);
border-left: 3px solid #667eea;
margin: 1rem 1.5rem;
border-radius: 0 8px 8px 0;
font-size: 0.95rem;
line-height: 1.5;
color: #cbd5e0;
font-style: italic;
position: relative;
}
.track-prompt::before {
content: '"';
position: absolute;
left: -0.5rem;
top: -0.5rem;
font-size: 2rem;
color: #667eea;
font-weight: bold;
}
/* Track Metadata */
.track-metadata {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
gap: 1rem;
padding: 1.5rem;
background: linear-gradient(135deg,
rgba(0, 0, 0, 0.2) 0%,
rgba(15, 15, 25, 0.3) 100%);
border-top: 1px solid rgba(255, 255, 255, 0.05);
}
.metadata-item {
text-align: center;
padding: 0.8rem;
background: rgba(255, 255, 255, 0.03);
border-radius: 12px;
border: 1px solid rgba(255, 255, 255, 0.05);
transition: all 0.3s ease;
}
.metadata-item:hover {
background: rgba(102, 126, 234, 0.1);
border-color: rgba(102, 126, 234, 0.3);
transform: translateY(-2px);
}
.metadata-label {
font-size: 0.7rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 1px;
color: #a0aec0;
margin-bottom: 0.3rem;
}
.metadata-value {
font-size: 1rem;
font-weight: 800;
color: #e2e8f0;
}
/* Track Actions */
.track-actions-modern {
display: flex;
gap: 1rem;
padding: 1.5rem;
flex-wrap: wrap;
justify-content: center;
}
.action-btn {
background: linear-gradient(135deg, rgba(102, 126, 234, 0.2), rgba(118, 75, 162, 0.2));
border: 1px solid rgba(102, 126, 234, 0.4);
color: #667eea;
padding: 0.8rem 1.5rem;
border-radius: 12px;
font-size: 0.9rem;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
backdrop-filter: blur(10px);
display: flex;
align-items: center;
gap: 0.5rem;
}
.action-btn:hover {
background: linear-gradient(135deg, rgba(102, 126, 234, 0.3), rgba(118, 75, 162, 0.3));
border-color: rgba(102, 126, 234, 0.6);
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
}
.action-btn.primary {
background: linear-gradient(135deg, #667eea, #764ba2);
border-color: #667eea;
color: white;
}
.action-btn.primary:hover {
background: linear-gradient(135deg, #5a67d8, #6b46c1);
transform: translateY(-3px);
box-shadow: 0 8px 25px rgba(102, 126, 234, 0.4);
}
.action-btn.primary.playing {
background: linear-gradient(135deg, #f59e0b, #d97706);
border-color: #f59e0b;
animation: playingPulse 2s ease-in-out infinite;
}
.action-btn.danger {
background: linear-gradient(135deg, rgba(239, 68, 68, 0.2), rgba(220, 38, 38, 0.2));
border-color: rgba(239, 68, 68, 0.4);
color: #ef4444;
}
.action-btn.danger:hover {
background: linear-gradient(135deg, rgba(239, 68, 68, 0.3), rgba(220, 38, 38, 0.3));
border-color: rgba(239, 68, 68, 0.6);
}
@keyframes playingPulse {
0%, 100% { box-shadow: 0 0 20px rgba(245, 158, 11, 0.5); }
50% { box-shadow: 0 0 30px rgba(245, 158, 11, 0.8); }
}
/* Status Indicators */
.status-complete {
background: linear-gradient(135deg, #48bb78, #38a169);
color: white;
padding: 0.3rem 0.8rem;
border-radius: 12px;
font-size: 0.7rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.5px;
box-shadow: 0 2px 8px rgba(72, 187, 120, 0.3);
}
.status-processing {
background: linear-gradient(135deg, #f59e0b, #d97706);
color: white;
padding: 0.3rem 0.8rem;
border-radius: 12px;
font-size: 0.7rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.5px;
box-shadow: 0 2px 8px rgba(245, 158, 11, 0.3);
}
.status-failed {
background: linear-gradient(135deg, #ef4444, #dc2626);
color: white;
padding: 0.3rem 0.8rem;
border-radius: 12px;
font-size: 0.7rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.5px;
box-shadow: 0 2px 8px rgba(239, 68, 68, 0.3);
}
/* Error Message Styling */
.error-message-modern {
background: linear-gradient(135deg,
rgba(239, 68, 68, 0.1) 0%,
rgba(220, 38, 38, 0.05) 100%);
border: 1px solid rgba(239, 68, 68, 0.3);
border-radius: 12px;
padding: 1rem;
margin: 1rem 1.5rem;
}
.error-header {
color: #ef4444;
font-weight: 700;
margin-bottom: 0.5rem;
display: flex;
align-items: center;
gap: 0.5rem;
}
.error-content {
color: #fca5a5;
font-size: 0.9rem;
line-height: 1.5;
margin-bottom: 0.5rem;
}
.error-tip {
background: rgba(102, 126, 234, 0.1);
border-left: 3px solid #667eea;
padding: 0.5rem 1rem;
border-radius: 0 8px 8px 0;
color: #a0aec0;
font-size: 0.85rem;
font-style: italic;
}
/* Empty State */
.empty-state {
text-align: center;
padding: 4rem 2rem;
background: linear-gradient(135deg,
rgba(0, 0, 0, 0.3) 0%,
rgba(15, 15, 25, 0.4) 100%);
border-radius: 20px;
border: 1px solid rgba(102, 126, 234, 0.2);
margin: 2rem 0;
}
.empty-icon {
font-size: 4rem;
color: #667eea;
margin-bottom: 1rem;
opacity: 0.7;
}
.empty-title {
font-size: 1.5rem;
font-weight: 700;
color: #e2e8f0;
margin-bottom: 1rem;
}
.empty-description {
color: #a0aec0;
margin-bottom: 2rem;
line-height: 1.6;
}
.create-first-btn {
background: linear-gradient(135deg, #667eea, #764ba2);
color: white;
border: none;
padding: 1rem 2rem;
border-radius: 12px;
font-size: 1rem;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
text-decoration: none;
display: inline-flex;
align-items: center;
gap: 0.5rem;
}
.create-first-btn:hover {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(102, 126, 234, 0.4);
}
/* Mobile Responsive */
@media (max-width: 768px) {
.hero {
padding: 3rem 0 2rem;
}
.hero .container {
flex-direction: column;
text-align: center;
min-height: auto;
}
.hero-content {
max-width: 100%;
margin-bottom: 2rem;
}
.hero-title {
font-size: 2.5rem;
}
.stats-grid {
grid-template-columns: repeat(2, 1fr);
}
.filter-row {
flex-direction: column;
align-items: stretch;
}
.track-actions-modern {
flex-direction: column;
}
.action-btn {
justify-content: center;
}
}
</style>
<!-- Hero Section -->
<div class="hero">
<div class="container">
<div class="hero-content">
<div class="hero-badge">
<i class="fas fa-music"></i>
Your Music Library
</div>
<h1 class="hero-title">Your Studio Collection</h1>
<p class="hero-subtitle">
Manage, play, and share your AI-generated tracks. Every creation is a masterpiece waiting to be discovered.
</p>
</div>
<div class="hero-visual">
<div class="floating-elements">
<div class="floating-note">🎵</div>
<div class="floating-note">🎶</div>
<div class="floating-note">🎼</div>
<div class="floating-note">🎹</div>
<div class="floating-note">🎸</div>
</div>
</div>
</div>
</div>
<!-- Stats Grid -->
<div class="stats-grid">
<div class="stat-card">
<div class="stat-value"><?= $user_stats['total_tracks'] ?></div>
<div class="stat-label">Total Tracks</div>
</div>
<div class="stat-card">
<div class="stat-value"><?= $user_stats['completed_tracks'] ?></div>
<div class="stat-label">Completed</div>
</div>
<div class="stat-card">
<div class="stat-value"><?= $user_stats['processing_tracks'] ?></div>
<div class="stat-label">Processing</div>
</div>
<div class="stat-card">
<div class="stat-value"><?= $credits ?></div>
<div class="stat-label">Credits Left</div>
</div>
</div>
<!-- Filter Controls -->
<div class="filter-controls">
<div class="filter-row">
<div class="filter-group">
<label class="filter-label">Status:</label>
<select class="filter-select" onchange="window.location.href='?status=' + this.value + '&sort=<?= $sort_filter ?>'">
<option value="all" <?= $status_filter === 'all' ? 'selected' : '' ?>>All Tracks</option>
<option value="complete" <?= $status_filter === 'complete' ? 'selected' : '' ?>>Completed</option>
<option value="processing" <?= $status_filter === 'processing' ? 'selected' : '' ?>>Processing</option>
<option value="failed" <?= $status_filter === 'failed' ? 'selected' : '' ?>>Failed</option>
</select>
</div>
<div class="filter-group">
<label class="filter-label">Sort By:</label>
<select class="filter-select" onchange="window.location.href='?status=<?= $status_filter ?>&sort=' + this.value">
<option value="latest" <?= $sort_filter === 'latest' ? 'selected' : '' ?>>Latest First</option>
<option value="oldest" <?= $sort_filter === 'oldest' ? 'selected' : '' ?>>Oldest First</option>
<option value="popular" <?= $sort_filter === 'popular' ? 'selected' : '' ?>>Most Popular</option>
<option value="most-played" <?= $sort_filter === 'most-played' ? 'selected' : '' ?>>Most Played</option>
</select>
</div>
</div>
</div>
<!-- Tracks Grid -->
<div class="tracks-container">
<?php if (empty($tracks_with_variations)): ?>
<div class="empty-state">
<div class="empty-icon">🎵</div>
<h2 class="empty-title">No Tracks Yet</h2>
<p class="empty-description">
Start creating your first AI-generated track and build your music library.
</p>
<a href="/#create" class="create-first-btn">
<i class="fas fa-plus"></i>
Create Your First Track
</a>
</div>
<?php else: ?>
<?php foreach ($tracks_with_variations as $track):
$displayTitle = $track['title'] ?: 'Untitled Track';
$duration = floor($track['duration'] / 60) . 'm ' . ($track['duration'] % 60) . 's';
$created_date = date('M j, Y', strtotime($track['created_at']));
$error_message = $track['error_message'] ?? null;
?>
<div class="track-card" data-track-id="<?= $track['id'] ?>" data-status="<?= $track['status'] ?>" data-variations="<?= htmlspecialchars(json_encode($track['variations'] ?? [])) ?>" data-selected-variation="<?= $track['selected_variation_index'] ?? 0 ?>">
<!-- Track Header -->
<div class="track-header">
<?php if ($track['badge']): ?>
<div class="track-badge"><?= $track['badge'] ?></div>
<?php endif; ?>
<h2 class="track-title"><?= htmlspecialchars($displayTitle) ?></h2>
<div class="track-metadata">
<div class="metadata-item">
<div class="metadata-label">Duration</div>
<div class="metadata-value"><?= $duration ?></div>
</div>
<div class="metadata-item">
<div class="metadata-label">Created</div>
<div class="metadata-value"><?= $created_date ?></div>
</div>
<div class="metadata-item">
<div class="metadata-label">Status</div>
<div class="metadata-value">
<?php if ($track['status'] === 'complete'): ?>
<span class="status-complete">Complete</span>
<?php elseif ($track['status'] === 'processing'): ?>
<span class="status-processing">Processing</span>
<?php elseif ($track['status'] === 'failed'): ?>
<span class="status-failed">Failed</span>
<?php endif; ?>
</div>
</div>
<?php if ($track['variation_count'] > 0): ?>
<div class="metadata-item">
<div class="metadata-label">Variations</div>
<div class="metadata-value"><?= $track['variation_count'] ?></div>
</div>
<?php endif; ?>
</div>
</div>
<!-- Track Prompt -->
<?php if ($track['prompt']): ?>
<div class="track-prompt">
<?= htmlspecialchars($track['prompt']) ?>
</div>
<?php endif; ?>
<!-- Error Message for Failed Tracks -->
<?php if ($track['status'] === 'failed' && $error_message): ?>
<div class="error-message-modern">
<div class="error-header">
<i class="fas fa-exclamation-triangle"></i>
<strong>Error Details:</strong>
</div>
<div class="error-content">
<?= htmlspecialchars($error_message) ?>
</div>
<div class="error-tip">
<i class="fas fa-lightbulb"></i>
<strong>Quick Fix:</strong>
<?php if (stripos($error_message, 'artist name') !== false): ?>
Avoid mentioning existing artists or bands. Use music genres and styles instead.
<?php elseif (stripos($error_message, 'copyright') !== false): ?>
Don't reference existing songs, lyrics, or copyrighted material.
<?php elseif (stripos($error_message, 'inappropriate') !== false): ?>
Keep content family-friendly and appropriate.
<?php else: ?>
Try modifying your prompt to be more generic and avoid specific names.
<?php endif; ?>
</div>
</div>
<?php endif; ?>
<!-- Track Actions -->
<div class="track-actions-modern">
<?php if ($track['status'] === 'complete'): ?>
<button class="action-btn primary" onclick="playTrackFromButton(this)"
data-audio-url="<?= htmlspecialchars($track['audio_url']) ?>"
data-title="<?= htmlspecialchars($displayTitle) ?>"
data-artist="<?= htmlspecialchars($user_name) ?>"
title="Play Track">
<i class="fas fa-play"></i>
Play
</button>
<button class="action-btn" onclick="downloadTrack(<?= $track['id'] ?>)" title="Download Track">
<i class="fas fa-download"></i>
Download
</button>
<?php if ($track['variation_count'] > 0): ?>
<button class="action-btn" onclick="showVariations(<?= $track['id'] ?>)" title="View Variations">
<i class="fas fa-layer-group"></i>
Variations
</button>
<?php endif; ?>
<button class="action-btn" onclick="showLyrics(<?= $track['id'] ?>)" title="View Lyrics">
<i class="fas fa-music"></i>
Lyrics
</button>
<?php elseif ($track['status'] === 'processing'): ?>
<div class="processing-actions">
<button class="action-btn" onclick="checkTrackStatus(<?= $track['id'] ?>)" title="Check Status">
<i class="fas fa-sync-alt"></i>
Check Status
</button>
</div>
<?php elseif ($track['status'] === 'failed'): ?>
<div class="failed-actions-modern">
<button class="action-btn primary" onclick="retryTrack(<?= $track['id'] ?>)" title="Create a new version with the same prompt">
<i class="fas fa-redo"></i>
Retry
</button>
<button class="action-btn" onclick="showFailureHelp(<?= $track['id'] ?>)" title="Why did this fail?">
<i class="fas fa-question-circle"></i>
Help
</button>
<button class="action-btn danger" onclick="deleteFailedTrack(<?= $track['id'] ?>)" title="Delete this failed track">
<i class="fas fa-trash"></i>
Delete
</button>
</div>
<?php endif; ?>
</div>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
</div>
<?php
// Include the existing modals and JavaScript functions
// This ensures all functionality is preserved
include 'includes/footer.php';
?>