![]() 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
session_start();
require_once 'config/database.php';
require_once 'includes/translations.php';
// Initialize database connection
$pdo = getDBConnection();
if (!$pdo) {
die("Database connection failed. Please try again later.");
}
// Check if user is logged in
if (!isset($_SESSION['user_id'])) {
header('Location: auth/login.php');
exit;
}
$user_id = $_SESSION['user_id'];
// Check if this is an AJAX request
$isAjaxRequest = isset($_GET['ajax']) && $_GET['ajax'] == '1';
// Redirect to tracks tab if no tab parameter is provided (only for non-AJAX requests)
if (!isset($_GET['tab']) && !$isAjaxRequest) {
header('Location: artist_dashboard.php?tab=tracks');
exit;
}
$current_tab = $_GET['tab'] ?? 'tracks';
// Get user info
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$user_id]);
$user = $stmt->fetch();
// Validate user exists
if (!$user) {
session_destroy();
header('Location: auth/login.php');
exit;
}
// Handle track updates
if ($_POST['action'] ?? '' === 'update_track') {
// Validate and sanitize input
$track_id = isset($_POST['track_id']) ? (int)$_POST['track_id'] : 0;
$title = isset($_POST['title']) ? trim(htmlspecialchars($_POST['title'], ENT_QUOTES, 'UTF-8')) : '';
$description = isset($_POST['description']) ? trim(htmlspecialchars($_POST['description'], ENT_QUOTES, 'UTF-8')) : '';
$price = isset($_POST['price']) ? max(0, floatval($_POST['price'])) : 0;
$is_public = isset($_POST['is_public']) ? 1 : 0;
// Validate required fields
if ($track_id > 0 && !empty($title)) {
// Verify track ownership
$stmt = $pdo->prepare("SELECT id FROM music_tracks WHERE id = ? AND user_id = ?");
$stmt->execute([$track_id, $user_id]);
if ($stmt->fetch()) {
try {
$stmt = $pdo->prepare("
UPDATE music_tracks
SET title = ?, prompt = ?, price = ?, is_public = ?
WHERE id = ? AND user_id = ?
");
$stmt->execute([$title, $description, $price, $is_public, $track_id, $user_id]);
$success_message = t('dashboard.track_updated_success');
} catch (Exception $e) {
$error_message = t('dashboard.track_update_failed');
}
} else {
$error_message = t('dashboard.track_not_found');
}
} else {
$error_message = t('dashboard.invalid_track_title');
}
}
// Get artist statistics
try {
$stats_query = $pdo->prepare("
SELECT
COUNT(*) as total_tracks,
COUNT(CASE WHEN status = 'complete' THEN 1 END) as published_tracks,
COALESCE(SUM(price), 0) as total_catalog_value
FROM music_tracks
WHERE user_id = ?
");
$stats_query->execute([$user_id]);
$stats = $stats_query->fetch() ?: ['total_tracks' => 0, 'published_tracks' => 0, 'total_catalog_value' => 0];
} catch (Exception $e) {
$stats = ['total_tracks' => 0, 'published_tracks' => 0, 'total_catalog_value' => 0];
}
// Get ALL sales for this artist (regardless of revenue_recipient flag)
// The commission rate determines the split, not the revenue_recipient field
try {
$earnings_query = $pdo->prepare("
SELECT
COALESCE(SUM(amount), 0) as total_sales,
COUNT(*) as total_orders
FROM sales
WHERE artist_id = ?
");
$earnings_query->execute([$user_id]);
$earnings = $earnings_query->fetch() ?: ['total_sales' => 0, 'total_orders' => 0];
} catch (Exception $e) {
// If sales table doesn't exist or other error, use default values
$earnings = ['total_sales' => 0, 'total_orders' => 0];
}
// For display purposes, track platform vs artist revenue splits
// (Note: This is now calculated from commission rate, not revenue_recipient field)
$platform_revenue = [
'platform_sales' => 0,
'platform_orders' => 0
];
// Check user's plan to determine business model explanation
$user_plan = strtolower($user['plan'] ?? 'free');
// Get effective plan (checks subscription first, then users.plan)
require_once __DIR__ . '/utils/subscription_helpers.php';
$effective_plan = getEffectivePlan($user_id);
$user_plan = $effective_plan; // Use effective plan for earnings calculation
// SoundStudioPro commission rate based on plan:
// Paid plans (Pro, Premium, Enterprise): 15% commission (artist keeps 85%)
// Lower paid plans (Essential, Starter): 15% commission (artist keeps 85%) - they're paying subscribers
// Free plan: 85% commission (artist keeps 15%)
//
// NOTE: All paid subscription plans should get 85% earnings rate
// Only free users get 15% earnings rate
$is_paid_plan = in_array($user_plan, ['essential', 'starter', 'pro', 'premium', 'enterprise']);
$commission_rate = $is_paid_plan ? 0.15 : 0.85; // Paid plans: 15% commission, Free: 85% commission
$artist_earnings = $earnings['total_sales'] * (1 - $commission_rate);
$platform_commission = $earnings['total_sales'] * $commission_rate;
// Calculate percentages for display
$artist_percentage = (1 - $commission_rate) * 100;
$platform_percentage = $commission_rate * 100;
?>
<?php if (!$isAjaxRequest): ?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Artist Dashboard - SoundStudioPro</title>
<link href="/assets/fontawesome/fontawesome-free-6.5.1-web/css/all.min.css" rel="stylesheet">
<style>
<?php else: ?>
<style>
<?php endif; ?>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
margin: 0;
padding: 0;
}
<?php if (!$isAjaxRequest): ?>
body {
font-family: 'Inter', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #0a0a0a 0%, #1a1a1a 50%, #0a0a0a 100%);
min-height: 100vh;
color: white;
margin: 0;
padding-top: 80px;
padding-bottom: 120px;
position: relative;
}
<?php else: ?>
/* When loaded via AJAX, don't override body styles - use container spacing instead */
.artist-dashboard-container {
padding-top: 0;
}
<?php endif; ?>
<?php if (!$isAjaxRequest): ?>
body::before {
content: '';
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><pattern id="grid" width="10" height="10" patternUnits="userSpaceOnUse"><path d="M 10 0 L 0 0 0 10" fill="none" stroke="rgba(102,126,234,0.1)" stroke-width="0.5"/></pattern></defs><rect width="100" height="100" fill="url(%23grid)"/></svg>');
opacity: 0.3;
pointer-events: none;
z-index: -1;
}
<?php endif; ?>
.container {
max-width: 1400px;
margin: 0 auto;
padding: <?= $isAjaxRequest ? '2rem' : '3rem' ?> 2rem;
position: relative;
z-index: 2;
}
<?php if ($isAjaxRequest): ?>
/* When loaded via AJAX, body already has padding-top: 100px from header */
/* Container should start immediately after header, no additional margin needed */
.container {
margin-top: 0 !important;
padding-top: 2rem;
}
/* Mobile spacing fix - ensure container respects body padding */
@media (max-width: 768px) {
.container {
margin-top: 0 !important;
padding-top: 1.5rem;
}
}
<?php endif; ?>
.dashboard-header {
text-align: center;
margin-bottom: 3rem;
position: relative;
}
<?php if (!$isAjaxRequest): ?>
.dashboard-header {
margin-top: 1rem;
}
<?php endif; ?>
.dashboard-header::before {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 200px;
height: 200px;
background: radial-gradient(circle, rgba(102, 126, 234, 0.1) 0%, transparent 70%);
transform: translate(-50%, -50%);
border-radius: 50%;
z-index: -1;
}
.dashboard-header h1 {
font-size: 3.5rem;
font-weight: 800;
margin-bottom: 1rem;
background: linear-gradient(135deg, #ffffff, #667eea);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
position: relative;
display: inline-block;
color: white; /* Fallback for browsers that don't support gradient text */
border: none;
outline: none;
}
.dashboard-header h1 i {
margin-right: 1rem;
animation: musicPulse 2s ease-in-out infinite;
}
@keyframes musicPulse {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.1); }
}
.dashboard-header p {
font-size: 1.3rem;
color: #a0aec0;
max-width: 600px;
margin: 0 auto;
line-height: 1.6;
}
.dashboard-nav {
display: flex;
justify-content: center;
gap: 1.5rem;
margin-bottom: 3rem;
flex-wrap: wrap;
position: relative;
}
.nav-tab {
background: rgba(255, 255, 255, 0.05);
backdrop-filter: blur(20px);
border: 1px solid rgba(255, 255, 255, 0.1);
color: white;
padding: 1.2rem 2.5rem;
border-radius: 16px;
text-decoration: none;
font-weight: 600;
font-size: 1.1rem;
transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
display: flex;
align-items: center;
gap: 0.8rem;
position: relative;
overflow: hidden;
}
.nav-tab::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.1), transparent);
transition: left 0.5s ease;
}
.nav-tab:hover::before {
left: 100%;
}
.nav-tab:hover {
background: rgba(255, 255, 255, 0.1);
transform: translateY(-3px);
box-shadow: 0 10px 30px rgba(102, 126, 234, 0.3);
}
.nav-tab.active {
background: linear-gradient(135deg, #667eea, #764ba2);
box-shadow: 0 8px 25px rgba(102, 126, 234, 0.4);
border-color: transparent;
}
.nav-tab i {
font-size: 1.2rem;
transition: transform 0.3s ease;
}
.nav-tab:hover i {
transform: scale(1.1);
}
.stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 2rem;
margin-bottom: 3rem;
}
.stat-card {
background: linear-gradient(135deg, rgba(20, 20, 20, 0.95) 0%, rgba(30, 30, 30, 0.95) 100%);
backdrop-filter: blur(30px);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 24px;
padding: 2.5rem;
text-align: center;
position: relative;
overflow: hidden;
transition: all 0.4s ease;
}
.stat-card::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><pattern id="grid" width="10" height="10" patternUnits="userSpaceOnUse"><path d="M 10 0 L 0 0 0 10" fill="none" stroke="rgba(102,126,234,0.1)" stroke-width="0.5"/></pattern></defs><rect width="100" height="100" fill="url(%23grid)"/></svg>');
opacity: 0.3;
pointer-events: none;
border-radius: 24px;
}
.stat-card:hover {
transform: translateY(-5px);
box-shadow: 0 20px 40px rgba(102, 126, 234, 0.2);
border-color: rgba(102, 126, 234, 0.3);
}
.stat-icon {
font-size: 3.5rem;
margin-bottom: 1.5rem;
background: linear-gradient(135deg, #667eea, #764ba2);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
position: relative;
z-index: 2;
}
.stat-value {
font-size: 3rem;
font-weight: 800;
margin-bottom: 0.5rem;
color: white;
position: relative;
z-index: 2;
}
.stat-label {
color: #a0aec0;
font-size: 1.3rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 1px;
position: relative;
z-index: 2;
}
.content-section {
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(20px);
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 20px;
padding: 2rem;
margin-bottom: 2rem;
}
.tracks-grid {
display: grid;
gap: 1.5rem;
}
.track-item {
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 15px;
padding: 1.5rem;
display: grid;
grid-template-columns: auto 1fr auto auto;
gap: 1.5rem;
align-items: center;
overflow: hidden;
}
.track-thumbnail {
width: 80px;
height: 80px;
background: linear-gradient(135deg, #667eea, #764ba2);
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
font-size: 2rem;
color: white;
}
.track-info {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.track-title {
font-size: 1.2rem;
font-weight: 600;
color: white;
}
.track-meta {
color: #a0aec0;
font-size: 0.9rem;
}
.track-stats {
display: flex;
gap: 1rem;
font-size: 0.9rem;
color: #cbd5e0;
}
.track-actions {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
min-width: fit-content;
justify-content: flex-end;
align-items: center;
}
.btn {
background: rgba(255, 255, 255, 0.1);
border: 1px solid rgba(255, 255, 255, 0.2);
color: white;
padding: 0.8rem 1.5rem;
border-radius: 8px;
cursor: pointer;
font-size: 0.9rem;
transition: all 0.3s ease;
text-decoration: none;
display: inline-flex;
align-items: center;
gap: 0.5rem;
white-space: nowrap;
flex-shrink: 0;
user-select: none;
-webkit-tap-highlight-color: transparent;
}
.btn:active {
transform: scale(0.98);
}
.btn:focus {
outline: 2px solid rgba(102, 126, 234, 0.5);
outline-offset: 2px;
}
.btn:hover {
background: rgba(255, 255, 255, 0.2);
transform: translateY(-1px);
}
/* Enhanced Business Model Section */
.business-model {
background: linear-gradient(135deg, rgba(20, 20, 20, 0.95) 0%, rgba(30, 30, 30, 0.95) 100%);
backdrop-filter: blur(30px);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 24px;
padding: 2.5rem;
margin-bottom: 3rem;
position: relative;
overflow: hidden;
}
.business-model::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><pattern id="grid" width="10" height="10" patternUnits="userSpaceOnUse"><path d="M 10 0 L 0 0 0 10" fill="none" stroke="rgba(102,126,234,0.1)" stroke-width="0.5"/></pattern></defs><rect width="100" height="100" fill="url(%23grid)"/></svg>');
opacity: 0.3;
pointer-events: none;
border-radius: 24px;
}
.business-model h3 {
font-size: 1.8rem;
font-weight: 700;
margin-bottom: 1.5rem;
background: linear-gradient(135deg, #ffffff, #667eea);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
position: relative;
z-index: 2;
}
.business-model-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
position: relative;
z-index: 2;
}
.business-model-item {
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 16px;
padding: 2rem;
transition: all 0.3s ease;
}
.business-model-item:hover {
transform: translateY(-3px);
box-shadow: 0 10px 30px rgba(102, 126, 234, 0.2);
border-color: rgba(102, 126, 234, 0.3);
}
.business-model-item h4 {
font-size: 1.3rem;
font-weight: 600;
margin-bottom: 1rem;
position: relative;
z-index: 2;
}
.business-model-item p {
color: #a0aec0;
line-height: 1.6;
margin-bottom: 1rem;
position: relative;
z-index: 2;
}
.business-model-item .amount {
font-size: 2rem;
font-weight: 800;
position: relative;
z-index: 2;
}
/* Enhanced Alert Styling */
.alert {
background: linear-gradient(135deg, rgba(72, 187, 120, 0.1) 0%, rgba(56, 161, 105, 0.1) 100%);
backdrop-filter: blur(20px);
border: 1px solid rgba(72, 187, 120, 0.3);
border-radius: 16px;
padding: 1.5rem 2rem;
margin-bottom: 2rem;
display: flex;
align-items: center;
gap: 1rem;
position: relative;
overflow: hidden;
}
.alert::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(90deg, transparent, rgba(72, 187, 120, 0.1), transparent);
animation: alertShine 2s ease-in-out infinite;
}
@keyframes alertShine {
0% { transform: translateX(-100%); }
100% { transform: translateX(100%); }
}
.alert-success {
background: linear-gradient(135deg, rgba(72, 187, 120, 0.1) 0%, rgba(56, 161, 105, 0.1) 100%);
border-color: rgba(72, 187, 120, 0.3);
}
.btn-primary {
background: linear-gradient(135deg, #667eea, #764ba2);
}
.btn-success {
background: linear-gradient(135deg, #48bb78, #38a169);
}
.btn-warning {
background: linear-gradient(135deg, #ed8936, #dd6b20);
}
.btn-danger {
background: linear-gradient(135deg, #f56565, #e53e3e);
}
.earnings-breakdown {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 1rem;
margin-top: 1rem;
}
.earnings-item {
background: rgba(255, 255, 255, 0.05);
padding: 1rem;
border-radius: 12px;
text-align: center;
}
.earnings-amount {
font-size: 1.5rem;
font-weight: bold;
color: #48bb78;
}
.commission-amount {
color: #ed8936;
}
.modal {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.8);
z-index: 10001;
backdrop-filter: blur(5px);
}
.modal-content {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(20px);
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 20px;
padding: 2rem;
width: 90%;
max-width: 600px;
color: white;
}
.form-group {
margin-bottom: 1rem;
}
.form-label {
display: block;
margin-bottom: 0.5rem;
font-weight: 600;
color: #cbd5e0;
}
.form-input {
width: 100%;
background: rgba(255, 255, 255, 0.1);
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 8px;
padding: 0.8rem;
color: white;
font-size: 1rem;
}
.form-input::placeholder {
color: #a0aec0;
}
.checkbox-group {
display: flex;
align-items: center;
gap: 0.5rem;
}
@media (max-width: 768px) {
body {
padding-top: 70px;
padding-bottom: 80px;
}
.container {
padding: 1rem;
}
.dashboard-header {
margin-bottom: 2rem;
}
.dashboard-header h1 {
font-size: 2rem;
margin-bottom: 0.5rem;
}
.dashboard-header h1 i {
margin-right: 0.5rem;
font-size: 1.5rem;
}
.dashboard-header p {
font-size: 1rem;
padding: 0 1rem;
}
.dashboard-nav {
flex-direction: column;
align-items: stretch;
gap: 0.75rem;
margin-bottom: 2rem;
}
.nav-tab {
padding: 1rem 1.5rem;
font-size: 1rem;
width: 100%;
justify-content: center;
}
.stats-grid {
grid-template-columns: 1fr;
gap: 1rem;
margin-bottom: 2rem;
}
.stat-card {
padding: 1.5rem;
}
.stat-icon {
font-size: 2.5rem;
margin-bottom: 1rem;
}
.stat-value {
font-size: 2rem;
}
.stat-label {
font-size: 1rem;
}
.content-section {
padding: 1.5rem;
margin-bottom: 1.5rem;
}
.track-item {
grid-template-columns: 1fr;
text-align: center;
padding: 1rem;
gap: 1rem;
}
.track-thumbnail {
width: 60px;
height: 60px;
font-size: 1.5rem;
margin: 0 auto;
}
.track-info {
align-items: center;
}
.track-title {
font-size: 1rem;
}
.track-meta {
font-size: 0.85rem;
}
.track-stats {
justify-content: center;
flex-wrap: wrap;
gap: 0.5rem;
font-size: 0.8rem;
}
.track-actions {
justify-content: center;
width: 100%;
flex-wrap: wrap;
}
.btn {
padding: 0.7rem 1.2rem;
font-size: 0.85rem;
width: 100%;
justify-content: center;
}
.business-model {
padding: 1.5rem;
margin-bottom: 2rem;
}
.business-model h3 {
font-size: 1.4rem;
margin-bottom: 1rem;
}
.business-model-grid {
grid-template-columns: 1fr;
gap: 1rem;
}
.business-model-item {
padding: 1.5rem;
}
.business-model-item h4 {
font-size: 1.1rem;
}
.business-model-item .amount {
font-size: 1.5rem;
}
.earnings-breakdown {
grid-template-columns: 1fr;
gap: 0.75rem;
}
.modal-content {
width: 95%;
padding: 1.5rem;
max-height: 90vh;
overflow-y: auto;
}
.form-group {
margin-bottom: 1rem;
}
.form-input {
padding: 0.7rem;
font-size: 0.95rem;
}
}
@media (max-width: 480px) {
.dashboard-header h1 {
font-size: 1.75rem;
}
.dashboard-header p {
font-size: 0.9rem;
}
.nav-tab {
padding: 0.9rem 1.2rem;
font-size: 0.95rem;
}
.stat-card {
padding: 1.25rem;
}
.stat-icon {
font-size: 2rem;
}
.stat-value {
font-size: 1.75rem;
}
.stat-label {
font-size: 0.9rem;
}
.content-section {
padding: 1rem;
}
.track-item {
padding: 0.75rem;
}
.btn {
padding: 0.6rem 1rem;
font-size: 0.8rem;
}
.business-model {
padding: 1.25rem;
}
.business-model h3 {
font-size: 1.2rem;
}
.business-model-item {
padding: 1.25rem;
}
.modal-content {
padding: 1.25rem;
}
}
</style>
</head>
<body>
<?php
// Set page variables for header
$current_page = 'artist_dashboard';
$page_title = 'Artist Dashboard - SoundStudioPro';
$page_description = 'Manage your tracks and monitor your success on SoundStudioPro.';
// Only include header for full page loads, not AJAX requests
if (!$isAjaxRequest) {
include 'includes/header.php';
}
?>
<div class="container">
<div class="dashboard-header">
<h1><i class="fas fa-music"></i> <?= t('dashboard.title') ?></h1>
<p><?= t('dashboard.welcome_back', ['name' => htmlspecialchars($user['name'] ?? 'Artist')]) ?></p>
</div>
<!-- Navigation Tabs -->
<div class="dashboard-nav">
<a href="artist_dashboard.php?tab=tracks" class="nav-tab no-ajax <?= $current_tab === 'tracks' ? 'active' : '' ?>">
<i class="fas fa-music"></i> <?= t('dashboard.my_tracks') ?>
</a>
<a href="artist_dashboard.php?tab=earnings" class="nav-tab no-ajax <?= $current_tab === 'earnings' ? 'active' : '' ?>">
<i class="fas fa-dollar-sign"></i> <?= t('dashboard.sales_earnings') ?>
</a>
<a href="artist_dashboard.php?tab=radio" class="nav-tab no-ajax <?= $current_tab === 'radio' ? 'active' : '' ?>">
<i class="fas fa-broadcast-tower"></i> <?= t('radio_performance.title') ?>
</a>
<a href="artist_dashboard.php?tab=analytics" class="nav-tab no-ajax <?= $current_tab === 'analytics' ? 'active' : '' ?>">
<i class="fas fa-chart-line"></i> <?= t('dashboard.analytics') ?>
</a>
</div>
<!-- Statistics Grid -->
<div class="stats-grid">
<div class="stat-card">
<div class="stat-icon"><i class="fas fa-music"></i></div>
<div class="stat-value"><?= number_format($stats['total_tracks']) ?></div>
<div class="stat-label"><?= t('dashboard.total_tracks') ?></div>
</div>
<div class="stat-card">
<div class="stat-icon"><i class="fas fa-eye"></i></div>
<div class="stat-value"><?= number_format($stats['published_tracks']) ?></div>
<div class="stat-label"><?= t('dashboard.published') ?></div>
</div>
<div class="stat-card">
<div class="stat-icon"><i class="fas fa-shopping-cart"></i></div>
<div class="stat-value"><?= number_format($earnings['total_orders']) ?></div>
<div class="stat-label"><?= t('dashboard.revenue_sales') ?></div>
</div>
<?php if ($platform_revenue['platform_orders'] > 0): ?>
<div class="stat-card">
<div class="stat-icon"><i class="fas fa-building"></i></div>
<div class="stat-value"><?= number_format($platform_revenue['platform_orders']) ?></div>
<div class="stat-label"><?= t('dashboard.platform_sales') ?></div>
</div>
<?php endif; ?>
<div class="stat-card">
<div class="stat-icon"><i class="fas fa-dollar-sign"></i></div>
<div class="stat-value">$<?= number_format($artist_earnings, 2) ?></div>
<div class="stat-label"><?= t('dashboard.your_earnings') ?></div>
</div>
<?php
// Get radio earnings for quick stat (table may not exist)
$radio_total = 0;
try {
$radio_quick = $pdo->prepare("SELECT COALESCE(SUM(artist_payout), 0) as total FROM radio_royalties WHERE artist_id = ?");
$radio_quick->execute([$user_id]);
$radio_total = $radio_quick->fetchColumn() ?: 0;
} catch (Exception $e) {
// Table doesn't exist yet, ignore
}
if ($radio_total > 0):
?>
<div class="stat-card">
<div class="stat-icon"><i class="fas fa-broadcast-tower"></i></div>
<div class="stat-value">$<?= number_format($radio_total, 2) ?></div>
<div class="stat-label"><?= t('radio_performance.total_royalties') ?></div>
</div>
<?php endif; ?>
</div>
<?php if (isset($success_message)): ?>
<div class="alert alert-success">
<i class="fas fa-check-circle"></i> <?= htmlspecialchars($success_message) ?>
</div>
<?php endif; ?>
<?php if (isset($error_message)): ?>
<div class="alert" style="background: linear-gradient(135deg, rgba(245, 101, 101, 0.1) 0%, rgba(229, 62, 62, 0.1) 100%); border-color: rgba(245, 101, 101, 0.3); color: #f56565;">
<i class="fas fa-exclamation-circle"></i> <?= htmlspecialchars($error_message) ?>
</div>
<?php endif; ?>
<!-- Business Model Explanation -->
<?php if ($user_plan === 'free'): ?>
<div class="business-model" style="border-left: 4px solid #ed8936;">
<h3><i class="fas fa-info-circle"></i> <?= t('dashboard.free_plan_revenue_model') ?></h3>
<div class="business-model-grid">
<div class="business-model-item">
<h4 style="color: #48bb78;"><?= t('dashboard.your_revenue_sales') ?></h4>
<p>
<?php if ($is_paid_plan): ?>
<?= t('dashboard.pro_sales_description') ?>
<?php else: ?>
<?= t('dashboard.free_sales_description') ?>
<?php endif; ?>
</p>
<div class="amount" style="color: #48bb78;">$<?= number_format($artist_earnings, 2) ?></div>
</div>
<div class="business-model-item">
<h4 style="color: #ed8936;"><?= t('dashboard.platform_revenue') ?></h4>
<p><?= t('dashboard.platform_revenue_description') ?></p>
<div class="amount" style="color: #ed8936;">$<?= number_format($platform_revenue['platform_sales'], 2) ?></div>
</div>
<div class="business-model-item">
<h4 style="color: #4299e1;"><?= t('dashboard.upgrade_benefits') ?></h4>
<p><?= t('dashboard.upgrade_benefits_description') ?></p>
<a href="/subscribe.php?plan=pro" style="color: #4299e1; text-decoration: none; font-weight: 600; display: inline-block; margin-top: 1rem; padding: 0.8rem 1.5rem; background: rgba(66, 153, 225, 0.1); border-radius: 12px; transition: all 0.3s ease;"><?= t('dashboard.view_plans') ?> →</a>
</div>
</div>
</div>
<?php else: ?>
<div class="business-model" style="border-left: 4px solid #48bb78;">
<h3><i class="fas fa-crown"></i> <?= t('dashboard.plan_benefits', ['plan' => ucfirst($user_plan)]) ?></h3>
<div class="business-model-grid">
<div class="business-model-item">
<h4 style="color: #48bb78;">✅ <?= t('dashboard.revenue_sharing') ?></h4>
<p><?= t('dashboard.revenue_sharing_description') ?></p>
</div>
<div class="business-model-item">
<h4 style="color: #48bb78;">✅ <?= t('dashboard.advanced_features') ?></h4>
<p><?= t('dashboard.advanced_features_description') ?></p>
</div>
<div class="business-model-item">
<h4 style="color: #48bb78;">✅ <?= t('dashboard.priority_support') ?></h4>
<p><?= t('dashboard.priority_support_description') ?></p>
</div>
</div>
</div>
<?php endif; ?>
<!-- Content Sections -->
<?php if ($current_tab === 'tracks'): ?>
<?php include 'artist_includes/tracks_management.php'; ?>
<?php elseif ($current_tab === 'earnings'): ?>
<?php include 'artist_includes/earnings_dashboard.php'; ?>
<?php elseif ($current_tab === 'radio'): ?>
<?php include 'artist_includes/radio_performance.php'; ?>
<?php elseif ($current_tab === 'analytics'): ?>
<?php include 'artist_includes/analytics_dashboard.php'; ?>
<?php endif; ?>
</div>
<!-- Track Edit Modal -->
<div id="editTrackModal" class="modal">
<div class="modal-content">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 1.5rem;">
<h2><?= t('dashboard.edit_track') ?></h2>
<button onclick="closeEditModal()" class="btn">
<i class="fas fa-times"></i>
</button>
</div>
<form method="POST" id="editTrackForm">
<input type="hidden" name="action" value="update_track">
<input type="hidden" name="track_id" id="editTrackId">
<div class="form-group">
<label class="form-label"><?= t('dashboard.track_title') ?></label>
<input type="text" name="title" id="editTitle" class="form-input" required>
</div>
<div class="form-group">
<label class="form-label"><?= t('dashboard.description_prompt') ?></label>
<textarea name="description" id="editDescription" class="form-input" rows="3" placeholder="<?= t('dashboard.describe_track') ?>"></textarea>
</div>
<div class="form-group">
<label class="form-label"><?= t('dashboard.price') ?> ($)</label>
<input type="number" name="price" id="editPrice" class="form-input" min="0" step="0.01" placeholder="0.00">
</div>
<div class="form-group">
<div class="checkbox-group">
<input type="checkbox" name="is_public" id="editIsPublic">
<label for="editIsPublic" class="form-label"><?= t('dashboard.make_track_public') ?></label>
</div>
</div>
<div style="display: flex; gap: 1rem; justify-content: flex-end;">
<button type="button" onclick="closeEditModal()" class="btn"><?= t('btn.cancel') ?></button>
<button type="submit" class="btn btn-primary"><?= t('btn.save_changes') ?></button>
</div>
</form>
</div>
</div>
<script>
// Make editTrack function globally accessible
window.editTrack = function(trackId, title, description, price, isPublic) {
const modal = document.getElementById('editTrackModal');
if (!modal) {
console.error('Edit modal not found');
alert('Edit modal not found. Please refresh the page.');
return;
}
document.getElementById('editTrackId').value = trackId;
document.getElementById('editTitle').value = title || 'Untitled Track';
document.getElementById('editDescription').value = description || '';
document.getElementById('editPrice').value = price || '0';
document.getElementById('editIsPublic').checked = isPublic == 1;
modal.style.display = 'block';
};
window.closeEditModal = function() {
const modal = document.getElementById('editTrackModal');
if (modal) {
modal.style.display = 'none';
}
};
// Close modal when clicking outside
document.addEventListener('DOMContentLoaded', function() {
window.onclick = function(event) {
const modal = document.getElementById('editTrackModal');
if (event.target === modal) {
window.closeEditModal();
}
};
});
</script>
<?php
// Only include footer for full page loads, not AJAX requests
if (!$isAjaxRequest) {
include 'includes/footer.php';
}
?>
</body>
</html>