/home/ejrndhmu/.trash/reseller.6/dashboard.php
<?php
require_once dirname(__DIR__) . '/config/database.php';
require_once dirname(__DIR__) . '/includes/functions.php';
startSecureSession();
// Check if user is logged in and is a reseller or agen
if (!isLoggedIn() || !in_array($_SESSION['user_type'], ['reseller', 'agen'])) {
header('Location: ../login.php');
exit();
}
$user_id = $_SESSION['user_id'];
$username = $_SESSION['username'];
$full_name = $_SESSION['full_name'];
// Get site name from settings
$siteName = getSetting('site_name', 'Panel Digital');
// Get current user data including expiry info
$current_user = getUserById($user_id);
// Get reseller statistics
$stats = getResellerStats($user_id);
// Get product quota information
$productQuotaInfo = checkResellerProductQuota($user_id);
// Handle actions
if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'POST') {
$action = $_POST['action'] ?? '';
$csrf_token = $_POST['csrf_token'] ?? '';
if (!verifyCSRFToken($csrf_token)) {
$error = 'Token keamanan tidak valid.';
} else {
switch ($action) {
case 'add_user':
$username_new = sanitizeInput($_POST['username'] ?? '');
$email = sanitizeInput($_POST['email'] ?? '');
$full_name_new = sanitizeInput($_POST['full_name'] ?? '');
$password = $_POST['password'] ?? '';
if (empty($username_new) || empty($email) || empty($full_name_new) || empty($password)) {
$error = 'Semua field harus diisi.';
} elseif (strlen($password) < 6) {
$error = 'Password minimal 6 karakter.';
} else {
$result = createUser($username_new, $email, $full_name_new, $password, 'user', $user_id);
if ($result['success']) {
$success = 'User berhasil ditambahkan.';
$stats = getResellerStats($user_id); // Refresh stats
} else {
$error = $result['message'];
}
}
break;
case 'toggle_user_status':
$target_user_id = (int)($_POST['user_id'] ?? 0);
if ($target_user_id > 0) {
$result = toggleUserStatus($target_user_id, $user_id);
if ($result['success']) {
$success = 'Status user berhasil diubah.';
} else {
$error = $result['message'];
}
}
break;
case 'delete_user':
$target_user_id = (int)($_POST['user_id'] ?? 0);
if ($target_user_id > 0) {
$result = deleteUser($target_user_id, $user_id);
if ($result['success']) {
$success = 'User berhasil dihapus.';
$stats = getResellerStats($user_id); // Refresh stats
} else {
$error = $result['message'];
}
}
break;
case 'add_product':
// Check product quota first
$quotaCheck = checkResellerProductQuota($user_id);
if (!$quotaCheck['can_add']) {
$error = 'Quota produk Anda sudah habis. Hubungi admin untuk menambah quota.';
break;
}
$productData = [
'name' => sanitizeInput($_POST['name'] ?? ''),
'description' => sanitizeInput($_POST['description'] ?? ''),
'price' => (float)($_POST['price'] ?? 0),
'category' => sanitizeInput($_POST['category'] ?? ''),
'file_url' => sanitizeInput($_POST['file_url'] ?? ''),
'thumbnail' => sanitizeInput($_POST['thumbnail'] ?? ''),
'status' => sanitizeInput($_POST['status'] ?? 'active'),
'reseller_id' => $user_id // Set reseller_id to current user
];
if (empty($productData['name'])) {
$error = 'Nama produk harus diisi.';
} elseif ($productData['price'] < 0) {
$error = 'Harga produk tidak valid.';
} elseif (createProduct($productData, $user_id)) {
$success = 'Produk berhasil ditambahkan.';
$stats = getResellerStats($user_id); // Refresh stats
} else {
$error = 'Gagal menambahkan produk. Mungkin quota sudah habis.';
}
break;
case 'edit_product':
$productId = (int)$_POST['product_id'];
$productData = [
'name' => sanitizeInput($_POST['name'] ?? ''),
'description' => sanitizeInput($_POST['description'] ?? ''),
'price' => (float)($_POST['price'] ?? 0),
'category' => sanitizeInput($_POST['category'] ?? ''),
'file_url' => sanitizeInput($_POST['file_url'] ?? ''),
'thumbnail' => sanitizeInput($_POST['thumbnail'] ?? ''),
'status' => sanitizeInput($_POST['status'] ?? 'active')
];
// Check if product belongs to this reseller
$product = getProductById($productId);
if (!$product || $product['reseller_id'] != $user_id) {
$error = 'Anda tidak memiliki akses untuk mengedit produk ini.';
} elseif (empty($productData['name'])) {
$error = 'Nama produk harus diisi.';
} elseif ($productData['price'] < 0) {
$error = 'Harga produk tidak valid.';
} elseif (updateProduct($productId, $productData)) {
$success = 'Produk berhasil diupdate.';
} else {
$error = 'Gagal mengupdate produk.';
}
break;
case 'delete_product':
$productId = (int)$_POST['product_id'];
// Check if product belongs to this reseller
$product = getProductById($productId);
if (!$product || $product['reseller_id'] != $user_id) {
$error = 'Anda tidak memiliki akses untuk menghapus produk ini.';
} elseif (deleteProduct($productId)) {
$success = 'Produk berhasil dihapus.';
$stats = getResellerStats($user_id); // Refresh stats
} else {
$error = 'Gagal menghapus produk.';
}
break;
}
}
}
// Handle AJAX requests for getting product data
if ($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['action']) && $_GET['action'] === 'get_product') {
header('Content-Type: application/json');
$productId = (int)($_GET['id'] ?? 0);
if ($productId > 0) {
$product = getProductById($productId);
if ($product && $product['reseller_id'] == $user_id) {
echo json_encode(['success' => true, 'product' => $product]);
} else {
echo json_encode(['success' => false, 'message' => 'Produk tidak ditemukan atau Anda tidak memiliki akses.']);
}
} else {
echo json_encode(['success' => false, 'message' => 'ID produk tidak valid.']);
}
exit;
}
// Get current page
$page = $_GET['page'] ?? 'dashboard';
// Get custom menus for reseller panel
$customMenus = getCustomMenusByPanel('reseller');
?>
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dashboard Reseller - <?php echo htmlspecialchars($siteName); ?></title>
<script src="https://cdn.tailwindcss.com"></script>
<script>
tailwind.config = {
theme: {
extend: {
colors: {
'blue-primary': '#1e40af',
'blue-secondary': '#3b82f6',
'blue-light': '#dbeafe',
'blue-dark': '#1e3a8a'
}
}
}
}
</script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
</head>
<body class="bg-gray-50">
<!-- Mobile Navigation -->
<nav class="lg:hidden bg-white shadow-lg border-b border-blue-100 fixed top-0 left-0 right-0 z-50">
<div class="flex items-center justify-between px-4 py-3">
<button onclick="toggleSidebar()" class="text-gray-600 hover:text-gray-900">
<i class="fas fa-bars text-xl"></i>
</button>
<div class="flex items-center">
<?php $logoSidebar = getLogoUrl('sidebar'); ?>
<?php if ($logoSidebar): ?>
<img src="<?php echo htmlspecialchars($logoSidebar); ?>" alt="Panel Reseller" class="h-6 max-w-full object-contain mr-2">
<?php else: ?>
<div class="bg-blue-primary w-6 h-6 rounded flex items-center justify-center mr-2">
<i class="fas fa-user-tie text-white text-xs"></i>
</div>
<?php endif; ?>
<h1 class="text-lg font-bold text-blue-dark">Panel Reseller</h1>
</div>
<a href="../config/logout.php" class="text-red-500 hover:text-red-600">
<i class="fas fa-sign-out-alt text-lg"></i>
</a>
</div>
</nav>
<!-- Desktop Navigation -->
<nav class="hidden lg:block bg-white shadow-lg border-b border-blue-100">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex justify-between h-16">
<div class="flex items-center">
<div class="flex-shrink-0 flex items-center">
<?php $logoSidebar = getLogoUrl('sidebar'); ?>
<?php if ($logoSidebar): ?>
<img src="<?php echo htmlspecialchars($logoSidebar); ?>" alt="Panel Reseller" class="h-8 max-w-full object-contain mr-3">
<?php else: ?>
<div class="bg-blue-primary w-8 h-8 rounded-lg flex items-center justify-center mr-3">
<i class="fas fa-user-tie text-white text-sm"></i>
</div>
<?php endif; ?>
<h1 class="text-xl font-bold text-blue-dark">Panel Reseller</h1>
</div>
</div>
<div class="flex items-center space-x-4">
<div class="text-sm text-gray-600">
<i class="fas fa-user mr-1"></i>
<?php echo htmlspecialchars($full_name); ?>
</div>
<a href="../config/logout.php" class="bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded-lg transition duration-200 text-sm">
<i class="fas fa-sign-out-alt mr-1"></i>
Logout
</a>
</div>
</div>
</div>
</nav>
<!-- Mobile sidebar overlay -->
<div class="fixed inset-0 z-30 bg-black bg-opacity-50 lg:hidden hidden" id="sidebar-overlay" onclick="toggleSidebar()"></div>
<div class="flex pt-16 lg:pt-0">
<!-- Sidebar -->
<div class="fixed inset-y-0 left-0 z-40 w-64 bg-white shadow-lg transform -translate-x-full lg:translate-x-0 lg:static lg:inset-0 transition-transform duration-300 ease-in-out" id="sidebar">
<div class="p-4 pt-20 lg:pt-4">
<nav class="space-y-2">
<a href="?page=dashboard" class="<?php echo $page === 'dashboard' ? 'bg-blue-primary text-white' : 'text-gray-700 hover:bg-blue-50'; ?> flex items-center px-4 py-3 rounded-lg transition duration-200">
<i class="fas fa-tachometer-alt mr-3"></i>
Dashboard
</a>
<a href="?page=products" class="<?php echo $page === 'products' ? 'bg-blue-primary text-white' : 'text-gray-700 hover:bg-blue-50'; ?> flex items-center px-4 py-3 rounded-lg transition duration-200">
<i class="fas fa-box mr-3"></i>
Akses Produk
</a>
<a href="?page=my_products" class="<?php echo $page === 'my_products' ? 'bg-blue-primary text-white' : 'text-gray-700 hover:bg-blue-50'; ?> flex items-center px-4 py-3 rounded-lg transition duration-200">
<i class="fas fa-plus-circle mr-3"></i>
Produk Saya
</a>
<a href="?page=panel" class="<?php echo $page === 'panel' ? 'bg-blue-primary text-white' : 'text-gray-700 hover:bg-blue-50'; ?> flex items-center px-4 py-3 rounded-lg transition duration-200">
<i class="fas fa-users mr-3"></i>
Panel Reseller
</a>
<a href="?page=settings" class="<?php echo $page === 'settings' ? 'bg-blue-primary text-white' : 'text-gray-700 hover:bg-blue-50'; ?> flex items-center px-4 py-3 rounded-lg transition duration-200">
<i class="fas fa-cog mr-3"></i>
Setting Akun
</a>
<?php if (!empty($customMenus)): ?>
<!-- Custom Menu Separator -->
<div class="border-t border-gray-200 my-4"></div>
<div class="text-xs font-semibold text-gray-500 uppercase tracking-wider px-4 mb-2">Menu Tambahan</div>
<?php foreach ($customMenus as $menu): ?>
<a href="<?php echo htmlspecialchars($menu['url']); ?>"
class="text-gray-700 hover:bg-blue-50 flex items-center px-4 py-3 rounded-lg transition duration-200"
<?php echo strpos($menu['url'], 'http') === 0 ? 'target="_blank" rel="noopener noreferrer"' : ''; ?>>
<i class="<?php echo htmlspecialchars($menu['icon']); ?> mr-3"></i>
<?php echo htmlspecialchars($menu['title']); ?>
<?php if (strpos($menu['url'], 'http') === 0): ?>
<i class="fas fa-external-link-alt ml-auto text-xs text-gray-400"></i>
<?php endif; ?>
</a>
<?php endforeach; ?>
<?php endif; ?>
</nav>
</div>
</div>
<!-- Main Content -->
<div class="flex-1 p-6">
<?php if (isset($error)): ?>
<div class="bg-red-50 border border-red-200 text-red-700 px-4 py-3 rounded-lg mb-6 flex items-center">
<i class="fas fa-exclamation-circle mr-2"></i>
<?php echo htmlspecialchars($error); ?>
</div>
<?php endif; ?>
<?php if (isset($success)): ?>
<div class="bg-green-50 border border-green-200 text-green-700 px-4 py-3 rounded-lg mb-6 flex items-center">
<i class="fas fa-check-circle mr-2"></i>
<?php echo htmlspecialchars($success); ?>
</div>
<?php endif; ?>
<?php if ($page === 'dashboard'): ?>
<!-- Dashboard Overview -->
<div class="mb-6">
<h2 class="text-2xl font-bold text-gray-800 mb-4">Dashboard Overview</h2>
<!-- Stats Cards -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-6 gap-6 mb-8">
<div class="bg-white rounded-lg shadow-sm border border-gray-200 p-6">
<div class="flex items-center">
<div class="bg-blue-100 p-3 rounded-lg">
<i class="fas fa-users text-blue-primary text-xl"></i>
</div>
<div class="ml-4">
<p class="text-sm font-medium text-gray-600">Total User</p>
<p class="text-2xl font-bold text-gray-900"><?php echo $stats['total_users']; ?></p>
</div>
</div>
</div>
<div class="bg-white rounded-lg shadow-sm border border-gray-200 p-6">
<div class="flex items-center">
<div class="bg-green-100 p-3 rounded-lg">
<i class="fas fa-user-check text-green-600 text-xl"></i>
</div>
<div class="ml-4">
<p class="text-sm font-medium text-gray-600">User Aktif</p>
<p class="text-2xl font-bold text-gray-900"><?php echo $stats['active_users']; ?></p>
</div>
</div>
</div>
<div class="bg-white rounded-lg shadow-sm border border-gray-200 p-6">
<div class="flex items-center">
<div class="<?php echo $stats['used_quota'] >= $stats['user_quota'] && $stats['user_quota'] > 0 ? 'bg-red-100' : 'bg-yellow-100'; ?> p-3 rounded-lg">
<i class="fas fa-chart-pie <?php echo $stats['used_quota'] >= $stats['user_quota'] && $stats['user_quota'] > 0 ? 'text-red-600' : 'text-yellow-600'; ?> text-xl"></i>
</div>
<div class="ml-4">
<p class="text-sm font-medium text-gray-600">Quota User</p>
<p class="text-2xl font-bold text-gray-900">
<?php echo $stats['used_quota']; ?>/<?php echo $stats['user_quota'] > 0 ? $stats['user_quota'] : '∞'; ?>
</p>
<?php if ($stats['user_quota'] > 0): ?>
<div class="w-full bg-gray-200 rounded-full h-2 mt-2">
<div class="<?php echo $stats['used_quota'] >= $stats['user_quota'] ? 'bg-red-500' : 'bg-yellow-500'; ?> h-2 rounded-full"
style="width: <?php echo min(100, ($stats['used_quota'] / $stats['user_quota']) * 100); ?>%"></div>
</div>
<?php endif; ?>
</div>
</div>
</div>
<div class="bg-white rounded-lg shadow-sm border border-gray-200 p-6">
<div class="flex items-center">
<div class="<?php echo ($productQuotaInfo['quota'] !== '∞' && !$productQuotaInfo['can_add']) ? 'bg-red-100' : ($productQuotaInfo['quota'] === '∞' ? 'bg-green-100' : 'bg-indigo-100'); ?> p-3 rounded-lg">
<i class="fas fa-shopping-bag <?php echo ($productQuotaInfo['quota'] !== '∞' && !$productQuotaInfo['can_add']) ? 'text-red-600' : ($productQuotaInfo['quota'] === '∞' ? 'text-green-600' : 'text-indigo-600'); ?> text-xl"></i>
</div>
<div class="ml-4">
<p class="text-sm font-medium text-gray-600">Quota Produk</p>
<p class="text-2xl font-bold text-gray-900">
<?php echo $productQuotaInfo['used']; ?>/<?php echo $productQuotaInfo['quota']; ?>
</p>
<?php if ($productQuotaInfo['quota'] !== '∞'): ?>
<div class="w-full bg-gray-200 rounded-full h-2 mt-2">
<div class="<?php echo !$productQuotaInfo['can_add'] ? 'bg-red-500' : 'bg-indigo-500'; ?> h-2 rounded-full"
style="width: <?php echo min(100, ($productQuotaInfo['used'] / $productQuotaInfo['quota']) * 100); ?>%"></div>
</div>
<?php else: ?>
<div class="w-full bg-gray-200 rounded-full h-2 mt-2">
<div class="bg-green-500 h-2 rounded-full" style="width: 25%"></div>
</div>
<?php endif; ?>
</div>
</div>
</div>
<div class="bg-white rounded-lg shadow-sm border border-gray-200 p-6">
<div class="flex items-center">
<div class="bg-purple-100 p-3 rounded-lg">
<i class="fas fa-box text-purple-600 text-xl"></i>
</div>
<div class="ml-4">
<p class="text-sm font-medium text-gray-600">Produk Tersedia</p>
<p class="text-2xl font-bold text-gray-900"><?php echo $stats['available_products']; ?></p>
</div>
</div>
</div>
<div class="bg-white rounded-lg shadow-sm border border-gray-200 p-6">
<div class="flex items-center">
<div class="bg-orange-100 p-3 rounded-lg">
<i class="fas fa-key text-orange-600 text-xl"></i>
</div>
<div class="ml-4">
<p class="text-sm font-medium text-gray-600">Akses Diberikan</p>
<p class="text-2xl font-bold text-gray-900"><?php echo $stats['total_access_granted']; ?></p>
</div>
</div>
</div>
</div>
<!-- User Expiry Status -->
<div class="bg-white rounded-lg shadow-sm border border-gray-200 p-6 mb-6">
<h3 class="text-lg font-semibold text-gray-800 mb-4 flex items-center">
<i class="fas fa-clock text-blue-primary mr-2"></i>
Status Masa Aktif Akun
</h3>
<div class="flex items-center justify-between">
<div class="flex items-center">
<?php
$expired_at = $current_user['expired_at'] ?? null;
$is_expired = false;
$days_remaining = null;
$status_class = 'text-green-600';
$status_icon = 'fa-check-circle';
$status_text = 'Aktif Selamanya';
if ($expired_at && $expired_at !== '0000-00-00 00:00:00') {
$expiry_date = new DateTime($expired_at);
$current_date = new DateTime();
$interval = $current_date->diff($expiry_date);
if ($current_date > $expiry_date) {
$is_expired = true;
$status_class = 'text-red-600';
$status_icon = 'fa-times-circle';
$status_text = 'Masa Aktif Habis';
} else {
$days_remaining = $interval->days;
if ($days_remaining <= 7) {
$status_class = 'text-yellow-600';
$status_icon = 'fa-exclamation-triangle';
$status_text = 'Akan Berakhir dalam ' . $days_remaining . ' hari';
} else {
$status_text = 'Aktif hingga ' . $expiry_date->format('d M Y');
}
}
}
?>
<div class="<?php echo str_replace('text-', 'bg-', str_replace('-600', '-100', $status_class)); ?> p-3 rounded-lg mr-4">
<i class="fas <?php echo $status_icon; ?> <?php echo $status_class; ?> text-xl"></i>
</div>
<div>
<p class="text-sm font-medium text-gray-600">Status Akun</p>
<p class="text-lg font-bold <?php echo $status_class; ?>"><?php echo $status_text; ?></p>
<?php if ($expired_at && $expired_at !== '0000-00-00 00:00:00' && !$is_expired): ?>
<p class="text-sm text-gray-500">Berakhir: <?php echo date('d M Y H:i', strtotime($expired_at)); ?></p>
<?php endif; ?>
</div>
</div>
<?php if ($is_expired): ?>
<div class="text-right">
<p class="text-sm text-red-600 font-medium">Hubungi admin untuk perpanjangan</p>
</div>
<?php elseif ($days_remaining !== null && $days_remaining <= 7): ?>
<div class="text-right">
<p class="text-sm text-yellow-600 font-medium">Segera hubungi admin</p>
</div>
<?php endif; ?>
</div>
</div>
</div>
<!-- Recent Activity -->
<div class="bg-white rounded-lg shadow-sm border border-gray-200 p-6">
<h3 class="text-lg font-semibold text-gray-800 mb-4">Aktivitas Terbaru</h3>
<div class="space-y-3">
<?php
$recent_users = getRecentUsersByReseller($user_id, 5);
if (empty($recent_users)):
?>
<p class="text-gray-500 text-center py-4">Belum ada aktivitas terbaru.</p>
<?php else: ?>
<?php foreach ($recent_users as $recent_user): ?>
<div class="flex items-center justify-between py-2 border-b border-gray-100 last:border-b-0">
<div class="flex items-center">
<div class="bg-blue-100 w-8 h-8 rounded-full flex items-center justify-center mr-3">
<i class="fas fa-user text-blue-primary text-xs"></i>
</div>
<div>
<p class="font-medium text-gray-800"><?php echo htmlspecialchars($recent_user['full_name']); ?></p>
<p class="text-sm text-gray-500">@<?php echo htmlspecialchars($recent_user['username']); ?></p>
</div>
</div>
<div class="text-right">
<span class="<?php echo $recent_user['status'] === 'active' ? 'bg-green-100 text-green-800' : 'bg-red-100 text-red-800'; ?> px-2 py-1 rounded-full text-xs font-medium">
<?php echo ucfirst($recent_user['status']); ?>
</span>
<p class="text-xs text-gray-500 mt-1"><?php echo formatDate($recent_user['created_at']); ?></p>
</div>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
</div>
<?php elseif ($page === 'products'): ?>
<?php include 'pages/products.php'; ?>
<?php elseif ($page === 'my_products'): ?>
<?php include 'pages/my_products.php'; ?>
<?php elseif ($page === 'panel'): ?>
<?php include 'pages/panel.php'; ?>
<?php elseif ($page === 'settings'): ?>
<?php include 'pages/settings.php'; ?>
<?php endif; ?>
</div>
</div>
<script>
function toggleSidebar() {
const sidebar = document.getElementById('sidebar');
const overlay = document.getElementById('sidebar-overlay');
sidebar.classList.toggle('-translate-x-full');
overlay.classList.toggle('hidden');
}
// Auto-hide alerts after 5 seconds
setTimeout(function() {
const alerts = document.querySelectorAll('.bg-red-50, .bg-green-50');
alerts.forEach(function(alert) {
alert.style.transition = 'opacity 0.5s';
alert.style.opacity = '0';
setTimeout(function() {
alert.remove();
}, 500);
});
}, 5000);
</script>
</body>
</html>