File: /home/h278792/public_html/disc/admin.php
<?php
require 'config.php';
if (!isset($_SESSION['admin_logged_in'])) {
header("Location: login.php");
exit;
}
// خروجی اکسل
if (isset($_GET['export_excel'])) {
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment; filename="customers_export_' . date('Y-m-d') . '.xls"');
$stmt = $pdo->prepare("SELECT c.*, r.referred_full_name, r.referred_phone
FROM customers c
LEFT JOIN referrals r ON c.id = r.referrer_id
ORDER BY c.created_at DESC");
$stmt->execute();
$customers = $stmt->fetchAll(PDO::FETCH_ASSOC);
echo "<table border='1'>";
echo "<tr>
<th>نام و نام خانوادگی</th>
<th>شماره موبایل</th>
<th>کد تخفیف</th>
<th>تاریخ انقضا</th>
<th>معرف</th>
<th>وضعیت</th>
<th>استفاده شده</th>
</tr>";
foreach ($customers as $customer) {
$is_expired = (new DateTime() > new DateTime($customer['expires_at'])) || $customer['is_used'];
echo "<tr>
<td>" . htmlspecialchars($customer['full_name']) . "</td>
<td>" . htmlspecialchars($customer['phone']) . "</td>
<td>" . htmlspecialchars($customer['discount_code']) . "</td>
<td>" . to_jalali($customer['expires_at']) . "</td>
<td>" . ($customer['referred_full_name'] ? htmlspecialchars($customer['referred_full_name'] . ' (' . $customer['referred_phone'] . ')') : '-') . "</td>
<td>" . ($is_expired ? 'غیرفعال' : 'فعال') . "</td>
<td>" . ($customer['is_used'] ? 'بله' : 'خیر') . "</td>
</tr>";
}
echo "</table>";
exit;
}
// بهروزرسانی وضعیت استفاده از تخفیف
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (!isset($_POST['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token']) {
die('درخواست نامعتبر!');
}
if (isset($_POST['action']) && $_POST['action'] === 'update_status') {
$id = (int)$_POST['id'];
$is_used = isset($_POST['is_used']) ? 1 : 0;
$stmt = $pdo->prepare("UPDATE customers SET is_used = ? WHERE id = ?");
$stmt->execute([$is_used, $id]);
}
elseif (isset($_POST['action']) && $_POST['action'] === 'edit_customer') {
$id = (int)$_POST['id'];
$full_name = htmlspecialchars(trim($_POST['full_name']));
$phone = htmlspecialchars(trim($_POST['phone']));
$discount_code = htmlspecialchars(trim($_POST['discount_code']));
$expires_at = $_POST['expires_at'];
$stmt = $pdo->prepare("UPDATE customers SET full_name = ?, phone = ?, discount_code = ?, expires_at = ? WHERE id = ?");
$stmt->execute([$full_name, $phone, $discount_code, $expires_at, $id]);
}
elseif (isset($_POST['action']) && $_POST['action'] === 'delete_customer') {
$id = (int)$_POST['id'];
try {
$pdo->beginTransaction();
$stmt = $pdo->prepare("DELETE FROM referrals WHERE referrer_id = ?");
$stmt->execute([$id]);
$stmt = $pdo->prepare("DELETE FROM customers WHERE id = ?");
$stmt->execute([$id]);
$pdo->commit();
} catch (Exception $e) {
$pdo->rollBack();
die('خطا در حذف مشتری: ' . $e->getMessage());
}
}
}
// جستجوی پیشرفته
$search = isset($_GET['search']) ? htmlspecialchars(trim($_GET['search'])) : '';
$where = '';
if ($search) {
$search_bidirect = "%{$search}%";
$where = "WHERE c.full_name LIKE ? OR c.phone LIKE ? OR c.discount_code LIKE ?";
}
// دریافت دادهها
$stmt = $pdo->prepare("SELECT c.*, r.referred_full_name, r.referred_phone
FROM customers c
LEFT JOIN referrals r ON c.id = r.referrer_id
$where
ORDER BY c.created_at DESC");
if ($search) {
$stmt->execute([$search_bidirect, $search_bidirect, $search_bidirect]);
} else {
$stmt->execute();
}
$customers = $stmt->fetchAll(PDO::FETCH_ASSOC);
// محاسبه تعداد کاربران فعال و غیرفعال برای نمودار
$active_count = 0;
$inactive_count = 0;
foreach ($customers as $customer) {
$is_expired = (new DateTime() > new DateTime($customer['expires_at'])) || $customer['is_used'];
if ($is_expired) {
$inactive_count++;
} else {
$active_count++;
}
}
// Generate CSRF token
if (empty($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
?>
<!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>پنل مدیریت تخفیفها</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.0/font/bootstrap-icons.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"/>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
</head>
<body class="bg-gradient-to-br from-purple-100 to-indigo-200 min-h-screen">
<nav class="bg-gradient-to-r from-purple-600 to-indigo-600 text-white shadow-lg py-4">
<div class="container mx-auto px-4 flex justify-between items-center">
<a class="text-xl font-bold animate__animated animate__bounceIn" href="#"><i class="bi bi-percent ml-2"></i> سیستم مدیریت تخفیفها</a>
<div class="flex items-center space-x-4 space-x-reverse">
<a href="?export_excel=1" class="bg-white text-purple-600 px-4 py-2 rounded-lg hover:bg-gray-100 transition-all duration-300">
<i class="bi bi-file-earmark-excel ml-2"></i> خروجی اکسل
</a>
<span class="ml-4">سلام، مدیر!</span>
<a href="login.php?logout=1" class="bg-white text-purple-600 px-4 py-2 rounded-lg hover:bg-gray-100 transition-all duration-300">
<i class="bi bi-box-arrow-left ml-2"></i> خروج
</a>
</div>
</div>
</nav>
<div class="container mx-auto px-4 py-8">
<!-- نمودار وضعیت کاربران -->
<div class="bg-white rounded-2xl shadow-2xl p-6 mb-6 animate__animated animate__fadeIn">
<h3 class="text-lg font-semibold text-gray-700 mb-4">وضعیت کاربران</h3>
<div class="w-full md:w-1/2 mx-auto">
<canvas id="statusChart" height="200"></canvas>
</div>
<script>
const ctx = document.getElementById('statusChart').getContext('2d');
const statusChart = new Chart(ctx, {
type: 'pie',
data: {
labels: ['فعال', 'غیرفعال'],
datasets: [{
data: [<?= $active_count ?>, <?= $inactive_count ?>],
backgroundColor: ['#34D399', '#F87171'],
borderColor: ['#ffffff', '#ffffff'],
borderWidth: 2
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'bottom',
labels: {
font: {
size: 12
}
}
},
title: {
display: false
}
}
}
});
</script>
</div>
<div class="bg-white rounded-2xl shadow-2xl p-6 mb-6 animate__animated animate__fadeIn">
<form method="GET" class="flex flex-col md:flex-row items-center space-y-4 md:space-y-0 md:space-x-4">
<input type="text" name="search" class="w-full md:w-1/2 p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-600 focus:border-transparent transition-all duration-300" placeholder="جستجو بر اساس نام، شماره، یا کد تخفیف" value="<?= htmlspecialchars($search) ?>">
<button type="submit" class="bg-purple-600 text-white px-4 py-3 rounded-lg hover:bg-purple-700 transition-all duration-300">
<i class="bi bi-search ml-2"></i> جستجو
</button>
</form>
</div>
<div class="bg-white rounded-2xl shadow-2xl overflow-hidden animate__animated animate__fadeIn">
<div class="overflow-x-auto">
<table class="w-full table-auto">
<thead class="bg-gradient-to-r from-purple-600 to-indigo-600 text-white">
<tr>
<th class="p-3">نام و نام خانوادگی</th>
<th class="p-3">شماره موبایل</th>
<th class="p-3">کد تخفیف</th>
<th class="p-3">تاریخ انقضا</th>
<th class="p-3">معرف</th>
<th class="p-3">وضعیت</th>
<th class="p-3">استفاده شده</th>
<th class="p-3">عملیات</th>
</tr>
</thead>
<tbody>
<?php foreach ($customers as $customer):
$is_expired = (new DateTime() > new DateTime($customer['expires_at'])) || $customer['is_used'];
// تولید لینک واتساپ برای مشتریانی که معرف دارند
$whatsapp_link = '';
if ($customer['referred_full_name'] && $customer['referred_phone']) {
$expires_at_jalali = to_jalali($customer['expires_at']);
$message = urlencode("سلام {$customer['referred_full_name']}\nشما از طرف {$customer['full_name']} 10% تخفیف برای دورههای آموزشی الکترونیک و رباتیک دریافت کردید که تا تاریخ $expires_at_jalali معتبر است.\nلطفا به آموزشگاه افق روشن نوین مراجعه کرده و از کد تخفیف استفاده نمایید.\nکد تخفیف شما: {$customer['discount_code']}\nشماره تماس: ۰۲۶۳۲۲۲۷۵۲۵");
$formatted_phone = preg_replace('/^0/', '+98', $customer['referred_phone']);
$whatsapp_link = "https://wa.me/$formatted_phone?text=$message";
}
?>
<tr class="border-b hover:bg-gray-50 transition-all duration-300">
<td class="p-3"><?= htmlspecialchars($customer['full_name']) ?></td>
<td class="p-3"><?= htmlspecialchars($customer['phone']) ?></td>
<td class="p-3"><span class="bg-blue-100 text-blue-800 px-2 py-1 rounded"><?= htmlspecialchars($customer['discount_code']) ?></span></td>
<td class="p-3"><?= to_jalali($customer['expires_at']) ?></td>
<td class="p-3"><?= $customer['referred_full_name'] ? htmlspecialchars($customer['referred_full_name'] . ' (' . $customer['referred_phone'] . ')') : '-' ?></td>
<td class="p-3">
<span class="px-2 py-1 rounded text-sm <?= $is_expired ? 'bg-red-100 text-red-800' : 'bg-green-100 text-green-800' ?>">
<?= $is_expired ? 'غیرفعال' : 'فعال' ?>
</span>
</td>
<td class="p-3">
<form method="POST" class="inline">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<input type="hidden" name="action" value="update_status">
<input type="hidden" name="id" value="<?= $customer['id'] ?>">
<input type="checkbox" name="is_used" <?= $customer['is_used'] ? 'checked' : '' ?> onchange="this.form.submit()" class="h-5 w-5 text-purple-600 focus:ring-purple-500 border-gray-300 rounded">
</form>
</td>
<td class="p-3 flex space-x-2 space-x-reverse">
<button onclick="openEditModal(<?= htmlspecialchars(json_encode($customer)) ?>)" class="text-blue-600 hover:text-blue-800">
<i class="bi bi-pencil-square"></i>
</button>
<form method="POST" class="inline" onsubmit="return confirmDelete(event)">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<input type="hidden" name="action" value="delete_customer">
<input type="hidden" name="id" value="<?= $customer['id'] ?>">
<button type="submit" class="text-red-600 hover:text-red-800">
<i class="bi bi-trash"></i>
</button>
</form>
<?php if ($whatsapp_link): ?>
<a href="<?= $whatsapp_link ?>" target="_blank" class="text-green-600 hover:text-green-800">
<i class="bi bi-whatsapp"></i>
</a>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</div>
<!-- مودال ویرایش -->
<div id="editModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center hidden z-50">
<div class="bg-white rounded-2xl shadow-2xl p-6 w-full max-w-md animate__animated animate__fadeIn">
<h3 class="text-xl font-semibold mb-4">ویرایش کاربر</h3>
<form id="editForm" method="POST">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<input type="hidden" name="action" value="edit_customer">
<input type="hidden" name="id" id="edit_id">
<div class="space-y-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">نام و نام خانوادگی</label>
<input type="text" name="full_name" id="edit_full_name" class="w-full p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-600 focus:border-transparent transition-all duration-300" required>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">شماره موبایل</label>
<input type="tel" name="phone" id="edit_phone" class="w-full p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-600 focus:border-transparent transition-all duration-300" pattern="09[0-9]{9}" required>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">کد تخفیف</label>
<input type="text" name="discount_code" id="edit_discount_code" class="w-full p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-600 focus:border-transparent transition-all duration-300" required>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">تاریخ انقضا (میلادی)</label>
<input type="datetime-local" name="expires_at" id="edit_expires_at" class="w-full p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-600 focus:border-transparent transition-all duration-300" required>
</div>
</div>
<div class="mt-6 flex justify-end space-x-4 space-x-reverse">
<button type="button" onclick="closeEditModal()" class="px-4 py-2 border border-gray-300 rounded-lg hover:bg-gray-100 transition-all duration-300">انصراف</button>
<button type="submit" class="bg-purple-600 text-white px-4 py-2 rounded-lg hover:bg-purple-700 transition-all duration-300">ذخیره تغییرات</button>
</div>
</form>
</div>
</div>
<script>
function openEditModal(customer) {
document.getElementById('edit_id').value = customer.id;
document.getElementById('edit_full_name').value = customer.full_name;
document.getElementById('edit_phone').value = customer.phone;
document.getElementById('edit_discount_code').value = customer.discount_code;
// تبدیل تاریخ به فرمت مناسب برای input datetime-local
const expiresAt = new Date(customer.expires_at);
const formattedDate = expiresAt.toISOString().slice(0, 16);
document.getElementById('edit_expires_at').value = formattedDate;
document.getElementById('editModal').classList.remove('hidden');
}
function closeEditModal() {
document.getElementById('editModal').classList.add('hidden');
}
function confirmDelete(event) {
event.preventDefault();
const form = event.target;
Swal.fire({
title: 'آیا مطمئن هستید؟',
text: "این عمل قابل بازگشت نیست!",
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
confirmButtonText: 'بله، حذف شود',
cancelButtonText: 'انصراف',
reverseButtons: true
}).then((result) => {
if (result.isConfirmed) {
form.submit();
}
});
return false;
}
</script>
</body>
</html>