125 lines
6.4 KiB
PHP
125 lines
6.4 KiB
PHP
<?php
|
|
$pageTitle = $title ?? 'Store';
|
|
$tablesReady = (bool)($tables_ready ?? false);
|
|
$privateRoot = (string)($private_root ?? '');
|
|
$privateRootReady = (bool)($private_root_ready ?? false);
|
|
$stats = is_array($stats ?? null) ? $stats : [];
|
|
$recentOrders = is_array($recent_orders ?? null) ? $recent_orders : [];
|
|
$newCustomers = is_array($new_customers ?? null) ? $new_customers : [];
|
|
$currency = (string)($currency ?? 'GBP');
|
|
$totalOrders = (int)($stats['total_orders'] ?? 0);
|
|
$paidOrders = (int)($stats['paid_orders'] ?? 0);
|
|
$totalRevenue = (float)($stats['total_revenue'] ?? 0);
|
|
$totalCustomers = (int)($stats['total_customers'] ?? 0);
|
|
ob_start();
|
|
?>
|
|
<section class="admin-card">
|
|
<div class="badge">Store</div>
|
|
<div style="display:flex; align-items:center; justify-content:space-between; gap:16px; margin-top:16px;">
|
|
<div>
|
|
<h1 style="font-size:28px; margin:0;">Store</h1>
|
|
<p style="color: var(--muted); margin-top:6px;">Commerce layer for releases/tracks.</p>
|
|
</div>
|
|
<div style="display:flex; gap:10px; align-items:center;">
|
|
<a href="/admin/store/settings" class="btn outline">Settings</a>
|
|
<a href="/admin/store/orders" class="btn outline">Orders</a>
|
|
<a href="/admin/store/customers" class="btn outline">Customers</a>
|
|
</div>
|
|
</div>
|
|
<div style="display:flex; flex-wrap:wrap; gap:8px; margin-top:12px;">
|
|
<a href="/admin/store" class="btn outline small">Overview</a>
|
|
<a href="/admin/store/settings" class="btn outline small">Settings</a>
|
|
<a href="/admin/store/orders" class="btn outline small">Orders</a>
|
|
<a href="/admin/store/customers" class="btn outline small">Customers</a>
|
|
</div>
|
|
|
|
<?php if (!$tablesReady): ?>
|
|
<div class="admin-card" style="margin-top:16px; padding:16px; display:flex; align-items:center; justify-content:space-between; gap:16px;">
|
|
<div>
|
|
<div style="font-weight:600;">Store tables not initialized</div>
|
|
<div style="color: var(--muted); font-size:13px; margin-top:4px;">Create store tables before configuring products and checkout.</div>
|
|
</div>
|
|
<form method="post" action="/admin/store/install">
|
|
<button type="submit" class="btn small">Create Tables</button>
|
|
</form>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<div class="admin-card" style="margin-top:16px; padding:16px;">
|
|
<div style="font-weight:600;">Private download root</div>
|
|
<div style="color: var(--muted); font-size:13px; margin-top:4px; font-family:'IBM Plex Mono', monospace;">
|
|
<?= htmlspecialchars($privateRoot, ENT_QUOTES, 'UTF-8') ?>
|
|
</div>
|
|
<div style="margin-top:8px; font-size:12px; color: <?= $privateRootReady ? '#9be7c6' : '#f3b0b0' ?>;">
|
|
<?= $privateRootReady ? 'Ready' : 'Missing or not writable' ?>
|
|
</div>
|
|
</div>
|
|
|
|
<div style="display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:10px; margin-top:16px;">
|
|
<div class="admin-card" style="padding:14px;">
|
|
<div class="label">Total Orders</div>
|
|
<div style="font-size:26px; font-weight:700; margin-top:8px;"><?= $totalOrders ?></div>
|
|
<div style="font-size:12px; color:var(--muted); margin-top:4px;">Paid: <?= $paidOrders ?></div>
|
|
</div>
|
|
<div class="admin-card" style="padding:14px;">
|
|
<div class="label">Revenue</div>
|
|
<div style="font-size:26px; font-weight:700; margin-top:8px;"><?= htmlspecialchars($currency, ENT_QUOTES, 'UTF-8') ?> <?= number_format($totalRevenue, 2) ?></div>
|
|
</div>
|
|
<div class="admin-card" style="padding:14px;">
|
|
<div class="label">Total Customers</div>
|
|
<div style="font-size:26px; font-weight:700; margin-top:8px;"><?= $totalCustomers ?></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div style="display:grid; grid-template-columns:1fr 1fr; gap:10px; margin-top:16px;">
|
|
<div class="admin-card" style="padding:14px;">
|
|
<div style="font-weight:600;">Last 5 purchases</div>
|
|
<?php if (!$recentOrders): ?>
|
|
<div style="margin-top:8px; color:var(--muted); font-size:13px;">No orders yet.</div>
|
|
<?php else: ?>
|
|
<div style="margin-top:10px; display:grid; gap:8px;">
|
|
<?php foreach ($recentOrders as $order): ?>
|
|
<div class="admin-card" style="padding:10px;">
|
|
<div style="display:flex; justify-content:space-between; gap:10px; font-size:13px;">
|
|
<strong><?= htmlspecialchars((string)($order['order_no'] ?? '-'), ENT_QUOTES, 'UTF-8') ?></strong>
|
|
<span><?= htmlspecialchars((string)($order['status'] ?? 'pending'), ENT_QUOTES, 'UTF-8') ?></span>
|
|
</div>
|
|
<div style="display:flex; justify-content:space-between; gap:10px; color:var(--muted); font-size:12px; margin-top:4px;">
|
|
<span><?= htmlspecialchars((string)($order['email'] ?? ''), ENT_QUOTES, 'UTF-8') ?></span>
|
|
<span><?= htmlspecialchars((string)($order['currency'] ?? $currency), ENT_QUOTES, 'UTF-8') ?> <?= number_format((float)($order['total'] ?? 0), 2) ?></span>
|
|
</div>
|
|
<div style="margin-top:8px;">
|
|
<a href="/admin/store/order?id=<?= (int)($order['id'] ?? 0) ?>" class="btn outline small">View Order</a>
|
|
</div>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<div class="admin-card" style="padding:14px;">
|
|
<div style="font-weight:600;">Top 5 new customers</div>
|
|
<?php if (!$newCustomers): ?>
|
|
<div style="margin-top:8px; color:var(--muted); font-size:13px;">No customers yet.</div>
|
|
<?php else: ?>
|
|
<div style="margin-top:10px; display:grid; gap:8px;">
|
|
<?php foreach ($newCustomers as $customer): ?>
|
|
<div class="admin-card" style="padding:10px;">
|
|
<div style="display:flex; justify-content:space-between; gap:10px; font-size:13px;">
|
|
<strong><?= htmlspecialchars((string)($customer['name'] ?? 'Customer'), ENT_QUOTES, 'UTF-8') ?></strong>
|
|
<span style="color:<?= (int)($customer['is_active'] ?? 0) === 1 ? '#9be7c6' : '#f3b0b0' ?>;">
|
|
<?= (int)($customer['is_active'] ?? 0) === 1 ? 'Active' : 'Disabled' ?>
|
|
</span>
|
|
</div>
|
|
<div style="color:var(--muted); font-size:12px; margin-top:4px;"><?= htmlspecialchars((string)($customer['email'] ?? ''), ENT_QUOTES, 'UTF-8') ?></div>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
<?php
|
|
$content = ob_get_clean();
|
|
require __DIR__ . '/../../../../modules/admin/views/layout.php';
|