224 lines
11 KiB
PHP
224 lines
11 KiB
PHP
<?php
|
|
require_once __DIR__ . '/includes/app.php';
|
|
$user = current_user();
|
|
$pageTitle = tr('لوحة التحكم', 'Dashboard');
|
|
$activeNav = 'dashboard';
|
|
$dbError = null;
|
|
$metrics = ['today_sales' => 0, 'today_revenue' => 0.0, 'pos_count' => 0, 'normal_count' => 0, 'recent' => []];
|
|
try {
|
|
$metrics = dashboard_metrics();
|
|
} catch (Throwable $e) {
|
|
$dbError = $e->getMessage();
|
|
}
|
|
require __DIR__ . '/includes/header.php';
|
|
?>
|
|
|
|
<?php if (!$user): ?>
|
|
<div class="alert alert-info border mb-4 d-flex align-items-center justify-content-between">
|
|
<div>
|
|
<h5 class="alert-heading mb-1"><i class="bi bi-info-circle me-2"></i><?= h(tr('نسخة استعراضية عامة', 'Public preview mode')) ?></h5>
|
|
<p class="mb-0 small"><?= h(tr('يمكنك معاينة الهيكل والتصميم الآن، ثم تسجيل الدخول لتجربة سير العمل الكامل.', 'You can preview the structure and design now, then sign in to try the full workflow.')) ?></p>
|
|
</div>
|
|
<a class="btn btn-primary" href="<?= h(url_for('login.php')) ?>"><?= h(tr('فتح تسجيل الدخول', 'Open sign in')) ?></a>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<?php if ($dbError): ?>
|
|
<div class="alert alert-danger mb-4"><i class="bi bi-exclamation-triangle me-2"></i><?= h(tr('تعذر تحميل بيانات قاعدة البيانات حالياً:', 'Database data could not be loaded right now:')) ?> <?= h($dbError) ?></div>
|
|
<?php endif; ?>
|
|
|
|
<!-- Metrics Row -->
|
|
<div class="row g-4 mb-4">
|
|
<div class="col-sm-6 col-xl-3">
|
|
<div class="card text-white bg-primary h-100">
|
|
<div class="card-body d-flex flex-column justify-content-between">
|
|
<div class="d-flex justify-content-between align-items-start">
|
|
<h6 class="text-white-50 text-uppercase mb-0"><?= h(tr('مبيعات اليوم', 'Today sales')) ?></h6>
|
|
<i class="bi bi-receipt fs-4 text-white-50"></i>
|
|
</div>
|
|
<h2 class="display-6 fw-bold mb-0"><?= h((string) $metrics['today_sales']) ?></h2>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-sm-6 col-xl-3">
|
|
<div class="card text-white bg-success h-100">
|
|
<div class="card-body d-flex flex-column justify-content-between">
|
|
<div class="d-flex justify-content-between align-items-start">
|
|
<h6 class="text-white-50 text-uppercase mb-0"><?= h(tr('إيراد اليوم', 'Today revenue')) ?></h6>
|
|
<i class="bi bi-cash-stack fs-4 text-white-50"></i>
|
|
</div>
|
|
<h2 class="display-6 fw-bold mb-0"><?= h(currency((float) $metrics['today_revenue'])) ?></h2>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-sm-6 col-xl-3">
|
|
<div class="card text-white bg-info h-100">
|
|
<div class="card-body d-flex flex-column justify-content-between">
|
|
<div class="d-flex justify-content-between align-items-start">
|
|
<h6 class="text-white-50 text-uppercase mb-0">POS</h6>
|
|
<i class="bi bi-cart fs-4 text-white-50"></i>
|
|
</div>
|
|
<h2 class="display-6 fw-bold mb-0"><?= h((string) $metrics['pos_count']) ?></h2>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-sm-6 col-xl-3">
|
|
<div class="card text-white bg-warning h-100">
|
|
<div class="card-body d-flex flex-column justify-content-between">
|
|
<div class="d-flex justify-content-between align-items-start">
|
|
<h6 class="text-white-50 text-uppercase mb-0"><?= h(tr('بيع عادي', 'Normal sale')) ?></h6>
|
|
<i class="bi bi-basket fs-4 text-white-50"></i>
|
|
</div>
|
|
<h2 class="display-6 fw-bold mb-0"><?= h((string) $metrics['normal_count']) ?></h2>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row g-4 mb-4">
|
|
<!-- Recent Sales -->
|
|
<div class="col-xl-8">
|
|
<div class="card h-100">
|
|
<div class="card-header bg-white d-flex justify-content-between align-items-center py-3">
|
|
<h5 class="mb-0 fw-semibold"><i class="bi bi-clock-history me-2"></i><?= h(tr('آخر المبيعات', 'Latest sales')) ?></h5>
|
|
<a class="btn btn-sm btn-outline-primary" href="<?= h(url_for('sales.php')) ?>"><?= h(tr('عرض الكل', 'View all')) ?></a>
|
|
</div>
|
|
<div class="card-body p-0">
|
|
<?php if (!$metrics['recent']): ?>
|
|
<div class="text-center p-5 text-muted">
|
|
<i class="bi bi-inbox fs-1 mb-3 d-block text-secondary"></i>
|
|
<h5><?= h(tr('لا توجد مبيعات بعد', 'No sales yet')) ?></h5>
|
|
<p class="mb-3"><?= h(tr('ابدأ بأول فاتورة من صفحة نقاط البيع.', 'Start your first receipt from the POS page.')) ?></p>
|
|
<a class="btn btn-primary" href="<?= h(url_for('pos.php')) ?>"><?= h(tr('إنشاء بيع POS', 'Create POS sale')) ?></a>
|
|
</div>
|
|
<?php else: ?>
|
|
<div class="table-responsive">
|
|
<table class="table table-hover align-middle mb-0">
|
|
<thead class="table-light">
|
|
<tr>
|
|
<th class="ps-3"><?= h(tr('رقم الإيصال', 'Receipt No')) ?></th>
|
|
<th><?= h(tr('الفرع', 'Branch')) ?></th>
|
|
<th><?= h(tr('النوع', 'Type')) ?></th>
|
|
<th><?= h(tr('التاريخ', 'Date')) ?></th>
|
|
<th class="text-end pe-3"><?= h(tr('الإجمالي', 'Total')) ?></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php foreach ($metrics['recent'] as $sale): ?>
|
|
<tr>
|
|
<td class="ps-3">
|
|
<a href="<?= h(url_for('sale.php', ['id' => $sale['id']])) ?>" class="fw-semibold text-decoration-none">
|
|
<?= h($sale['receipt_no']) ?>
|
|
</a>
|
|
</td>
|
|
<td><?= h(branch_label((string) $sale['branch_code'])) ?></td>
|
|
<td><span class="badge bg-secondary"><?= h(sale_mode_label((string) $sale['sale_mode'])) ?></span></td>
|
|
<td><small class="text-muted"><?= h(date('M d, H:i', strtotime((string) $sale['sale_date']))) ?></small></td>
|
|
<td class="text-end pe-3 fw-bold"><?= h(currency((float) $sale['total_amount'])) ?></td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Quick Actions / Status -->
|
|
<div class="col-xl-4">
|
|
<div class="card h-100">
|
|
<div class="card-header bg-white py-3">
|
|
<h5 class="mb-0 fw-semibold"><i class="bi bi-lightning-charge me-2"></i><?= h(tr('إجراءات سريعة', 'Quick Actions')) ?></h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="d-grid gap-3">
|
|
<a href="<?= h(url_for('pos.php')) ?>" class="btn btn-primary btn-lg d-flex align-items-center justify-content-between">
|
|
<span><i class="bi bi-cart-plus me-2"></i> <?= h(tr('نقطة بيع جديدة', 'New POS Sale')) ?></span>
|
|
<i class="bi bi-chevron-right"></i>
|
|
</a>
|
|
<a href="<?= h(url_for('normal_sale.php')) ?>" class="btn btn-outline-primary btn-lg d-flex align-items-center justify-content-between">
|
|
<span><i class="bi bi-receipt me-2"></i> <?= h(tr('بيع عادي', 'Normal Sale')) ?></span>
|
|
<i class="bi bi-chevron-right"></i>
|
|
</a>
|
|
<button type="button" class="btn btn-outline-secondary btn-lg d-flex align-items-center justify-content-between" data-bs-toggle="modal" data-bs-target="#quickNoteModal">
|
|
<span><i class="bi bi-pencil-square me-2"></i> <?= h(tr('ملاحظة سريعة', 'Quick Note')) ?></span>
|
|
<i class="bi bi-chevron-right"></i>
|
|
</button>
|
|
</div>
|
|
|
|
<div class="mt-4 pt-4 border-top">
|
|
<?php if ($user): ?>
|
|
<h6 class="text-muted text-uppercase small fw-bold mb-3"><?= h(tr('معلومات الحساب', 'Account Info')) ?></h6>
|
|
<div class="d-flex align-items-center mb-2">
|
|
<i class="bi bi-person-badge fs-4 me-3 text-secondary"></i>
|
|
<div>
|
|
<p class="mb-0 fw-semibold"><?= h(current_lang() === 'ar' ? $user['name_ar'] : $user['name_en']) ?></p>
|
|
<small class="text-muted"><?= h(role_label($user['role'])) ?> - <?= h(branch_label($user['branch_code'])) ?></small>
|
|
</div>
|
|
</div>
|
|
<?php else: ?>
|
|
<div class="text-center">
|
|
<p class="text-muted mb-3"><?= h(tr('جرّب المالك أو مدير الفرع أو الكاشير لرؤية اختلاف الصلاحيات.', 'Try owner, branch manager, or cashier to see different permissions.')) ?></p>
|
|
<a class="btn btn-dark w-100" href="<?= h(url_for('login.php')) ?>"><?= h(tr('تسجيل الدخول للبدء', 'Sign in to start')) ?></a>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Modal Form Example -->
|
|
<div class="modal fade" id="quickNoteModal" tabindex="-1" aria-labelledby="quickNoteModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<form onsubmit="handleQuickNote(event)">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="quickNoteModalLabel"><?= h(tr('إضافة ملاحظة سريعة', 'Add Quick Note')) ?></h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="mb-3">
|
|
<label for="noteTitle" class="form-label"><?= h(tr('العنوان', 'Title')) ?></label>
|
|
<input type="text" class="form-control" id="noteTitle" required>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label for="noteContent" class="form-label"><?= h(tr('التفاصيل', 'Details')) ?></label>
|
|
<textarea class="form-control" id="noteContent" rows="3" required></textarea>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal"><?= h(tr('إلغاء', 'Cancel')) ?></button>
|
|
<button type="submit" class="btn btn-primary"><?= h(tr('حفظ', 'Save')) ?></button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
function handleQuickNote(e) {
|
|
e.preventDefault();
|
|
var modalEl = document.getElementById('quickNoteModal');
|
|
var modal = bootstrap.Modal.getInstance(modalEl);
|
|
modal.hide();
|
|
|
|
Swal.fire({
|
|
title: '<?= h(tr('تم الحفظ!', 'Saved!')) ?>',
|
|
text: '<?= h(tr('تم حفظ الملاحظة بنجاح.', 'Note saved successfully.')) ?>',
|
|
icon: 'success',
|
|
toast: true,
|
|
position: 'top-end',
|
|
showConfirmButton: false,
|
|
timer: 3000
|
|
});
|
|
|
|
e.target.reset();
|
|
}
|
|
</script>
|
|
|
|
<?php require __DIR__ . '/includes/footer.php'; ?>
|