Autosave: 20260303-065452
This commit is contained in:
parent
e9ceb4546d
commit
d2a2461bda
219
admin.php
219
admin.php
@ -2,11 +2,37 @@
|
||||
$title = 'dashboard';
|
||||
require_once __DIR__ . '/includes/header.php';
|
||||
|
||||
// Helper functions for status colors
|
||||
if (!function_exists('getStatusColor')) {
|
||||
function getStatusColor($status) {
|
||||
return [
|
||||
'received' => 'secondary',
|
||||
'processing' => 'primary',
|
||||
'ready' => 'success',
|
||||
'delivered' => 'dark',
|
||||
'cancelled' => 'danger',
|
||||
][$status] ?? 'info';
|
||||
}
|
||||
}
|
||||
if (!function_exists('getPaymentStatusColor')) {
|
||||
function getPaymentStatusColor($status) {
|
||||
return [
|
||||
'unpaid' => 'danger',
|
||||
'partially_paid' => 'warning',
|
||||
'paid' => 'success',
|
||||
][$status] ?? 'info';
|
||||
}
|
||||
}
|
||||
|
||||
// Stats logic
|
||||
$branch_id = $_SESSION['branch_id'];
|
||||
$is_super = ($current_role === 'super_admin');
|
||||
$is_limited = ($current_role === 'limited_viewer');
|
||||
|
||||
// For super_admin, "all" means no branch filtering.
|
||||
// Otherwise, we filter by the selected branch.
|
||||
$filter_branch = ($branch_id !== 'all');
|
||||
|
||||
if (!$is_limited) {
|
||||
$stats = [
|
||||
'today_revenue' => 0,
|
||||
@ -16,47 +42,47 @@ if (!$is_limited) {
|
||||
];
|
||||
|
||||
// Today's revenue
|
||||
$rev_where = $is_super ? "" : " AND order_id IN (SELECT id FROM orders WHERE branch_id = ?)";
|
||||
$rev_params = $is_super ? [] : [$branch_id];
|
||||
$rev_where = !$filter_branch ? "" : " AND order_id IN (SELECT id FROM orders WHERE branch_id = ?)";
|
||||
$rev_params = !$filter_branch ? [] : [$branch_id];
|
||||
$stmt = db()->prepare("SELECT SUM(amount) as total FROM payments WHERE created_at >= CURDATE() $rev_where");
|
||||
$stmt->execute($rev_params);
|
||||
$stats['today_revenue'] = $stmt->fetch()['total'] ?? 0;
|
||||
|
||||
// Active orders (received, processing)
|
||||
$ord_where = $is_super ? "WHERE status IN ('received', 'processing')" : "WHERE branch_id = ? AND status IN ('received', 'processing')";
|
||||
$ord_params = $is_super ? [] : [$branch_id];
|
||||
$ord_where = !$filter_branch ? "WHERE status IN ('received', 'processing')" : "WHERE branch_id = ? AND status IN ('received', 'processing')";
|
||||
$ord_params = !$filter_branch ? [] : [$branch_id];
|
||||
$stmt = db()->prepare("SELECT COUNT(*) as count FROM orders $ord_where");
|
||||
$stmt->execute($ord_params);
|
||||
$stats['active_orders'] = $stmt->fetch()['count'] ?? 0;
|
||||
|
||||
// Ready orders
|
||||
$ready_where = $is_super ? "WHERE status = 'ready'" : "WHERE branch_id = ? AND status = 'ready'";
|
||||
$ready_params = $is_super ? [] : [$branch_id];
|
||||
$ready_where = !$filter_branch ? "WHERE status = 'ready'" : "WHERE branch_id = ? AND status = 'ready'";
|
||||
$ready_params = !$filter_branch ? [] : [$branch_id];
|
||||
$stmt = db()->prepare("SELECT COUNT(*) as count FROM orders $ready_where");
|
||||
$stmt->execute($ready_params);
|
||||
$stats['ready_orders'] = $stmt->fetch()['count'] ?? 0;
|
||||
|
||||
// New customers today
|
||||
$cust_where = $is_super ? "WHERE created_at >= CURDATE()" : "WHERE branch_id = ? AND created_at >= CURDATE()";
|
||||
$cust_params = $is_super ? [] : [$branch_id];
|
||||
$cust_where = !$filter_branch ? "WHERE created_at >= CURDATE()" : "WHERE branch_id = ? AND created_at >= CURDATE()";
|
||||
$cust_params = !$filter_branch ? [] : [$branch_id];
|
||||
$stmt = db()->prepare("SELECT COUNT(*) as count FROM customers $cust_where");
|
||||
$stmt->execute($cust_params);
|
||||
$stats['new_customers'] = $stmt->fetch()['count'] ?? 0;
|
||||
|
||||
// Recent orders
|
||||
$recent_where = $is_super ? "" : "WHERE o.branch_id = ?";
|
||||
$recent_params = $is_super ? [] : [$branch_id];
|
||||
$stmt = db()->prepare("SELECT o.*, c.name_en as customer_name_en, c.name_ar as customer_name_ar
|
||||
FROM orders o
|
||||
LEFT JOIN customers c ON o.customer_id = c.id
|
||||
$recent_where
|
||||
ORDER BY o.created_at DESC LIMIT 5");
|
||||
$stmt->execute($recent_params);
|
||||
$recent_orders = $stmt->fetchAll();
|
||||
// Monthly Orders (Last 12 months)
|
||||
$monthly_where = !$filter_branch ? "WHERE created_at >= DATE_SUB(CURDATE(), INTERVAL 12 MONTH)" : "WHERE branch_id = ? AND created_at >= DATE_SUB(CURDATE(), INTERVAL 12 MONTH)";
|
||||
$monthly_params = !$filter_branch ? [] : [$branch_id];
|
||||
$stmt = db()->prepare("SELECT DATE_FORMAT(created_at, '%Y-%m') as month_year, COUNT(*) as count
|
||||
FROM orders
|
||||
$monthly_where
|
||||
GROUP BY month_year
|
||||
ORDER BY month_year ASC");
|
||||
$stmt->execute($monthly_params);
|
||||
$monthly_orders = $stmt->fetchAll();
|
||||
|
||||
// Charts data for Dashboard (Last 7 days)
|
||||
$chart_where = $is_super ? "WHERE created_at >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)" : "WHERE branch_id = ? AND created_at >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)";
|
||||
$chart_params = $is_super ? [] : [$branch_id];
|
||||
$chart_where = !$filter_branch ? "WHERE created_at >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)" : "WHERE branch_id = ? AND created_at >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)";
|
||||
$chart_params = !$filter_branch ? [] : [$branch_id];
|
||||
|
||||
// Daily Revenue
|
||||
$stmt = db()->prepare("SELECT DATE(created_at) as date, SUM(total_price) as revenue
|
||||
@ -68,8 +94,8 @@ if (!$is_limited) {
|
||||
$daily_revenue = $stmt->fetchAll();
|
||||
|
||||
// Orders by Status (All time or current)
|
||||
$status_where = $is_super ? "" : "WHERE branch_id = ?";
|
||||
$status_params = $is_super ? [] : [$branch_id];
|
||||
$status_where = !$filter_branch ? "" : "WHERE branch_id = ?";
|
||||
$status_params = !$filter_branch ? [] : [$branch_id];
|
||||
$stmt = db()->prepare("SELECT status, COUNT(*) as count FROM orders $status_where GROUP BY status");
|
||||
$stmt->execute($status_params);
|
||||
$orders_by_status = $stmt->fetchAll();
|
||||
@ -164,37 +190,8 @@ if (!$is_limited) {
|
||||
<div class="row g-4">
|
||||
<div class="col-md-8">
|
||||
<div class="card p-4 h-100">
|
||||
<h5 class="fw-bold mb-4"><?= __('recent_orders') ?></h5>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th><?= __('customer_name') ?></th>
|
||||
<th><?= __('total') ?></th>
|
||||
<th><?= __('status') ?></th>
|
||||
<th><?= __('payment_status') ?></th>
|
||||
<th><?= __('actions') ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach($recent_orders as $order): ?>
|
||||
<tr>
|
||||
<td><?= $order['id'] ?></td>
|
||||
<td><?= $lang === 'ar' ? ($order['customer_name_ar'] ?: $order['customer_name_en']) : $order['customer_name_en'] ?></td>
|
||||
<td><?= format_amount($order['total_price']) ?></td>
|
||||
<td><span class="badge bg-<?= getStatusColor($order['status']) ?> rounded-pill px-3 py-1"><?= __($order['status']) ?></span></td>
|
||||
<td><span class="badge badge-soft-<?= getPaymentStatusColor($order['payment_status']) ?> rounded-pill px-3 py-1"><?= __($order['payment_status']) ?></span></td>
|
||||
<td>
|
||||
<a href="order_details.php?id=<?= $order['id'] ?>" class="btn btn-sm btn-light border-0" style="border-radius: 8px;">
|
||||
<i class="bi bi-eye"></i>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<h5 class="fw-bold mb-4"><?= __('orders_per_month') ?></h5>
|
||||
<canvas id="monthlyOrdersChart" height="120"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
@ -216,62 +213,76 @@ if (!$is_limited) {
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
<script>
|
||||
// Revenue Chart
|
||||
new Chart(document.getElementById('revenueChart'), {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: <?= json_encode(array_column($daily_revenue, 'date')) ?>,
|
||||
datasets: [{
|
||||
label: '<?= __('revenue') ?>',
|
||||
data: <?= json_encode(array_column($daily_revenue, 'revenue')) ?>,
|
||||
borderColor: '#3b82f6',
|
||||
backgroundColor: 'rgba(59, 130, 246, 0.1)',
|
||||
fill: true,
|
||||
tension: 0.4
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
plugins: { legend: { display: false } },
|
||||
scales: { y: { beginAtZero: true } }
|
||||
}
|
||||
});
|
||||
if (document.getElementById('revenueChart')) {
|
||||
new Chart(document.getElementById('revenueChart'), {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: <?= json_encode(array_column($daily_revenue, 'date')) ?>,
|
||||
datasets: [{
|
||||
label: '<?= __('revenue') ?>',
|
||||
data: <?= json_encode(array_column($daily_revenue, 'revenue')) ?>,
|
||||
borderColor: '#3b82f6',
|
||||
backgroundColor: 'rgba(59, 130, 246, 0.1)',
|
||||
fill: true,
|
||||
tension: 0.4
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
plugins: { legend: { display: false } },
|
||||
scales: { y: { beginAtZero: true } }
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Status Chart
|
||||
new Chart(document.getElementById('statusChart'), {
|
||||
type: 'doughnut',
|
||||
data: {
|
||||
labels: <?= json_encode(array_map(function($s) { return __($s['status']); }, $orders_by_status)) ?>,
|
||||
datasets: [{
|
||||
data: <?= json_encode(array_column($orders_by_status, 'count')) ?>,
|
||||
backgroundColor: ['#6c757d', '#3b82f6', '#10b981', '#111827', '#ef4444']
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
plugins: { legend: { position: 'bottom' } }
|
||||
}
|
||||
});
|
||||
if (document.getElementById('statusChart')) {
|
||||
new Chart(document.getElementById('statusChart'), {
|
||||
type: 'doughnut',
|
||||
data: {
|
||||
labels: <?= json_encode(array_map(function($s) { return __($s['status']); }, $orders_by_status)) ?>,
|
||||
datasets: [{
|
||||
data: <?= json_encode(array_column($orders_by_status, 'count')) ?>,
|
||||
backgroundColor: ['#6c757d', '#3b82f6', '#10b981', '#111827', '#ef4444']
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
plugins: { legend: { position: 'bottom' } }
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Monthly Orders Chart
|
||||
if (document.getElementById('monthlyOrdersChart')) {
|
||||
new Chart(document.getElementById('monthlyOrdersChart'), {
|
||||
type: 'bar',
|
||||
data: {
|
||||
labels: <?= json_encode(array_column($monthly_orders, 'month_year')) ?>,
|
||||
datasets: [{
|
||||
label: '<?= __('orders') ?>',
|
||||
data: <?= json_encode(array_column($monthly_orders, 'count')) ?>,
|
||||
backgroundColor: '#10b981',
|
||||
borderRadius: 8
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
plugins: { legend: { display: false } },
|
||||
scales: {
|
||||
y: {
|
||||
beginAtZero: true,
|
||||
ticks: {
|
||||
stepSize: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php
|
||||
if (!$is_limited) {
|
||||
function getStatusColor($status) {
|
||||
return [
|
||||
'received' => 'secondary',
|
||||
'processing' => 'primary',
|
||||
'ready' => 'success',
|
||||
'delivered' => 'dark',
|
||||
'cancelled' => 'danger',
|
||||
][$status] ?? 'info';
|
||||
}
|
||||
function getPaymentStatusColor($status) {
|
||||
return [
|
||||
'unpaid' => 'danger',
|
||||
'partially_paid' => 'warning',
|
||||
'paid' => 'success',
|
||||
][$status] ?? 'info';
|
||||
}
|
||||
}
|
||||
require_once __DIR__ . '/includes/footer.php';
|
||||
?>
|
||||
BIN
assets/images/users/user_1_1772520504.jfif
Normal file
BIN
assets/images/users/user_1_1772520504.jfif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.7 KiB |
@ -3,37 +3,39 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
const chatInput = document.getElementById('chat-input');
|
||||
const chatMessages = document.getElementById('chat-messages');
|
||||
|
||||
const appendMessage = (text, sender) => {
|
||||
const msgDiv = document.createElement('div');
|
||||
msgDiv.classList.add('message', sender);
|
||||
msgDiv.textContent = text;
|
||||
chatMessages.appendChild(msgDiv);
|
||||
chatMessages.scrollTop = chatMessages.scrollHeight;
|
||||
};
|
||||
if (chatForm && chatInput && chatMessages) {
|
||||
const appendMessage = (text, sender) => {
|
||||
const msgDiv = document.createElement('div');
|
||||
msgDiv.classList.add('message', sender);
|
||||
msgDiv.textContent = text;
|
||||
chatMessages.appendChild(msgDiv);
|
||||
chatMessages.scrollTop = chatMessages.scrollHeight;
|
||||
};
|
||||
|
||||
chatForm.addEventListener('submit', async (e) => {
|
||||
e.preventDefault();
|
||||
const message = chatInput.value.trim();
|
||||
if (!message) return;
|
||||
chatForm.addEventListener('submit', async (e) => {
|
||||
e.preventDefault();
|
||||
const message = chatInput.value.trim();
|
||||
if (!message) return;
|
||||
|
||||
appendMessage(message, 'visitor');
|
||||
chatInput.value = '';
|
||||
appendMessage(message, 'visitor');
|
||||
chatInput.value = '';
|
||||
|
||||
try {
|
||||
const response = await fetch('api/chat.php', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ message })
|
||||
});
|
||||
const data = await response.json();
|
||||
|
||||
// Artificial delay for realism
|
||||
setTimeout(() => {
|
||||
appendMessage(data.reply, 'bot');
|
||||
}, 500);
|
||||
} catch (error) {
|
||||
console.error('Error:', error);
|
||||
appendMessage("Sorry, something went wrong. Please try again.", 'bot');
|
||||
}
|
||||
});
|
||||
});
|
||||
try {
|
||||
const response = await fetch('api/chat.php', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ message })
|
||||
});
|
||||
const data = await response.json();
|
||||
|
||||
// Artificial delay for realism
|
||||
setTimeout(() => {
|
||||
appendMessage(data.reply, 'bot');
|
||||
}, 500);
|
||||
} catch (error) {
|
||||
console.error('Error:', error);
|
||||
appendMessage("Sorry, something went wrong. Please try again.", 'bot');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -1,8 +1,81 @@
|
||||
</main>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
||||
<!-- Separate Popper and Bootstrap for maximum compatibility and debugging -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/2.11.8/umd/popper.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.3/js/bootstrap.min.js"></script>
|
||||
<script src="assets/js/main.js?v=<?php echo time(); ?>"></script>
|
||||
<script>
|
||||
// Robust dropdown initialization and diagnostic
|
||||
(function() {
|
||||
function checkDependencies() {
|
||||
console.log('--- Dependency Check ---');
|
||||
console.log('Popper.js:', typeof Popper !== 'undefined' ? 'Loaded' : 'MISSING');
|
||||
console.log('Bootstrap:', typeof bootstrap !== 'undefined' ? 'Loaded' : 'MISSING');
|
||||
if (typeof bootstrap !== 'undefined' && bootstrap.Dropdown) {
|
||||
console.log('Bootstrap Dropdown:', 'Available');
|
||||
} else {
|
||||
console.warn('Bootstrap Dropdown: NOT Available');
|
||||
}
|
||||
}
|
||||
|
||||
function initDropdowns() {
|
||||
checkDependencies();
|
||||
|
||||
if (typeof bootstrap !== 'undefined' && bootstrap.Dropdown) {
|
||||
console.log('Initializing Bootstrap Dropdowns...');
|
||||
var dropdownElementList = [].slice.call(document.querySelectorAll('.dropdown-toggle'));
|
||||
dropdownElementList.forEach(function (dropdownToggleEl) {
|
||||
try {
|
||||
// Clean up any existing instances first
|
||||
var existing = bootstrap.Dropdown.getInstance(dropdownToggleEl);
|
||||
if (existing) existing.dispose();
|
||||
|
||||
// New instance
|
||||
new bootstrap.Dropdown(dropdownToggleEl);
|
||||
} catch (err) {
|
||||
console.error('Error initializing dropdown for:', dropdownToggleEl, err);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.error('Bootstrap JS or Dropdown module not loaded!');
|
||||
// Emergency Fallback: simple manual toggle if Bootstrap fails
|
||||
document.querySelectorAll('.dropdown-toggle').forEach(function(btn) {
|
||||
btn.style.cursor = 'pointer';
|
||||
btn.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
console.log('Emergency fallback toggle triggered');
|
||||
var menu = this.nextElementSibling;
|
||||
if (menu && menu.classList.contains('dropdown-menu')) {
|
||||
var isShown = menu.classList.contains('show');
|
||||
// Close others
|
||||
document.querySelectorAll('.dropdown-menu.show').forEach(function(m) {
|
||||
m.classList.remove('show');
|
||||
});
|
||||
if (!isShown) menu.classList.add('show');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', initDropdowns);
|
||||
} else {
|
||||
initDropdowns();
|
||||
}
|
||||
|
||||
// Global click listener to close dropdowns
|
||||
document.addEventListener('click', function(e) {
|
||||
if (!e.target.closest('.dropdown')) {
|
||||
document.querySelectorAll('.dropdown-menu.show').forEach(function(menu) {
|
||||
menu.classList.remove('show');
|
||||
});
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
@ -14,17 +14,39 @@ $current_role = $_SESSION['role'] ?? 'cashier';
|
||||
|
||||
// Branch switching logic
|
||||
if (isset($_GET['switch_branch']) && $current_user_id) {
|
||||
$new_branch_id = (int)$_GET['switch_branch'];
|
||||
// Verify user has access to this branch
|
||||
$stmt = db()->prepare("SELECT b.* FROM user_branches ub JOIN branches b ON ub.branch_id = b.id WHERE ub.user_id = ? AND ub.branch_id = ?");
|
||||
$stmt->execute([$current_user_id, $new_branch_id]);
|
||||
$new_branch_id = $_GET['switch_branch'];
|
||||
|
||||
if ($new_branch_id === 'all' && $current_role === 'super_admin') {
|
||||
$_SESSION['branch_id'] = 'all';
|
||||
$_SESSION['branch_name'] = __('all_branches');
|
||||
// Redirect back to same page without the switch_branch param but keeping others
|
||||
$params = $_GET;
|
||||
unset($params['switch_branch']);
|
||||
$query = count($params) > 0 ? '?' . http_build_query($params) : '';
|
||||
$url = strtok($_SERVER["REQUEST_URI"], '?') . $query;
|
||||
header("Location: $url");
|
||||
exit;
|
||||
}
|
||||
|
||||
$new_branch_id = (int)$new_branch_id;
|
||||
// Verify user has access to this branch (or is super_admin)
|
||||
if ($current_role === 'super_admin') {
|
||||
$stmt = db()->prepare("SELECT * FROM branches WHERE id = ?");
|
||||
$stmt->execute([$new_branch_id]);
|
||||
} else {
|
||||
$stmt = db()->prepare("SELECT b.* FROM user_branches ub JOIN branches b ON ub.branch_id = b.id WHERE ub.user_id = ? AND ub.branch_id = ?");
|
||||
$stmt->execute([$current_user_id, $new_branch_id]);
|
||||
}
|
||||
$branch = $stmt->fetch();
|
||||
|
||||
if ($branch) {
|
||||
$_SESSION['branch_id'] = $branch['id'];
|
||||
$_SESSION['branch_name'] = $lang === 'ar' ? ($branch['name_ar'] ?: $branch['name_en']) : $branch['name_en'];
|
||||
// Redirect back to same page without the query param
|
||||
$url = strtok($_SERVER["REQUEST_URI"], '?');
|
||||
// Redirect back to same page without the switch_branch param but keeping others
|
||||
$params = $_GET;
|
||||
unset($params['switch_branch']);
|
||||
$query = count($params) > 0 ? '?' . http_build_query($params) : '';
|
||||
$url = strtok($_SERVER["REQUEST_URI"], '?') . $query;
|
||||
header("Location: $url");
|
||||
exit;
|
||||
}
|
||||
@ -33,9 +55,29 @@ if (isset($_GET['switch_branch']) && $current_user_id) {
|
||||
// Fetch user branches
|
||||
$user_branches = [];
|
||||
if ($current_user_id) {
|
||||
$stmt = db()->prepare("SELECT b.* FROM user_branches ub JOIN branches b ON ub.branch_id = b.id WHERE ub.user_id = ?");
|
||||
$stmt->execute([$current_user_id]);
|
||||
$user_branches = $stmt->fetchAll();
|
||||
if ($current_role === 'super_admin') {
|
||||
$user_branches = db()->query("SELECT * FROM branches")->fetchAll();
|
||||
} else {
|
||||
$stmt = db()->prepare("SELECT b.* FROM user_branches ub JOIN branches b ON ub.branch_id = b.id WHERE ub.user_id = ?");
|
||||
$stmt->execute([$current_user_id]);
|
||||
$user_branches = $stmt->fetchAll();
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure branch_name is set if not already
|
||||
if (!isset($_SESSION['branch_name']) || empty($_SESSION['branch_name'])) {
|
||||
if (isset($_SESSION['branch_id'])) {
|
||||
if ($_SESSION['branch_id'] === 'all') {
|
||||
$_SESSION['branch_name'] = __('all_branches');
|
||||
} else {
|
||||
$stmt = db()->prepare("SELECT * FROM branches WHERE id = ?");
|
||||
$stmt->execute([$_SESSION['branch_id']]);
|
||||
$b = $stmt->fetch();
|
||||
if ($b) {
|
||||
$_SESSION['branch_name'] = $lang === 'ar' ? ($b['name_ar'] ?: $b['name_en']) : $b['name_en'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch Global Company Info
|
||||
@ -54,9 +96,6 @@ if ($current_user_id) {
|
||||
$current_page = basename($_SERVER['PHP_SELF']);
|
||||
if ($current_user_id && $current_page !== 'login.php' && $current_page !== 'logout.php') {
|
||||
if (!has_permission('view', $current_page)) {
|
||||
// Allow access to admin.php if it's the dashboard and maybe it's named differently?
|
||||
// No, it's admin.php.
|
||||
// If they don't have view permission for the current page, redirect to a safe page or show error.
|
||||
if ($current_page !== 'admin.php' && has_permission('view', 'admin.php')) {
|
||||
header('Location: admin.php');
|
||||
exit;
|
||||
@ -81,8 +120,8 @@ if ($current_user_id && $current_page !== 'login.php' && $current_page !== 'logo
|
||||
<link rel="icon" type="image/x-icon" href="<?= $company_info['favicon'] ?>">
|
||||
<?php endif; ?>
|
||||
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.<?= is_rtl() ? 'rtl.' : '' ?>min.css">
|
||||
<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/bootstrap/5.3.3/css/bootstrap.<?= is_rtl() ? 'rtl.' : '' ?>min.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-icons/1.11.3/font/bootstrap-icons.min.css">
|
||||
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
@ -140,6 +179,27 @@ if ($current_user_id && $current_page !== 'login.php' && $current_page !== 'logo
|
||||
margin-right: 0.5rem;
|
||||
<?= is_rtl() ? 'margin-left: 0.5rem; margin-right: 0;' : '' ?>
|
||||
}
|
||||
.user-dropdown-btn {
|
||||
background-color: white;
|
||||
border: 1px solid #dee2e6;
|
||||
border-radius: 50rem;
|
||||
padding: 0.25rem 1rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.user-dropdown-btn:hover {
|
||||
background-color: #f8f9fa;
|
||||
border-color: #ced4da;
|
||||
}
|
||||
/* Ensure dropdowns are above everything */
|
||||
.dropdown-menu {
|
||||
z-index: 9999 !important;
|
||||
}
|
||||
.dropdown-toggle {
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@ -240,15 +300,6 @@ if ($current_user_id && $current_page !== 'login.php' && $current_page !== 'logo
|
||||
|
||||
<hr class="mx-3 my-2 text-secondary">
|
||||
|
||||
<?php if (has_permission('view', 'profile.php')): ?>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link <?= basename($_SERVER['PHP_SELF']) == 'profile.php' ? 'active' : '' ?>" href="profile.php">
|
||||
<i class="bi bi-person-circle"></i>
|
||||
<?= __('user_profile') ?>
|
||||
</a>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (has_permission('view', 'company_profile.php')): ?>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link <?= basename($_SERVER['PHP_SELF']) == 'company_profile.php' ? 'active' : '' ?>" href="company_profile.php">
|
||||
@ -274,17 +325,25 @@ if ($current_user_id && $current_page !== 'login.php' && $current_page !== 'logo
|
||||
<main class="col-md-9 ms-sm-auto col-lg-10 px-md-4 main-content">
|
||||
<header class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
|
||||
<h1 class="h2"><?= __($title ?? 'dashboard') ?></h1>
|
||||
<div class="btn-toolbar mb-2 mb-md-0">
|
||||
<div class="mb-2 mb-md-0">
|
||||
<div class="d-flex align-items-center">
|
||||
<?php if (count($user_branches) > 1): ?>
|
||||
<?php if (count($user_branches) > 1 || $current_role === 'super_admin'): ?>
|
||||
<div class="dropdown me-2">
|
||||
<button class="btn btn-sm btn-outline-primary dropdown-toggle rounded-pill px-3" type="button" data-bs-toggle="dropdown">
|
||||
<button class="btn btn-sm btn-outline-primary dropdown-toggle rounded-pill px-3" type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
<i class="bi bi-shop me-1"></i> <?= $_SESSION['branch_name'] ?? '' ?>
|
||||
</button>
|
||||
<ul class="dropdown-menu shadow border-0 mt-2">
|
||||
<?php if ($current_role === 'super_admin'): ?>
|
||||
<li>
|
||||
<a class="dropdown-item <?= ($_SESSION['branch_id'] ?? '') === 'all' ? 'active' : '' ?>" href="<?= branch_url('all') ?>">
|
||||
<?= __('all_branches') ?>
|
||||
</a>
|
||||
</li>
|
||||
<li><hr class="dropdown-divider"></li>
|
||||
<?php endif; ?>
|
||||
<?php foreach ($user_branches as $ub): ?>
|
||||
<li>
|
||||
<a class="dropdown-item <?= $ub['id'] == $_SESSION['branch_id'] ? 'active' : '' ?>" href="?switch_branch=<?= $ub['id'] ?>">
|
||||
<a class="dropdown-item <?= $ub['id'] == ($_SESSION['branch_id'] ?? '') ? 'active' : '' ?>" href="<?= branch_url($ub['id']) ?>">
|
||||
<?= $lang === 'ar' ? ($ub['name_ar'] ?: $ub['name_en']) : $ub['name_en'] ?>
|
||||
</a>
|
||||
</li>
|
||||
@ -297,17 +356,17 @@ if ($current_user_id && $current_page !== 'login.php' && $current_page !== 'logo
|
||||
|
||||
<!-- Language Switch -->
|
||||
<div class="dropdown me-2">
|
||||
<button class="btn btn-sm btn-outline-secondary dropdown-toggle rounded-pill px-3" type="button" data-bs-toggle="dropdown">
|
||||
<button class="btn btn-sm btn-outline-secondary dropdown-toggle rounded-pill px-3" type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
<i class="bi bi-translate me-1"></i> <?= $lang === 'ar' ? 'العربية' : 'English' ?>
|
||||
</button>
|
||||
<ul class="dropdown-menu shadow border-0 mt-2">
|
||||
<li>
|
||||
<a class="dropdown-item <?= $lang === 'en' ? 'active' : '' ?>" href="?lang=en">
|
||||
<a class="dropdown-item <?= $lang === 'en' ? 'active' : '' ?>" href="<?= lang_url('en') ?>">
|
||||
English
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item <?= $lang === 'ar' ? 'active' : '' ?>" href="?lang=ar">
|
||||
<a class="dropdown-item <?= $lang === 'ar' ? 'active' : '' ?>" href="<?= lang_url('ar') ?>">
|
||||
العربية
|
||||
</a>
|
||||
</li>
|
||||
@ -315,14 +374,14 @@ if ($current_user_id && $current_page !== 'login.php' && $current_page !== 'logo
|
||||
</div>
|
||||
|
||||
<div class="dropdown">
|
||||
<div class="d-flex align-items-center bg-white border rounded-pill px-3 py-1 dropdown-toggle" role="button" id="userDropdown" data-bs-toggle="dropdown" aria-expanded="false" style="cursor: pointer;">
|
||||
<button class="user-dropdown-btn dropdown-toggle" type="button" id="userDropdown" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
<?php if ($current_user_data['profile_picture'] ?? null): ?>
|
||||
<img src="<?= $current_user_data['profile_picture'] ?>" alt="Profile" class="user-avatar-sm me-2">
|
||||
<?php else: ?>
|
||||
<i class="bi bi-person-circle fs-5 me-2 text-secondary"></i>
|
||||
<?php endif; ?>
|
||||
<span class="small fw-bold"><?= $_SESSION['full_name'] ?? '' ?></span>
|
||||
</div>
|
||||
<span class="small fw-bold d-none d-sm-inline"><?= $_SESSION['full_name'] ?? '' ?></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu dropdown-menu-end shadow border-0 mt-2" aria-labelledby="userDropdown" style="border-radius: 12px;">
|
||||
<?php if (has_permission('view', 'profile.php')): ?>
|
||||
<li>
|
||||
|
||||
@ -148,7 +148,7 @@ $translations = [
|
||||
'next' => 'Next',
|
||||
'page' => 'Page',
|
||||
'of' => 'of',
|
||||
'Access Denied' => 'Access Denied',
|
||||
'Access Denied' => 'تم رفض الوصول',
|
||||
'active_orders' => 'Active Orders',
|
||||
'add_branch' => 'Add Branch',
|
||||
'add_new_branch' => 'Add New Branch',
|
||||
@ -193,7 +193,8 @@ $translations = [
|
||||
'confirm_delete_user' => 'Are you sure you want to delete this user?',
|
||||
'leave_blank_to_keep_current' => 'leave blank to keep current',
|
||||
'permissions' => 'Permissions',
|
||||
'user_permissions' => 'User Permissions'
|
||||
'user_permissions' => 'User Permissions',
|
||||
'orders_per_month' => 'Orders per Month'
|
||||
],
|
||||
'ar' => [
|
||||
'dashboard' => 'لوحة القيادة',
|
||||
@ -380,7 +381,8 @@ $translations = [
|
||||
'confirm_delete_user' => 'هل أنت متأكد من حذف هذا المستخدم؟',
|
||||
'leave_blank_to_keep_current' => 'اتركه فارغاً للاحتفاظ بكلمة المرور الحالية',
|
||||
'permissions' => 'الصلاحيات',
|
||||
'user_permissions' => 'صلاحيات المستخدم'
|
||||
'user_permissions' => 'صلاحيات المستخدم',
|
||||
'orders_per_month' => 'الطلبات شهرياً'
|
||||
]
|
||||
];
|
||||
|
||||
@ -409,4 +411,16 @@ function decimals() {
|
||||
|
||||
function format_amount($amount) {
|
||||
return number_format((float)$amount, decimals()) . ' ' . currency();
|
||||
}
|
||||
|
||||
function lang_url($new_lang) {
|
||||
$params = $_GET;
|
||||
$params['lang'] = $new_lang;
|
||||
return '?' . http_build_query($params);
|
||||
}
|
||||
|
||||
function branch_url($new_branch_id) {
|
||||
$params = $_GET;
|
||||
$params['switch_branch'] = $new_branch_id;
|
||||
return '?' . http_build_query($params);
|
||||
}
|
||||
@ -1,8 +1,9 @@
|
||||
<?php
|
||||
session_start();
|
||||
require_once __DIR__ . '/includes/lang.php';
|
||||
|
||||
if (isset($_SESSION['user_id'])) {
|
||||
header('Location: admin.php');
|
||||
} else {
|
||||
header('Location: login.php');
|
||||
}
|
||||
exit;
|
||||
exit;
|
||||
116
items.php
116
items.php
@ -202,11 +202,38 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
|
||||
$title = 'items';
|
||||
require_once __DIR__ . '/includes/header.php';
|
||||
|
||||
// Filter logic
|
||||
$search = $_GET['search'] ?? '';
|
||||
$category_filter = $_GET['category_id'] ?? '';
|
||||
|
||||
$categories = db()->query("SELECT * FROM categories ORDER BY name_en ASC")->fetchAll();
|
||||
$items = db()->query("SELECT i.*, c.name_en as cat_en, c.name_ar as cat_ar
|
||||
FROM items i
|
||||
LEFT JOIN categories c ON i.category_id = c.id
|
||||
ORDER BY i.name_en ASC")->fetchAll();
|
||||
|
||||
$query = "SELECT i.*, c.name_en as cat_en, c.name_ar as cat_ar
|
||||
FROM items i
|
||||
LEFT JOIN categories c ON i.category_id = c.id";
|
||||
$params = [];
|
||||
$where = [];
|
||||
|
||||
if ($search) {
|
||||
$where[] = "(i.name_en LIKE ? OR i.name_ar LIKE ?)";
|
||||
$params[] = "%$search%";
|
||||
$params[] = "%$search%";
|
||||
}
|
||||
|
||||
if ($category_filter) {
|
||||
$where[] = "i.category_id = ?";
|
||||
$params[] = $category_filter;
|
||||
}
|
||||
|
||||
if ($where) {
|
||||
$query .= " WHERE " . implode(" AND ", $where);
|
||||
}
|
||||
|
||||
$query .= " ORDER BY i.name_en ASC";
|
||||
$stmt = db()->prepare($query);
|
||||
$stmt->execute($params);
|
||||
$items = $stmt->fetchAll();
|
||||
|
||||
$services = db()->query("SELECT * FROM services ORDER BY name_en ASC")->fetchAll();
|
||||
|
||||
$stmt = db()->prepare("SELECT * FROM prices ");
|
||||
@ -235,6 +262,42 @@ foreach ($prices_raw as $p) {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Filter Bar -->
|
||||
<div class="card border-0 shadow-sm mb-4" style="border-radius: 20px;">
|
||||
<div class="card-body p-4">
|
||||
<form method="GET" class="row g-3 align-items-end">
|
||||
<div class="col-md-5">
|
||||
<label class="form-label fw-bold small text-muted text-uppercase mb-2"><?= __('search') ?></label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text bg-light border-0" style="border-radius: 12px 0 0 12px;">
|
||||
<i class="bi bi-search"></i>
|
||||
</span>
|
||||
<input type="text" name="search" class="form-control bg-light border-0" value="<?= htmlspecialchars($search) ?>" placeholder="<?= __('search_placeholder') ?? 'Search items...' ?>" style="border-radius: 0 12px 12px 0;">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label fw-bold small text-muted text-uppercase mb-2"><?= __('category') ?></label>
|
||||
<select name="category_id" class="form-select bg-light border-0" style="border-radius: 12px;">
|
||||
<option value=""><?= __('all') ?></option>
|
||||
<?php foreach($categories as $cat): ?>
|
||||
<option value="<?= $cat['id'] ?>" <?= $category_filter == $cat['id'] ? 'selected' : '' ?> >
|
||||
<?= $lang === 'ar' ? ($cat['name_ar'] ?: $cat['name_en']) : $cat['name_en'] ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-3 d-flex gap-2">
|
||||
<button type="submit" class="btn btn-primary flex-grow-1 fw-bold" style="border-radius: 12px; height: 45px;">
|
||||
<i class="bi bi-filter me-2"></i><?= __('submit') ?>
|
||||
</button>
|
||||
<a href="items.php" class="btn btn-light fw-bold" style="border-radius: 12px; height: 45px;">
|
||||
<i class="bi bi-x-lg"></i>
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if(isset($_GET['success'])): ?>
|
||||
<div class="alert alert-success alert-dismissible fade show rounded-4 shadow-sm mb-4 border-0" role="alert">
|
||||
<i class="bi bi-check-circle-fill me-2"></i>
|
||||
@ -263,23 +326,31 @@ foreach ($prices_raw as $p) {
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach($items as $item):
|
||||
<?php if (empty($items)): ?>
|
||||
<tr>
|
||||
<td colspan="5" class="text-center py-5">
|
||||
<i class="bi bi-box-seam display-4 text-muted mb-3 d-block"></i>
|
||||
<p class="text-muted"><?= __('no_items_found') ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<?php else: ?>
|
||||
<?php foreach($items as $item):
|
||||
?><tr>
|
||||
<td class="ps-4">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="bg-light rounded-3 me-3 d-flex align-items-center justify-content-center" style="width: 48px; height: 48px; overflow: hidden;">
|
||||
<?php if($item['image_url']):
|
||||
?><img src="<?= $item['image_url'] ?>?v=<?= time() ?>" alt="" style="width: 100%; height: 100%; object-fit: cover;">
|
||||
<?php else:
|
||||
?><i class="bi bi-image text-muted"></i>
|
||||
<?php if($item['image_url']): ?>
|
||||
<img src="<?= $item['image_url'] ?>?v=<?= time() ?>" alt="" style="width: 100%; height: 100%; object-fit: cover;">
|
||||
<?php else: ?>
|
||||
<i class="bi bi-image text-muted"></i>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div>
|
||||
<div class="fw-bold"><?= $lang === 'ar' ? ($item['name_ar'] ?: $item['name_en']) : $item['name_en'] ?></div>
|
||||
<?php if($lang === 'ar' && $item['name_ar']):
|
||||
?><small class="text-muted"><?= $item['name_en'] ?></small>
|
||||
<?php elseif($lang === 'en' && $item['name_ar']):
|
||||
?><small class="text-muted"><?= $item['name_ar'] ?></small>
|
||||
<?php if($lang === 'ar' && $item['name_ar']): ?>
|
||||
<small class="text-muted"><?= $item['name_en'] ?></small>
|
||||
<?php elseif($lang === 'en' && $item['name_ar']): ?>
|
||||
<small class="text-muted"><?= $item['name_ar'] ?></small>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
@ -296,19 +367,20 @@ foreach ($prices_raw as $p) {
|
||||
</button>
|
||||
</td>
|
||||
<td class="pe-4 text-end">
|
||||
<?php if (has_permission('edit')):
|
||||
?><button class="btn btn-sm btn-light p-2 me-1" style="border-radius: 10px;" onclick="openItemModal(<?= htmlspecialchars(json_encode($item)) ?>)">
|
||||
<i class="bi bi-pencil text-primary"></i>
|
||||
</button>
|
||||
<?php if (has_permission('edit')): ?>
|
||||
<button class="btn btn-sm btn-light p-2 me-1" style="border-radius: 10px;" onclick="openItemModal(<?= htmlspecialchars(json_encode($item)) ?>)">
|
||||
<i class="bi bi-pencil text-primary"></i>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
<?php if (has_permission('delete')):
|
||||
?><button class="btn btn-sm btn-light p-2" style="border-radius: 10px;" onclick="confirmDelete('item', <?= $item['id'] ?>)">
|
||||
<i class="bi bi-trash text-danger"></i>
|
||||
</button>
|
||||
<?php if (has_permission('delete')): ?>
|
||||
<button class="btn btn-sm btn-light p-2" style="border-radius: 10px;" onclick="confirmDelete('item', <?= $item['id'] ?>)">
|
||||
<i class="bi bi-trash text-danger"></i>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@ -769,4 +841,4 @@ document.getElementById('itemImageFile').addEventListener('change', function(e)
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php require_once __DIR__ . '/includes/footer.php'; ?>
|
||||
<?php require_once __DIR__ . '/includes/footer.php'; ?>
|
||||
|
||||
18
login.php
18
login.php
@ -49,7 +49,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
<link rel="icon" type="image/x-icon" href="<?= $company_info['favicon'] ?>">
|
||||
<?php endif; ?>
|
||||
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.<?= is_rtl() ? 'rtl.' : '' ?>min.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.3/css/bootstrap.<?= is_rtl() ? 'rtl.' : '' ?>min.css">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&family=Cairo:wght@400;600;700&display=swap" rel="stylesheet">
|
||||
@ -76,6 +76,18 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
width: auto;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
.btn-primary {
|
||||
background-color: #3b82f6;
|
||||
border-color: #3b82f6;
|
||||
}
|
||||
.btn-primary:hover {
|
||||
background-color: #2563eb;
|
||||
border-color: #2563eb;
|
||||
}
|
||||
.form-control:focus {
|
||||
border-color: #3b82f6;
|
||||
box-shadow: 0 0 0 0.25rem rgba(59, 130, 246, 0.25);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@ -106,9 +118,9 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
|
||||
<div class="text-center mt-3 pt-3 border-top">
|
||||
<div class="nav-link text-muted small">
|
||||
<a href="?lang=en" class="text-decoration-none <?= $lang === 'en' ? 'fw-bold text-primary' : '' ?>">English</a>
|
||||
<a href="<?= lang_url('en') ?>" class="text-decoration-none <?= $lang === 'en' ? 'fw-bold text-primary' : '' ?>">English</a>
|
||||
<span class="mx-2 text-secondary opacity-25">|</span>
|
||||
<a href="?lang=ar" class="text-decoration-none <?= $lang === 'ar' ? 'fw-bold text-primary' : '' ?>">العربية</a>
|
||||
<a href="<?= lang_url('ar') ?>" class="text-decoration-none <?= $lang === 'ar' ? 'fw-bold text-primary' : '' ?>">العربية</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
14
orders.php
14
orders.php
@ -3,12 +3,13 @@ $title = 'orders';
|
||||
require_once __DIR__ . '/includes/header.php';
|
||||
|
||||
$current_role = $_SESSION['role'] ?? 'cashier';
|
||||
$session_branch_id = $_SESSION['branch_id'];
|
||||
$session_branch_id = $_SESSION['branch_id'] ?? 'all';
|
||||
|
||||
// Filters
|
||||
$status_filter = $_GET['status'] ?? '';
|
||||
$payment_filter = $_GET['payment_status'] ?? '';
|
||||
$branch_filter = $_GET['branch_id'] ?? '';
|
||||
// Default to session branch if no explicit GET filter
|
||||
$branch_filter = $_GET['branch_id'] ?? $session_branch_id;
|
||||
$from_date = $_GET['from_date'] ?? '';
|
||||
$to_date = $_GET['to_date'] ?? '';
|
||||
$search = $_GET['search'] ?? '';
|
||||
@ -26,10 +27,7 @@ $sql_base = " FROM orders o
|
||||
$params = [];
|
||||
|
||||
// Branch restriction
|
||||
if ($current_role !== 'super_admin') {
|
||||
$sql_base .= " AND o.branch_id = ?";
|
||||
$params[] = $session_branch_id;
|
||||
} elseif ($branch_filter) {
|
||||
if ($branch_filter !== 'all') {
|
||||
$sql_base .= " AND o.branch_id = ?";
|
||||
$params[] = $branch_filter;
|
||||
}
|
||||
@ -98,7 +96,7 @@ if ($current_role === 'super_admin') {
|
||||
<?php if ($current_role === 'super_admin'): ?>
|
||||
<div class="col-md-2">
|
||||
<select name="branch_id" class="form-select" style="border-radius: 12px;" onchange="this.form.submit()">
|
||||
<option value=""><?= __('all_branches') ?></option>
|
||||
<option value="all"><?= __('all_branches') ?></option>
|
||||
<?php foreach($branches as $b): ?>
|
||||
<option value="<?= $b['id'] ?>" <?= $branch_filter == $b['id'] ? 'selected' : '' ?>>
|
||||
<?= $lang === 'ar' ? ($b['name_ar'] ?: $b['name_en']) : $b['name_en'] ?>
|
||||
@ -351,4 +349,4 @@ function getPaymentStatusColor($status) {
|
||||
][$status] ?? 'info';
|
||||
}
|
||||
require_once __DIR__ . '/includes/footer.php';
|
||||
?>
|
||||
?>
|
||||
@ -5,9 +5,11 @@ require_once __DIR__ . '/includes/header.php';
|
||||
// View check is already handled by header.php global check.
|
||||
// If someone needs specific action permission on reports, we could check has_permission('add') etc.
|
||||
|
||||
$session_branch_id = $_SESSION['branch_id'] ?? 'all';
|
||||
$from_date = $_GET['from_date'] ?? date('Y-m-01');
|
||||
$to_date = $_GET['to_date'] ?? date('Y-m-t');
|
||||
$branch_filter = $_GET['branch_id'] ?? 'all';
|
||||
// Default to session branch if no explicit GET filter
|
||||
$branch_filter = $_GET['branch_id'] ?? $session_branch_id;
|
||||
$user_filter = $_GET['user_id'] ?? 'all';
|
||||
|
||||
// Base queries
|
||||
@ -392,4 +394,4 @@ if ($user_filter !== 'all') {
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php require_once __DIR__ . '/includes/footer.php'; ?>
|
||||
<?php require_once __DIR__ . '/includes/footer.php'; ?>
|
||||
Loading…
x
Reference in New Issue
Block a user