add calander
This commit is contained in:
parent
2c097e9eb5
commit
9f7d3b9c16
@ -97,13 +97,13 @@ $ledger = get_ledger_paginated($search, $date_from, $date_to, $limit, $offset);
|
||||
<div class="card-body py-2">
|
||||
<form method="GET" class="row g-2 align-items-center">
|
||||
<div class="col-md-5">
|
||||
<input type="text" name="search" class="form-control form-control-sm" placeholder="بحث..." value="<?= htmlspecialchars($search) ?>">
|
||||
<input type="text" name="search" class="form-control form-control-sm" placeholder="بحث..." value="<?= htmlspecialchars($search ?? '') ?>">
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<input type="date" name="date_from" class="form-control form-control-sm" value="<?= htmlspecialchars($date_from) ?>">
|
||||
<input type="date" name="date_from" class="form-control form-control-sm" value="<?= htmlspecialchars($date_from ?? '') ?>">
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<input type="date" name="date_to" class="form-control form-control-sm" value="<?= htmlspecialchars($date_to) ?>">
|
||||
<input type="date" name="date_to" class="form-control form-control-sm" value="<?= htmlspecialchars($date_to ?? '') ?>">
|
||||
</div>
|
||||
<div class="col-md-3 text-end">
|
||||
<button type="submit" class="btn btn-sm btn-secondary"><i class="fas fa-filter"></i> تصفية</button>
|
||||
@ -144,7 +144,7 @@ $ledger = get_ledger_paginated($search, $date_from, $date_to, $limit, $offset);
|
||||
<select name="debit_account" class="form-select accountSelect" required style="width: 100%;">
|
||||
<option value="" disabled selected>اختر الحساب...</option>
|
||||
<?php foreach (get_all_accounts() as $acc): ?>
|
||||
<option value="<?= htmlspecialchars($acc['name']) ?>"><?= htmlspecialchars($acc['name']) ?></option>
|
||||
<option value="<?= htmlspecialchars($acc['name'] ?? '') ?>"><?= htmlspecialchars($acc['name'] ?? '') ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
@ -153,7 +153,7 @@ $ledger = get_ledger_paginated($search, $date_from, $date_to, $limit, $offset);
|
||||
<select name="credit_account" class="form-select accountSelect" required style="width: 100%;">
|
||||
<option value="" disabled selected>اختر الحساب...</option>
|
||||
<?php foreach (get_all_accounts() as $acc): ?>
|
||||
<option value="<?= htmlspecialchars($acc['name']) ?>"><?= htmlspecialchars($acc['name']) ?></option>
|
||||
<option value="<?= htmlspecialchars($acc['name'] ?? '') ?>"><?= htmlspecialchars($acc['name'] ?? '') ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
@ -204,7 +204,7 @@ $ledger = get_ledger_paginated($search, $date_from, $date_to, $limit, $offset);
|
||||
<select name="debit_account" id="edit_debit_account" class="form-select accountSelectEdit" required style="width: 100%;">
|
||||
<option value="" disabled>اختر الحساب...</option>
|
||||
<?php foreach (get_all_accounts() as $acc): ?>
|
||||
<option value="<?= htmlspecialchars($acc['name']) ?>"><?= htmlspecialchars($acc['name']) ?></option>
|
||||
<option value="<?= htmlspecialchars($acc['name'] ?? '') ?>"><?= htmlspecialchars($acc['name'] ?? '') ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
@ -213,7 +213,7 @@ $ledger = get_ledger_paginated($search, $date_from, $date_to, $limit, $offset);
|
||||
<select name="credit_account" id="edit_credit_account" class="form-select accountSelectEdit" required style="width: 100%;">
|
||||
<option value="" disabled>اختر الحساب...</option>
|
||||
<?php foreach (get_all_accounts() as $acc): ?>
|
||||
<option value="<?= htmlspecialchars($acc['name']) ?>"><?= htmlspecialchars($acc['name']) ?></option>
|
||||
<option value="<?= htmlspecialchars($acc['name'] ?? '') ?>"><?= htmlspecialchars($acc['name'] ?? '') ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
@ -246,20 +246,20 @@ $ledger = get_ledger_paginated($search, $date_from, $date_to, $limit, $offset);
|
||||
<?php endif; ?>
|
||||
<?php foreach ($ledger as $row): ?>
|
||||
<tr>
|
||||
<td><?= htmlspecialchars($row['date']) ?></td>
|
||||
<td><?= htmlspecialchars($row['description']) ?></td>
|
||||
<td><?= htmlspecialchars($row['reference']) ?></td>
|
||||
<td><?= htmlspecialchars($row['account_name']) ?></td>
|
||||
<td><?= htmlspecialchars($row['date'] ?? '') ?></td>
|
||||
<td><?= htmlspecialchars($row['description'] ?? '') ?></td>
|
||||
<td><?= htmlspecialchars($row['reference'] ?? '') ?></td>
|
||||
<td><?= htmlspecialchars($row['account_name'] ?? '') ?></td>
|
||||
<td><?= number_format($row['debit'], 2) ?></td>
|
||||
<td><?= number_format($row['credit'], 2) ?></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($row['created_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($row['created_by'] ?? $row['updated_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user-edit text-warning opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($row['updated_by'] ?? null)) ?></small></td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-sm btn-link text-warning p-0 me-2" title="تعديل" onclick="openEditModal(<?= $row['id'] ?>)"><i class="fas fa-edit"></i></button>
|
||||
|
||||
<form method="POST" class="d-inline delete-form">
|
||||
<input type="hidden" name="delete_entry" value="1">
|
||||
<input type="hidden" name="delete_id" value="<?= htmlspecialchars($row['id']) ?>">
|
||||
<input type="hidden" name="delete_id" value="<?= htmlspecialchars($row['id'] ?? '') ?>">
|
||||
<button type="button" class="btn btn-sm btn-link text-danger p-0 delete-btn" title="حذف">
|
||||
<i class="fas fa-trash"></i>
|
||||
</button>
|
||||
|
||||
@ -1,196 +0,0 @@
|
||||
<?php
|
||||
require_once 'db/config.php';
|
||||
require_once 'includes/header.php';
|
||||
require_once 'includes/accounting_functions.php';
|
||||
|
||||
// Check permission
|
||||
$user_id = $_SESSION['user_id'];
|
||||
$stmt = db()->prepare("SELECT * FROM user_permissions WHERE user_id = ? AND page = 'accounting' AND can_view = 1");
|
||||
$stmt->execute([$user_id]);
|
||||
if (!$stmt->fetch()) {
|
||||
echo "<div class='container mt-4' dir='rtl'>لا تملك صلاحية الوصول لهذه الصفحة.</div>";
|
||||
require_once 'includes/footer.php';
|
||||
exit;
|
||||
}
|
||||
|
||||
// Handle form submission
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_entry'])) {
|
||||
$date = $_POST["date"] ?? "";
|
||||
$description = $_POST["description"] ?? "";
|
||||
$reference = $_POST["reference"] ?? "";
|
||||
$entries = [
|
||||
["account" => $_POST["debit_account"] ?? "", "debit" => (float)($_POST["amount"] ?? 0), "credit" => 0],
|
||||
["account" => $_POST["credit_account"] ?? "", "debit" => 0, "credit" => (float)($_POST["amount"] ?? 0)]
|
||||
];
|
||||
|
||||
if (add_journal_entry($date, $description, $reference, $entries)) {
|
||||
$message = "تم إضافة القيد بنجاح.";
|
||||
} else {
|
||||
$error = "حدث خطأ أثناء إضافة القيد.";
|
||||
}
|
||||
}
|
||||
|
||||
// Pagination and Filtering setup
|
||||
$page = isset($_GET['p']) ? (int)$_GET['p'] : 1;
|
||||
$limit = 10;
|
||||
$offset = ($page - 1) * $limit;
|
||||
$search = $_GET['search'] ?? '';
|
||||
$date_from = $_GET['date_from'] ?? '';
|
||||
$date_to = $_GET['date_to'] ?? '';
|
||||
|
||||
// Fetch ledger data with filters
|
||||
$ledger_all = get_full_ledger_filtered($search, $date_from, $date_to);
|
||||
$total_items = count($ledger_all);
|
||||
$total_pages = ceil($total_items / $limit);
|
||||
$ledger = array_slice($ledger_all, $offset, $limit);
|
||||
?>
|
||||
|
||||
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
|
||||
<link href="https://cdn.jsdelivr.net/npm/select2-bootstrap-5-theme@1.3.0/dist/select2-bootstrap-5-theme.min.css" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
|
||||
<style>
|
||||
.table td, .table th { padding: 0.3rem 0.5rem; }
|
||||
.action-icon { cursor: pointer; text-decoration: none; }
|
||||
.action-icon:hover { opacity: 0.7; }
|
||||
</style>
|
||||
|
||||
<div class="container mt-4" dir="rtl">
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h2 class="text-right">المحاسبة (Accounting)</h2>
|
||||
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#journalModal">
|
||||
<i class="fas fa-plus"></i> إضافة قيد جديد
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<?php if (isset($message)) echo "<div class='alert alert-success'>$message</div>"; ?>
|
||||
<?php if (isset($error)) echo "<div class='alert alert-danger'>$error</div>"; ?>
|
||||
|
||||
<!-- Filter Form -->
|
||||
<div class="card mb-4 shadow-sm">
|
||||
<div class="card-body py-2">
|
||||
<form method="GET" class="row g-2 align-items-center">
|
||||
<div class="col-md-5">
|
||||
<input type="text" name="search" class="form-control form-control-sm" placeholder="بحث..." value="<?= htmlspecialchars($search) ?>">
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<input type="date" name="date_from" class="form-control form-control-sm" value="<?= htmlspecialchars($date_from) ?>">
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<input type="date" name="date_to" class="form-control form-control-sm" value="<?= htmlspecialchars($date_to) ?>">
|
||||
</div>
|
||||
<div class="col-md-3 text-end">
|
||||
<button type="submit" class="btn btn-sm btn-secondary"><i class="fas fa-filter"></i> تصفية</button>
|
||||
<a href="accounting.php" class="btn btn-sm btn-outline-secondary"><i class="fas fa-sync"></i></a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Journal Modal -->
|
||||
<div class="modal fade" id="journalModal" tabindex="-1" aria-labelledby="journalModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<form method="POST">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="journalModalLabel">إضافة قيد محاسبي</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<input type="hidden" name="add_entry" value="1">
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label>التاريخ</label>
|
||||
<input type="date" name="date" class="form-control" required value="<?= date('Y-m-d') ?>">
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label>المرجع</label>
|
||||
<input type="text" name="reference" class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label>الوصف</label>
|
||||
<input type="text" name="description" class="form-control" required>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4 mb-3">
|
||||
<label>حساب المدين</label>
|
||||
<select name="debit_account" class="form-select accountSelect" required style="width: 100%;">
|
||||
<?php foreach (get_all_accounts() as $acc): ?>
|
||||
<option value="<?= htmlspecialchars($acc['name']) ?>"><?= htmlspecialchars($acc['name']) ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<label>حساب الدائن</label>
|
||||
<select name="credit_account" class="form-select accountSelect" required style="width: 100%;">
|
||||
<?php foreach (get_all_accounts() as $acc): ?>
|
||||
<option value="<?= htmlspecialchars($acc['name']) ?>"><?= htmlspecialchars($acc['name']) ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<label>المبلغ</label>
|
||||
<input type="number" step="0.01" name="amount" class="form-control" required min="0.01">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">إغلاق</button>
|
||||
<button type="submit" class="btn btn-primary">حفظ القيد</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h3 class="text-right">دفتر الأستاذ (General Ledger)</h3>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover table-bordered text-right align-middle table-sm">
|
||||
<thead class="table-light"><tr><th>التاريخ</th><th>الوصف</th><th>المرجع</th><th>الحساب</th><th>مدين</th><th>دائن</th><th>الإجراءات</th></tr></thead>
|
||||
<tbody>
|
||||
<?php foreach ($ledger as $row): ?>
|
||||
<tr>
|
||||
<td><?= htmlspecialchars($row['date']) ?></td>
|
||||
<td><?= htmlspecialchars($row['description']) ?></td>
|
||||
<td><?= htmlspecialchars($row['reference']) ?></td>
|
||||
<td><?= htmlspecialchars($row['account_name']) ?></td>
|
||||
<td><?= number_format($row['debit'], 2) ?></td>
|
||||
<td><?= number_format($row['credit'], 2) ?></td>
|
||||
<td>
|
||||
<a href="#" class="action-icon text-warning me-2" title="تعديل" onclick="alert('تعديل القيد <?= $row['id'] ?>')"><i class="fas fa-edit"></i></a>
|
||||
<a href="#" class="action-icon text-danger" title="حذف" onclick="if(confirm('هل أنت متأكد؟')) alert('حذف القيد <?= $row['id'] ?>')"><i class="fas fa-trash"></i></a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<nav>
|
||||
<ul class="pagination pagination-sm justify-content-center">
|
||||
<?php for ($i = 1; $i <= $total_pages; $i++): ?>
|
||||
<li class="page-item <?= $i == $page ? 'active' : '' ?>">
|
||||
<a class="page-link" href="?p=<?= $i ?>&search=<?= urlencode($search) ?>&date_from=<?= urlencode($date_from) ?>&date_to=<?= urlencode($date_to) ?>"><?= $i ?></a>
|
||||
</li>
|
||||
<?php endfor; ?>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$('.accountSelect').select2({
|
||||
theme: 'bootstrap-5',
|
||||
dir: 'rtl',
|
||||
dropdownParent: $('#journalModal')
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php require_once 'includes/footer.php'; ?>
|
||||
@ -1,2 +0,0 @@
|
||||
<span class="my-custom-action text-warning me-2" title="تعديل" onclick='alert("تعديل القيد " + <?= json_encode($row["id"]) ?>)'><i class="fas fa-edit"></i></span>
|
||||
<span class="my-custom-action text-danger" title="حذف" onclick='if(confirm("هل أنت متأكد؟")) alert("حذف القيد " + <?= json_encode($row["id"]) ?>)'><i class="fas fa-trash"></i></span>
|
||||
@ -137,13 +137,13 @@ $typeMap = [
|
||||
<tbody>
|
||||
<?php foreach ($accounts as $account): ?>
|
||||
<tr>
|
||||
<td><?= htmlspecialchars($account['name']) ?></td>
|
||||
<td><?= htmlspecialchars($account['name'] ?? '') ?></td>
|
||||
<td>
|
||||
<span class="badge badge-info px-2 py-1" style="color: black;">
|
||||
<?= htmlspecialchars($typeMap[$account['type']] ?? $account['type']) ?>
|
||||
</span>
|
||||
</td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($account['created_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($account['created_by'] ?? $account['updated_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user-edit text-warning opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($account['updated_by'] ?? null)) ?></small></td>
|
||||
<td class="text-center">
|
||||
<button class="btn btn-warning text-white btn-sm shadow-sm mx-1" onclick="editAccount(<?= $account['id'] ?>, '<?= htmlspecialchars($account['name'], ENT_QUOTES) ?>', '<?= htmlspecialchars($account['type'], ENT_QUOTES) ?>')" title="تعديل">
|
||||
@ -190,7 +190,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
Swal.fire({
|
||||
icon: 'success',
|
||||
title: 'نجاح!',
|
||||
text: '<?= htmlspecialchars($message) ?>',
|
||||
text: '<?= htmlspecialchars($message ?? '') ?>',
|
||||
confirmButtonText: 'حسناً',
|
||||
confirmButtonColor: '#28a745',
|
||||
timer: 3000,
|
||||
|
||||
333
admin_dashboard.php
Normal file
333
admin_dashboard.php
Normal file
@ -0,0 +1,333 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/includes/header.php';
|
||||
|
||||
// Role-based routing: Admins stay here, others go to their dashboard
|
||||
if (!isAdmin()) {
|
||||
redirect('user_dashboard.php');
|
||||
}
|
||||
|
||||
$user_id = $_SESSION['user_id'];
|
||||
$is_admin = isAdmin();
|
||||
|
||||
// Stats - Total counts from separate tables
|
||||
$total_inbound = canView('inbound') ? db()->query("SELECT COUNT(*) FROM inbound_mail")->fetchColumn() : 0;
|
||||
$total_outbound = canView('outbound') ? db()->query("SELECT COUNT(*) FROM outbound_mail")->fetchColumn() : 0;
|
||||
|
||||
// Fetch statuses for badge and count
|
||||
$statuses_data = db()->query("SELECT * FROM mailbox_statuses")->fetchAll(PDO::FETCH_UNIQUE);
|
||||
|
||||
$in_progress_id = null;
|
||||
foreach ($statuses_data as $id => $s) {
|
||||
if ($s['name'] == 'in_progress') {
|
||||
$in_progress_id = $id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$in_progress_count = 0;
|
||||
if ($in_progress_id) {
|
||||
if (canView('inbound')) {
|
||||
$stmt = db()->prepare("SELECT COUNT(*) FROM inbound_mail WHERE status_id = ?");
|
||||
$stmt->execute([$in_progress_id]);
|
||||
$in_progress_count += $stmt->fetchColumn();
|
||||
}
|
||||
if (canView('outbound')) {
|
||||
$stmt = db()->prepare("SELECT COUNT(*) FROM outbound_mail WHERE status_id = ?");
|
||||
$stmt->execute([$in_progress_id]);
|
||||
$in_progress_count += $stmt->fetchColumn();
|
||||
}
|
||||
}
|
||||
|
||||
// My Assignments - Combine from all tables
|
||||
$my_assignments = [];
|
||||
$queries = [];
|
||||
if (canView('inbound')) {
|
||||
$queries[] = "SELECT id, 'inbound' as type, ref_no, subject, due_date, status_id, created_at FROM inbound_mail WHERE assigned_to = $user_id";
|
||||
}
|
||||
if (canView('outbound')) {
|
||||
$queries[] = "SELECT id, 'outbound' as type, ref_no, subject, due_date, status_id, created_at FROM outbound_mail WHERE assigned_to = $user_id";
|
||||
}
|
||||
if (canView('internal')) {
|
||||
$queries[] = "SELECT id, 'internal' as type, ref_no, subject, due_date, status_id, created_at FROM internal_mail WHERE assigned_to = $user_id";
|
||||
}
|
||||
|
||||
if (!empty($queries)) {
|
||||
$full_query = "(" . implode(") UNION ALL (", $queries) . ") ORDER BY created_at DESC LIMIT 5";
|
||||
$stmt = db()->query($full_query);
|
||||
$my_assignments = $stmt->fetchAll();
|
||||
|
||||
// Add status info to assignments
|
||||
foreach ($my_assignments as &$m) {
|
||||
$m['status_name'] = $statuses_data[$m['status_id']]['name'] ?? 'unknown';
|
||||
$m['status_color'] = $statuses_data[$m['status_id']]['color'] ?? '#6c757d';
|
||||
}
|
||||
}
|
||||
|
||||
// Recent Mail (Global for Admin/Clerk, otherwise limited)
|
||||
$recent_mail = [];
|
||||
$recent_queries = [];
|
||||
if (canView('inbound')) {
|
||||
$recent_queries[] = "SELECT m.id, 'inbound' as type, m.ref_no, m.subject, m.due_date, m.sender, m.recipient, m.status_id, m.assigned_to, m.created_by, m.date_registered, m.created_at, u.full_name as assigned_to_name
|
||||
FROM inbound_mail m LEFT JOIN users u ON m.assigned_to = u.id";
|
||||
}
|
||||
if (canView('outbound')) {
|
||||
$recent_queries[] = "SELECT m.id, 'outbound' as type, m.ref_no, m.subject, m.due_date, m.sender, m.recipient, m.status_id, m.assigned_to, m.created_by, m.date_registered, m.created_at, u.full_name as assigned_to_name
|
||||
FROM outbound_mail m LEFT JOIN users u ON m.assigned_to = u.id";
|
||||
}
|
||||
|
||||
if (!empty($recent_queries)) {
|
||||
$full_recent_query = "(" . implode(") UNION ALL (", $recent_queries) . ")";
|
||||
|
||||
if (!$is_admin && ($_SESSION['user_role'] ?? '') !== 'clerk') {
|
||||
$full_recent_query = "SELECT * FROM ($full_recent_query) AS combined WHERE assigned_to = $user_id OR created_by = $user_id ORDER BY created_at DESC LIMIT 10";
|
||||
} else {
|
||||
$full_recent_query = "SELECT * FROM ($full_recent_query) AS combined ORDER BY created_at DESC LIMIT 10";
|
||||
}
|
||||
|
||||
$stmt = db()->query($full_recent_query);
|
||||
$recent_mail = $stmt->fetchAll();
|
||||
|
||||
// Add status info
|
||||
foreach ($recent_mail as &$m) {
|
||||
$m['status_name'] = $statuses_data[$m['status_id']]['name'] ?? 'unknown';
|
||||
$m['status_color'] = $statuses_data[$m['status_id']]['color'] ?? '#6c757d';
|
||||
}
|
||||
}
|
||||
|
||||
function getStatusBadge($mail) {
|
||||
$status_name = $mail['status_name'] ?? 'غير معروف';
|
||||
$status_color = $mail['status_color'] ?? '#6c757d';
|
||||
|
||||
$display_name = $status_name;
|
||||
if ($status_name == 'received') $display_name = 'تم الاستلام';
|
||||
if ($status_name == 'in_progress') $display_name = 'قيد المعالجة';
|
||||
if ($status_name == 'closed') $display_name = 'مكتمل';
|
||||
|
||||
return '<span class="badge" style="background-color: ' . $status_color . ';">' . htmlspecialchars($display_name ?? '') . '</span>';
|
||||
}
|
||||
?>
|
||||
|
||||
<div 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">لوحة التحكم الإدارية</h1>
|
||||
<div class="btn-toolbar mb-2 mb-md-0">
|
||||
<div class="btn-group me-2">
|
||||
<?php if (canView('settings')): ?>
|
||||
<a href="charity-settings.php" class="btn btn-sm btn-outline-dark"><i class="fas fa-cog me-1"></i> الإعدادات</a>
|
||||
<?php endif; ?>
|
||||
<?php if (canAdd('inbound')): ?>
|
||||
<a href="inbound.php?action=add" class="btn btn-sm btn-outline-primary">إضافة بريد وارد</a>
|
||||
<?php endif; ?>
|
||||
<?php if (canAdd('outbound')): ?>
|
||||
<a href="outbound.php?action=add" class="btn btn-sm btn-outline-secondary">إضافة بريد صادر</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Overdue Alert -->
|
||||
<?php
|
||||
if (canView('reports')):
|
||||
// Combine overdue counts from inbound and outbound
|
||||
$overdue_count = 0;
|
||||
$overdue_count += db()->query("SELECT COUNT(*) FROM inbound_mail WHERE due_date < CURDATE() AND status_id IN (SELECT id FROM mailbox_statuses WHERE name != 'closed')")->fetchColumn();
|
||||
$overdue_count += db()->query("SELECT COUNT(*) FROM outbound_mail WHERE due_date < CURDATE() AND status_id IN (SELECT id FROM mailbox_statuses WHERE name != 'closed')")->fetchColumn();
|
||||
|
||||
if ($overdue_count > 0):
|
||||
?>
|
||||
<div class="row mb-4">
|
||||
<div class="col-12">
|
||||
<div class="alert alert-danger shadow-sm border-0 d-flex align-items-center justify-content-between mb-0">
|
||||
<div>
|
||||
<i class="fas fa-exclamation-triangle fs-4 me-3"></i>
|
||||
<span class="fw-bold">هناك <?= $overdue_count ?> مهام متأخرة تتطلب انتباهك!</span>
|
||||
</div>
|
||||
<a href="overdue_report.php" class="btn btn-danger btn-sm">عرض التقرير</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
endif;
|
||||
endif;
|
||||
?>
|
||||
|
||||
<!-- Stats Cards -->
|
||||
<div class="row g-4 mb-4">
|
||||
<?php if (canView('inbound')): ?>
|
||||
<div class="col-md-3">
|
||||
<div class="card h-100 p-3 shadow-sm border-0 border-start border-primary border-4">
|
||||
<div class="d-flex align-items-center justify-content-between">
|
||||
<div>
|
||||
<h6 class="text-muted mb-1">البريد الوارد</h6>
|
||||
<h3 class="fw-bold mb-0"><?= $total_inbound ?></h3>
|
||||
</div>
|
||||
<div class="bg-primary bg-opacity-10 p-3 rounded-circle">
|
||||
<i class="fas fa-download text-primary fs-4"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (canView('outbound')): ?>
|
||||
<div class="col-md-3">
|
||||
<div class="card h-100 p-3 shadow-sm border-0 border-start border-success border-4">
|
||||
<div class="d-flex align-items-center justify-content-between">
|
||||
<div>
|
||||
<h6 class="text-muted mb-1">البريد الصادر</h6>
|
||||
<h3 class="fw-bold mb-0"><?= $total_outbound ?></h3>
|
||||
</div>
|
||||
<div class="bg-success bg-opacity-10 p-3 rounded-circle">
|
||||
<i class="fas fa-upload text-success fs-4"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (canView('inbound') || canView('outbound')): ?>
|
||||
<div class="col-md-3">
|
||||
<div class="card h-100 p-3 shadow-sm border-0 border-start border-info border-4">
|
||||
<div class="d-flex align-items-center justify-content-between">
|
||||
<div>
|
||||
<h6 class="text-muted mb-1">قيد المعالجة</h6>
|
||||
<h3 class="fw-bold mb-0"><?= $in_progress_count ?></h3>
|
||||
</div>
|
||||
<div class="bg-info bg-opacity-10 p-3 rounded-circle">
|
||||
<i class="fas fa-clock text-info fs-4"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (canView('users')): ?>
|
||||
<div class="col-md-3">
|
||||
<div class="card h-100 p-3 shadow-sm border-0 border-start border-warning border-4">
|
||||
<div class="d-flex align-items-center justify-content-between">
|
||||
<div>
|
||||
<h6 class="text-muted mb-1">المستخدمين</h6>
|
||||
<h3 class="fw-bold mb-0"><?= db()->query("SELECT COUNT(*) FROM users")->fetchColumn() ?></h3>
|
||||
</div>
|
||||
<div class="bg-warning bg-opacity-10 p-3 rounded-circle">
|
||||
<i class="fas fa-users text-warning fs-4"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($my_assignments)): ?>
|
||||
<!-- My Assignments Section -->
|
||||
<div class="card shadow-sm border-0 mb-4 bg-primary bg-opacity-10 border-top border-primary border-3">
|
||||
<div class="card-header bg-transparent py-3 border-0">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<h5 class="mb-0 fw-bold text-primary"><i class="fas fa-tasks me-2"></i> مهامي الحالية</h5>
|
||||
<span class="badge bg-primary rounded-pill"><?= count($my_assignments) ?></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle mb-0">
|
||||
<tbody>
|
||||
<?php foreach ($my_assignments as $mail): ?>
|
||||
<tr style="cursor: pointer;" onclick="window.location='view_mail.php?id=<?= $mail['id'] ?>&type=<?= $mail['type'] ?>'">
|
||||
<td class="ps-4" width="120">
|
||||
<small class="text-muted d-block">رقم القيد</small>
|
||||
<span class="fw-bold text-primary"><?= $mail['ref_no'] ?></span>
|
||||
</td>
|
||||
<td>
|
||||
<small class="text-muted d-block">الموضوع</small>
|
||||
<span class="fw-bold"><?= htmlspecialchars($mail['subject'] ?? '') ?></span>
|
||||
</td>
|
||||
<td>
|
||||
<small class="text-muted d-block">الموعد النهائي</small>
|
||||
<?php if ($mail['due_date']): ?>
|
||||
<span class="<?= (strtotime($mail['due_date']) < time() && $mail['status_name'] != 'closed') ? 'text-danger fw-bold' : '' ?>">
|
||||
<?= $mail['due_date'] ?>
|
||||
</span>
|
||||
<?php else: ?>
|
||||
<span class="text-muted">-</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<small class="text-muted d-block mb-1">الحالة</small>
|
||||
<?= getStatusBadge($mail) ?>
|
||||
</td>
|
||||
<td class="pe-4 text-end">
|
||||
<i class="fas fa-chevron-left text-primary"></i>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($recent_mail)): ?>
|
||||
<!-- Recent Mail -->
|
||||
<div class="card shadow-sm border-0 mb-4">
|
||||
<div class="card-header bg-white py-3">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<h5 class="mb-0 fw-bold"><?= $is_admin ? 'آخر المراسلات المسجلة' : 'آخر المراسلات' ?></h5>
|
||||
<a href="inbound.php" class="btn btn-sm btn-link text-decoration-none">عرض الكل</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle mb-0">
|
||||
<thead class="bg-light">
|
||||
<tr>
|
||||
<th class="ps-4">رقم القيد</th>
|
||||
<th>النوع</th>
|
||||
<th>الموضوع</th>
|
||||
<th>الموعد النهائي</th>
|
||||
<th>المرسل/المستلم</th>
|
||||
<th>المسؤول</th>
|
||||
<th>الحالة</th>
|
||||
<th class="pe-4 text-center">التاريخ</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($recent_mail as $mail): ?>
|
||||
<tr style="cursor: pointer;" onclick="window.location='view_mail.php?id=<?= $mail['id'] ?>&type=<?= $mail['type'] ?>'">
|
||||
<td class="ps-4 fw-bold text-primary"><?= $mail['ref_no'] ?></td>
|
||||
<td>
|
||||
<?php if ($mail['type'] == 'inbound'): ?>
|
||||
<span class="text-primary"><i class="fas fa-arrow-down me-1"></i> وارد</span>
|
||||
<?php else: ?>
|
||||
<span class="text-success"><i class="fas fa-arrow-up me-1"></i> صادر</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><?= htmlspecialchars($mail['subject'] ?? '') ?></td>
|
||||
<td>
|
||||
<?php if ($mail['due_date']): ?>
|
||||
<small class="<?= (strtotime($mail['due_date']) < time() && $mail['status_name'] != 'closed') ? 'text-danger fw-bold' : 'text-muted' ?>">
|
||||
<?= $mail['due_date'] ?>
|
||||
</small>
|
||||
<?php else: ?>
|
||||
<small class="text-muted">-</small>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><?= htmlspecialchars($mail['sender'] ?: $mail['recipient']) ?></td>
|
||||
<td>
|
||||
<?php if ($mail['assigned_to_name']): ?>
|
||||
<small><i class="fas fa-user-tag me-1 text-muted"></i> <?= htmlspecialchars($mail['assigned_to_name'] ?? '') ?></small>
|
||||
<?php else: ?>
|
||||
<small class="text-muted">غير معين</small>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><?= getStatusBadge($mail) ?></td>
|
||||
<td class="pe-4 text-center"><?= date('Y-m-d', strtotime($mail['date_registered'])) ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php require_once __DIR__ . '/includes/footer.php'; ?>
|
||||
@ -4,7 +4,7 @@ require_once __DIR__ . '/m_services/MailService.php';
|
||||
|
||||
// Only users with settings view permission can access this page
|
||||
if (!canView('settings')) {
|
||||
redirect("index.php");
|
||||
redirect("user_dashboard.php");
|
||||
}
|
||||
|
||||
$success_msg = '';
|
||||
@ -76,9 +76,10 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['update_advanced'])) {
|
||||
$site_maintenance = isset($_POST['site_maintenance']) ? 1 : 0;
|
||||
$allow_registration = isset($_POST['allow_registration']) ? 1 : 0;
|
||||
$site_footer = $_POST['site_footer'];
|
||||
$site_version = $_POST['site_version'] ?? '1.3.0';
|
||||
|
||||
$stmt = db()->prepare("UPDATE charity_settings SET site_maintenance = ?, allow_registration = ?, site_footer = ? WHERE id = 1");
|
||||
$stmt->execute([$site_maintenance, $allow_registration, $site_footer]);
|
||||
$stmt = db()->prepare("UPDATE charity_settings SET site_maintenance = ?, allow_registration = ?, site_footer = ?, site_version = ? WHERE id = 1");
|
||||
$stmt->execute([$site_maintenance, $allow_registration, $site_footer, $site_version]);
|
||||
$_SESSION['success'] = 'تم تحديث الإعدادات المتقدمة بنجاح';
|
||||
}
|
||||
redirect('charity-settings.php');
|
||||
@ -403,6 +404,12 @@ $post_max = ini_get('post_max_size');
|
||||
<p class="small text-muted mb-0">تفعيل خيار "إنشاء حساب جديد" في صفحة تسجيل الدخول.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<div class="mb-3">
|
||||
<label class="form-label fw-bold">نسخة النظام (System Version)</label>
|
||||
<input type="text" name="site_version" class="form-control" value="<?= htmlspecialchars($charity['site_version'] ?? '1.3.0') ?>">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="mb-3">
|
||||
<label class="form-label fw-bold">نص تذييل الموقع (Footer Text)</label>
|
||||
@ -436,7 +443,7 @@ $post_max = ini_get('post_max_size');
|
||||
<tr>
|
||||
<td>
|
||||
<span class="badge px-3 py-2" style="background-color: <?= $status['color'] ?>;">
|
||||
<?= htmlspecialchars($status['name']) ?>
|
||||
<?= htmlspecialchars($status['name'] ?? '') ?>
|
||||
</span>
|
||||
</td>
|
||||
<td><code><?= $status['color'] ?></code></td>
|
||||
@ -485,8 +492,8 @@ $post_max = ini_get('post_max_size');
|
||||
<?php foreach ($email_logs as $log): ?>
|
||||
<tr>
|
||||
<td class="ps-3 small"><?= date('Y-m-d H:i:s', strtotime($log['created_at'])) ?></td>
|
||||
<td><span class="fw-bold"><?= htmlspecialchars($log['recipient']) ?></span></td>
|
||||
<td class="small"><?= htmlspecialchars($log['subject']) ?></td>
|
||||
<td><span class="fw-bold"><?= htmlspecialchars($log['recipient'] ?? '') ?></span></td>
|
||||
<td class="small"><?= htmlspecialchars($log['subject'] ?? '') ?></td>
|
||||
<td>
|
||||
<span class="badge bg-<?= $log['status'] === 'success' ? 'success' : 'danger' ?>">
|
||||
<?= $log['status'] === 'success' ? 'تم الإرسال' : 'فشل' ?>
|
||||
|
||||
@ -48,7 +48,17 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
}
|
||||
|
||||
// Fetch members
|
||||
$stmt = db()->query("SELECT * FROM charity_members ORDER BY name ASC");
|
||||
$search = $_GET['search'] ?? '';
|
||||
$query = "SELECT * FROM charity_members";
|
||||
$params = [];
|
||||
if (!empty($search)) {
|
||||
$query .= " WHERE name LIKE ? OR role LIKE ? OR phone LIKE ? OR email LIKE ?";
|
||||
$searchTerm = "%$search%";
|
||||
$params = [$searchTerm, $searchTerm, $searchTerm, $searchTerm];
|
||||
}
|
||||
$query .= " ORDER BY name ASC";
|
||||
$stmt = db()->prepare($query);
|
||||
$stmt->execute($params);
|
||||
$members = $stmt->fetchAll();
|
||||
?>
|
||||
|
||||
@ -68,16 +78,31 @@ $members = $stmt->fetchAll();
|
||||
|
||||
<?php if (isset($_SESSION['success'])): ?>
|
||||
<div class="alert alert-success alert-dismissible fade show" role="alert">
|
||||
<?= htmlspecialchars($_SESSION['success']) ?>
|
||||
<?= htmlspecialchars($_SESSION['success'] ?? '') ?>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
<?php unset($_SESSION['success']); ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-body">
|
||||
<div class="card-header bg-white border-0 pt-3 pb-0">
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<form method="GET" action="">
|
||||
<div class="input-group input-group-sm">
|
||||
<input type="text" name="search" class="form-control" placeholder="بحث بالاسم، الجوال، الإيميل..." value="<?= htmlspecialchars($search ?? '') ?>">
|
||||
<button class="btn btn-outline-secondary" type="submit"><i class="fas fa-search"></i></button>
|
||||
<?php if (!empty($search)): ?>
|
||||
<a href="charity_members.php" class="btn btn-outline-danger"><i class="fas fa-times"></i></a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body pt-3">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle">
|
||||
<table class="table table-sm table-hover align-middle" style="font-size: 0.9rem;">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>الاسم</th>
|
||||
@ -96,26 +121,26 @@ $members = $stmt->fetchAll();
|
||||
<tr>
|
||||
<td>
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="bg-primary bg-opacity-10 text-primary rounded-circle d-flex align-items-center justify-content-center me-3" style="width: 40px; height: 40px;">
|
||||
<div class="bg-primary bg-opacity-10 text-primary rounded-circle d-flex align-items-center justify-content-center me-3" style="width: 32px; height: 32px; font-size: 0.85rem;">
|
||||
<i class="fas fa-user"></i>
|
||||
</div>
|
||||
<div>
|
||||
<div class="fw-bold"><?= htmlspecialchars($member['name']) ?></div>
|
||||
<div class="fw-bold"><?= htmlspecialchars($member['name'] ?? '') ?></div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td><?= htmlspecialchars($member['role']) ?></td>
|
||||
<td><?= htmlspecialchars($member['phone']) ?></td>
|
||||
<td><?= htmlspecialchars($member['email']) ?></td>
|
||||
<td><?= htmlspecialchars($member['join_date']) ?></td>
|
||||
<td><?= htmlspecialchars($member['role'] ?? '') ?></td>
|
||||
<td><?= htmlspecialchars($member['phone'] ?? '') ?></td>
|
||||
<td><?= htmlspecialchars($member['email'] ?? '') ?></td>
|
||||
<td><?= htmlspecialchars($member['join_date'] ?? '') ?></td>
|
||||
<td>
|
||||
<?php if ($member['status'] === 'active'): ?>
|
||||
<span class="badge bg-success bg-opacity-10 text-success px-3 py-2 rounded-pill">نشط</span>
|
||||
<span class="badge bg-success bg-opacity-10 text-success px-2 py-1 rounded-pill">نشط</span>
|
||||
<?php else: ?>
|
||||
<span class="badge bg-secondary bg-opacity-10 text-secondary px-3 py-2 rounded-pill">غير نشط</span>
|
||||
<span class="badge bg-secondary bg-opacity-10 text-secondary px-2 py-1 rounded-pill">غير نشط</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($member['created_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($member['created_by'] ?? $member['updated_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user-edit text-warning opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($member['updated_by'] ?? null)) ?></small></td>
|
||||
<td class="text-end">
|
||||
<?php if (isAdmin() || canEdit('charity_members')): ?>
|
||||
@ -146,23 +171,23 @@ $members = $stmt->fetchAll();
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">الاسم</label>
|
||||
<input type="text" class="form-control" name="name" value="<?= htmlspecialchars($member['name']) ?>" required>
|
||||
<input type="text" class="form-control" name="name" value="<?= htmlspecialchars($member['name'] ?? '') ?>" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">الدور/الصفة في الجمعية</label>
|
||||
<input type="text" class="form-control" name="role" value="<?= htmlspecialchars($member['role']) ?>" placeholder="مثال: عضو مجلس الإدارة، مدير عام...">
|
||||
<input type="text" class="form-control" name="role" value="<?= htmlspecialchars($member['role'] ?? '') ?>" placeholder="مثال: عضو مجلس الإدارة، مدير عام...">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">رقم الجوال</label>
|
||||
<input type="text" class="form-control" name="phone" value="<?= htmlspecialchars($member['phone']) ?>">
|
||||
<input type="text" class="form-control" name="phone" value="<?= htmlspecialchars($member['phone'] ?? '') ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">البريد الإلكتروني</label>
|
||||
<input type="email" class="form-control" name="email" value="<?= htmlspecialchars($member['email']) ?>">
|
||||
<input type="email" class="form-control" name="email" value="<?= htmlspecialchars($member['email'] ?? '') ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">تاريخ الانضمام</label>
|
||||
<input type="date" class="form-control" name="join_date" value="<?= htmlspecialchars($member['join_date']) ?>">
|
||||
<input type="date" class="form-control" name="join_date" value="<?= htmlspecialchars($member['join_date'] ?? '') ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">الحالة</label>
|
||||
@ -192,7 +217,7 @@ $members = $stmt->fetchAll();
|
||||
<div class="modal-body text-center p-4">
|
||||
<i class="fas fa-exclamation-triangle text-danger fa-3x mb-3"></i>
|
||||
<h4 class="mb-3">هل أنت متأكد؟</h4>
|
||||
<p class="text-muted">هل تريد حقاً حذف العضو "<?= htmlspecialchars($member['name']) ?>"؟ لا يمكن التراجع عن هذا الإجراء وسيتم حذفه من أي لجان مرتبط بها.</p>
|
||||
<p class="text-muted">هل تريد حقاً حذف العضو "<?= htmlspecialchars($member['name'] ?? '') ?>"؟ لا يمكن التراجع عن هذا الإجراء وسيتم حذفه من أي لجان مرتبط بها.</p>
|
||||
</div>
|
||||
<div class="modal-footer justify-content-center border-0">
|
||||
<form method="POST">
|
||||
|
||||
@ -94,7 +94,7 @@ $status_labels = [
|
||||
|
||||
<?php if (isset($_SESSION['success'])): ?>
|
||||
<div class="alert alert-success alert-dismissible fade show" role="alert">
|
||||
<?= htmlspecialchars($_SESSION['success']) ?>
|
||||
<?= htmlspecialchars($_SESSION['success'] ?? '') ?>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
<?php unset($_SESSION['success']); ?>
|
||||
@ -172,8 +172,8 @@ $status_labels = [
|
||||
?>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="fw-bold"><?= htmlspecialchars($plan['title']) ?></div>
|
||||
<div class="small text-muted text-truncate" style="max-width: 250px;"><?= htmlspecialchars($plan['description']) ?></div>
|
||||
<div class="fw-bold"><?= htmlspecialchars($plan['title'] ?? '') ?></div>
|
||||
<div class="small text-muted text-truncate" style="max-width: 250px;"><?= htmlspecialchars($plan['description'] ?? '') ?></div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="small"><i class="fas fa-calendar-alt text-muted me-1"></i> من: <?= $plan['start_date'] ?></div>
|
||||
@ -192,7 +192,7 @@ $status_labels = [
|
||||
<?= $status_labels[$plan['status']] ?>
|
||||
</span>
|
||||
</td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($plan['created_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($plan['created_by'] ?? $plan['updated_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user-edit text-warning opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($plan['updated_by'] ?? null)) ?></small></td>
|
||||
<td class="text-end">
|
||||
<?php if (isAdmin() || canEdit('charity_plans')): ?>
|
||||
@ -223,11 +223,11 @@ $status_labels = [
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">العنوان</label>
|
||||
<input type="text" class="form-control" name="title" value="<?= htmlspecialchars($plan['title']) ?>" required>
|
||||
<input type="text" class="form-control" name="title" value="<?= htmlspecialchars($plan['title'] ?? '') ?>" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">الوصف</label>
|
||||
<textarea class="form-control" name="description" rows="2"><?= htmlspecialchars($plan['description']) ?></textarea>
|
||||
<textarea class="form-control" name="description" rows="2"><?= htmlspecialchars($plan['description'] ?? '') ?></textarea>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
|
||||
0
check_data.php
Normal file
0
check_data.php
Normal file
0
check_db.php
Normal file
0
check_db.php
Normal file
0
check_users.php
Normal file
0
check_users.php
Normal file
@ -185,7 +185,7 @@ usort($committees, function($a, $b) {
|
||||
<span class="text-muted fw-bold ms-2">#<?= $index + 1 ?></span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class="fw-bold fs-6"><?= htmlspecialchars($c['name']) ?></td>
|
||||
<td class="fw-bold fs-6"><?= htmlspecialchars($c['name'] ?? '') ?></td>
|
||||
<td class="text-center">
|
||||
<span class="badge bg-light text-dark border p-2 rounded-circle fs-6"><?= $c['members_count'] ?></span>
|
||||
</td>
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
require_once __DIR__ . '/includes/header.php';
|
||||
|
||||
if (!canView('committees')) {
|
||||
redirect('index.php');
|
||||
redirect('user_dashboard.php');
|
||||
}
|
||||
|
||||
$error = '';
|
||||
@ -108,10 +108,10 @@ if (isset($_SESSION['error'])) {
|
||||
<?php if (count($committees) > 0): ?>
|
||||
<?php foreach ($committees as $committee): ?>
|
||||
<tr>
|
||||
<td class="ps-4"><?= htmlspecialchars($committee['id']) ?></td>
|
||||
<td class="fw-bold"><?= htmlspecialchars($committee['name']) ?></td>
|
||||
<td class="ps-4"><?= htmlspecialchars($committee['id'] ?? '') ?></td>
|
||||
<td class="fw-bold"><?= htmlspecialchars($committee['name'] ?? '') ?></td>
|
||||
<td><?= htmlspecialchars($committee['description'] ?? '') ?></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($committee['created_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($committee['created_by'] ?? $committee['updated_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user-edit text-warning opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($committee['updated_by'] ?? null)) ?></small></td>
|
||||
<td class="text-center">
|
||||
<a href="view_committee.php?id=<?= $committee['id'] ?>" class="btn btn-sm btn-outline-info me-1" title="إدارة اللجنة"><i class="fas fa-cog"></i> إدارة</a>
|
||||
|
||||
@ -20,6 +20,14 @@ function db() {
|
||||
$pdo->exec("SET @app_user_id = " . (int)$_SESSION['user_id']);
|
||||
}
|
||||
}
|
||||
|
||||
// FORCE SET IT EVERY TIME db() IS CALLED just in case the connection was dropped or it wasn't set!
|
||||
if (isset($_SESSION['user_id']) && $pdo) {
|
||||
try {
|
||||
$pdo->exec("SET @app_user_id = " . (int)$_SESSION['user_id']);
|
||||
} catch (Exception $e) {}
|
||||
}
|
||||
|
||||
return $pdo;
|
||||
}
|
||||
|
||||
|
||||
1
db/migrations/036_add_site_version_to_settings.sql
Normal file
1
db/migrations/036_add_site_version_to_settings.sql
Normal file
@ -0,0 +1 @@
|
||||
ALTER TABLE charity_settings ADD COLUMN IF NOT EXISTS site_version varchar(50) DEFAULT '1.3.0';
|
||||
13
db/migrations/037_add_events_module.sql
Normal file
13
db/migrations/037_add_events_module.sql
Normal file
@ -0,0 +1,13 @@
|
||||
CREATE TABLE IF NOT EXISTS events (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
title VARCHAR(255) NOT NULL,
|
||||
description TEXT,
|
||||
event_date DATE NOT NULL,
|
||||
start_time TIME DEFAULT NULL,
|
||||
end_time TIME DEFAULT NULL,
|
||||
location VARCHAR(255) DEFAULT NULL,
|
||||
created_by INT,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (created_by) REFERENCES users(id) ON DELETE SET NULL
|
||||
);
|
||||
0
desc_db.php
Normal file
0
desc_db.php
Normal file
314
events.php
Normal file
314
events.php
Normal file
@ -0,0 +1,314 @@
|
||||
<?php
|
||||
require_once 'includes/header.php';
|
||||
|
||||
if (!canView('events')) {
|
||||
echo "<div class='alert alert-danger m-4'>ليس لديك صلاحية لعرض هذه الصفحة.</div>";
|
||||
require_once 'includes/footer.php';
|
||||
exit;
|
||||
}
|
||||
|
||||
$can_add = canAdd('events');
|
||||
$can_edit = canEdit('events');
|
||||
$can_delete = canDelete('events');
|
||||
|
||||
// Handle AJAX requests
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_GET['ajax'])) {
|
||||
ob_clean(); header('Content-Type: application/json');
|
||||
$action = $_POST['action'] ?? '';
|
||||
|
||||
if ($action === 'fetch') {
|
||||
$stmt = db()->query("SELECT id, title, description, event_date, start_time, end_time, location FROM events");
|
||||
$events = $stmt->fetchAll();
|
||||
$fc_events = [];
|
||||
foreach($events as $e) {
|
||||
$start = $e['event_date'];
|
||||
if ($e['start_time']) $start .= 'T' . $e['start_time'];
|
||||
|
||||
$end = $e['event_date'];
|
||||
if ($e['end_time']) $end .= 'T' . $e['end_time'];
|
||||
|
||||
$fc_events[] = [
|
||||
'id' => $e['id'],
|
||||
'title' => $e['title'],
|
||||
'start' => $start,
|
||||
'end' => $end,
|
||||
'extendedProps' => [
|
||||
'description' => $e['description'] ?? '',
|
||||
'location' => $e['location'] ?? '',
|
||||
'start_time' => $e['start_time'] ? substr($e['start_time'], 0, 5) : '',
|
||||
'end_time' => $e['end_time'] ? substr($e['end_time'], 0, 5) : ''
|
||||
]
|
||||
];
|
||||
}
|
||||
echo json_encode($fc_events);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($action === 'save' && ($can_add || $can_edit)) {
|
||||
$id = $_POST['id'] ?? 0;
|
||||
$title = $_POST['title'] ?? '';
|
||||
$date = $_POST['event_date'] ?? '';
|
||||
$start_time = !empty($_POST['start_time']) ? $_POST['start_time'] : null;
|
||||
$end_time = !empty($_POST['end_time']) ? $_POST['end_time'] : null;
|
||||
$location = $_POST['location'] ?? '';
|
||||
$description = $_POST['description'] ?? '';
|
||||
|
||||
if (!$title || !$date) {
|
||||
echo json_encode(['success' => false, 'error' => 'البيانات الأساسية مطلوبة']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($id && $can_edit) {
|
||||
$stmt = db()->prepare("UPDATE events SET title=?, description=?, event_date=?, start_time=?, end_time=?, location=? WHERE id=?");
|
||||
$stmt->execute([$title, $description, $date, $start_time, $end_time, $location, $id]);
|
||||
} elseif (!$id && $can_add) {
|
||||
$stmt = db()->prepare("INSERT INTO events (title, description, event_date, start_time, end_time, location, created_by) VALUES (?, ?, ?, ?, ?, ?, ?)");
|
||||
$stmt->execute([$title, $description, $date, $start_time, $end_time, $location, $_SESSION['user_id']]);
|
||||
}
|
||||
|
||||
echo json_encode(['success' => true]);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($action === 'delete' && $can_delete) {
|
||||
$id = $_POST['id'] ?? 0;
|
||||
db()->prepare("DELETE FROM events WHERE id=?")->execute([$id]);
|
||||
echo json_encode(['success' => true]);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<link href='https://cdn.jsdelivr.net/npm/fullcalendar@5.11.3/main.min.css' rel='stylesheet' />
|
||||
<script src='https://cdn.jsdelivr.net/npm/fullcalendar@5.11.3/main.min.js'></script>
|
||||
<script src='https://cdn.jsdelivr.net/npm/fullcalendar@5.11.3/locales/ar.js'></script>
|
||||
|
||||
<div class="container-fluid py-4">
|
||||
<div class="row mb-4 align-items-center">
|
||||
<div class="col">
|
||||
<h2 class="h4 mb-0"><i class="fas fa-calendar-alt text-primary me-2"></i> التقويم والأحداث</h2>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<a href="print_events.php" target="_blank" class="btn btn-secondary me-2">
|
||||
<i class="fas fa-print me-1"></i> طباعة الأحداث
|
||||
</a>
|
||||
<?php if ($can_add): ?>
|
||||
<button class="btn btn-primary" onclick="openEventModal()">
|
||||
<i class="fas fa-plus me-1"></i> إضافة حدث جديد
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card shadow-sm border-0">
|
||||
<div class="card-body p-4">
|
||||
<div id='calendar'></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Event Modal -->
|
||||
<div class="modal fade" id="eventModal" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="eventModalTitle">إضافة حدث</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form id="eventForm">
|
||||
<input type="hidden" id="event_id" name="id">
|
||||
<input type="hidden" name="action" value="save">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">عنوان الحدث <span class="text-danger">*</span></label>
|
||||
<input type="text" class="form-control" id="event_title" name="title" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">التاريخ <span class="text-danger">*</span></label>
|
||||
<input type="date" class="form-control" id="event_date" name="event_date" required>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<div class="col-6">
|
||||
<label class="form-label">وقت البدء</label>
|
||||
<input type="time" class="form-control" id="event_start_time" name="start_time">
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<label class="form-label">وقت الانتهاء</label>
|
||||
<input type="time" class="form-control" id="event_end_time" name="end_time">
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">المكان</label>
|
||||
<input type="text" class="form-control" id="event_location" name="location">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">التفاصيل</label>
|
||||
<textarea class="form-control" id="event_description" name="description" rows="3"></textarea>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer justify-content-between">
|
||||
<div>
|
||||
<?php if ($can_delete): ?>
|
||||
<button type="button" class="btn btn-danger d-none" id="btnDeleteEvent" onclick="deleteEvent()">حذف</button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div>
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">إلغاء</button>
|
||||
<button type="button" class="btn btn-primary" onclick="saveEvent()">حفظ</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
let calendar;
|
||||
let eventModal;
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
var calendarEl = document.getElementById('calendar');
|
||||
calendar = new FullCalendar.Calendar(calendarEl, {
|
||||
locale: 'ar',
|
||||
direction: 'rtl',
|
||||
initialView: 'dayGridMonth',
|
||||
headerToolbar: {
|
||||
left: 'prev,next today',
|
||||
center: 'title',
|
||||
right: 'dayGridMonth,timeGridWeek,timeGridDay'
|
||||
},
|
||||
events: function(info, successCallback, failureCallback) {
|
||||
let fd = new FormData();
|
||||
fd.append('action', 'fetch');
|
||||
fetch('events.php?ajax=1', {
|
||||
method: 'POST',
|
||||
body: fd
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(data => successCallback(data))
|
||||
.catch(err => failureCallback(err));
|
||||
},
|
||||
dateClick: function(info) {
|
||||
openEventModal({ date: info.dateStr });
|
||||
},
|
||||
eventClick: function(info) {
|
||||
let ev = info.event;
|
||||
let props = ev.extendedProps;
|
||||
|
||||
// Format date for <input type="date"> which expects YYYY-MM-DD
|
||||
let dateStr = ev.start.getFullYear() + '-' +
|
||||
String(ev.start.getMonth() + 1).padStart(2, '0') + '-' +
|
||||
String(ev.start.getDate()).padStart(2, '0');
|
||||
|
||||
openEventModal({
|
||||
id: ev.id,
|
||||
title: ev.title,
|
||||
date: dateStr,
|
||||
start_time: props.start_time,
|
||||
end_time: props.end_time,
|
||||
location: props.location,
|
||||
description: props.description
|
||||
});
|
||||
}
|
||||
});
|
||||
calendar.render();
|
||||
eventModal = new bootstrap.Modal(document.getElementById('eventModal'));
|
||||
});
|
||||
|
||||
function openEventModal(data = null) {
|
||||
document.getElementById('eventForm').reset();
|
||||
document.getElementById('event_id').value = '';
|
||||
document.getElementById('eventModalTitle').innerText = 'إضافة حدث جديد';
|
||||
|
||||
let btnDel = document.getElementById('btnDeleteEvent');
|
||||
if (btnDel) btnDel.classList.add('d-none');
|
||||
|
||||
if (data) {
|
||||
document.getElementById('event_id').value = data.id || '';
|
||||
document.getElementById('event_title').value = data.title || '';
|
||||
document.getElementById('event_date').value = data.date || '';
|
||||
document.getElementById('event_start_time').value = data.start_time || '';
|
||||
document.getElementById('event_end_time').value = data.end_time || '';
|
||||
document.getElementById('event_location').value = data.location || '';
|
||||
document.getElementById('event_description').value = data.description || '';
|
||||
|
||||
if (data.id) {
|
||||
document.getElementById('eventModalTitle').innerText = 'تعديل حدث';
|
||||
if (btnDel) btnDel.classList.remove('d-none');
|
||||
}
|
||||
}
|
||||
|
||||
eventModal.show();
|
||||
}
|
||||
|
||||
function saveEvent() {
|
||||
const form = document.getElementById('eventForm');
|
||||
if (!form.reportValidity()) return;
|
||||
|
||||
fetch('events.php?ajax=1', {
|
||||
method: 'POST',
|
||||
body: new FormData(form)
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(res => {
|
||||
if (res.success) {
|
||||
eventModal.hide();
|
||||
calendar.refetchEvents();
|
||||
Swal.fire({icon: 'success', title: 'تم الحفظ', showConfirmButton: false, timer: 1500});
|
||||
} else {
|
||||
Swal.fire({icon: 'error', title: 'خطأ', text: res.error || 'حدث خطأ أثناء الحفظ'});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function deleteEvent() {
|
||||
const id = document.getElementById('event_id').value;
|
||||
if (!id) return;
|
||||
|
||||
Swal.fire({
|
||||
title: 'هل أنت متأكد؟',
|
||||
text: "لن تتمكن من التراجع عن هذا!",
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: '#d33',
|
||||
cancelButtonColor: '#3085d6',
|
||||
confirmButtonText: 'نعم، احذف!',
|
||||
cancelButtonText: 'إلغاء'
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
let fd = new FormData();
|
||||
fd.append('action', 'delete');
|
||||
fd.append('id', id);
|
||||
fetch('events.php?ajax=1', {
|
||||
method: 'POST',
|
||||
body: fd
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(res => {
|
||||
if (res.success) {
|
||||
eventModal.hide();
|
||||
calendar.refetchEvents();
|
||||
Swal.fire({icon: 'success', title: 'تم الحذف', showConfirmButton: false, timer: 1500});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
/* FullCalendar customization */
|
||||
.fc-theme-standard .fc-scrollgrid { border-color: var(--bs-border-color); }
|
||||
.fc-theme-standard td, .fc-theme-standard th { border-color: var(--bs-border-color); }
|
||||
.fc .fc-button-primary { background-color: #0d6efd; border-color: #0d6efd; }
|
||||
.fc .fc-button-primary:not(:disabled):active, .fc .fc-button-primary:not(:disabled).fc-button-active {
|
||||
background-color: #0a58ca; border-color: #0a53be;
|
||||
}
|
||||
.fc-event { cursor: pointer; }
|
||||
.fc .fc-toolbar-title { font-size: 1.25em; font-weight: bold; }
|
||||
[data-bs-theme="dark"] .fc-theme-standard .fc-scrollgrid { border-color: rgba(255,255,255,0.1); }
|
||||
[data-bs-theme="dark"] .fc-theme-standard td, [data-bs-theme="dark"] .fc-theme-standard th { border-color: rgba(255,255,255,0.1); }
|
||||
[data-bs-theme="dark"] .fc-day-today { background-color: rgba(255,255,255,0.05) !important; }
|
||||
</style>
|
||||
|
||||
<?php require_once 'includes/footer.php'; ?>
|
||||
@ -2,7 +2,7 @@
|
||||
require_once __DIR__ . '/includes/header.php';
|
||||
|
||||
if (!canView('expense_settings')) {
|
||||
redirect('index.php');
|
||||
redirect('user_dashboard.php');
|
||||
}
|
||||
|
||||
$error = '';
|
||||
@ -109,16 +109,16 @@ if (isset($_SESSION['error'])) {
|
||||
<tbody>
|
||||
<?php foreach ($categories as $cat): ?>
|
||||
<tr>
|
||||
<td class="ps-4 fw-bold"><?= htmlspecialchars($cat['name']) ?></td>
|
||||
<td class="ps-4 fw-bold"><?= htmlspecialchars($cat['name'] ?? '') ?></td>
|
||||
<td>
|
||||
<?php if($cat['account_name']): ?>
|
||||
<span class="badge bg-info text-dark"><?= htmlspecialchars($cat['account_name']) ?></span>
|
||||
<span class="badge bg-info text-dark"><?= htmlspecialchars($cat['account_name'] ?? '') ?></span>
|
||||
<?php else: ?>
|
||||
<span class="text-muted text-small">غير مرتبط</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><?= htmlspecialchars($cat['description']) ?></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($cat['created_by'] ?? null)) ?></small></td>
|
||||
<td><?= htmlspecialchars($cat['description'] ?? '') ?></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($cat['created_by'] ?? $cat['updated_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user-edit text-warning opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($cat['updated_by'] ?? null)) ?></small></td>
|
||||
<td class="text-center">
|
||||
<?php if (canEdit('expense_settings')): ?>
|
||||
@ -164,7 +164,7 @@ if (isset($_SESSION['error'])) {
|
||||
<option value="">-- اختر الحساب --</option>
|
||||
<?php foreach($accounts as $acc): ?>
|
||||
<option value="<?= $acc['id'] ?>">
|
||||
<?= htmlspecialchars($acc['name']) ?> (<?= $acc['type'] ?>)
|
||||
<?= htmlspecialchars($acc['name'] ?? '') ?> (<?= $acc['type'] ?>)
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
require_once __DIR__ . '/includes/header.php';
|
||||
|
||||
if (!canView('expenses')) {
|
||||
redirect('index.php');
|
||||
redirect('user_dashboard.php');
|
||||
}
|
||||
|
||||
// Params
|
||||
@ -89,7 +89,7 @@ $categories = db()->query("SELECT * FROM expense_categories ORDER BY name")->fet
|
||||
<select name="category_id" class="form-select">
|
||||
<option value="">الكل</option>
|
||||
<?php foreach ($categories as $cat): ?>
|
||||
<option value="<?= $cat['id'] ?>" <?= $category_id == $cat['id'] ? 'selected' : '' ?>><?= htmlspecialchars($cat['name']) ?></option>
|
||||
<option value="<?= $cat['id'] ?>" <?= $category_id == $cat['id'] ? 'selected' : '' ?>><?= htmlspecialchars($cat['name'] ?? '') ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
@ -134,7 +134,7 @@ $categories = db()->query("SELECT * FROM expense_categories ORDER BY name")->fet
|
||||
<?php foreach ($category_breakdown as $name => $amount): ?>
|
||||
<div class="col-6 col-md-4">
|
||||
<div class="p-2 border rounded bg-light">
|
||||
<small class="d-block text-muted"><?= htmlspecialchars($name) ?></small>
|
||||
<small class="d-block text-muted"><?= htmlspecialchars($name ?? '') ?></small>
|
||||
<span class="fw-bold"><?= number_format($amount, 3) ?></span>
|
||||
</div>
|
||||
</div>
|
||||
@ -173,11 +173,11 @@ $categories = db()->query("SELECT * FROM expense_categories ORDER BY name")->fet
|
||||
<?php foreach ($expenses as $exp): ?>
|
||||
<tr>
|
||||
<td class="ps-3"><?= $exp['date'] ?></td>
|
||||
<td><?= htmlspecialchars($exp['category_name']) ?></td>
|
||||
<td><?= htmlspecialchars($exp['description']) ?></td>
|
||||
<td><?= htmlspecialchars($exp['category_name'] ?? '') ?></td>
|
||||
<td><?= htmlspecialchars($exp['description'] ?? '') ?></td>
|
||||
<td><?= htmlspecialchars($exp['vendor'] ?: '-') ?></td>
|
||||
<td><?= htmlspecialchars($exp['reference'] ?: '-') ?></td>
|
||||
<td><?= htmlspecialchars($exp['payment_method']) ?></td>
|
||||
<td><?= htmlspecialchars($exp['payment_method'] ?? '') ?></td>
|
||||
<td><small><?= htmlspecialchars($exp['created_by'] ?: '-') ?></small></td>
|
||||
<td class="text-end pe-3 fw-bold"><?= number_format($exp['amount'], 2) ?></td>
|
||||
</tr>
|
||||
|
||||
20
expenses.php
20
expenses.php
@ -4,7 +4,7 @@ require_once __DIR__ . '/includes/accounting_functions.php'; // Include accounti
|
||||
require_once __DIR__ . '/includes/pagination.php';
|
||||
|
||||
if (!canView('expenses')) {
|
||||
redirect('index.php');
|
||||
redirect('user_dashboard.php');
|
||||
}
|
||||
|
||||
$error = '';
|
||||
@ -254,14 +254,14 @@ if (isset($_SESSION['success'])) {
|
||||
<select name="category_id" class="form-select">
|
||||
<option value="">الكل</option>
|
||||
<?php foreach ($categories as $cat): ?>
|
||||
<option value="<?= $cat['id'] ?>" <?= $category_filter == $cat['id'] ? 'selected' : '' ?>><?= htmlspecialchars($cat['name']) ?></option>
|
||||
<option value="<?= $cat['id'] ?>" <?= $category_filter == $cat['id'] ? 'selected' : '' ?>><?= htmlspecialchars($cat['name'] ?? '') ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label">بحث</label>
|
||||
<div class="input-group">
|
||||
<input type="text" name="search" class="form-control" placeholder="وصف، مورد، مرجع..." value="<?= htmlspecialchars($search) ?>">
|
||||
<input type="text" name="search" class="form-control" placeholder="وصف، مورد، مرجع..." value="<?= htmlspecialchars($search ?? '') ?>">
|
||||
<button class="btn btn-primary" type="submit"><i class="fas fa-search"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
@ -297,21 +297,21 @@ if (isset($_SESSION['success'])) {
|
||||
<?php foreach ($expenses as $exp): ?>
|
||||
<tr>
|
||||
<td class="ps-4"><?= $exp['date'] ?></td>
|
||||
<td><span class="badge bg-secondary bg-opacity-10 text-secondary"><?= htmlspecialchars($exp['category_name']) ?></span></td>
|
||||
<td><span class="badge bg-secondary bg-opacity-10 text-secondary"><?= htmlspecialchars($exp['category_name'] ?? '') ?></span></td>
|
||||
<td>
|
||||
<?= htmlspecialchars($exp['description']) ?>
|
||||
<?= htmlspecialchars($exp['description'] ?? '') ?>
|
||||
<?php if ($exp['reference']): ?>
|
||||
<br><small class="text-muted">Ref: <?= htmlspecialchars($exp['reference']) ?></small>
|
||||
<br><small class="text-muted">Ref: <?= htmlspecialchars($exp['reference'] ?? '') ?></small>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><?= htmlspecialchars($exp['vendor'] ?: '-') ?></td>
|
||||
<td class="fw-bold text-danger"><?= number_format($exp['amount'], 2) ?></td>
|
||||
<td><?= htmlspecialchars($exp['payment_method']) ?></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($exp['created_by'] ?? null)) ?></small></td>
|
||||
<td><?= htmlspecialchars($exp['payment_method'] ?? '') ?></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($exp['created_by'] ?? $exp['updated_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user-edit text-warning opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($exp['updated_by'] ?? null)) ?></small></td>
|
||||
<td>
|
||||
<?php if ($exp['receipt_file']): ?>
|
||||
<a href="<?= htmlspecialchars($exp['receipt_file']) ?>" target="_blank" class="btn btn-sm btn-outline-secondary">
|
||||
<a href="<?= htmlspecialchars($exp['receipt_file'] ?? '') ?>" target="_blank" class="btn btn-sm btn-outline-secondary">
|
||||
<i class="fas fa-paperclip"></i>
|
||||
</a>
|
||||
<?php else: ?>
|
||||
@ -377,7 +377,7 @@ if (isset($_SESSION['success'])) {
|
||||
<select name="category_id" id="modalCategory" class="form-select" required>
|
||||
<option value="">اختر التصنيف...</option>
|
||||
<?php foreach ($categories as $cat): ?>
|
||||
<option value="<?= $cat['id'] ?>"><?= htmlspecialchars($cat['name']) ?></option>
|
||||
<option value="<?= $cat['id'] ?>"><?= htmlspecialchars($cat['name'] ?? '') ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
require_once __DIR__ . '/includes/header.php';
|
||||
|
||||
if (!canView('expenses')) {
|
||||
redirect('index.php');
|
||||
redirect('user_dashboard.php');
|
||||
}
|
||||
|
||||
// Helper to get totals
|
||||
@ -153,13 +153,13 @@ $recent_expenses = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
<?php foreach ($recent_expenses as $exp): ?>
|
||||
<tr>
|
||||
<td class="ps-4"><?= $exp['date'] ?></td>
|
||||
<td><span class="badge bg-secondary bg-opacity-10 text-secondary"><?= htmlspecialchars($exp['category_name']) ?></span></td>
|
||||
<td><span class="badge bg-secondary bg-opacity-10 text-secondary"><?= htmlspecialchars($exp['category_name'] ?? '') ?></span></td>
|
||||
<td>
|
||||
<div class="fw-bold"><?= htmlspecialchars($exp['description'] ?: '-') ?></div>
|
||||
<div class="small text-muted"><?= htmlspecialchars($exp['vendor'] ?: '') ?></div>
|
||||
</td>
|
||||
<td class="fw-bold text-danger"><?= number_format($exp['amount'], 2) ?></td>
|
||||
<td><?= htmlspecialchars($exp['payment_method']) ?></td>
|
||||
<td><?= htmlspecialchars($exp['payment_method'] ?? '') ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
|
||||
1
fix_audit.php
Normal file
1
fix_audit.php
Normal file
@ -0,0 +1 @@
|
||||
|
||||
18
fix_nulls.php
Normal file
18
fix_nulls.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
$files = ['charity_members.php', 'charity_plans.php', 'committees.php', 'expenses.php', 'accounts.php', 'accounting.php'];
|
||||
foreach ($files as $file) {
|
||||
if (file_exists($file)) {
|
||||
$content = file_get_contents($file);
|
||||
|
||||
// Use ~ as delimiter to avoid issues with /
|
||||
$pattern1 = "~htmlspecialchars\(\s*\\\$([a-zA-Z0-9_]+)\\[\'([a-zA-Z0-9_]+)\\'\]\s*\)~s";
|
||||
$pattern2 = '~htmlspecialchars\(\s*\$([a-zA-Z0-9_]+)\["([a-zA-Z0-9_]+)"\]\s*\)~s';
|
||||
|
||||
$content = preg_replace($pattern1, "htmlspecialchars(\\\\$1[\\\'\\2\\] ?? '')", $content);
|
||||
$content = preg_replace($pattern2, 'htmlspecialchars($\1["\2"] ?? "")', $content);
|
||||
|
||||
file_put_contents($file, $content);
|
||||
echo "Processed $file\n";
|
||||
}
|
||||
}
|
||||
?>
|
||||
@ -3,7 +3,7 @@ require_once __DIR__ . '/includes/header.php';
|
||||
require_once __DIR__ . '/m_services/MailService.php';
|
||||
|
||||
if (isLoggedIn()) {
|
||||
redirect('index.php');
|
||||
redirect('user_dashboard.php');
|
||||
}
|
||||
|
||||
$error = '';
|
||||
@ -92,7 +92,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
<div class="card p-4 shadow-sm border-0 text-center">
|
||||
<div class="mb-4">
|
||||
<?php if (!empty($charity_info['charity_logo'])): ?>
|
||||
<img src="<?= htmlspecialchars($charity_info['charity_logo']) ?>" alt="Logo" class="mb-3" style="max-height: 80px;">
|
||||
<img src="<?= htmlspecialchars($charity_info['charity_logo'] ?? '') ?>" alt="Logo" class="mb-3" style="max-height: 80px;">
|
||||
<?php endif; ?>
|
||||
<h4 class="fw-bold">استعادة كلمة المرور</h4>
|
||||
<p class="text-muted small">بريد <?= htmlspecialchars($charity_info['charity_name'] ?? 'النظام') ?></p>
|
||||
|
||||
@ -81,10 +81,10 @@ $records = $stmt->fetchAll();
|
||||
</div>
|
||||
|
||||
<?php if ($error): ?>
|
||||
<div class="alert alert-danger"><?= htmlspecialchars($error) ?></div>
|
||||
<div class="alert alert-danger"><?= htmlspecialchars($error ?? '') ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if ($success): ?>
|
||||
<div class="alert alert-success"><?= htmlspecialchars($success) ?></div>
|
||||
<div class="alert alert-success"><?= htmlspecialchars($success ?? '') ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="card shadow-sm border-0">
|
||||
@ -113,7 +113,7 @@ $records = $stmt->fetchAll();
|
||||
<?php foreach ($records as $row): ?>
|
||||
<tr class="<?= !$row['att_id'] ? 'table-light text-muted' : '' ?>">
|
||||
<td class="fw-bold"><?= htmlspecialchars($row['first_name'] . ' ' . $row['last_name']) ?></td>
|
||||
<td class="small"><?= htmlspecialchars($row['job_title']) ?></td>
|
||||
<td class="small"><?= htmlspecialchars($row['job_title'] ?? '') ?></td>
|
||||
<td>
|
||||
<?php if ($row['att_id']): ?>
|
||||
<?php
|
||||
@ -142,7 +142,7 @@ $records = $stmt->fetchAll();
|
||||
<td><?= $row['check_in'] ? date('h:i A', strtotime($row['check_in'])) : '-' ?></td>
|
||||
<td><?= $row['check_out'] ? date('h:i A', strtotime($row['check_out'])) : '-' ?></td>
|
||||
<td class="text-truncate" style="max-width: 150px;"><?= htmlspecialchars($row['notes'] ?? '') ?></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($row['created_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($row['created_by'] ?? $row['updated_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user-edit text-warning opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($row['updated_by'] ?? null)) ?></small></td>
|
||||
<td>
|
||||
<?php if (canEdit('hr_attendance')): ?>
|
||||
|
||||
@ -101,7 +101,7 @@ $recent_employees = db()->query("SELECT * FROM hr_employees ORDER BY join_date D
|
||||
<?php foreach ($recent_employees as $emp): ?>
|
||||
<tr>
|
||||
<td><?= htmlspecialchars($emp['first_name'] . ' ' . $emp['last_name']) ?></td>
|
||||
<td><?= htmlspecialchars($emp['job_title']) ?></td>
|
||||
<td><?= htmlspecialchars($emp['job_title'] ?? '') ?></td>
|
||||
<td><?= date('Y-m-d', strtotime($emp['join_date'])) ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
|
||||
@ -112,10 +112,10 @@ $pagination = getPagination($page, $totalEmployees, $perPage);
|
||||
</div>
|
||||
|
||||
<?php if ($error): ?>
|
||||
<div class="alert alert-danger"><?= htmlspecialchars($error) ?></div>
|
||||
<div class="alert alert-danger"><?= htmlspecialchars($error ?? '') ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if ($success): ?>
|
||||
<div class="alert alert-success"><?= htmlspecialchars($success) ?></div>
|
||||
<div class="alert alert-success"><?= htmlspecialchars($success ?? '') ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Departments Modal -->
|
||||
@ -134,7 +134,7 @@ $pagination = getPagination($page, $totalEmployees, $perPage);
|
||||
<ul class="list-group">
|
||||
<?php foreach ($departments as $dept): ?>
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||
<?= htmlspecialchars($dept['name']) ?>
|
||||
<?= htmlspecialchars($dept['name'] ?? '') ?>
|
||||
<form method="post" onsubmit="return confirm('هل أنت متأكد؟');">
|
||||
<input type="hidden" name="id" value="<?= $dept['id'] ?>">
|
||||
<button type="submit" name="delete_department" class="btn btn-sm btn-danger"><i class="fas fa-trash"></i></button>
|
||||
@ -204,7 +204,7 @@ $pagination = getPagination($page, $totalEmployees, $perPage);
|
||||
<select name="department_id" id="empDept" class="form-select">
|
||||
<option value="">-- اختر القسم --</option>
|
||||
<?php foreach ($departments as $dept): ?>
|
||||
<option value="<?= $dept['id'] ?>"><?= htmlspecialchars($dept['name']) ?></option>
|
||||
<option value="<?= $dept['id'] ?>"><?= htmlspecialchars($dept['name'] ?? '') ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
@ -285,12 +285,12 @@ $pagination = getPagination($page, $totalEmployees, $perPage);
|
||||
</div>
|
||||
<div>
|
||||
<div class="fw-bold"><?= htmlspecialchars($row['first_name'] . ' ' . $row['last_name']) ?></div>
|
||||
<div class="small text-muted"><?= htmlspecialchars($row['email']) ?></div>
|
||||
<div class="small text-muted"><?= htmlspecialchars($row['email'] ?? '') ?></div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td><span class="badge bg-secondary"><?= htmlspecialchars($row['dept_name'] ?? '-') ?></span></td>
|
||||
<td><?= htmlspecialchars($row['job_title']) ?></td>
|
||||
<td><?= htmlspecialchars($row['job_title'] ?? '') ?></td>
|
||||
<td><?= $row['join_date'] ?></td>
|
||||
<td>
|
||||
<?php
|
||||
@ -302,10 +302,10 @@ $pagination = getPagination($page, $totalEmployees, $perPage);
|
||||
default => 'secondary'
|
||||
};
|
||||
?>
|
||||
<span class="badge bg-<?= $status_cls ?>"><?= htmlspecialchars($row['status']) ?></span>
|
||||
<span class="badge bg-<?= $status_cls ?>"><?= htmlspecialchars($row['status'] ?? '') ?></span>
|
||||
</td>
|
||||
<td><span class="badge bg-light text-dark border"><?= htmlspecialchars($row['zkteco_uid'] ?: '-') ?></span></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($emp['created_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($emp['created_by'] ?? $emp['updated_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user-edit text-warning opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($emp['updated_by'] ?? null)) ?></small></td>
|
||||
<td>
|
||||
<div class="btn-group">
|
||||
@ -314,14 +314,14 @@ $pagination = getPagination($page, $totalEmployees, $perPage);
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#employeeModal"
|
||||
data-id="<?= $row['id'] ?>"
|
||||
data-fname="<?= htmlspecialchars($row['first_name']) ?>"
|
||||
data-lname="<?= htmlspecialchars($row['last_name']) ?>"
|
||||
data-email="<?= htmlspecialchars($row['email']) ?>"
|
||||
data-phone="<?= htmlspecialchars($row['phone']) ?>"
|
||||
data-fname="<?= htmlspecialchars($row['first_name'] ?? '') ?>"
|
||||
data-lname="<?= htmlspecialchars($row['last_name'] ?? '') ?>"
|
||||
data-email="<?= htmlspecialchars($row['email'] ?? '') ?>"
|
||||
data-phone="<?= htmlspecialchars($row['phone'] ?? '') ?>"
|
||||
data-gender="<?= $row['gender'] ?>"
|
||||
data-bdate="<?= $row['birth_date'] ?>"
|
||||
data-dept="<?= $row['department_id'] ?>"
|
||||
data-job="<?= htmlspecialchars($row['job_title']) ?>"
|
||||
data-job="<?= htmlspecialchars($row['job_title'] ?? '') ?>"
|
||||
data-join="<?= $row['join_date'] ?>"
|
||||
data-salary="<?= $row['basic_salary'] ?>"
|
||||
data-status="<?= $row['status'] ?>" data-user="<?= $row['user_id'] ?>"
|
||||
|
||||
@ -59,10 +59,10 @@ $holidays = db()->query("SELECT * FROM hr_holidays ORDER BY date_from DESC")->fe
|
||||
</div>
|
||||
|
||||
<?php if ($error): ?>
|
||||
<div class="alert alert-danger"><?= htmlspecialchars($error) ?></div>
|
||||
<div class="alert alert-danger"><?= htmlspecialchars($error ?? '') ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if ($success): ?>
|
||||
<div class="alert alert-success"><?= htmlspecialchars($success) ?></div>
|
||||
<div class="alert alert-success"><?= htmlspecialchars($success ?? '') ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="card shadow-sm">
|
||||
@ -98,11 +98,11 @@ $holidays = db()->query("SELECT * FROM hr_holidays ORDER BY date_from DESC")->fe
|
||||
}
|
||||
?>
|
||||
<tr>
|
||||
<td class="fw-bold"><?= htmlspecialchars($row['name']) ?></td>
|
||||
<td class="fw-bold"><?= htmlspecialchars($row['name'] ?? '') ?></td>
|
||||
<td><?= $row['date_from'] ?></td>
|
||||
<td><?= $row['date_to'] ?></td>
|
||||
<td><span class="badge bg-<?= $status_cls ?>"><?= $status_txt ?></span></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($row['created_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($row['created_by'] ?? $row['updated_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user-edit text-warning opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($row['updated_by'] ?? null)) ?></small></td>
|
||||
<td>
|
||||
<?php if (canEdit('hr_attendance')): ?>
|
||||
@ -110,7 +110,7 @@ $holidays = db()->query("SELECT * FROM hr_holidays ORDER BY date_from DESC")->fe
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#holidayModal"
|
||||
data-id="<?= $row['id'] ?>"
|
||||
data-name="<?= htmlspecialchars($row['name']) ?>"
|
||||
data-name="<?= htmlspecialchars($row['name'] ?? '') ?>"
|
||||
data-from="<?= $row['date_from'] ?>"
|
||||
data-to="<?= $row['date_to'] ?>"
|
||||
onclick="editHoliday(this)">
|
||||
|
||||
@ -134,10 +134,10 @@ $requests = $stmt->fetchAll();
|
||||
</div>
|
||||
|
||||
<?php if ($error): ?>
|
||||
<div class="alert alert-danger"><?= htmlspecialchars($error) ?></div>
|
||||
<div class="alert alert-danger"><?= htmlspecialchars($error ?? '') ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if ($success): ?>
|
||||
<div class="alert alert-success"><?= htmlspecialchars($success) ?></div>
|
||||
<div class="alert alert-success"><?= htmlspecialchars($success ?? '') ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<ul class="nav nav-tabs mb-4">
|
||||
@ -153,10 +153,10 @@ $requests = $stmt->fetchAll();
|
||||
<div class="card shadow-sm mb-4">
|
||||
<div class="card-body">
|
||||
<form method="GET" class="row g-3 align-items-center">
|
||||
<input type="hidden" name="tab" value="<?= htmlspecialchars($tab) ?>">
|
||||
<input type="hidden" name="tab" value="<?= htmlspecialchars($tab ?? '') ?>">
|
||||
|
||||
<div class="col-md-4">
|
||||
<input type="text" name="search" class="form-control" placeholder="بحث باسم الموظف أو السبب..." value="<?= htmlspecialchars($search) ?>">
|
||||
<input type="text" name="search" class="form-control" placeholder="بحث باسم الموظف أو السبب..." value="<?= htmlspecialchars($search ?? '') ?>">
|
||||
</div>
|
||||
|
||||
<div class="col-md-3">
|
||||
@ -185,7 +185,7 @@ $requests = $stmt->fetchAll();
|
||||
<div class="col-md-2 d-flex gap-2">
|
||||
<button type="submit" class="btn btn-primary flex-grow-1"><i class="fas fa-search"></i> بحث</button>
|
||||
<?php if ($search || $filter_type || $filter_status): ?>
|
||||
<a href="?tab=<?= htmlspecialchars($tab) ?>" class="btn btn-outline-secondary">إلغاء</a>
|
||||
<a href="?tab=<?= htmlspecialchars($tab ?? '') ?>" class="btn btn-outline-secondary">إلغاء</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</form>
|
||||
@ -234,7 +234,7 @@ $requests = $stmt->fetchAll();
|
||||
من <?= $req['start_date'] ?><br>إلى <?= $req['end_date'] ?>
|
||||
</td>
|
||||
<td><?= $req['days_count'] ?> يوم</td>
|
||||
<td class="text-truncate" style="max-width: 150px;"><?= htmlspecialchars($req['reason']) ?></td>
|
||||
<td class="text-truncate" style="max-width: 150px;"><?= htmlspecialchars($req['reason'] ?? '') ?></td>
|
||||
<td>
|
||||
<?php
|
||||
$status_cls = match($req['status']) {
|
||||
@ -253,7 +253,7 @@ $requests = $stmt->fetchAll();
|
||||
<?php if ($tab === 'all'): ?>
|
||||
<td class="small"><?= htmlspecialchars($req['approver_name'] ?? '-') ?></td>
|
||||
<?php endif; ?>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($req['created_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($req['created_by'] ?? $req['updated_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user-edit text-warning opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($req['updated_by'] ?? null)) ?></small></td>
|
||||
<td>
|
||||
<?php if ($req['status'] === 'pending' && canEdit('hr_leaves')): ?>
|
||||
@ -266,7 +266,7 @@ $requests = $stmt->fetchAll();
|
||||
data-type="<?= $req['leave_type'] ?>"
|
||||
data-start="<?= $req['start_date'] ?>"
|
||||
data-end="<?= $req['end_date'] ?>"
|
||||
data-reason="<?= htmlspecialchars($req['reason']) ?>"
|
||||
data-reason="<?= htmlspecialchars($req['reason'] ?? '') ?>"
|
||||
onclick="editLeave(this)">
|
||||
<i class="fas fa-edit"></i>
|
||||
</button>
|
||||
|
||||
@ -175,10 +175,10 @@ $total_salaries = $sumStmt->fetchColumn() ?: 0;
|
||||
</div>
|
||||
|
||||
<?php if ($error): ?>
|
||||
<div class="alert alert-danger"><?= htmlspecialchars($error) ?></div>
|
||||
<div class="alert alert-danger"><?= htmlspecialchars($error ?? '') ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if ($success): ?>
|
||||
<div class="alert alert-success"><?= htmlspecialchars($success) ?></div>
|
||||
<div class="alert alert-success"><?= htmlspecialchars($success ?? '') ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="row mb-3">
|
||||
@ -217,7 +217,7 @@ $total_salaries = $sumStmt->fetchColumn() ?: 0;
|
||||
<tr>
|
||||
<td>
|
||||
<div class="fw-bold"><?= htmlspecialchars($row['first_name'] . ' ' . $row['last_name']) ?></div>
|
||||
<div class="small text-muted"><?= htmlspecialchars($row['job_title']) ?></div>
|
||||
<div class="small text-muted"><?= htmlspecialchars($row['job_title'] ?? '') ?></div>
|
||||
</td>
|
||||
<td><?= number_format($row['basic_salary'], 2) ?></td>
|
||||
<td class="text-success"><?= number_format($row['bonuses'], 2) ?></td>
|
||||
@ -231,7 +231,7 @@ $total_salaries = $sumStmt->fetchColumn() ?: 0;
|
||||
<span class="badge bg-info text-dark" title="مرحل للمحاسبة"><i class="fas fa-check-circle"></i></span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($row['created_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($row['created_by'] ?? $row['updated_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user-edit text-warning opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($row['updated_by'] ?? null)) ?></small></td>
|
||||
<td>
|
||||
<?php if (canEdit('hr_payroll')): ?>
|
||||
@ -239,7 +239,7 @@ $total_salaries = $sumStmt->fetchColumn() ?: 0;
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#editPayModal"
|
||||
data-id="<?= $row['id'] ?>"
|
||||
data-name="<?= htmlspecialchars($row['first_name']) ?>"
|
||||
data-name="<?= htmlspecialchars($row['first_name'] ?? '') ?>"
|
||||
data-bonus="<?= $row['bonuses'] ?>"
|
||||
data-deduct="<?= $row['deductions'] ?>"
|
||||
data-status="<?= $row['status'] ?>">
|
||||
|
||||
@ -146,10 +146,10 @@ $year = $_GET['year'] ?? date('Y');
|
||||
<td>#<?= $emp['id'] ?></td>
|
||||
<td><?= htmlspecialchars($emp['first_name'] . ' ' . $emp['last_name']) ?></td>
|
||||
<td><?= htmlspecialchars($emp['dept_name'] ?? '-') ?></td>
|
||||
<td><?= htmlspecialchars($emp['job_title']) ?></td>
|
||||
<td><?= htmlspecialchars($emp['job_title'] ?? '') ?></td>
|
||||
<td><?= $emp['join_date'] ?></td>
|
||||
<td><?= number_format($emp['basic_salary'], 2) ?></td>
|
||||
<td><?= htmlspecialchars($emp['phone']) ?></td>
|
||||
<td><?= htmlspecialchars($emp['phone'] ?? '') ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
|
||||
@ -149,14 +149,14 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
|
||||
<?php if ($error): ?>
|
||||
<div class="alert alert-danger shadow-sm border-0 border-start border-danger border-4 alert-dismissible fade show" role="alert">
|
||||
<i class="fas fa-exclamation-circle me-2"></i> <?= htmlspecialchars($error) ?>
|
||||
<i class="fas fa-exclamation-circle me-2"></i> <?= htmlspecialchars($error ?? '') ?>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($success): ?>
|
||||
<div class="alert alert-success shadow-sm border-0 border-start border-success border-4 alert-dismissible fade show" role="alert">
|
||||
<i class="fas fa-check-circle me-2"></i> <?= htmlspecialchars($success) ?>
|
||||
<i class="fas fa-check-circle me-2"></i> <?= htmlspecialchars($success ?? '') ?>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
@ -193,11 +193,11 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
<form method="POST" action="">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">IP Address (عنوان الجهاز)</label>
|
||||
<input type="text" class="form-control" name="ip_address" value="<?= htmlspecialchars($ip) ?>" required placeholder="مثال: 192.168.1.201">
|
||||
<input type="text" class="form-control" name="ip_address" value="<?= htmlspecialchars($ip ?? '') ?>" required placeholder="مثال: 192.168.1.201">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Port (المنفذ)</label>
|
||||
<input type="number" class="form-control" name="port" value="<?= htmlspecialchars($port) ?>" required placeholder="الافتراضي: 4370">
|
||||
<input type="number" class="form-control" name="port" value="<?= htmlspecialchars($port ?? '') ?>" required placeholder="الافتراضي: 4370">
|
||||
</div>
|
||||
<div class="d-grid gap-2 d-md-flex justify-content-md-start">
|
||||
<button type="submit" name="save_settings" class="btn btn-primary"><i class="fas fa-save me-1"></i> حفظ الإعدادات</button>
|
||||
|
||||
10
inbound.php
10
inbound.php
@ -253,20 +253,20 @@ if (isset($_GET['id'])) {
|
||||
<?php endif; ?>
|
||||
<?php foreach ($mails as $mail): ?>
|
||||
<tr>
|
||||
<td class="ps-4"><span class="fw-bold text-primary"><?= htmlspecialchars($mail['ref_no']) ?></span></td>
|
||||
<td class="ps-4"><span class="fw-bold text-primary"><?= htmlspecialchars($mail['ref_no'] ?? '') ?></span></td>
|
||||
<td><?= date('Y-m-d', strtotime($mail['date_registered'])) ?></td>
|
||||
<td>
|
||||
<div class="fw-semibold text-truncate" style="max-width: 250px;"><?= htmlspecialchars($mail['subject']) ?></div>
|
||||
<div class="fw-semibold text-truncate" style="max-width: 250px;"><?= htmlspecialchars($mail['subject'] ?? '') ?></div>
|
||||
<?php if ($mail['attachment_names']): ?>
|
||||
<span class="badge bg-light text-muted fw-normal" style="font-size: 0.65rem;">
|
||||
<i class="fas fa-paperclip me-1"></i> <?= count(explode('|||', $mail['attachment_names'])) ?> مرفقات
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><?= htmlspecialchars($mail['sender']) ?></td>
|
||||
<td><?= htmlspecialchars($mail['sender'] ?? '') ?></td>
|
||||
<td>
|
||||
<span class="badge rounded-pill" style="background-color: <?= $mail['status_color'] ?>20; color: <?= $mail['status_color'] ?>;">
|
||||
<i class="fas fa-circle me-1 small"></i> <?= htmlspecialchars($mail['status_name']) ?>
|
||||
<i class="fas fa-circle me-1 small"></i> <?= htmlspecialchars($mail['status_name'] ?? '') ?>
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
@ -277,7 +277,7 @@ if (isset($_GET['id'])) {
|
||||
<span class="small"><?= htmlspecialchars($mail['assigned_to_name'] ?: 'غير محدد') ?></span>
|
||||
</div>
|
||||
</td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($mail['created_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($mail['created_by'] ?? $mail['updated_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user-edit text-warning opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($mail['updated_by'] ?? null)) ?></small></td>
|
||||
<td class="text-center pe-4">
|
||||
<div class="btn-group shadow-sm rounded">
|
||||
|
||||
@ -1,21 +1,22 @@
|
||||
<?php if (isLoggedIn()): ?>
|
||||
<?php if (isLoggedIn() && empty($hide_layout)): ?>
|
||||
</main><!-- Close main-content -->
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (empty($hide_layout)): ?>
|
||||
<footer class="footer mt-auto py-4 bg-white border-top">
|
||||
<div class="container-fluid px-md-4 text-center">
|
||||
<div class="d-flex flex-column align-items-center">
|
||||
<?php if (!empty($sys_settings['site_footer'])): ?>
|
||||
<div class="mb-3 text-secondary" style="max-width: 800px; line-height: 1.6;">
|
||||
<?= nl2br(htmlspecialchars($sys_settings['site_footer'])) ?>
|
||||
<?= nl2br(htmlspecialchars($sys_settings['site_footer'] ?? '')) ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<span class="text-muted small mb-1">
|
||||
© <?= date('Y') ?> <?= htmlspecialchars($sys_settings['site_name']) ?>. جميع الحقوق محفوظة.
|
||||
© <?= date('Y') ?> <?= htmlspecialchars($sys_settings['site_name'] ?? '') ?>. جميع الحقوق محفوظة.
|
||||
</span>
|
||||
<div class="d-flex align-items-center gap-3">
|
||||
<span class="badge bg-secondary opacity-50 fw-normal" style="font-size: 0.65rem;">نسخة النظام 1.3.0</span>
|
||||
<span class="badge bg-secondary opacity-50 fw-normal" style="font-size: 0.65rem;">نسخة النظام <?= htmlspecialchars($sys_settings['site_version'] ?? '1.3.0') ?></span>
|
||||
<?php if (isAdmin()): ?>
|
||||
<a href="charity-settings.php" onclick="localStorage.setItem('activeSettingsTab', '#general');" class="text-muted text-decoration-none small hover-primary border-start ps-3">
|
||||
<i class="fas fa-cog me-1"></i> الإعدادات
|
||||
@ -28,6 +29,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
<?php endif; ?>
|
||||
|
||||
<style>
|
||||
.hover-primary:hover {
|
||||
|
||||
@ -51,7 +51,7 @@ if (isLoggedIn()) {
|
||||
}
|
||||
|
||||
// Auth Check (after fetch to ensure session is updated)
|
||||
if (!isLoggedIn() && basename($_SERVER['PHP_SELF']) !== 'login.php' && basename($_SERVER['PHP_SELF']) !== 'forgot_password.php' && basename($_SERVER['PHP_SELF']) !== 'install.php') {
|
||||
if (!isLoggedIn() && basename($_SERVER['PHP_SELF']) !== 'login.php' && basename($_SERVER['PHP_SELF']) !== 'forgot_password.php' && basename($_SERVER['PHP_SELF']) !== 'install.php' && basename($_SERVER['PHP_SELF']) !== 'index.php') {
|
||||
redirect('login.php');
|
||||
}
|
||||
|
||||
@ -77,10 +77,13 @@ $committees_pages = ["committees.php", "view_committee.php", "committee_reports.
|
||||
$is_committees_open = in_array($cp, $committees_pages);
|
||||
|
||||
|
||||
$events_pages = ['events.php'];
|
||||
$is_events_open = in_array($cp, $events_pages);
|
||||
|
||||
$meetings_pages = ['meetings.php'];
|
||||
$is_meetings_open = in_array($cp, $meetings_pages);
|
||||
|
||||
$admin_pages = ['index.php', 'users.php', 'charity-settings.php', 'charity_members.php', 'charity_plans.php'];
|
||||
$admin_pages = ['admin_dashboard.php', 'users.php', 'charity-settings.php', 'charity_members.php', 'charity_plans.php'];
|
||||
$is_admin_open = in_array($cp, $admin_pages);
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
@ -88,7 +91,7 @@ $is_admin_open = in_array($cp, $admin_pages);
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title><?= htmlspecialchars($sys_settings['site_name']) ?></title>
|
||||
<title><?= htmlspecialchars($sys_settings['site_name'] ?? '') ?></title>
|
||||
|
||||
<!-- Bootstrap 5 RTL -->
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.rtl.min.css">
|
||||
@ -199,7 +202,7 @@ $is_admin_open = in_array($cp, $admin_pages);
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<?php if (isLoggedIn()): ?>
|
||||
<?php if (isLoggedIn() && empty($hide_layout)): ?>
|
||||
<!-- Sidebar -->
|
||||
<div class="sidebar d-flex flex-column" id="sidebar">
|
||||
<div class="p-3 text-center border-bottom border-secondary">
|
||||
@ -207,7 +210,7 @@ $is_admin_open = in_array($cp, $admin_pages);
|
||||
<?php if (!empty($sys_settings['site_logo'])): ?>
|
||||
<img src="<?= $sys_settings['site_logo'] ?>" alt="Logo" class="img-fluid mb-2" style="max-height: 50px;">
|
||||
<?php endif; ?>
|
||||
<h5 class="mb-0 fw-bold"><?= htmlspecialchars($sys_settings['site_name']) ?></h5>
|
||||
<h5 class="mb-0 fw-bold"><?= htmlspecialchars($sys_settings['site_name'] ?? '') ?></h5>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@ -521,6 +524,26 @@ $is_admin_open = in_array($cp, $admin_pages);
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Events Group -->
|
||||
<?php if (canView('events')): ?>
|
||||
<li class="nav-item">
|
||||
<button class="sidebar-group-btn <?= $is_events_open ? '' : 'collapsed' ?>" type="button" data-bs-toggle="collapse" data-bs-target="#menu-events" aria-expanded="<?= $is_events_open ? 'true' : 'false' ?>">
|
||||
<span class="group-content group-events" style="color: #6f42c1;">
|
||||
<i class="fas fa-calendar-alt"></i> التقويم والأحداث
|
||||
</span>
|
||||
<i class="fas fa-chevron-down arrow-icon"></i>
|
||||
</button>
|
||||
<div class="collapse <?= $is_events_open ? 'show' : '' ?>" id="menu-events">
|
||||
<ul class="nav flex-column">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link <?= $cp == 'events.php' ? 'active' : '' ?>" href="events.php">
|
||||
التقويم
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
<!-- Admin Group -->
|
||||
<?php if (canView('users') || canView('settings') || isAdmin() || canView('committees')): ?>
|
||||
<li class="nav-item">
|
||||
@ -547,7 +570,7 @@ $is_admin_open = in_array($cp, $admin_pages);
|
||||
|
||||
<?php if (isAdmin()): ?>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link <?= $cp == 'index.php' ? 'active' : '' ?>" href="index.php">
|
||||
<a class="nav-link <?= $cp == 'admin_dashboard.php' ? 'active' : '' ?>" href="admin_dashboard.php">
|
||||
إحصائيات النظام
|
||||
</a>
|
||||
</li>
|
||||
@ -575,7 +598,7 @@ $is_admin_open = in_array($cp, $admin_pages);
|
||||
</ul>
|
||||
|
||||
<div class="mt-auto p-3 text-center opacity-50 small">
|
||||
© <?= date('Y') ?> <?= htmlspecialchars($sys_settings['site_name']) ?>
|
||||
© <?= date('Y') ?> <?= htmlspecialchars($sys_settings['site_name'] ?? '') ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -65,7 +65,9 @@ function canViewInternal() {
|
||||
|
||||
// Added for auditing display
|
||||
function getAuditUserName($user_id) {
|
||||
if (!$user_id) return 'غير متوفر';
|
||||
// Debugging modification to see what was actually passed
|
||||
if ($user_id === null || $user_id === '') return 'غير متوفر (Empty)';
|
||||
|
||||
static $userCache = null;
|
||||
if ($userCache === null) {
|
||||
$userCache = [];
|
||||
@ -76,5 +78,6 @@ function getAuditUserName($user_id) {
|
||||
}
|
||||
} catch(Exception $e) {}
|
||||
}
|
||||
return $userCache[$user_id] ?? '-';
|
||||
}
|
||||
|
||||
return $userCache[$user_id] ?? 'غير معروف (ID: ' . htmlspecialchars($user_id ?? '') . ')';
|
||||
}
|
||||
@ -24,6 +24,7 @@ if (!function_exists('get_settings')) {
|
||||
'site_phone' => $charity['charity_phone'] ?? '',
|
||||
'site_address' => $charity['charity_address'] ?? '',
|
||||
'site_logo' => $charity['charity_logo'] ?? '',
|
||||
'site_version' => $charity['site_version'] ?? '1.3.0',
|
||||
'site_favicon' => $charity['charity_favicon'] ?? '',
|
||||
'site_maintenance' => (bool)($charity['site_maintenance'] ?? 0),
|
||||
'site_footer' => $charity['site_footer'] ?? '',
|
||||
|
||||
471
index.php
471
index.php
@ -1,333 +1,174 @@
|
||||
<?php
|
||||
$hide_layout = true;
|
||||
require_once __DIR__ . '/includes/header.php';
|
||||
|
||||
// Role-based routing: Admins stay here, others go to their dashboard
|
||||
if (!isAdmin()) {
|
||||
redirect('user_dashboard.php');
|
||||
}
|
||||
|
||||
$user_id = $_SESSION['user_id'];
|
||||
$is_admin = isAdmin();
|
||||
|
||||
// Stats - Total counts from separate tables
|
||||
$total_inbound = canView('inbound') ? db()->query("SELECT COUNT(*) FROM inbound_mail")->fetchColumn() : 0;
|
||||
$total_outbound = canView('outbound') ? db()->query("SELECT COUNT(*) FROM outbound_mail")->fetchColumn() : 0;
|
||||
|
||||
// Fetch statuses for badge and count
|
||||
$statuses_data = db()->query("SELECT * FROM mailbox_statuses")->fetchAll(PDO::FETCH_UNIQUE);
|
||||
|
||||
$in_progress_id = null;
|
||||
foreach ($statuses_data as $id => $s) {
|
||||
if ($s['name'] == 'in_progress') {
|
||||
$in_progress_id = $id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$in_progress_count = 0;
|
||||
if ($in_progress_id) {
|
||||
if (canView('inbound')) {
|
||||
$stmt = db()->prepare("SELECT COUNT(*) FROM inbound_mail WHERE status_id = ?");
|
||||
$stmt->execute([$in_progress_id]);
|
||||
$in_progress_count += $stmt->fetchColumn();
|
||||
}
|
||||
if (canView('outbound')) {
|
||||
$stmt = db()->prepare("SELECT COUNT(*) FROM outbound_mail WHERE status_id = ?");
|
||||
$stmt->execute([$in_progress_id]);
|
||||
$in_progress_count += $stmt->fetchColumn();
|
||||
}
|
||||
}
|
||||
|
||||
// My Assignments - Combine from all tables
|
||||
$my_assignments = [];
|
||||
$queries = [];
|
||||
if (canView('inbound')) {
|
||||
$queries[] = "SELECT id, 'inbound' as type, ref_no, subject, due_date, status_id, created_at FROM inbound_mail WHERE assigned_to = $user_id";
|
||||
}
|
||||
if (canView('outbound')) {
|
||||
$queries[] = "SELECT id, 'outbound' as type, ref_no, subject, due_date, status_id, created_at FROM outbound_mail WHERE assigned_to = $user_id";
|
||||
}
|
||||
if (canView('internal')) {
|
||||
$queries[] = "SELECT id, 'internal' as type, ref_no, subject, due_date, status_id, created_at FROM internal_mail WHERE assigned_to = $user_id";
|
||||
}
|
||||
|
||||
if (!empty($queries)) {
|
||||
$full_query = "(" . implode(") UNION ALL (", $queries) . ") ORDER BY created_at DESC LIMIT 5";
|
||||
$stmt = db()->query($full_query);
|
||||
$my_assignments = $stmt->fetchAll();
|
||||
|
||||
// Add status info to assignments
|
||||
foreach ($my_assignments as &$m) {
|
||||
$m['status_name'] = $statuses_data[$m['status_id']]['name'] ?? 'unknown';
|
||||
$m['status_color'] = $statuses_data[$m['status_id']]['color'] ?? '#6c757d';
|
||||
}
|
||||
}
|
||||
|
||||
// Recent Mail (Global for Admin/Clerk, otherwise limited)
|
||||
$recent_mail = [];
|
||||
$recent_queries = [];
|
||||
if (canView('inbound')) {
|
||||
$recent_queries[] = "SELECT m.id, 'inbound' as type, m.ref_no, m.subject, m.due_date, m.sender, m.recipient, m.status_id, m.assigned_to, m.created_by, m.date_registered, m.created_at, u.full_name as assigned_to_name
|
||||
FROM inbound_mail m LEFT JOIN users u ON m.assigned_to = u.id";
|
||||
}
|
||||
if (canView('outbound')) {
|
||||
$recent_queries[] = "SELECT m.id, 'outbound' as type, m.ref_no, m.subject, m.due_date, m.sender, m.recipient, m.status_id, m.assigned_to, m.created_by, m.date_registered, m.created_at, u.full_name as assigned_to_name
|
||||
FROM outbound_mail m LEFT JOIN users u ON m.assigned_to = u.id";
|
||||
}
|
||||
|
||||
if (!empty($recent_queries)) {
|
||||
$full_recent_query = "(" . implode(") UNION ALL (", $recent_queries) . ")";
|
||||
|
||||
if (!$is_admin && ($_SESSION['user_role'] ?? '') !== 'clerk') {
|
||||
$full_recent_query = "SELECT * FROM ($full_recent_query) AS combined WHERE assigned_to = $user_id OR created_by = $user_id ORDER BY created_at DESC LIMIT 10";
|
||||
} else {
|
||||
$full_recent_query = "SELECT * FROM ($full_recent_query) AS combined ORDER BY created_at DESC LIMIT 10";
|
||||
}
|
||||
|
||||
$stmt = db()->query($full_recent_query);
|
||||
$recent_mail = $stmt->fetchAll();
|
||||
|
||||
// Add status info
|
||||
foreach ($recent_mail as &$m) {
|
||||
$m['status_name'] = $statuses_data[$m['status_id']]['name'] ?? 'unknown';
|
||||
$m['status_color'] = $statuses_data[$m['status_id']]['color'] ?? '#6c757d';
|
||||
}
|
||||
}
|
||||
|
||||
function getStatusBadge($mail) {
|
||||
$status_name = $mail['status_name'] ?? 'غير معروف';
|
||||
$status_color = $mail['status_color'] ?? '#6c757d';
|
||||
|
||||
$display_name = $status_name;
|
||||
if ($status_name == 'received') $display_name = 'تم الاستلام';
|
||||
if ($status_name == 'in_progress') $display_name = 'قيد المعالجة';
|
||||
if ($status_name == 'closed') $display_name = 'مكتمل';
|
||||
|
||||
return '<span class="badge" style="background-color: ' . $status_color . ';">' . htmlspecialchars($display_name) . '</span>';
|
||||
}
|
||||
$is_logged_in = isLoggedIn();
|
||||
?>
|
||||
|
||||
<div 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">لوحة التحكم الإدارية</h1>
|
||||
<div class="btn-toolbar mb-2 mb-md-0">
|
||||
<div class="btn-group me-2">
|
||||
<?php if (canView('settings')): ?>
|
||||
<a href="charity-settings.php" class="btn btn-sm btn-outline-dark"><i class="fas fa-cog me-1"></i> الإعدادات</a>
|
||||
<div class="landing-page-wrapper">
|
||||
<!-- Abstract Background Shapes -->
|
||||
<div class="bg-shape shape-blue"></div>
|
||||
<div class="bg-shape shape-green"></div>
|
||||
<div class="bg-shape shape-yellow"></div>
|
||||
|
||||
<div class="landing-content p-4 text-center">
|
||||
<!-- Logo -->
|
||||
<div class="logo-container mb-4">
|
||||
<?php if (!empty($sys_settings['site_logo'])): ?>
|
||||
<img src="<?= htmlspecialchars($sys_settings['site_logo']) ?>" alt="Logo" class="site-logo img-fluid">
|
||||
<?php else: ?>
|
||||
<div class="text-primary fallback-logo">
|
||||
<i class="fas fa-hands-helping fa-5x"></i>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if (canAdd('inbound')): ?>
|
||||
<a href="inbound.php?action=add" class="btn btn-sm btn-outline-primary">إضافة بريد وارد</a>
|
||||
<?php endif; ?>
|
||||
<?php if (canAdd('outbound')): ?>
|
||||
<a href="outbound.php?action=add" class="btn btn-sm btn-outline-secondary">إضافة بريد صادر</a>
|
||||
</div>
|
||||
|
||||
<!-- Site Name -->
|
||||
<h1 class="site-title fw-bold mb-3"><?= htmlspecialchars($sys_settings['site_name'] ?? 'النظام الإداري') ?></h1>
|
||||
|
||||
<!-- Slogan -->
|
||||
<?php if (!empty($sys_settings['site_slogan'])): ?>
|
||||
<p class="site-slogan text-secondary mb-5 fs-5">
|
||||
<?= htmlspecialchars($sys_settings['site_slogan']) ?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Action Button -->
|
||||
<div class="action-buttons mt-2">
|
||||
<?php if ($is_logged_in): ?>
|
||||
<a href="user_dashboard.php" class="btn btn-primary btn-lg rounded-pill px-5 py-3 shadow-sm hover-lift">
|
||||
<i class="fas fa-tachometer-alt me-2"></i> الدخول إلى لوحة التحكم
|
||||
</a>
|
||||
<?php else: ?>
|
||||
<a href="login.php" class="btn btn-primary btn-lg rounded-pill px-5 py-3 shadow-sm hover-lift">
|
||||
<i class="fas fa-sign-in-alt me-2"></i> تسجيل الدخول
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Overdue Alert -->
|
||||
<?php
|
||||
if (canView('reports')):
|
||||
// Combine overdue counts from inbound and outbound
|
||||
$overdue_count = 0;
|
||||
$overdue_count += db()->query("SELECT COUNT(*) FROM inbound_mail WHERE due_date < CURDATE() AND status_id IN (SELECT id FROM mailbox_statuses WHERE name != 'closed')")->fetchColumn();
|
||||
$overdue_count += db()->query("SELECT COUNT(*) FROM outbound_mail WHERE due_date < CURDATE() AND status_id IN (SELECT id FROM mailbox_statuses WHERE name != 'closed')")->fetchColumn();
|
||||
<style>
|
||||
/* Full Page Reset for Landing */
|
||||
html, body {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
|
||||
.landing-page-wrapper {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: linear-gradient(135deg, #fdfdfd 0%, #f1f3f5 100%);
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.landing-content {
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
background: rgba(255, 255, 255, 0.85);
|
||||
backdrop-filter: blur(16px);
|
||||
-webkit-backdrop-filter: blur(16px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.5);
|
||||
border-radius: 2rem;
|
||||
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.08);
|
||||
max-width: 650px;
|
||||
width: 90%;
|
||||
padding: 3rem !important;
|
||||
animation: fadeIn 0.8s ease-out forwards;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; transform: translateY(20px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
|
||||
.site-logo {
|
||||
max-height: 140px;
|
||||
transition: transform 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
||||
}
|
||||
|
||||
.site-logo:hover, .fallback-logo:hover {
|
||||
transform: scale(1.08);
|
||||
}
|
||||
|
||||
.site-title {
|
||||
color: #2c3e50;
|
||||
font-size: 2.5rem;
|
||||
letter-spacing: -0.5px;
|
||||
}
|
||||
|
||||
.site-slogan {
|
||||
font-weight: 300;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.hover-lift {
|
||||
transition: all 0.3s ease;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
if ($overdue_count > 0):
|
||||
?>
|
||||
<div class="row mb-4">
|
||||
<div class="col-12">
|
||||
<div class="alert alert-danger shadow-sm border-0 d-flex align-items-center justify-content-between mb-0">
|
||||
<div>
|
||||
<i class="fas fa-exclamation-triangle fs-4 me-3"></i>
|
||||
<span class="fw-bold">هناك <?= $overdue_count ?> مهام متأخرة تتطلب انتباهك!</span>
|
||||
</div>
|
||||
<a href="overdue_report.php" class="btn btn-danger btn-sm">عرض التقرير</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
endif;
|
||||
endif;
|
||||
?>
|
||||
.hover-lift:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: 0 10px 20px rgba(13, 110, 253, 0.3) !important;
|
||||
}
|
||||
|
||||
<!-- Stats Cards -->
|
||||
<div class="row g-4 mb-4">
|
||||
<?php if (canView('inbound')): ?>
|
||||
<div class="col-md-3">
|
||||
<div class="card h-100 p-3 shadow-sm border-0 border-start border-primary border-4">
|
||||
<div class="d-flex align-items-center justify-content-between">
|
||||
<div>
|
||||
<h6 class="text-muted mb-1">البريد الوارد</h6>
|
||||
<h3 class="fw-bold mb-0"><?= $total_inbound ?></h3>
|
||||
</div>
|
||||
<div class="bg-primary bg-opacity-10 p-3 rounded-circle">
|
||||
<i class="fas fa-download text-primary fs-4"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
/* Abstract Background Shapes with smooth animation */
|
||||
.bg-shape {
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
filter: blur(80px);
|
||||
opacity: 0.5;
|
||||
z-index: 0;
|
||||
animation: float 25s infinite ease-in-out alternate;
|
||||
}
|
||||
|
||||
<?php if (canView('outbound')): ?>
|
||||
<div class="col-md-3">
|
||||
<div class="card h-100 p-3 shadow-sm border-0 border-start border-success border-4">
|
||||
<div class="d-flex align-items-center justify-content-between">
|
||||
<div>
|
||||
<h6 class="text-muted mb-1">البريد الصادر</h6>
|
||||
<h3 class="fw-bold mb-0"><?= $total_outbound ?></h3>
|
||||
</div>
|
||||
<div class="bg-success bg-opacity-10 p-3 rounded-circle">
|
||||
<i class="fas fa-upload text-success fs-4"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
.shape-blue {
|
||||
width: 50vw;
|
||||
height: 50vw;
|
||||
background: #0d6efd; /* Bootstrap Primary */
|
||||
top: -15%;
|
||||
right: -10%;
|
||||
animation-delay: 0s;
|
||||
}
|
||||
|
||||
<?php if (canView('inbound') || canView('outbound')): ?>
|
||||
<div class="col-md-3">
|
||||
<div class="card h-100 p-3 shadow-sm border-0 border-start border-info border-4">
|
||||
<div class="d-flex align-items-center justify-content-between">
|
||||
<div>
|
||||
<h6 class="text-muted mb-1">قيد المعالجة</h6>
|
||||
<h3 class="fw-bold mb-0"><?= $in_progress_count ?></h3>
|
||||
</div>
|
||||
<div class="bg-info bg-opacity-10 p-3 rounded-circle">
|
||||
<i class="fas fa-clock text-info fs-4"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
.shape-green {
|
||||
width: 45vw;
|
||||
height: 45vw;
|
||||
background: #198754; /* Bootstrap Success */
|
||||
bottom: -20%;
|
||||
left: -15%;
|
||||
animation-delay: -7s;
|
||||
}
|
||||
|
||||
<?php if (canView('users')): ?>
|
||||
<div class="col-md-3">
|
||||
<div class="card h-100 p-3 shadow-sm border-0 border-start border-warning border-4">
|
||||
<div class="d-flex align-items-center justify-content-between">
|
||||
<div>
|
||||
<h6 class="text-muted mb-1">المستخدمين</h6>
|
||||
<h3 class="fw-bold mb-0"><?= db()->query("SELECT COUNT(*) FROM users")->fetchColumn() ?></h3>
|
||||
</div>
|
||||
<div class="bg-warning bg-opacity-10 p-3 rounded-circle">
|
||||
<i class="fas fa-users text-warning fs-4"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
.shape-yellow {
|
||||
width: 30vw;
|
||||
height: 30vw;
|
||||
background: #ffc107; /* Bootstrap Warning */
|
||||
top: 30%;
|
||||
left: 20%;
|
||||
animation-delay: -14s;
|
||||
}
|
||||
|
||||
<?php if (!empty($my_assignments)): ?>
|
||||
<!-- My Assignments Section -->
|
||||
<div class="card shadow-sm border-0 mb-4 bg-primary bg-opacity-10 border-top border-primary border-3">
|
||||
<div class="card-header bg-transparent py-3 border-0">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<h5 class="mb-0 fw-bold text-primary"><i class="fas fa-tasks me-2"></i> مهامي الحالية</h5>
|
||||
<span class="badge bg-primary rounded-pill"><?= count($my_assignments) ?></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle mb-0">
|
||||
<tbody>
|
||||
<?php foreach ($my_assignments as $mail): ?>
|
||||
<tr style="cursor: pointer;" onclick="window.location='view_mail.php?id=<?= $mail['id'] ?>&type=<?= $mail['type'] ?>'">
|
||||
<td class="ps-4" width="120">
|
||||
<small class="text-muted d-block">رقم القيد</small>
|
||||
<span class="fw-bold text-primary"><?= $mail['ref_no'] ?></span>
|
||||
</td>
|
||||
<td>
|
||||
<small class="text-muted d-block">الموضوع</small>
|
||||
<span class="fw-bold"><?= htmlspecialchars($mail['subject']) ?></span>
|
||||
</td>
|
||||
<td>
|
||||
<small class="text-muted d-block">الموعد النهائي</small>
|
||||
<?php if ($mail['due_date']): ?>
|
||||
<span class="<?= (strtotime($mail['due_date']) < time() && $mail['status_name'] != 'closed') ? 'text-danger fw-bold' : '' ?>">
|
||||
<?= $mail['due_date'] ?>
|
||||
</span>
|
||||
<?php else: ?>
|
||||
<span class="text-muted">-</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<small class="text-muted d-block mb-1">الحالة</small>
|
||||
<?= getStatusBadge($mail) ?>
|
||||
</td>
|
||||
<td class="pe-4 text-end">
|
||||
<i class="fas fa-chevron-left text-primary"></i>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
@keyframes float {
|
||||
0% { transform: translate(0, 0) scale(1); }
|
||||
33% { transform: translate(3%, 5%) scale(1.05); }
|
||||
66% { transform: translate(-2%, 8%) scale(0.95); }
|
||||
100% { transform: translate(-5%, -2%) scale(1.02); }
|
||||
}
|
||||
|
||||
<?php if (!empty($recent_mail)): ?>
|
||||
<!-- Recent Mail -->
|
||||
<div class="card shadow-sm border-0 mb-4">
|
||||
<div class="card-header bg-white py-3">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<h5 class="mb-0 fw-bold"><?= $is_admin ? 'آخر المراسلات المسجلة' : 'آخر المراسلات' ?></h5>
|
||||
<a href="inbound.php" class="btn btn-sm btn-link text-decoration-none">عرض الكل</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle mb-0">
|
||||
<thead class="bg-light">
|
||||
<tr>
|
||||
<th class="ps-4">رقم القيد</th>
|
||||
<th>النوع</th>
|
||||
<th>الموضوع</th>
|
||||
<th>الموعد النهائي</th>
|
||||
<th>المرسل/المستلم</th>
|
||||
<th>المسؤول</th>
|
||||
<th>الحالة</th>
|
||||
<th class="pe-4 text-center">التاريخ</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($recent_mail as $mail): ?>
|
||||
<tr style="cursor: pointer;" onclick="window.location='view_mail.php?id=<?= $mail['id'] ?>&type=<?= $mail['type'] ?>'">
|
||||
<td class="ps-4 fw-bold text-primary"><?= $mail['ref_no'] ?></td>
|
||||
<td>
|
||||
<?php if ($mail['type'] == 'inbound'): ?>
|
||||
<span class="text-primary"><i class="fas fa-arrow-down me-1"></i> وارد</span>
|
||||
<?php else: ?>
|
||||
<span class="text-success"><i class="fas fa-arrow-up me-1"></i> صادر</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><?= htmlspecialchars($mail['subject']) ?></td>
|
||||
<td>
|
||||
<?php if ($mail['due_date']): ?>
|
||||
<small class="<?= (strtotime($mail['due_date']) < time() && $mail['status_name'] != 'closed') ? 'text-danger fw-bold' : 'text-muted' ?>">
|
||||
<?= $mail['due_date'] ?>
|
||||
</small>
|
||||
<?php else: ?>
|
||||
<small class="text-muted">-</small>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><?= htmlspecialchars($mail['sender'] ?: $mail['recipient']) ?></td>
|
||||
<td>
|
||||
<?php if ($mail['assigned_to_name']): ?>
|
||||
<small><i class="fas fa-user-tag me-1 text-muted"></i> <?= htmlspecialchars($mail['assigned_to_name']) ?></small>
|
||||
<?php else: ?>
|
||||
<small class="text-muted">غير معين</small>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><?= getStatusBadge($mail) ?></td>
|
||||
<td class="pe-4 text-center"><?= date('Y-m-d', strtotime($mail['date_registered'])) ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
/* Mobile Adjustments */
|
||||
@media (max-width: 576px) {
|
||||
.site-title { font-size: 2rem; }
|
||||
.landing-content { padding: 2rem !important; }
|
||||
.site-logo { max-height: 100px; }
|
||||
}
|
||||
</style>
|
||||
|
||||
<?php require_once __DIR__ . '/includes/footer.php'; ?>
|
||||
<?php require_once __DIR__ . '/includes/footer.php'; ?>
|
||||
|
||||
16
install.php
16
install.php
@ -68,7 +68,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$content .= "}\n";
|
||||
|
||||
if (file_put_contents($config_file, $content)) {
|
||||
header('Location: ' . htmlspecialchars($_SERVER['SCRIPT_NAME']) . '?step=3');
|
||||
header('Location: ' . htmlspecialchars($_SERVER['SCRIPT_NAME'] ?? '') . '?step=3');
|
||||
exit;
|
||||
} else {
|
||||
$error = "Failed to write configuration file to $config_file. Please check permissions.";
|
||||
@ -118,7 +118,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
if (empty($sql)) continue;
|
||||
|
||||
// Split SQL into individual statements by ; followed by newline
|
||||
$statements = preg_split('/;(?:\\s*[
|
||||
$statements = preg_split('/;(?:\\s*[
|
||||
]+)/', $sql);
|
||||
|
||||
$file_success = true;
|
||||
@ -168,7 +168,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
|
||||
if (empty($errors)) {
|
||||
$success = "Successfully applied migrations.";
|
||||
header('Location: ' . htmlspecialchars($_SERVER['SCRIPT_NAME']) . '?step=4');
|
||||
header('Location: ' . htmlspecialchars($_SERVER['SCRIPT_NAME'] ?? '') . '?step=4');
|
||||
exit;
|
||||
} else {
|
||||
$error = "Applied migrations, but some errors occurred:<br><ul><li>" . implode('</li><li>', $errors) . "</li></ul>";
|
||||
@ -199,7 +199,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$pdo->exec("INSERT IGNORE INTO charity_settings (id, charity_name) VALUES (1, 'Admin Panel')");
|
||||
$pdo->exec("INSERT IGNORE INTO smtp_settings (id, is_enabled) VALUES (1, 0)");
|
||||
|
||||
header('Location: ' . htmlspecialchars($_SERVER['SCRIPT_NAME']) . '?step=5');
|
||||
header('Location: ' . htmlspecialchars($_SERVER['SCRIPT_NAME'] ?? '') . '?step=5');
|
||||
exit;
|
||||
} catch (Throwable $e) {
|
||||
$error = "Failed to create admin account: " . $e->getMessage();
|
||||
@ -263,7 +263,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
</ul>
|
||||
<div class="d-grid">
|
||||
<?php if ($all_requirements_met): ?>
|
||||
<a href="<?= htmlspecialchars($_SERVER['SCRIPT_NAME']) ?>?step=2" class="btn btn-primary">Next: Database Config</a>
|
||||
<a href="<?= htmlspecialchars($_SERVER['SCRIPT_NAME'] ?? '') ?>?step=2" class="btn btn-primary">Next: Database Config</a>
|
||||
<?php else:
|
||||
echo "<button class=\"btn btn-secondary\" disabled>Fix requirements to continue</button>";
|
||||
endif; ?>
|
||||
@ -271,7 +271,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
|
||||
<?php elseif ($step === 2): ?>
|
||||
<h4>Step 2: Database Connection</h4>
|
||||
<form method="POST" action="<?= htmlspecialchars($_SERVER['SCRIPT_NAME']) ?>?step=2">
|
||||
<form method="POST" action="<?= htmlspecialchars($_SERVER['SCRIPT_NAME'] ?? '') ?>?step=2">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Database Host</label>
|
||||
<input type="text" name="db_host" class="form-control" value="127.0.0.1" required>
|
||||
@ -296,7 +296,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
<?php elseif ($step === 3): ?>
|
||||
<h4>Step 3: Database Migrations</h4>
|
||||
<p>We will now run the SQL scripts to set up your database tables.</p>
|
||||
<form method="POST" action="<?= htmlspecialchars($_SERVER['SCRIPT_NAME']) ?>?step=3">
|
||||
<form method="POST" action="<?= htmlspecialchars($_SERVER['SCRIPT_NAME'] ?? '') ?>?step=3">
|
||||
<div class="d-grid">
|
||||
<button type="submit" class="btn btn-primary">Run Migrations</button>
|
||||
</div>
|
||||
@ -304,7 +304,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
|
||||
<?php elseif ($step === 4): ?>
|
||||
<h4>Step 4: Admin Account</h4>
|
||||
<form method="POST" action="<?= htmlspecialchars($_SERVER['SCRIPT_NAME']) ?>?step=4">
|
||||
<form method="POST" action="<?= htmlspecialchars($_SERVER['SCRIPT_NAME'] ?? '') ?>?step=4">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Admin Username</label>
|
||||
<input type="text" name="admin_user" class="form-control" value="admin" required>
|
||||
|
||||
@ -3,7 +3,7 @@ require_once __DIR__ . '/includes/header.php';
|
||||
|
||||
// Every logged-in user can access their own internal mail if they have permission
|
||||
if (!canView('internal')) {
|
||||
redirect('index.php');
|
||||
redirect('user_dashboard.php');
|
||||
}
|
||||
|
||||
$user_id = $_SESSION['user_id'];
|
||||
@ -55,7 +55,7 @@ function getStatusBadgeInternal($mail) {
|
||||
if ($status_name == 'in_progress') $display_name = 'قيد المعالجة';
|
||||
if ($status_name == 'closed') $display_name = 'مؤرشف';
|
||||
|
||||
return '<span class="badge" style="background-color: ' . $status_color . ';">' . htmlspecialchars($display_name) . '</span>';
|
||||
return '<span class="badge" style="background-color: ' . $status_color . ';">' . htmlspecialchars($display_name ?? '') . '</span>';
|
||||
}
|
||||
?>
|
||||
|
||||
@ -72,7 +72,7 @@ function getStatusBadgeInternal($mail) {
|
||||
|
||||
<?php if ($success): ?>
|
||||
<div class="alert alert-success alert-dismissible fade show" role="alert">
|
||||
<?= htmlspecialchars($success) ?>
|
||||
<?= htmlspecialchars($success ?? '') ?>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
@ -83,7 +83,7 @@ function getStatusBadgeInternal($mail) {
|
||||
<div class="col-md-6">
|
||||
<div class="input-group">
|
||||
<span class="input-group-text bg-light border-end-0"><i class="fas fa-search text-muted"></i></span>
|
||||
<input type="text" name="search" class="form-control border-start-0" placeholder="بحث في الموضوع، الرسالة، أو المرسل..." value="<?= htmlspecialchars($search) ?>">
|
||||
<input type="text" name="search" class="form-control border-start-0" placeholder="بحث في الموضوع، الرسالة، أو المرسل..." value="<?= htmlspecialchars($search ?? '') ?>">
|
||||
<button type="submit" class="btn btn-primary">بحث</button>
|
||||
</div>
|
||||
</div>
|
||||
@ -126,14 +126,14 @@ function getStatusBadgeInternal($mail) {
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="fw-bold"><?= htmlspecialchars($msg['subject']) ?></div>
|
||||
<div class="fw-bold"><?= htmlspecialchars($msg['subject'] ?? '') ?></div>
|
||||
<small class="text-muted text-truncate d-inline-block" style="max-width: 300px;">
|
||||
<?= strip_tags($msg['description']) ?>
|
||||
</small>
|
||||
</td>
|
||||
<td>
|
||||
<?php if (!empty($msg['attachment_names'])): ?>
|
||||
<small class="text-muted"><i class="fas fa-paperclip me-1"></i> <?= htmlspecialchars($msg['attachment_names']) ?></small>
|
||||
<small class="text-muted"><i class="fas fa-paperclip me-1"></i> <?= htmlspecialchars($msg['attachment_names'] ?? '') ?></small>
|
||||
<?php else: ?>
|
||||
<span class="text-muted">-</span>
|
||||
<?php endif; ?>
|
||||
@ -142,7 +142,7 @@ function getStatusBadgeInternal($mail) {
|
||||
<small class="text-muted"><?= date('Y-m-d H:i', strtotime($msg['created_at'])) ?></small>
|
||||
</td>
|
||||
<td><?= getStatusBadgeInternal($msg) ?></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($msg['created_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($msg['created_by'] ?? $msg['updated_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user-edit text-warning opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($msg['updated_by'] ?? null)) ?></small></td>
|
||||
<td class="pe-4 text-center">
|
||||
<a href="view_mail.php?id=<?= $msg['id'] ?>&type=internal" class="btn btn-sm btn-light rounded-pill px-3">عرض</a>
|
||||
|
||||
@ -3,7 +3,7 @@ require_once __DIR__ . '/includes/header.php';
|
||||
require_once __DIR__ . '/m_services/MailService.php';
|
||||
|
||||
if (!canView('internal')) {
|
||||
redirect('index.php');
|
||||
redirect('user_dashboard.php');
|
||||
}
|
||||
|
||||
$user_id = $_SESSION['user_id'];
|
||||
@ -67,8 +67,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['
|
||||
$htmlBody = "
|
||||
<div dir='rtl' style='font-family: Arial, sans-serif;'>
|
||||
<h3>لديك رسالة داخلية جديدة</h3>
|
||||
<p><strong>الموضوع:</strong> " . htmlspecialchars($subject) . "</p>
|
||||
<p><strong>المرسل:</strong> " . htmlspecialchars($_SESSION['name']) . "</p>
|
||||
<p><strong>الموضوع:</strong> " . htmlspecialchars($subject ?? '') . "</p>
|
||||
<p><strong>المرسل:</strong> " . htmlspecialchars($_SESSION['name'] ?? '') . "</p>
|
||||
<hr>
|
||||
<div>" . $description . "</div>
|
||||
<br>
|
||||
@ -150,7 +150,7 @@ function getStatusBadgeInternal($mail) {
|
||||
if ($status_name == 'in_progress') $display_name = 'قيد المتابعة';
|
||||
if ($status_name == 'closed') $display_name = 'مؤرشفة';
|
||||
|
||||
return '<span class="badge" style="background-color: ' . $status_color . ';">' . htmlspecialchars($display_name) . '</span>';
|
||||
return '<span class="badge" style="background-color: ' . $status_color . ';">' . htmlspecialchars($display_name ?? '') . '</span>';
|
||||
}
|
||||
?>
|
||||
|
||||
@ -167,14 +167,14 @@ function getStatusBadgeInternal($mail) {
|
||||
|
||||
<?php if ($success): ?>
|
||||
<div class="alert alert-success alert-dismissible fade show" role="alert">
|
||||
<?= htmlspecialchars($success) ?>
|
||||
<?= htmlspecialchars($success ?? '') ?>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($error): ?>
|
||||
<div class="alert alert-danger alert-dismissible fade show" role="alert">
|
||||
<?= htmlspecialchars($error) ?>
|
||||
<?= htmlspecialchars($error ?? '') ?>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
@ -185,7 +185,7 @@ function getStatusBadgeInternal($mail) {
|
||||
<div class="col-md-6">
|
||||
<div class="input-group">
|
||||
<span class="input-group-text bg-light border-end-0"><i class="fas fa-search text-muted"></i></span>
|
||||
<input type="text" name="search" class="form-control border-start-0" placeholder="بحث في الموضوع، الرسالة، أو المستلم..." value="<?= htmlspecialchars($search) ?>">
|
||||
<input type="text" name="search" class="form-control border-start-0" placeholder="بحث في الموضوع، الرسالة، أو المستلم..." value="<?= htmlspecialchars($search ?? '') ?>">
|
||||
<button type="submit" class="btn btn-primary">بحث</button>
|
||||
</div>
|
||||
</div>
|
||||
@ -228,14 +228,14 @@ function getStatusBadgeInternal($mail) {
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="fw-bold"><?= htmlspecialchars($msg['subject']) ?></div>
|
||||
<div class="fw-bold"><?= htmlspecialchars($msg['subject'] ?? '') ?></div>
|
||||
<small class="text-muted text-truncate d-inline-block" style="max-width: 300px;">
|
||||
<?= strip_tags($msg['description']) ?>
|
||||
</small>
|
||||
</td>
|
||||
<td>
|
||||
<?php if (!empty($msg['attachment_names'])): ?>
|
||||
<small class="text-muted"><i class="fas fa-paperclip me-1"></i> <?= htmlspecialchars($msg['attachment_names']) ?></small>
|
||||
<small class="text-muted"><i class="fas fa-paperclip me-1"></i> <?= htmlspecialchars($msg['attachment_names'] ?? '') ?></small>
|
||||
<?php else: ?>
|
||||
<span class="text-muted">-</span>
|
||||
<?php endif; ?>
|
||||
@ -244,7 +244,7 @@ function getStatusBadgeInternal($mail) {
|
||||
<small class="text-muted"><?= date('Y-m-d H:i', strtotime($msg['created_at'])) ?></small>
|
||||
</td>
|
||||
<td><?= getStatusBadgeInternal($msg) ?></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($msg['created_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($msg['created_by'] ?? $msg['updated_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user-edit text-warning opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($msg['updated_by'] ?? null)) ?></small></td>
|
||||
<td class="pe-4 text-center">
|
||||
<a href="view_mail.php?id=<?= $msg['id'] ?>&type=internal" class="btn btn-sm btn-light rounded-pill px-3">عرض</a>
|
||||
|
||||
@ -40,9 +40,9 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
<div class="text-center mb-4">
|
||||
<a href="index.php" class="text-decoration-none text-dark d-block">
|
||||
<?php if (!empty($sys_settings['site_logo'])): ?>
|
||||
<img src="<?php echo htmlspecialchars($sys_settings['site_logo']); ?>" alt="Logo" class="img-fluid mb-3" style="max-height: 80px;">
|
||||
<img src="<?php echo htmlspecialchars($sys_settings['site_logo'] ?? ''); ?>" alt="Logo" class="img-fluid mb-3" style="max-height: 80px;">
|
||||
<?php endif; ?>
|
||||
<h4 class="fw-bold mb-0"><?php echo htmlspecialchars($sys_settings['site_name']); ?></h4>
|
||||
<h4 class="fw-bold mb-0"><?php echo htmlspecialchars($sys_settings['site_name'] ?? ''); ?></h4>
|
||||
<p class="text-danger mb-0 fw-bold">نظام إدارة الفرق التطوعية ولجان الزكاة</p>
|
||||
</a>
|
||||
<p class="text-muted small">يرجى إدخال بيانات الاعتماد الخاصة بك</p>
|
||||
|
||||
14
meetings.php
14
meetings.php
@ -4,7 +4,7 @@ require_once __DIR__ . '/includes/header.php';
|
||||
require_once __DIR__ . '/includes/pagination.php';
|
||||
|
||||
if (!canView('meetings')) {
|
||||
redirect('index.php');
|
||||
redirect('user_dashboard.php');
|
||||
}
|
||||
|
||||
$error = '';
|
||||
@ -190,7 +190,7 @@ if (isset($_SESSION['success'])) {
|
||||
<div class="col-md-3">
|
||||
<label class="form-label">بحث</label>
|
||||
<div class="input-group">
|
||||
<input type="text" name="search" class="form-control" placeholder="عنوان، وصف، مكان..." value="<?= htmlspecialchars($search) ?>">
|
||||
<input type="text" name="search" class="form-control" placeholder="عنوان، وصف، مكان..." value="<?= htmlspecialchars($search ?? '') ?>">
|
||||
<button class="btn btn-primary" type="submit"><i class="fas fa-search"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
@ -240,9 +240,9 @@ if (isset($_SESSION['success'])) {
|
||||
?>
|
||||
<tr>
|
||||
<td class="ps-4 fw-bold">
|
||||
<?= htmlspecialchars($meeting['title']) ?>
|
||||
<?= htmlspecialchars($meeting['title'] ?? '') ?>
|
||||
<?php if ($agenda_preview): ?>
|
||||
<div class="small text-muted fw-normal text-truncate" style="max-width: 250px;"><?= htmlspecialchars($agenda_preview) ?></div>
|
||||
<div class="small text-muted fw-normal text-truncate" style="max-width: 250px;"><?= htmlspecialchars($agenda_preview ?? '') ?></div>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td>
|
||||
@ -251,14 +251,14 @@ if (isset($_SESSION['success'])) {
|
||||
</td>
|
||||
<td>
|
||||
<?php if ($meeting['location']): ?>
|
||||
<i class="fas fa-map-marker-alt text-danger me-1"></i> <?= htmlspecialchars($meeting['location']) ?>
|
||||
<i class="fas fa-map-marker-alt text-danger me-1"></i> <?= htmlspecialchars($meeting['location'] ?? '') ?>
|
||||
<?php else: ?>
|
||||
-
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><?= htmlspecialchars($meeting['created_by_name']) ?></td>
|
||||
<td><?= htmlspecialchars($meeting['created_by_name'] ?? '') ?></td>
|
||||
<td><span class="badge <?= $status_class ?>"><?= $status_text ?></span></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($meeting['created_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($meeting['created_by'] ?? $meeting['updated_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user-edit text-warning opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($meeting['updated_by'] ?? null)) ?></small></td>
|
||||
<td class="text-center">
|
||||
<?php if (canEdit('meetings')): ?>
|
||||
|
||||
@ -93,10 +93,10 @@ $requests = $stmt->fetchAll();
|
||||
</div>
|
||||
|
||||
<?php if ($error): ?>
|
||||
<div class="alert alert-danger"><?= htmlspecialchars($error) ?></div>
|
||||
<div class="alert alert-danger"><?= htmlspecialchars($error ?? '') ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if ($success): ?>
|
||||
<div class="alert alert-success"><?= htmlspecialchars($success) ?></div>
|
||||
<div class="alert alert-success"><?= htmlspecialchars($success ?? '') ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="card shadow-sm">
|
||||
@ -137,7 +137,7 @@ $requests = $stmt->fetchAll();
|
||||
من <?= $req['start_date'] ?><br>إلى <?= $req['end_date'] ?>
|
||||
</td>
|
||||
<td><?= $req['days_count'] ?> يوم</td>
|
||||
<td class="text-truncate" style="max-width: 150px;"><?= htmlspecialchars($req['reason']) ?></td>
|
||||
<td class="text-truncate" style="max-width: 150px;"><?= htmlspecialchars($req['reason'] ?? '') ?></td>
|
||||
<td class="small"><?= date('Y-m-d', strtotime($req['created_at'])) ?></td>
|
||||
<td>
|
||||
<?php
|
||||
|
||||
10
outbound.php
10
outbound.php
@ -242,23 +242,23 @@ if (isset($_GET['id'])) {
|
||||
<?php endif; ?>
|
||||
<?php foreach ($mails as $mail): ?>
|
||||
<tr>
|
||||
<td class="ps-4"><span class="fw-bold text-primary"><?= htmlspecialchars($mail['ref_no']) ?></span></td>
|
||||
<td class="ps-4"><span class="fw-bold text-primary"><?= htmlspecialchars($mail['ref_no'] ?? '') ?></span></td>
|
||||
<td><?= date('Y-m-d', strtotime($mail['date_registered'])) ?></td>
|
||||
<td>
|
||||
<div class="fw-semibold text-truncate" style="max-width: 300px;"><?= htmlspecialchars($mail['subject']) ?></div>
|
||||
<div class="fw-semibold text-truncate" style="max-width: 300px;"><?= htmlspecialchars($mail['subject'] ?? '') ?></div>
|
||||
<?php if ($mail['attachment_names']): ?>
|
||||
<span class="badge bg-light text-muted fw-normal" style="font-size: 0.65rem;">
|
||||
<i class="fas fa-paperclip me-1"></i> <?= count(explode('|||', $mail['attachment_names'])) ?> مرفقات
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><?= htmlspecialchars($mail['recipient']) ?></td>
|
||||
<td><?= htmlspecialchars($mail['recipient'] ?? '') ?></td>
|
||||
<td>
|
||||
<span class="badge rounded-pill" style="background-color: <?= $mail['status_color'] ?>20; color: <?= $mail['status_color'] ?>;">
|
||||
<i class="fas fa-circle me-1 small"></i> <?= htmlspecialchars($mail['status_name']) ?>
|
||||
<i class="fas fa-circle me-1 small"></i> <?= htmlspecialchars($mail['status_name'] ?? '') ?>
|
||||
</span>
|
||||
</td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($mail['created_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($mail['created_by'] ?? $mail['updated_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user-edit text-warning opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($mail['updated_by'] ?? null)) ?></small></td>
|
||||
<td class="text-center pe-4">
|
||||
<div class="btn-group shadow-sm rounded">
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
require_once 'includes/header.php';
|
||||
|
||||
if (!canView('reports')) {
|
||||
redirect('index.php');
|
||||
redirect('user_dashboard.php');
|
||||
}
|
||||
|
||||
$type_filter = $_GET['type'] ?? '';
|
||||
@ -64,7 +64,7 @@ function getStatusBadgeForReport($item) {
|
||||
if ($status_name == 'in_progress') $display_name = 'قيد المعالجة';
|
||||
if ($status_name == 'closed') $display_name = 'مكتمل';
|
||||
|
||||
return '<span class="badge" style="background-color: ' . $status_color . ';">' . htmlspecialchars($display_name) . '</span>';
|
||||
return '<span class="badge" style="background-color: ' . $status_color . ';">' . htmlspecialchars($display_name ?? '') . '</span>';
|
||||
}
|
||||
?>
|
||||
|
||||
@ -89,7 +89,7 @@ function getStatusBadgeForReport($item) {
|
||||
<option value="">الكل</option>
|
||||
<?php foreach ($users as $user): ?>
|
||||
<option value="<?= $user['id'] ?>" <?= $user_filter == $user['id'] ? 'selected' : '' ?>>
|
||||
<?= htmlspecialchars($user['full_name']) ?>
|
||||
<?= htmlspecialchars($user['full_name'] ?? '') ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
@ -132,13 +132,13 @@ function getStatusBadgeForReport($item) {
|
||||
$diff = $today->diff($due_date)->format("%a");
|
||||
?>
|
||||
<tr>
|
||||
<td class="fw-bold"><?= htmlspecialchars($item['ref_no']) ?></td>
|
||||
<td class="fw-bold"><?= htmlspecialchars($item['ref_no'] ?? '') ?></td>
|
||||
<td>
|
||||
<span class="badge bg-<?= $item['type'] == 'inbound' ? 'info' : 'warning' ?>">
|
||||
<?= $item['type'] == 'inbound' ? 'وارد' : 'صادر' ?>
|
||||
</span>
|
||||
</td>
|
||||
<td><?= htmlspecialchars($item['subject']) ?></td>
|
||||
<td><?= htmlspecialchars($item['subject'] ?? '') ?></td>
|
||||
<td><?= htmlspecialchars($item['assigned_name'] ?? 'غير معين') ?></td>
|
||||
<td><?= getStatusBadgeForReport($item) ?></td>
|
||||
<td class="text-danger fw-bold"><?= $item['due_date'] ?></td>
|
||||
|
||||
@ -94,13 +94,13 @@ $status_labels = [
|
||||
<!-- Header -->
|
||||
<div class="print-header">
|
||||
<div>
|
||||
<h2 class="mb-1 fw-bold"><?= htmlspecialchars($settings['site_name']) ?></h2>
|
||||
<h2 class="mb-1 fw-bold"><?= htmlspecialchars($settings['site_name'] ?? '') ?></h2>
|
||||
<p class="mb-0 text-muted fs-5">تقرير الجمعية الشامل (الخطط، الأهداف والأعضاء)</p>
|
||||
<small>تاريخ التقرير: <?= date('Y-m-d') ?></small>
|
||||
</div>
|
||||
<div>
|
||||
<?php if (!empty($settings['site_logo'])): ?>
|
||||
<img src="<?= htmlspecialchars($settings['site_logo']) ?>" class="print-logo" alt="Logo">
|
||||
<img src="<?= htmlspecialchars($settings['site_logo'] ?? '') ?>" class="print-logo" alt="Logo">
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
@ -154,9 +154,9 @@ $status_labels = [
|
||||
<tr>
|
||||
<td style="text-align: center;"><?= $index + 1 ?></td>
|
||||
<td>
|
||||
<strong><?= htmlspecialchars($plan['title']) ?></strong>
|
||||
<strong><?= htmlspecialchars($plan['title'] ?? '') ?></strong>
|
||||
<?php if($plan['description']): ?>
|
||||
<br><small class="text-muted"><?= htmlspecialchars($plan['description']) ?></small>
|
||||
<br><small class="text-muted"><?= htmlspecialchars($plan['description'] ?? '') ?></small>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class="small">
|
||||
@ -193,7 +193,7 @@ $status_labels = [
|
||||
<?php foreach ($members as $index => $m): ?>
|
||||
<tr>
|
||||
<td style="text-align: center;"><?= $index + 1 ?></td>
|
||||
<td><strong><?= htmlspecialchars($m['name']) ?></strong></td>
|
||||
<td><strong><?= htmlspecialchars($m['name'] ?? '') ?></strong></td>
|
||||
<td><?= htmlspecialchars($m['role'] ?: '-') ?></td>
|
||||
<td dir="ltr" style="text-align: right;"><?= htmlspecialchars($m['phone'] ?: '-') ?></td>
|
||||
<td dir="ltr" style="text-align: right;"><?= htmlspecialchars($m['email'] ?: '-') ?></td>
|
||||
@ -207,7 +207,7 @@ $status_labels = [
|
||||
|
||||
<!-- Footer -->
|
||||
<div class="mt-5 pt-3 border-top text-center text-muted small">
|
||||
هذا التقرير معتمد ومستخرج آلياً من نظام إدارة الجمعية - <?= htmlspecialchars($settings['site_name']) ?>
|
||||
هذا التقرير معتمد ومستخرج آلياً من نظام إدارة الجمعية - <?= htmlspecialchars($settings['site_name'] ?? '') ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -103,13 +103,13 @@ usort($committees, function($a, $b) {
|
||||
<!-- Header -->
|
||||
<div class="print-header">
|
||||
<div>
|
||||
<h2 class="mb-1 fw-bold"><?= htmlspecialchars($settings['site_name']) ?></h2>
|
||||
<h2 class="mb-1 fw-bold"><?= htmlspecialchars($settings['site_name'] ?? '') ?></h2>
|
||||
<p class="mb-0 text-muted fs-5">تقرير اللجان وتقييم الأداء العام</p>
|
||||
<small>تاريخ التقرير: <?= date('Y-m-d') ?></small>
|
||||
</div>
|
||||
<div>
|
||||
<?php if (!empty($settings['site_logo'])): ?>
|
||||
<img src="<?= htmlspecialchars($settings['site_logo']) ?>" class="print-logo" alt="Logo">
|
||||
<img src="<?= htmlspecialchars($settings['site_logo'] ?? '') ?>" class="print-logo" alt="Logo">
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
@ -123,7 +123,7 @@ usort($committees, function($a, $b) {
|
||||
<div class="committee-section">
|
||||
<div class="committee-title d-flex justify-content-between align-items-center">
|
||||
<span class="fs-5">
|
||||
<?= $index + 1 ?>. <?= htmlspecialchars($c['name']) ?>
|
||||
<?= $index + 1 ?>. <?= htmlspecialchars($c['name'] ?? '') ?>
|
||||
</span>
|
||||
<div class="score-badge">
|
||||
مؤشر الأداء (KPI): <strong><?= round($c['score']) ?>%</strong>
|
||||
@ -131,7 +131,7 @@ usort($committees, function($a, $b) {
|
||||
</div>
|
||||
|
||||
<p class="text-muted small mt-2 mb-2 px-2">
|
||||
<?= htmlspecialchars($c['description']) ?: 'لا يوجد وصف' ?>
|
||||
<?= htmlspecialchars($c['description'] ?? '') ?: 'لا يوجد وصف' ?>
|
||||
</p>
|
||||
|
||||
<div class="px-2 mb-3 small text-secondary">
|
||||
@ -154,8 +154,8 @@ usort($committees, function($a, $b) {
|
||||
<?php foreach ($c['members'] as $m_index => $m): ?>
|
||||
<tr>
|
||||
<td style="text-align: center;"><?= $m_index + 1 ?></td>
|
||||
<td><strong><?= htmlspecialchars($m['full_name']) ?></strong></td>
|
||||
<td><?= htmlspecialchars($m['role']) ?></td>
|
||||
<td><strong><?= htmlspecialchars($m['full_name'] ?? '') ?></strong></td>
|
||||
<td><?= htmlspecialchars($m['role'] ?? '') ?></td>
|
||||
<td dir="ltr" style="text-align: right;"><?= htmlspecialchars($m['phone'] ?? '-') ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
@ -170,7 +170,7 @@ usort($committees, function($a, $b) {
|
||||
|
||||
<!-- Footer -->
|
||||
<div class="mt-5 pt-3 border-top text-center text-muted small">
|
||||
هذا التقرير معتمد ومستخرج آلياً من نظام إدارة اللجان - <?= htmlspecialchars($settings['site_name']) ?>
|
||||
هذا التقرير معتمد ومستخرج آلياً من نظام إدارة اللجان - <?= htmlspecialchars($settings['site_name'] ?? '') ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
202
print_events.php
Normal file
202
print_events.php
Normal file
@ -0,0 +1,202 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/db/config.php';
|
||||
require_once __DIR__ . '/includes/settings.php';
|
||||
require_once __DIR__ . '/includes/permissions.php';
|
||||
|
||||
session_start();
|
||||
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
header("Location: login.php");
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!canView('events')) {
|
||||
die("ليس لديك صلاحية لعرض هذه الصفحة");
|
||||
}
|
||||
|
||||
try {
|
||||
$db = db();
|
||||
$stmt = $db->query("SELECT * FROM events ORDER BY event_date ASC, start_time ASC");
|
||||
$events = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
} catch (PDOException $e) {
|
||||
die("خطأ في قاعدة البيانات");
|
||||
}
|
||||
|
||||
$settings = get_settings();
|
||||
$logo_path = $settings['site_logo'] ?? '';
|
||||
|
||||
if (empty($logo_path) || !file_exists($logo_path)) {
|
||||
if (!empty($logo_path) && file_exists('uploads/charity/' . $logo_path)) {
|
||||
$logo_path = 'uploads/charity/' . $logo_path;
|
||||
} else {
|
||||
$possible_logos = glob('uploads/charity/*logo*.*');
|
||||
if (!empty($possible_logos)) {
|
||||
$logo_path = $possible_logos[0];
|
||||
} else {
|
||||
$logo_path = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$logo_html = '';
|
||||
if ($logo_path) {
|
||||
$logo_html = '<img src="' . $logo_path . '" alt="Logo" style="max-height: 80px;">';
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="ar" dir="rtl">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>طباعة الأحداث والتقويم</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Cairo:wght@400;700&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||||
<style>
|
||||
@page {
|
||||
size: A4;
|
||||
margin: 1.5cm;
|
||||
}
|
||||
body {
|
||||
font-family: 'Cairo', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background: #fff;
|
||||
color: #333;
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
direction: rtl;
|
||||
}
|
||||
.container {
|
||||
max-width: 1000px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.header {
|
||||
text-align: center;
|
||||
border-bottom: 2px solid #00827F;
|
||||
padding-bottom: 20px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
.header h1 {
|
||||
margin: 10px 0 5px;
|
||||
font-size: 24px;
|
||||
color: #00827F;
|
||||
}
|
||||
.header h2 {
|
||||
margin: 5px 0;
|
||||
font-size: 16px;
|
||||
color: #555;
|
||||
}
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
th, td {
|
||||
border: 1px solid #ddd;
|
||||
padding: 12px 8px;
|
||||
text-align: right;
|
||||
}
|
||||
th {
|
||||
background-color: #f4f7f6;
|
||||
color: #00827F;
|
||||
font-weight: bold;
|
||||
}
|
||||
tr:nth-child(even) {
|
||||
background-color: #fafafa;
|
||||
}
|
||||
.no-print {
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
left: 20px;
|
||||
background: #00827F;
|
||||
color: #fff;
|
||||
padding: 10px 25px;
|
||||
border: none;
|
||||
border-radius: 30px;
|
||||
cursor: pointer;
|
||||
z-index: 1000;
|
||||
font-family: 'Cairo', sans-serif;
|
||||
font-weight: bold;
|
||||
box-shadow: 0 4px 10px rgba(0,0,0,0.2);
|
||||
text-decoration: none;
|
||||
display: inline-block;
|
||||
}
|
||||
.date-badge {
|
||||
display: inline-block;
|
||||
background: #e9ecef;
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
}
|
||||
@media print {
|
||||
body { padding: 0; }
|
||||
.no-print { display: none; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<button class="no-print" onclick="window.print()">
|
||||
<i class="fas fa-print"></i> طباعة
|
||||
</button>
|
||||
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<?php if ($logo_html): ?>
|
||||
<div style="margin-bottom: 10px;"><?= $logo_html ?></div>
|
||||
<?php endif; ?>
|
||||
<h1><?= htmlspecialchars($settings['site_name'] ?? 'النظام') ?></h1>
|
||||
<?php if (!empty($settings['site_slogan'])): ?>
|
||||
<h2><?= htmlspecialchars($settings['site_slogan']) ?></h2>
|
||||
<?php endif; ?>
|
||||
<div style="margin-top: 20px; font-size: 20px; font-weight: bold;">قائمة الأحداث والفعاليات</div>
|
||||
</div>
|
||||
|
||||
<?php if (empty($events)): ?>
|
||||
<div style="text-align: center; padding: 50px; color: #777;">
|
||||
لا توجد أحداث مسجلة حالياً
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="5%">#</th>
|
||||
<th width="25%">عنوان الحدث</th>
|
||||
<th width="15%">التاريخ</th>
|
||||
<th width="15%">الوقت</th>
|
||||
<th width="15%">المكان</th>
|
||||
<th width="25%">التفاصيل</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
$count = 1;
|
||||
foreach ($events as $e):
|
||||
// Format date and time safely
|
||||
$date_obj = date_create($e['event_date']);
|
||||
$formatted_date = $date_obj ? date_format($date_obj, 'Y-m-d') : $e['event_date'];
|
||||
|
||||
$time_str = '';
|
||||
if (!empty($e['start_time'])) {
|
||||
$time_str = date('H:i', strtotime($e['start_time']));
|
||||
if (!empty($e['end_time'])) {
|
||||
$time_str .= ' - ' . date('H:i', strtotime($e['end_time']));
|
||||
}
|
||||
}
|
||||
?>
|
||||
<tr>
|
||||
<td><?= $count++ ?></td>
|
||||
<td><strong><?= htmlspecialchars($e['title'] ?? '') ?></strong></td>
|
||||
<td><span class="date-badge"><?= $formatted_date ?></span></td>
|
||||
<td><span dir="ltr"><?= htmlspecialchars($time_str) ?></span></td>
|
||||
<td><?= htmlspecialchars($e['location'] ?? 'غير محدد') ?></td>
|
||||
<td><?= nl2br(htmlspecialchars($e['description'] ?? '')) ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php endif; ?>
|
||||
|
||||
<div style="margin-top: 30px; text-align: center; font-size: 12px; color: #999;">
|
||||
تم استخراج هذا المستند إلكترونياً من النظام بتاريخ <?= date('Y-m-d H:i') ?>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@ -89,7 +89,7 @@ $hijriDate = gregorianToHijri($mail['date_registered']);
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>طباعة بريد وارد - <?= htmlspecialchars($mail['ref_no']) ?></title>
|
||||
<title>طباعة بريد وارد - <?= htmlspecialchars($mail['ref_no'] ?? '') ?></title>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Cairo:wght@400;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
@ -257,17 +257,17 @@ $hijriDate = gregorianToHijri($mail['date_registered']);
|
||||
<div class="header-container">
|
||||
<div class="header-logo">
|
||||
<?php if ($logo): ?>
|
||||
<img src="<?= htmlspecialchars($logo) ?>" alt="Logo">
|
||||
<img src="<?= htmlspecialchars($logo ?? '') ?>" alt="Logo">
|
||||
<?php else: ?>
|
||||
<div style="font-weight: bold; font-size: 26px; color: #00827F;"><?= htmlspecialchars($site_name) ?></div>
|
||||
<div style="font-weight: bold; font-size: 26px; color: #00827F;"><?= htmlspecialchars($site_name ?? '') ?></div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="header-info">
|
||||
<div class="site-name"><?= htmlspecialchars($site_name) ?></div>
|
||||
<div class="site-name"><?= htmlspecialchars($site_name ?? '') ?></div>
|
||||
<?php if (!empty($site_slogan)): ?>
|
||||
<div class="site-slogan"><?= htmlspecialchars($site_slogan) ?></div>
|
||||
<div class="site-slogan"><?= htmlspecialchars($site_slogan ?? '') ?></div>
|
||||
<?php endif; ?>
|
||||
<div style="font-size: 12px; color: #666;"><?= htmlspecialchars($site_address) ?></div>
|
||||
<div style="font-size: 12px; color: #666;"><?= htmlspecialchars($site_address ?? '') ?></div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
@ -278,8 +278,8 @@ $hijriDate = gregorianToHijri($mail['date_registered']);
|
||||
<tr>
|
||||
<td>
|
||||
<div class="mail-meta">
|
||||
<div><strong>رقم القيد:</strong> <?= htmlspecialchars($mail['ref_no']) ?></div>
|
||||
<div><strong>التاريخ:</strong> <?= htmlspecialchars($hijriDate) ?> | <?= htmlspecialchars($mail['date_registered']) ?>م</div>
|
||||
<div><strong>رقم القيد:</strong> <?= htmlspecialchars($mail['ref_no'] ?? '') ?></div>
|
||||
<div><strong>التاريخ:</strong> <?= htmlspecialchars($hijriDate ?? '') ?> | <?= htmlspecialchars($mail['date_registered'] ?? '') ?>م</div>
|
||||
</div>
|
||||
|
||||
<div class="mail-content">
|
||||
|
||||
@ -64,7 +64,7 @@ if ($logo_path) {
|
||||
<html lang="ar" dir="rtl">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>محضر اجتماع - <?= htmlspecialchars($meeting['title']) ?></title>
|
||||
<title>محضر اجتماع - <?= htmlspecialchars($meeting['title'] ?? '') ?></title>
|
||||
<style>
|
||||
body {
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
@ -187,9 +187,9 @@ if ($logo_path) {
|
||||
<?php if ($logo_html): ?>
|
||||
<div style="margin-bottom: 10px;"><?= $logo_html ?></div>
|
||||
<?php endif; ?>
|
||||
<h1><?= htmlspecialchars($settings['site_name']) ?></h1>
|
||||
<h1><?= htmlspecialchars($settings['site_name'] ?? '') ?></h1>
|
||||
<?php if ($settings['site_slogan']): ?>
|
||||
<h2><?= htmlspecialchars($settings['site_slogan']) ?></h2>
|
||||
<h2><?= htmlspecialchars($settings['site_slogan'] ?? '') ?></h2>
|
||||
<?php endif; ?>
|
||||
<div style="margin-top: 20px; font-size: 20px; font-weight: bold; text-decoration: underline;">محضر اجتماع رسمي</div>
|
||||
</div>
|
||||
@ -198,11 +198,11 @@ if ($logo_path) {
|
||||
<div class="info-grid">
|
||||
<div class="info-item">
|
||||
<span class="info-label">عنوان الاجتماع:</span>
|
||||
<?= htmlspecialchars($meeting['title']) ?>
|
||||
<?= htmlspecialchars($meeting['title'] ?? '') ?>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">المنظم:</span>
|
||||
<?= htmlspecialchars($meeting['created_by_name']) ?>
|
||||
<?= htmlspecialchars($meeting['created_by_name'] ?? '') ?>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">التاريخ:</span>
|
||||
|
||||
@ -89,7 +89,7 @@ $hijriDate = gregorianToHijri($mail['date_registered']);
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>طباعة بريد صادر - <?= htmlspecialchars($mail['ref_no']) ?></title>
|
||||
<title>طباعة بريد صادر - <?= htmlspecialchars($mail['ref_no'] ?? '') ?></title>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Cairo:wght@400;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
@ -257,17 +257,17 @@ $hijriDate = gregorianToHijri($mail['date_registered']);
|
||||
<div class="header-container">
|
||||
<div class="header-logo">
|
||||
<?php if ($logo): ?>
|
||||
<img src="<?= htmlspecialchars($logo) ?>" alt="Logo">
|
||||
<img src="<?= htmlspecialchars($logo ?? '') ?>" alt="Logo">
|
||||
<?php else: ?>
|
||||
<div style="font-weight: bold; font-size: 26px; color: #00827F;"><?= htmlspecialchars($site_name) ?></div>
|
||||
<div style="font-weight: bold; font-size: 26px; color: #00827F;"><?= htmlspecialchars($site_name ?? '') ?></div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="header-info">
|
||||
<div class="site-name"><?= htmlspecialchars($site_name) ?></div>
|
||||
<div class="site-name"><?= htmlspecialchars($site_name ?? '') ?></div>
|
||||
<?php if (!empty($site_slogan)): ?>
|
||||
<div class="site-slogan"><?= htmlspecialchars($site_slogan) ?></div>
|
||||
<div class="site-slogan"><?= htmlspecialchars($site_slogan ?? '') ?></div>
|
||||
<?php endif; ?>
|
||||
<div style="font-size: 12px; color: #666;"><?= htmlspecialchars($site_address) ?></div>
|
||||
<div style="font-size: 12px; color: #666;"><?= htmlspecialchars($site_address ?? '') ?></div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
@ -278,8 +278,8 @@ $hijriDate = gregorianToHijri($mail['date_registered']);
|
||||
<tr>
|
||||
<td>
|
||||
<div class="mail-meta">
|
||||
<div><strong>رقم القيد:</strong> <?= htmlspecialchars($mail['ref_no']) ?></div>
|
||||
<div><strong>التاريخ:</strong> <?= htmlspecialchars($hijriDate) ?> | <?= htmlspecialchars($mail['date_registered']) ?>م</div>
|
||||
<div><strong>رقم القيد:</strong> <?= htmlspecialchars($mail['ref_no'] ?? '') ?></div>
|
||||
<div><strong>التاريخ:</strong> <?= htmlspecialchars($hijriDate ?? '') ?> | <?= htmlspecialchars($mail['date_registered'] ?? '') ?>م</div>
|
||||
</div>
|
||||
|
||||
<div class="mail-content">
|
||||
|
||||
@ -133,8 +133,8 @@ $recent_transactions = $stmt->fetchAll();
|
||||
?>
|
||||
<span class="badge <?= $b[0] ?>"><?= $b[1] ?></span>
|
||||
</td>
|
||||
<td class="fw-bold"><?= htmlspecialchars($t['item_name']) ?></td>
|
||||
<td><?= htmlspecialchars($t['store_name']) ?></td>
|
||||
<td class="fw-bold"><?= htmlspecialchars($t['item_name'] ?? '') ?></td>
|
||||
<td><?= htmlspecialchars($t['store_name'] ?? '') ?></td>
|
||||
<td dir="ltr" class="text-end fw-bold"><?= number_format($t['quantity'], 2) ?></td>
|
||||
<td><?= htmlspecialchars($t['user_name'] ?? '-') ?></td>
|
||||
<td><?= date('Y-m-d H:i', strtotime($t['created_at'])) ?></td>
|
||||
|
||||
@ -125,7 +125,7 @@ $history = $stmt->fetchAll();
|
||||
<select name="store_id" class="form-select" required>
|
||||
<option value="">-- اختر المستودع --</option>
|
||||
<?php foreach ($stores as $store): ?>
|
||||
<option value="<?= $store['id'] ?>"><?= htmlspecialchars($store['name']) ?></option>
|
||||
<option value="<?= $store['id'] ?>"><?= htmlspecialchars($store['name'] ?? '') ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
@ -134,7 +134,7 @@ $history = $stmt->fetchAll();
|
||||
<select name="item_id" class="form-select" required>
|
||||
<option value="">-- اختر الصنف --</option>
|
||||
<?php foreach ($items as $item): ?>
|
||||
<option value="<?= $item['id'] ?>"><?= htmlspecialchars($item['name']) ?> (<?= htmlspecialchars($item['sku'] ?: '-') ?>)</option>
|
||||
<option value="<?= $item['id'] ?>"><?= htmlspecialchars($item['name'] ?? '') ?> (<?= htmlspecialchars($item['sku'] ?: '-') ?>)</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
@ -194,8 +194,8 @@ $history = $stmt->fetchAll();
|
||||
<?php foreach ($history as $h): ?>
|
||||
<tr>
|
||||
<td class="ps-4"><?= $h['id'] ?></td>
|
||||
<td class="fw-bold"><?= htmlspecialchars($h['item_name']) ?></td>
|
||||
<td><?= htmlspecialchars($h['store_name']) ?></td>
|
||||
<td class="fw-bold"><?= htmlspecialchars($h['item_name'] ?? '') ?></td>
|
||||
<td><?= htmlspecialchars($h['store_name'] ?? '') ?></td>
|
||||
<td class="text-success fw-bold" dir="ltr">+<?= number_format($h['quantity'], 2) ?></td>
|
||||
<td><?= htmlspecialchars($h['user_name'] ?? '-') ?></td>
|
||||
<td><?= date('Y-m-d H:i', strtotime($h['created_at'])) ?></td>
|
||||
|
||||
@ -173,7 +173,7 @@ $categories = db()->query("SELECT * FROM stock_categories ORDER BY name ASC")->f
|
||||
<?php endif; ?>
|
||||
<?php foreach ($items as $item): ?>
|
||||
<tr>
|
||||
<td class="ps-4 fw-bold"><?= htmlspecialchars($item['name']) ?></td>
|
||||
<td class="ps-4 fw-bold"><?= htmlspecialchars($item['name'] ?? '') ?></td>
|
||||
<td><?= htmlspecialchars($item['sku'] ?? '-') ?></td>
|
||||
<td><span class="badge bg-secondary"><?= htmlspecialchars($item['category_name'] ?? 'عام') ?></span></td>
|
||||
<td>
|
||||
@ -184,8 +184,8 @@ $categories = db()->query("SELECT * FROM stock_categories ORDER BY name ASC")->f
|
||||
<span class="<?= $cls ?>"><?= number_format($qty, 2) ?></span>
|
||||
</td>
|
||||
<td><?= number_format($item['min_quantity']) ?></td>
|
||||
<td><?= htmlspecialchars($item['unit']) ?></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($item['created_by'] ?? null)) ?></small></td>
|
||||
<td><?= htmlspecialchars($item['unit'] ?? '') ?></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($item['created_by'] ?? $item['updated_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user-edit text-warning opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($item['updated_by'] ?? null)) ?></small></td>
|
||||
<td class="text-center">
|
||||
<?php if (canEdit('stock_items')): ?>
|
||||
@ -238,7 +238,7 @@ $categories = db()->query("SELECT * FROM stock_categories ORDER BY name ASC")->f
|
||||
<select name="category_id" id="modalCategory" class="form-select">
|
||||
<option value="">-- اختر --</option>
|
||||
<?php foreach ($categories as $cat): ?>
|
||||
<option value="<?= $cat['id'] ?>"><?= htmlspecialchars($cat['name']) ?></option>
|
||||
<option value="<?= $cat['id'] ?>"><?= htmlspecialchars($cat['name'] ?? '') ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
@ -158,10 +158,10 @@ $items = db()->query("SELECT * FROM stock_items ORDER BY name ASC")->fetchAll();
|
||||
<?php foreach ($loans as $loan): ?>
|
||||
<tr>
|
||||
<td class="fw-bold">
|
||||
<?= htmlspecialchars($loan['borrower_name']) ?>
|
||||
<br><small class="text-muted"><?= htmlspecialchars($loan['borrower_phone']) ?></small>
|
||||
<?= htmlspecialchars($loan['borrower_name'] ?? '') ?>
|
||||
<br><small class="text-muted"><?= htmlspecialchars($loan['borrower_phone'] ?? '') ?></small>
|
||||
</td>
|
||||
<td><?= htmlspecialchars($loan['item_name']) ?></td>
|
||||
<td><?= htmlspecialchars($loan['item_name'] ?? '') ?></td>
|
||||
<td class="fw-bold"><?= number_format($loan['quantity'], 2) ?></td>
|
||||
<td><?= date('Y-m-d', strtotime($loan['lend_date'])) ?></td>
|
||||
<td>
|
||||
@ -172,7 +172,7 @@ $items = db()->query("SELECT * FROM stock_items ORDER BY name ASC")->fetchAll();
|
||||
<span class="<?= $cls ?>"><?= date('Y-m-d', $due) ?></span>
|
||||
</td>
|
||||
<td><span class="badge bg-warning text-dark">نشط</span></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($loan['created_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($loan['created_by'] ?? $loan['updated_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user-edit text-warning opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($loan['updated_by'] ?? null)) ?></small></td>
|
||||
<td>
|
||||
<form method="POST" onsubmit="return confirm('هل استلمت المواد المرجعة؟ سيتم إضافتها للمخزون.')">
|
||||
@ -208,7 +208,7 @@ $items = db()->query("SELECT * FROM stock_items ORDER BY name ASC")->fetchAll();
|
||||
<label class="form-label">المستودع</label>
|
||||
<select name="store_id" class="form-select" required>
|
||||
<?php foreach ($stores as $store): ?>
|
||||
<option value="<?= $store['id'] ?>"><?= htmlspecialchars($store['name']) ?></option>
|
||||
<option value="<?= $store['id'] ?>"><?= htmlspecialchars($store['name'] ?? '') ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
@ -216,7 +216,7 @@ $items = db()->query("SELECT * FROM stock_items ORDER BY name ASC")->fetchAll();
|
||||
<label class="form-label">المادة</label>
|
||||
<select name="item_id" class="form-select" required>
|
||||
<?php foreach ($items as $item): ?>
|
||||
<option value="<?= $item['id'] ?>"><?= htmlspecialchars($item['name']) ?></option>
|
||||
<option value="<?= $item['id'] ?>"><?= htmlspecialchars($item['name'] ?? '') ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
@ -125,7 +125,7 @@ $history = $stmt->fetchAll();
|
||||
<select name="store_id" class="form-select" required>
|
||||
<option value="">-- اختر المستودع --</option>
|
||||
<?php foreach ($stores as $store): ?>
|
||||
<option value="<?= $store['id'] ?>"><?= htmlspecialchars($store['name']) ?></option>
|
||||
<option value="<?= $store['id'] ?>"><?= htmlspecialchars($store['name'] ?? '') ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
@ -134,7 +134,7 @@ $history = $stmt->fetchAll();
|
||||
<select name="item_id" class="form-select" required>
|
||||
<option value="">-- اختر الصنف --</option>
|
||||
<?php foreach ($items as $item): ?>
|
||||
<option value="<?= $item['id'] ?>"><?= htmlspecialchars($item['name']) ?> (<?= htmlspecialchars($item['sku'] ?: '-') ?>)</option>
|
||||
<option value="<?= $item['id'] ?>"><?= htmlspecialchars($item['name'] ?? '') ?> (<?= htmlspecialchars($item['sku'] ?: '-') ?>)</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
@ -210,8 +210,8 @@ $history = $stmt->fetchAll();
|
||||
<span class="badge bg-danger">صرف</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class="fw-bold"><?= htmlspecialchars($h['item_name']) ?></td>
|
||||
<td><?= htmlspecialchars($h['store_name']) ?></td>
|
||||
<td class="fw-bold"><?= htmlspecialchars($h['item_name'] ?? '') ?></td>
|
||||
<td><?= htmlspecialchars($h['store_name'] ?? '') ?></td>
|
||||
<td class="text-danger fw-bold" dir="ltr">-<?= number_format($h['quantity'], 2) ?></td>
|
||||
<td><?= htmlspecialchars($h['user_name'] ?? '-') ?></td>
|
||||
<td><?= date('Y-m-d H:i', strtotime($h['created_at'])) ?></td>
|
||||
|
||||
@ -71,7 +71,7 @@ $items = db()->query("SELECT * FROM stock_items ORDER BY name ASC")->fetchAll();
|
||||
<select name="store_id" class="form-select">
|
||||
<option value="">الكل</option>
|
||||
<?php foreach ($stores as $s): ?>
|
||||
<option value="<?= $s['id'] ?>" <?= $store_id == $s['id'] ? 'selected' : '' ?>><?= htmlspecialchars($s['name']) ?></option>
|
||||
<option value="<?= $s['id'] ?>" <?= $store_id == $s['id'] ? 'selected' : '' ?>><?= htmlspecialchars($s['name'] ?? '') ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
@ -80,7 +80,7 @@ $items = db()->query("SELECT * FROM stock_items ORDER BY name ASC")->fetchAll();
|
||||
<select name="item_id" class="form-select">
|
||||
<option value="">الكل</option>
|
||||
<?php foreach ($items as $i): ?>
|
||||
<option value="<?= $i['id'] ?>" <?= $item_id == $i['id'] ? 'selected' : '' ?>><?= htmlspecialchars($i['name']) ?></option>
|
||||
<option value="<?= $i['id'] ?>" <?= $item_id == $i['id'] ? 'selected' : '' ?>><?= htmlspecialchars($i['name'] ?? '') ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
@ -137,8 +137,8 @@ $items = db()->query("SELECT * FROM stock_items ORDER BY name ASC")->fetchAll();
|
||||
echo $types[$t['transaction_type']] ?? $t['transaction_type'];
|
||||
?>
|
||||
</td>
|
||||
<td><?= htmlspecialchars($t['store_name']) ?></td>
|
||||
<td class="fw-bold"><?= htmlspecialchars($t['item_name']) ?></td>
|
||||
<td><?= htmlspecialchars($t['store_name'] ?? '') ?></td>
|
||||
<td class="fw-bold"><?= htmlspecialchars($t['item_name'] ?? '') ?></td>
|
||||
<td dir="ltr" class="text-end fw-bold">
|
||||
<?php if ($t['transaction_type'] == 'in' || $t['transaction_type'] == 'return'): ?>
|
||||
<span class="text-success">+<?= number_format($t['quantity'], 2) ?></span>
|
||||
@ -149,7 +149,7 @@ $items = db()->query("SELECT * FROM stock_items ORDER BY name ASC")->fetchAll();
|
||||
<td><?= htmlspecialchars($t['user_name'] ?? '-') ?></td>
|
||||
<td class="small text-muted">
|
||||
<?php if ($t['reference']): ?>
|
||||
<strong>المرجع:</strong> <?= htmlspecialchars($t['reference']) ?><br>
|
||||
<strong>المرجع:</strong> <?= htmlspecialchars($t['reference'] ?? '') ?><br>
|
||||
<?php endif; ?>
|
||||
<?= htmlspecialchars($t['notes'] ?? '') ?>
|
||||
</td>
|
||||
|
||||
@ -117,7 +117,7 @@ $categories = db()->query("SELECT * FROM stock_categories ORDER BY name ASC")->f
|
||||
<?php foreach ($stores as $s): ?>
|
||||
<tr>
|
||||
<td><?= $s['id'] ?></td>
|
||||
<td class="fw-bold"><?= htmlspecialchars($s['name']) ?></td>
|
||||
<td class="fw-bold"><?= htmlspecialchars($s['name'] ?? '') ?></td>
|
||||
<td><?= htmlspecialchars($s['location'] ?? '-') ?></td>
|
||||
<td><?= date('Y-m-d', strtotime($s['created_at'])) ?></td>
|
||||
<td>
|
||||
@ -166,7 +166,7 @@ $categories = db()->query("SELECT * FROM stock_categories ORDER BY name ASC")->f
|
||||
<?php foreach ($categories as $c): ?>
|
||||
<tr>
|
||||
<td><?= $c['id'] ?></td>
|
||||
<td class="fw-bold"><?= htmlspecialchars($c['name']) ?></td>
|
||||
<td class="fw-bold"><?= htmlspecialchars($c['name'] ?? '') ?></td>
|
||||
<td><?= htmlspecialchars($c['description'] ?? '-') ?></td>
|
||||
<td><?= date('Y-m-d', strtotime($c['created_at'])) ?></td>
|
||||
<td>
|
||||
|
||||
0
test_db.php
Normal file
0
test_db.php
Normal file
1
test_insert.php
Normal file
1
test_insert.php
Normal file
@ -0,0 +1 @@
|
||||
|
||||
0
test_trigger2.php
Normal file
0
test_trigger2.php
Normal file
0
test_trigger3.php
Normal file
0
test_trigger3.php
Normal file
@ -29,7 +29,7 @@ $trial_balance = get_trial_balance();
|
||||
$total_credit += $row['total_credit'];
|
||||
?>
|
||||
<tr>
|
||||
<td><?= htmlspecialchars($row['account_name']) ?></td>
|
||||
<td><?= htmlspecialchars($row['account_name'] ?? '') ?></td>
|
||||
<td><?= number_format($row['total_debit'], 2) ?></td>
|
||||
<td><?= number_format($row['total_credit'], 2) ?></td>
|
||||
</tr>
|
||||
|
||||
@ -85,7 +85,7 @@ function getStatusBadge($mail) {
|
||||
if ($status_name == 'in_progress') $display_name = 'قيد المعالجة';
|
||||
if ($status_name == 'closed') $display_name = 'مكتمل';
|
||||
|
||||
return '<span class="badge" style="background-color: ' . $status_color . ';">' . htmlspecialchars($display_name) . '</span>';
|
||||
return '<span class="badge" style="background-color: ' . $status_color . ';">' . htmlspecialchars($display_name ?? '') . '</span>';
|
||||
}
|
||||
?>
|
||||
|
||||
@ -257,7 +257,7 @@ function getStatusBadge($mail) {
|
||||
<?php foreach ($my_assignments as $mail): ?>
|
||||
<tr style="cursor: pointer;" onclick="window.location='view_mail.php?id=<?= $mail['id'] ?>&type=<?= $mail['type'] ?>'">
|
||||
<td class="ps-4 fw-bold text-primary"><?= $mail['ref_no'] ?></td>
|
||||
<td><?= htmlspecialchars($mail['subject']) ?></td>
|
||||
<td><?= htmlspecialchars($mail['subject'] ?? '') ?></td>
|
||||
<td>
|
||||
<?php if ($mail['due_date']): ?>
|
||||
<small class="<?= (strtotime($mail['due_date']) < time() && $mail['status_name'] != 'closed') ? 'text-danger fw-bold' : 'text-muted' ?>">
|
||||
@ -298,7 +298,7 @@ function getStatusBadge($mail) {
|
||||
<?php foreach ($recent_activity as $act): ?>
|
||||
<a href="view_mail.php?id=<?= $act['id'] ?>&type=<?= $act['type'] ?>" class="list-group-item list-group-item-action p-3 border-0 border-bottom">
|
||||
<div class="d-flex w-100 justify-content-between mb-1">
|
||||
<h6 class="mb-1 fw-bold text-truncate" title="<?= htmlspecialchars($act['subject']) ?>"><?= htmlspecialchars($act['subject']) ?></h6>
|
||||
<h6 class="mb-1 fw-bold text-truncate" title="<?= htmlspecialchars($act['subject'] ?? '') ?>"><?= htmlspecialchars($act['subject'] ?? '') ?></h6>
|
||||
<small class="text-muted"><?= date('m-d', strtotime($act['updated_at'])) ?></small>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
|
||||
11
users.php
11
users.php
@ -3,7 +3,7 @@ require_once __DIR__ . '/includes/header.php';
|
||||
require_once __DIR__ . '/includes/pagination.php';
|
||||
|
||||
if (!canView('users')) {
|
||||
redirect('index.php');
|
||||
redirect('user_dashboard.php');
|
||||
}
|
||||
|
||||
$error = '';
|
||||
@ -35,7 +35,8 @@ $modules = [
|
||||
'meetings' => 'الاجتماعات',
|
||||
'committees' => 'اللجان',
|
||||
'charity_members' => 'أعضاء الجمعية',
|
||||
'charity_plans' => 'الخطط والأهداف'
|
||||
'charity_plans' => 'الخطط والأهداف',
|
||||
'events' => 'التقويم والأحداث'
|
||||
];
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
@ -261,8 +262,8 @@ if (isset($_GET['action']) && $_GET['action'] === 'edit' && isset($_GET['id']))
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class="fw-bold"><?= htmlspecialchars($user['full_name']) ?></td>
|
||||
<td><?= htmlspecialchars($user['username']) ?></td>
|
||||
<td class="fw-bold"><?= htmlspecialchars($user['full_name'] ?? '') ?></td>
|
||||
<td><?= htmlspecialchars($user['username'] ?? '') ?></td>
|
||||
<td><?= htmlspecialchars($user['email'] ?? '-') ?></td>
|
||||
<td>
|
||||
<?php if ($user['role'] === 'admin'): ?>
|
||||
@ -274,7 +275,7 @@ if (isset($_GET['action']) && $_GET['action'] === 'edit' && isset($_GET['id']))
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><?= $user['created_at'] ?></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($user['created_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user text-primary opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($user['created_by'] ?? $user['updated_by'] ?? null)) ?></small></td>
|
||||
<td><small class="text-muted"><i class="fas fa-user-edit text-warning opacity-50 me-1"></i><?= htmlspecialchars(getAuditUserName($user['updated_by'] ?? null)) ?></small></td>
|
||||
<td class="pe-4 text-center">
|
||||
<?php if (canEdit('users')): ?>
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
require_once __DIR__ . '/includes/header.php';
|
||||
|
||||
if (!canView('committees')) {
|
||||
redirect('index.php');
|
||||
redirect('user_dashboard.php');
|
||||
}
|
||||
|
||||
$id = $_GET['id'] ?? 0;
|
||||
@ -170,7 +170,7 @@ if ($tab === 'members') {
|
||||
?>
|
||||
|
||||
<div 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">إدارة اللجنة: <?= htmlspecialchars($committee['name']) ?></h1>
|
||||
<h1 class="h2">إدارة اللجنة: <?= htmlspecialchars($committee['name'] ?? '') ?></h1>
|
||||
<a href="committees.php" class="btn btn-secondary shadow-sm">
|
||||
<i class="fas fa-arrow-right"></i> عودة للجان
|
||||
</a>
|
||||
@ -190,7 +190,7 @@ if ($tab === 'members') {
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<p class="lead text-muted"><?= nl2br(htmlspecialchars($committee['description'])) ?></p>
|
||||
<p class="lead text-muted"><?= nl2br(htmlspecialchars($committee['description'] ?? '')) ?></p>
|
||||
|
||||
<ul class="nav nav-tabs mb-4">
|
||||
<li class="nav-item">
|
||||
@ -237,10 +237,10 @@ if ($tab === 'members') {
|
||||
<?php if (count($members) > 0): ?>
|
||||
<?php foreach ($members as $m): ?>
|
||||
<tr>
|
||||
<td class="ps-4 fw-bold"><?= htmlspecialchars($m['full_name']) ?></td>
|
||||
<td><?= htmlspecialchars($m['email']) ?></td>
|
||||
<td class="ps-4 fw-bold"><?= htmlspecialchars($m['full_name'] ?? '') ?></td>
|
||||
<td><?= htmlspecialchars($m['email'] ?? '') ?></td>
|
||||
<td><a href="tel:<?= htmlspecialchars($m['phone'] ?? '') ?>"><?= htmlspecialchars($m['phone'] ?? '-' ) ?></a></td>
|
||||
<td><span class="badge bg-info text-dark"><?= htmlspecialchars($m['role']) ?></span></td>
|
||||
<td><span class="badge bg-info text-dark"><?= htmlspecialchars($m['role'] ?? '') ?></span></td>
|
||||
<td><?= $m['joined_at'] ?></td>
|
||||
<td class="text-center">
|
||||
<?php if (canEdit('committees')): ?>
|
||||
@ -285,7 +285,7 @@ if ($tab === 'members') {
|
||||
<select name="charity_member_id" class="form-select" required>
|
||||
<option value="">-- اختر مستخدم --</option>
|
||||
<?php foreach ($available_users as $u): ?>
|
||||
<option value="<?= $u['id'] ?>"><?= htmlspecialchars($u['full_name']) ?> (<?= htmlspecialchars($u['email']) ?>)</option>
|
||||
<option value="<?= $u['id'] ?>"><?= htmlspecialchars($u['full_name'] ?? '') ?> (<?= htmlspecialchars($u['email'] ?? '') ?>)</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
@ -379,7 +379,7 @@ if ($tab === 'members') {
|
||||
<?php foreach ($plans as $p): ?>
|
||||
<tr>
|
||||
<td class="ps-4 fw-bold">
|
||||
<?= htmlspecialchars($p['title']) ?>
|
||||
<?= htmlspecialchars($p['title'] ?? '') ?>
|
||||
<div class="small text-muted text-truncate" style="max-width: 200px;"><?= htmlspecialchars($p['description'] ?? '') ?></div>
|
||||
</td>
|
||||
<td><?= $p['start_date'] ?: '-' ?></td>
|
||||
@ -516,7 +516,7 @@ if ($tab === 'members') {
|
||||
<?php foreach ($activities as $a): ?>
|
||||
<tr>
|
||||
<td class="ps-4 fw-bold">
|
||||
<?= htmlspecialchars($a['title']) ?>
|
||||
<?= htmlspecialchars($a['title'] ?? '') ?>
|
||||
<div class="small text-muted text-truncate" style="max-width: 200px;"><?= htmlspecialchars($a['description'] ?? '') ?></div>
|
||||
</td>
|
||||
<td><?= $a['activity_date'] ?: '-' ?></td>
|
||||
|
||||
@ -5,7 +5,7 @@ require_once __DIR__ . '/m_services/MailService.php';
|
||||
$id = $_GET['id'] ?? 0;
|
||||
$type = $_GET['type'] ?? '';
|
||||
|
||||
if (!$id) redirect('index.php');
|
||||
if (!$id) redirect('user_dashboard.php');
|
||||
|
||||
// If type is not provided, try to find it in any of the tables (for backward compatibility if any links were missed)
|
||||
if (!$type) {
|
||||
@ -20,7 +20,7 @@ if (!$type) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!$type) redirect('index.php');
|
||||
if (!$type) redirect('user_dashboard.php');
|
||||
|
||||
$table_mail = $type . '_mail';
|
||||
$table_attachments = $type . '_attachments';
|
||||
@ -36,14 +36,14 @@ $stmt = db()->prepare("SELECT m.*, u1.full_name as assigned_name, u2.full_name a
|
||||
$stmt->execute([$id]);
|
||||
$mail = $stmt->fetch();
|
||||
|
||||
if (!$mail) redirect('index.php');
|
||||
if (!$mail) redirect('user_dashboard.php');
|
||||
|
||||
// Add back the type for logic below
|
||||
$mail['type'] = $type;
|
||||
|
||||
// Check if user has view permission for this mail type
|
||||
if (!canView($type)) {
|
||||
redirect('index.php');
|
||||
redirect('user_dashboard.php');
|
||||
}
|
||||
|
||||
// Security check for internal mail: only sender or recipient can view
|
||||
@ -81,15 +81,15 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_comment'])) {
|
||||
|
||||
$html = "
|
||||
<div dir='rtl'>
|
||||
<h3>مرحباً " . htmlspecialchars($referred_user['full_name']) . "</h3>
|
||||
<p>قام <strong>" . htmlspecialchars($sender_name) . "</strong> بإحالة بريد إليك مع التعليق التالي:</p>
|
||||
<h3>مرحباً " . htmlspecialchars($referred_user['full_name'] ?? '') . "</h3>
|
||||
<p>قام <strong>" . htmlspecialchars($sender_name ?? '') . "</strong> بإحالة بريد إليك مع التعليق التالي:</p>
|
||||
<blockquote style='background: #f9f9f9; padding: 10px; border-left: 5px solid #ccc;'>
|
||||
" . nl2br(htmlspecialchars($comment)) . "
|
||||
" . nl2br(htmlspecialchars($comment ?? '')) . "
|
||||
</blockquote>
|
||||
<p><strong>تفاصيل البريد:</strong></p>
|
||||
<ul>
|
||||
<li><strong>رقم القيد:</strong> " . htmlspecialchars($mail['ref_no']) . "</li>
|
||||
<li><strong>الموضوع:</strong> " . htmlspecialchars($mail['subject']) . "</li>
|
||||
<li><strong>رقم القيد:</strong> " . htmlspecialchars($mail['ref_no'] ?? '') . "</li>
|
||||
<li><strong>الموضوع:</strong> " . htmlspecialchars($mail['subject'] ?? '') . "</li>
|
||||
</ul>
|
||||
<p><a href='{$mail_link}' style='display: inline-block; padding: 10px 20px; background-color: #007bff; color: white; text-decoration: none; border-radius: 5px;'>عرض البريد</a></p>
|
||||
</div>
|
||||
@ -271,7 +271,7 @@ if ($type == 'internal') {
|
||||
if ($s_name == 'in_progress') $d_name = 'قيد المعالجة';
|
||||
if ($s_name == 'closed') $d_name = ($type == 'internal' ? 'مؤرشف' : 'مكتمل');
|
||||
?>
|
||||
<span class="badge" style="background-color: <?= $s_color ?>;"><?= htmlspecialchars($d_name) ?></span>
|
||||
<span class="badge" style="background-color: <?= $s_color ?>;"><?= htmlspecialchars($d_name ?? '') ?></span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
@ -281,7 +281,7 @@ if ($type == 'internal') {
|
||||
if ($type == 'outbound' || $type == 'internal') {
|
||||
echo $mail['subject'];
|
||||
} else {
|
||||
echo htmlspecialchars($mail['subject']);
|
||||
echo htmlspecialchars($mail['subject'] ?? '');
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
@ -290,11 +290,11 @@ if ($type == 'internal') {
|
||||
<?php if ($type == 'internal'): ?>
|
||||
<div class="col-md-6">
|
||||
<label class="text-muted small">المرسل</label>
|
||||
<p class="fw-bold text-primary"><?= htmlspecialchars($mail['creator_name']) ?></p>
|
||||
<p class="fw-bold text-primary"><?= htmlspecialchars($mail['creator_name'] ?? '') ?></p>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="text-muted small">المستلم</label>
|
||||
<p class="fw-bold text-success"><?= htmlspecialchars($mail['assigned_name']) ?></p>
|
||||
<p class="fw-bold text-success"><?= htmlspecialchars($mail['assigned_name'] ?? '') ?></p>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="col-md-6">
|
||||
@ -349,7 +349,7 @@ if ($type == 'internal') {
|
||||
<select name="referred_user_id" class="form-select form-select-sm">
|
||||
<option value="">-- اختر موظفاً للإحالة --</option>
|
||||
<?php foreach ($all_users as $u): ?>
|
||||
<option value="<?= $u['id'] ?>"><?= htmlspecialchars($u['full_name']) ?> (<?= ucfirst($u['role']) ?>)</option>
|
||||
<option value="<?= $u['id'] ?>"><?= htmlspecialchars($u['full_name'] ?? '') ?> (<?= ucfirst($u['role']) ?>)</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
@ -363,16 +363,16 @@ if ($type == 'internal') {
|
||||
<div class="border-bottom pb-2 mb-2">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div>
|
||||
<span class="fw-bold text-primary"><?= htmlspecialchars($c['full_name']) ?></span>
|
||||
<span class="fw-bold text-primary"><?= htmlspecialchars($c['full_name'] ?? '') ?></span>
|
||||
<?php if ($c['referred_name']): ?>
|
||||
<span class="badge bg-info text-dark ms-2 small">
|
||||
<i class="fas fa-share ms-1"></i> إحالة إلى: <?= htmlspecialchars($c['referred_name']) ?>
|
||||
<i class="fas fa-share ms-1"></i> إحالة إلى: <?= htmlspecialchars($c['referred_name'] ?? '') ?>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<span class="text-muted small"><?= $c['created_at'] ?></span>
|
||||
</div>
|
||||
<p class="mb-0 small"><?= nl2br(htmlspecialchars($c['comment'])) ?></p>
|
||||
<p class="mb-0 small"><?= nl2br(htmlspecialchars($c['comment'] ?? '')) ?></p>
|
||||
</div>
|
||||
<?php endforeach; else: ?>
|
||||
<p class="text-center text-muted small">لا توجد ردود بعد</p>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user