![]() 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/artist_includes/ |
<?php
/**
* Artist Earnings Dashboard
* Displays sales, revenue, and earning statistics for artists
*/
// Ensure translation system is loaded
if (!function_exists('t')) {
require_once __DIR__ . '/../includes/translations.php';
}
// ============================================
// INITIALIZE VARIABLES WITH SAFE DEFAULTS
// ============================================
// From parent file (artist_dashboard.php)
$user_id = $user_id ?? ($_SESSION['user_id'] ?? 0);
$pdo = $pdo ?? null;
$earnings = $earnings ?? ['total_sales' => 0, 'total_orders' => 0];
$commission_rate = $commission_rate ?? 0.85;
$user_plan = $user_plan ?? 'free';
$artist_percentage = $artist_percentage ?? 15;
$platform_percentage = $platform_percentage ?? 85;
// Local variables
$recent_sales = [];
$monthly_data = [];
$top_performing = [];
$db_error = false;
// ============================================
// FETCH DATA WITH ERROR HANDLING
// ============================================
if ($pdo && $user_id > 0) {
// Get recent sales
try {
$stmt = $pdo->prepare("
SELECT
s.id,
s.amount,
s.created_at,
s.revenue_recipient,
mt.title as track_title,
u.name as buyer_name
FROM sales s
LEFT JOIN music_tracks mt ON s.track_id = mt.id
LEFT JOIN users u ON s.buyer_id = u.id
WHERE s.artist_id = ?
ORDER BY s.created_at DESC
LIMIT 50
");
$stmt->execute([$user_id]);
$recent_sales = $stmt->fetchAll(PDO::FETCH_ASSOC) ?: [];
} catch (PDOException $e) {
$db_error = true;
$recent_sales = [];
}
// Get top performing tracks
try {
$stmt = $pdo->prepare("
SELECT
mt.id,
mt.title,
mt.price,
COUNT(s.id) as sales_count,
COALESCE(SUM(s.amount), 0) as gross_revenue
FROM music_tracks mt
LEFT JOIN sales s ON mt.id = s.track_id AND s.artist_id = ?
WHERE mt.user_id = ?
GROUP BY mt.id, mt.title, mt.price
HAVING sales_count > 0
ORDER BY gross_revenue DESC
LIMIT 10
");
$stmt->execute([$user_id, $user_id]);
$top_performing = $stmt->fetchAll(PDO::FETCH_ASSOC) ?: [];
} catch (PDOException $e) {
$top_performing = [];
}
}
// ============================================
// CALCULATE EARNINGS
// ============================================
$total_gross = floatval($earnings['total_sales'] ?? 0);
$total_orders = intval($earnings['total_orders'] ?? 0);
$artist_share = $total_gross * (1 - $commission_rate);
$platform_share = $total_gross * $commission_rate;
$pending_payout = $artist_share;
// Format for display
$fmt_gross = number_format($total_gross, 2);
$fmt_artist = number_format($artist_share, 2);
$fmt_platform = number_format($platform_share, 2);
$fmt_pending = number_format($pending_payout, 2);
$fmt_artist_pct = number_format($artist_percentage, 0);
$fmt_platform_pct = number_format($platform_percentage, 0);
?>
<style>
/* Earnings Dashboard Styles */
.earnings-container {
max-width: 1200px;
margin: 0 auto;
}
.earnings-section {
background: linear-gradient(135deg, rgba(30, 30, 40, 0.9) 0%, rgba(20, 20, 30, 0.95) 100%);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 20px;
padding: 2rem;
margin-bottom: 2rem;
backdrop-filter: blur(10px);
}
.earnings-section-title {
font-size: 1.5rem;
font-weight: 700;
color: #fff;
margin-bottom: 1.5rem;
display: flex;
align-items: center;
gap: 0.75rem;
}
.earnings-section-title i {
color: #667eea;
}
/* Stats Grid */
.earnings-stats {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 1.5rem;
margin-bottom: 2rem;
}
.stat-box {
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 16px;
padding: 1.5rem;
text-align: center;
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.stat-box:hover {
transform: translateY(-4px);
box-shadow: 0 8px 25px rgba(102, 126, 234, 0.2);
}
.stat-box .value {
font-size: 2.2rem;
font-weight: 800;
color: #fff;
margin-bottom: 0.5rem;
}
.stat-box .value.green { color: #48bb78; }
.stat-box .value.orange { color: #ed8936; }
.stat-box .value.blue { color: #4299e1; }
.stat-box .value.purple { color: #9f7aea; }
.stat-box .label {
font-size: 0.95rem;
color: #a0aec0;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.5px;
}
/* Upgrade Banner */
.upgrade-banner {
background: linear-gradient(135deg, rgba(102, 126, 234, 0.15) 0%, rgba(118, 75, 162, 0.15) 100%);
border: 2px solid rgba(102, 126, 234, 0.3);
border-radius: 16px;
padding: 2rem;
margin-bottom: 2rem;
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
gap: 1.5rem;
}
.upgrade-banner.pro {
background: linear-gradient(135deg, rgba(72, 187, 120, 0.15) 0%, rgba(56, 161, 105, 0.15) 100%);
border-color: rgba(72, 187, 120, 0.3);
}
.upgrade-info h3 {
font-size: 1.4rem;
font-weight: 700;
color: #fff;
margin: 0 0 0.5rem 0;
}
.upgrade-info p {
color: #cbd5e0;
margin: 0;
font-size: 1.1rem;
}
.upgrade-btn {
background: linear-gradient(135deg, #667eea, #764ba2);
color: #fff;
padding: 1rem 2rem;
border-radius: 12px;
text-decoration: none;
font-weight: 700;
font-size: 1.1rem;
display: inline-flex;
align-items: center;
gap: 0.5rem;
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.upgrade-btn:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(102, 126, 234, 0.4);
}
/* Breakdown Grid */
.breakdown-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 1.5rem;
}
.breakdown-card {
background: rgba(255, 255, 255, 0.03);
border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 12px;
padding: 1.5rem;
}
.breakdown-card .title {
font-size: 1rem;
color: #a0aec0;
margin-bottom: 0.5rem;
font-weight: 600;
}
.breakdown-card .amount {
font-size: 1.8rem;
font-weight: 700;
margin-bottom: 0.5rem;
color: #fff;
}
.breakdown-card .desc {
font-size: 0.9rem;
color: #718096;
}
/* Sales Table */
.sales-table-wrap {
overflow-x: auto;
}
.sales-table {
width: 100%;
border-collapse: collapse;
}
.sales-table th,
.sales-table td {
padding: 1rem;
text-align: left;
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}
.sales-table th {
background: rgba(255, 255, 255, 0.03);
color: #a0aec0;
font-weight: 600;
font-size: 0.9rem;
text-transform: uppercase;
}
.sales-table td {
color: #fff;
}
.sales-table tr:hover td {
background: rgba(255, 255, 255, 0.02);
}
.amount-green {
color: #48bb78;
font-weight: 600;
}
/* Empty State */
.empty-state {
text-align: center;
padding: 3rem 2rem;
color: #a0aec0;
}
.empty-state i {
font-size: 4rem;
opacity: 0.3;
margin-bottom: 1rem;
}
.empty-state h4 {
font-size: 1.3rem;
color: #fff;
margin: 0 0 0.5rem 0;
}
.empty-state p {
margin: 0;
font-size: 1rem;
}
/* Top Track Card */
.top-track {
display: flex;
align-items: center;
justify-content: space-between;
background: rgba(255, 255, 255, 0.03);
border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 12px;
padding: 1.25rem;
margin-bottom: 1rem;
transition: border-color 0.3s ease;
}
.top-track:hover {
border-color: rgba(102, 126, 234, 0.3);
}
.top-track:last-child {
margin-bottom: 0;
}
.top-track .info .name {
font-size: 1.1rem;
font-weight: 600;
color: #fff;
margin-bottom: 0.25rem;
}
.top-track .info .meta {
font-size: 0.9rem;
color: #a0aec0;
}
.top-track .revenue {
text-align: right;
}
.top-track .revenue .amount {
font-size: 1.3rem;
font-weight: 700;
color: #48bb78;
}
.top-track .revenue .label {
font-size: 0.8rem;
color: #718096;
}
@media (max-width: 768px) {
.earnings-section {
padding: 1.5rem;
}
.earnings-stats {
grid-template-columns: 1fr 1fr;
}
.stat-box .value {
font-size: 1.6rem;
}
.upgrade-banner {
flex-direction: column;
text-align: center;
}
.breakdown-grid {
grid-template-columns: 1fr;
}
.top-track {
flex-direction: column;
text-align: center;
gap: 1rem;
}
.top-track .revenue {
text-align: center;
}
}
@media (max-width: 480px) {
.earnings-stats {
grid-template-columns: 1fr;
}
}
</style>
<div class="earnings-container">
<!-- Header Stats -->
<div class="earnings-section">
<h2 class="earnings-section-title">
<i class="fas fa-chart-line"></i>
<?= t('earnings.title') ?>
</h2>
<div class="earnings-stats">
<div class="stat-box">
<div class="value">$<?= $fmt_gross ?></div>
<div class="label"><?= t('earnings.total_gross_sales') ?></div>
</div>
<div class="stat-box">
<div class="value green">$<?= $fmt_artist ?></div>
<div class="label"><?= t('earnings.your_earnings', ['percent' => $fmt_artist_pct]) ?></div>
</div>
<div class="stat-box">
<div class="value orange">$<?= $fmt_platform ?></div>
<div class="label"><?= t('earnings.platform_commission', ['percent' => $fmt_platform_pct]) ?></div>
</div>
<div class="stat-box">
<div class="value blue">$<?= $fmt_pending ?></div>
<div class="label"><?= t('earnings.pending_payout') ?></div>
</div>
</div>
</div>
<!-- Upgrade Banner / Pro Status -->
<?php if ($user_plan === 'pro'): ?>
<div class="upgrade-banner pro">
<div class="upgrade-info">
<h3><i class="fas fa-crown" style="color: #48bb78; margin-right: 0.5rem;"></i><?= t('earnings.pro_member_benefits') ?></h3>
<p><?= t('earnings.pro_member_keep_85') ?></p>
</div>
</div>
<?php else: ?>
<div class="upgrade-banner">
<div class="upgrade-info">
<h3><i class="fas fa-rocket" style="color: #667eea; margin-right: 0.5rem;"></i><?= t('earnings.upgrade_to_pro_keep_85') ?></h3>
<p><?= t('earnings.currently_keep', ['percent' => $fmt_artist_pct, 'more' => number_format(85 - $artist_percentage, 0)]) ?></p>
</div>
<a href="/subscribe.php?plan=pro" class="upgrade-btn">
<i class="fas fa-crown"></i>
<?= t('earnings.upgrade_to_pro') ?>
</a>
</div>
<?php endif; ?>
<!-- How Earnings Work -->
<div class="earnings-section">
<h3 class="earnings-section-title">
<i class="fas fa-info-circle"></i>
<?= t('earnings.how_earnings_work') ?>
</h3>
<div class="breakdown-grid">
<div class="breakdown-card">
<div class="title">🎯 <?= t('earnings.you_keep', ['percent' => $fmt_artist_pct]) ?></div>
<div class="amount" style="color: #48bb78;">$<?= $fmt_artist ?></div>
<div class="desc"><?= t('earnings.direct_to_account') ?></div>
</div>
<div class="breakdown-card">
<div class="title">🏢 <?= t('earnings.platform_fee', ['percent' => $fmt_platform_pct]) ?></div>
<div class="amount" style="color: #ed8936;">$<?= $fmt_platform ?></div>
<div class="desc"><?= t('earnings.hosting_processing') ?></div>
</div>
<div class="breakdown-card">
<div class="title">💳 <?= t('earnings.monthly_payouts') ?></div>
<div class="amount" style="color: #4299e1;">$25 <?= t('earnings.minimum') ?></div>
<div class="desc"><?= t('earnings.paypal_bank_transfer') ?></div>
</div>
</div>
</div>
<!-- Recent Sales -->
<div class="earnings-section">
<h3 class="earnings-section-title">
<i class="fas fa-clock"></i>
<?= t('earnings.recent_sales') ?>
</h3>
<?php if (empty($recent_sales)): ?>
<div class="empty-state">
<i class="fas fa-shopping-cart"></i>
<h4><?= t('earnings.no_sales_yet') ?></h4>
<p><?= t('earnings.sales_will_appear') ?></p>
</div>
<?php else: ?>
<div class="sales-table-wrap">
<table class="sales-table">
<thead>
<tr>
<th><?= t('earnings.track') ?></th>
<th><?= t('earnings.buyer') ?></th>
<th><?= t('earnings.amount') ?></th>
<th><?= t('earnings.date') ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($recent_sales as $sale): ?>
<tr>
<td><?= htmlspecialchars($sale['track_title'] ?? 'Unknown Track') ?></td>
<td><?= htmlspecialchars($sale['buyer_name'] ?? t('earnings.anonymous')) ?></td>
<td class="amount-green">$<?= number_format(floatval($sale['amount'] ?? 0), 2) ?></td>
<td><?= date('M j, Y', strtotime($sale['created_at'] ?? 'now')) ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php endif; ?>
</div>
<!-- Top Performing Tracks -->
<div class="earnings-section">
<h3 class="earnings-section-title">
<i class="fas fa-trophy"></i>
<?= t('earnings.top_performing_tracks') ?>
</h3>
<?php if (empty($top_performing)): ?>
<div class="empty-state">
<i class="fas fa-music"></i>
<h4><?= t('earnings.no_sales_yet') ?></h4>
<p><?= t('earnings.best_selling_tracks_will_appear') ?></p>
</div>
<?php else: ?>
<?php foreach ($top_performing as $track):
$track_revenue = floatval($track['gross_revenue'] ?? 0) * (1 - $commission_rate);
?>
<div class="top-track">
<div class="info">
<div class="name"><?= htmlspecialchars($track['title'] ?? 'Untitled') ?></div>
<div class="meta">
<?= intval($track['sales_count'] ?? 0) ?> <?= t('earnings.sales') ?>
• $<?= number_format(floatval($track['price'] ?? 0), 2) ?> <?= t('earnings.per_track') ?>
</div>
</div>
<div class="revenue">
<div class="amount">$<?= number_format($track_revenue, 2) ?></div>
<div class="label"><?= t('earnings.your_earnings_label') ?></div>
</div>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
</div>