editing forms redirections
This commit is contained in:
parent
fe46d13ff0
commit
e1febf7e84
@ -13,7 +13,8 @@ $error_msg = '';
|
|||||||
// Handle Re-enable SMTP
|
// Handle Re-enable SMTP
|
||||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['enable_smtp'])) {
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['enable_smtp'])) {
|
||||||
db()->query("UPDATE smtp_settings SET is_enabled = 1, consecutive_failures = 0 WHERE id = 1");
|
db()->query("UPDATE smtp_settings SET is_enabled = 1, consecutive_failures = 0 WHERE id = 1");
|
||||||
$success_msg = 'تم إعادة تفعيل SMTP وتصفير عداد الأخطاء';
|
$_SESSION['success'] = 'تم إعادة تفعيل SMTP وتصفير عداد الأخطاء';
|
||||||
|
redirect('charity-settings.php');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch charity settings
|
// Fetch charity settings
|
||||||
@ -54,9 +55,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['update_charity'])) {
|
|||||||
|
|
||||||
$stmt = db()->prepare("UPDATE charity_settings SET charity_name = ?, charity_email = ?, charity_phone = ?, charity_address = ?, charity_logo = ?, charity_favicon = ? WHERE id = 1");
|
$stmt = db()->prepare("UPDATE charity_settings SET charity_name = ?, charity_email = ?, charity_phone = ?, charity_address = ?, charity_logo = ?, charity_favicon = ? WHERE id = 1");
|
||||||
$stmt->execute([$charity_name, $charity_email, $charity_phone, $charity_address, $charity_logo, $charity_favicon]);
|
$stmt->execute([$charity_name, $charity_email, $charity_phone, $charity_address, $charity_logo, $charity_favicon]);
|
||||||
$success_msg = 'تم تحديث إعدادات الجمعية بنجاح';
|
$_SESSION['success'] = 'تم تحديث إعدادات الجمعية بنجاح';
|
||||||
$stmt = db()->query("SELECT * FROM charity_settings WHERE id = 1");
|
redirect('charity-settings.php');
|
||||||
$charity = $stmt->fetch();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle SMTP Settings Update
|
// Handle SMTP Settings Update
|
||||||
@ -73,9 +73,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['update_smtp'])) {
|
|||||||
$_POST['reply_to'],
|
$_POST['reply_to'],
|
||||||
(int)$_POST['max_failures']
|
(int)$_POST['max_failures']
|
||||||
]);
|
]);
|
||||||
$success_msg = 'تم تحديث إعدادات البريد (SMTP) بنجاح';
|
$_SESSION['success'] = 'تم تحديث إعدادات البريد (SMTP) بنجاح';
|
||||||
$stmt = db()->query("SELECT * FROM smtp_settings WHERE id = 1");
|
redirect('charity-settings.php');
|
||||||
$smtp = $stmt->fetch();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle Test Email
|
// Handle Test Email
|
||||||
@ -83,10 +82,11 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['test_email_addr'])) {
|
|||||||
$to = $_POST['test_email_addr'];
|
$to = $_POST['test_email_addr'];
|
||||||
$res = MailService::sendMail($to, "رسالة تجريبية - Test Email", "<p>إذا كنت ترى هذه الرسالة، فإن إعدادات SMTP تعمل بشكل صحيح.</p>");
|
$res = MailService::sendMail($to, "رسالة تجريبية - Test Email", "<p>إذا كنت ترى هذه الرسالة، فإن إعدادات SMTP تعمل بشكل صحيح.</p>");
|
||||||
if ($res['success']) {
|
if ($res['success']) {
|
||||||
$success_msg = "تم إرسال الرسالة التجريبية بنجاح إلى $to";
|
$_SESSION['success'] = "تم إرسال الرسالة التجريبية بنجاح إلى $to";
|
||||||
} else {
|
} else {
|
||||||
$error_msg = "فشل إرسال الرسالة التجريبية: " . $res['error'];
|
$_SESSION['error'] = "فشل إرسال الرسالة التجريبية: " . $res['error'];
|
||||||
}
|
}
|
||||||
|
redirect('charity-settings.php');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle Status Operations
|
// Handle Status Operations
|
||||||
@ -97,7 +97,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_status'])) {
|
|||||||
if ($is_default) db()->query("UPDATE mailbox_statuses SET is_default = 0");
|
if ($is_default) db()->query("UPDATE mailbox_statuses SET is_default = 0");
|
||||||
$stmt = db()->prepare("INSERT INTO mailbox_statuses (name, color, is_default) VALUES (?, ?, ?)");
|
$stmt = db()->prepare("INSERT INTO mailbox_statuses (name, color, is_default) VALUES (?, ?, ?)");
|
||||||
$stmt->execute([$name, $color, $is_default]);
|
$stmt->execute([$name, $color, $is_default]);
|
||||||
$success_msg = 'تم إضافة نوع الحالة بنجاح';
|
$_SESSION['success'] = 'تم إضافة نوع الحالة بنجاح';
|
||||||
|
redirect('charity-settings.php');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['update_status'])) {
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['update_status'])) {
|
||||||
@ -108,7 +109,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['update_status'])) {
|
|||||||
if ($is_default) db()->query("UPDATE mailbox_statuses SET is_default = 0");
|
if ($is_default) db()->query("UPDATE mailbox_statuses SET is_default = 0");
|
||||||
$stmt = db()->prepare("UPDATE mailbox_statuses SET name = ?, color = ?, is_default = ? WHERE id = ?");
|
$stmt = db()->prepare("UPDATE mailbox_statuses SET name = ?, color = ?, is_default = ? WHERE id = ?");
|
||||||
$stmt->execute([$name, $color, $is_default, $id]);
|
$stmt->execute([$name, $color, $is_default, $id]);
|
||||||
$success_msg = 'تم تحديث نوع الحالة بنجاح';
|
$_SESSION['success'] = 'تم تحديث نوع الحالة بنجاح';
|
||||||
|
redirect('charity-settings.php');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['delete_status'])) {
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['delete_status'])) {
|
||||||
@ -116,11 +118,22 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['delete_status'])) {
|
|||||||
$count = db()->prepare("SELECT COUNT(*) FROM mailbox WHERE status_id = ?");
|
$count = db()->prepare("SELECT COUNT(*) FROM mailbox WHERE status_id = ?");
|
||||||
$count->execute([$id]);
|
$count->execute([$id]);
|
||||||
if ($count->fetchColumn() > 0) {
|
if ($count->fetchColumn() > 0) {
|
||||||
$error_msg = 'لا يمكن حذف هذه الحالة لأنها مستخدمة في بعض السجلات';
|
$_SESSION['error'] = 'لا يمكن حذف هذه الحالة لأنها مستخدمة في بعض السجلات';
|
||||||
} else {
|
} else {
|
||||||
db()->prepare("DELETE FROM mailbox_statuses WHERE id = ?")->execute([$id]);
|
db()->prepare("DELETE FROM mailbox_statuses WHERE id = ?")->execute([$id]);
|
||||||
$success_msg = 'تم حذف نوع الحالة بنجاح';
|
$_SESSION['success'] = 'تم حذف نوع الحالة بنجاح';
|
||||||
}
|
}
|
||||||
|
redirect('charity-settings.php');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get session messages
|
||||||
|
if (isset($_SESSION['success'])) {
|
||||||
|
$success_msg = $_SESSION['success'];
|
||||||
|
unset($_SESSION['success']);
|
||||||
|
}
|
||||||
|
if (isset($_SESSION['error'])) {
|
||||||
|
$error_msg = $_SESSION['error'];
|
||||||
|
unset($_SESSION['error']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$statuses = db()->query("SELECT * FROM mailbox_statuses ORDER BY id ASC")->fetchAll();
|
$statuses = db()->query("SELECT * FROM mailbox_statuses ORDER BY id ASC")->fetchAll();
|
||||||
@ -392,6 +405,23 @@ function editStatus(id, name, color, isDefault) {
|
|||||||
document.getElementById('edit_is_default').checked = isDefault == 1;
|
document.getElementById('edit_is_default').checked = isDefault == 1;
|
||||||
new bootstrap.Modal(document.getElementById('editStatusModal')).show();
|
new bootstrap.Modal(document.getElementById('editStatusModal')).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
// Preserve active tab after redirect
|
||||||
|
var activeTab = localStorage.getItem('activeSettingsTab');
|
||||||
|
if (activeTab) {
|
||||||
|
var tabEl = document.querySelector('button[data-bs-target="' + activeTab + '"]');
|
||||||
|
if (tabEl) {
|
||||||
|
bootstrap.Tab.getInstance(tabEl)?.show() || new bootstrap.Tab(tabEl).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.querySelectorAll('button[data-bs-toggle="tab"]').forEach(function(tab) {
|
||||||
|
tab.addEventListener('shown.bs.tab', function(e) {
|
||||||
|
localStorage.setItem('activeSettingsTab', e.target.getAttribute('data-bs-target'));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<?php require_once __DIR__ . '/includes/footer.php'; ?>
|
<?php require_once __DIR__ . '/includes/footer.php'; ?>
|
||||||
|
|||||||
@ -15,3 +15,30 @@ function db() {
|
|||||||
}
|
}
|
||||||
return $pdo;
|
return $pdo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates the next reference number for a given type (inbound/outbound/internal)
|
||||||
|
* Format: IN-Year-Serial or OUT-Year-Serial or INT-Year-Serial
|
||||||
|
*/
|
||||||
|
function generateRefNo($type) {
|
||||||
|
$prefix = 'IN';
|
||||||
|
if ($type === 'outbound') $prefix = 'OUT';
|
||||||
|
if ($type === 'internal') $prefix = 'INT';
|
||||||
|
|
||||||
|
$year = date('Y');
|
||||||
|
$pattern = $prefix . '-' . $year . '-%';
|
||||||
|
|
||||||
|
$stmt = db()->prepare("SELECT ref_no FROM mailbox WHERE type = ? AND ref_no LIKE ? ORDER BY id DESC LIMIT 1");
|
||||||
|
$stmt->execute([$type, $pattern]);
|
||||||
|
$last_ref = $stmt->fetchColumn();
|
||||||
|
|
||||||
|
$serial = 1;
|
||||||
|
if ($last_ref) {
|
||||||
|
$parts = explode('-', $last_ref);
|
||||||
|
if (count($parts) === 3) {
|
||||||
|
$serial = (int)$parts[2] + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $prefix . '-' . $year . '-' . str_pad($serial, 3, '0', STR_PAD_LEFT);
|
||||||
|
}
|
||||||
2
db/migrations/012_add_internal_mail_type.sql
Normal file
2
db/migrations/012_add_internal_mail_type.sql
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
-- Migration: Add internal mail type to mailbox table
|
||||||
|
ALTER TABLE mailbox MODIFY COLUMN type ENUM('inbound', 'outbound', 'internal') NOT NULL;
|
||||||
24
inbound.php
24
inbound.php
@ -79,7 +79,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
sendAssignmentNotification($assigned_to, $ref_no, $subject);
|
sendAssignmentNotification($assigned_to, $ref_no, $subject);
|
||||||
}
|
}
|
||||||
|
|
||||||
$success = 'تمت إضافة البريد بنجاح';
|
$_SESSION['success'] = 'تمت إضافة البريد بنجاح';
|
||||||
|
redirect('inbound.php');
|
||||||
} elseif ($action === 'edit') {
|
} elseif ($action === 'edit') {
|
||||||
// Get previous assigned_to to check if it changed
|
// Get previous assigned_to to check if it changed
|
||||||
$stmt_old = db()->prepare("SELECT assigned_to FROM mailbox WHERE id = ?");
|
$stmt_old = db()->prepare("SELECT assigned_to FROM mailbox WHERE id = ?");
|
||||||
@ -93,7 +94,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
sendAssignmentNotification($assigned_to, $ref_no, $subject);
|
sendAssignmentNotification($assigned_to, $ref_no, $subject);
|
||||||
}
|
}
|
||||||
|
|
||||||
$success = 'تم تحديث البيانات بنجاح';
|
$_SESSION['success'] = 'تم تحديث البيانات بنجاح';
|
||||||
|
redirect('inbound.php');
|
||||||
}
|
}
|
||||||
} catch (PDOException $e) {
|
} catch (PDOException $e) {
|
||||||
if ($e->getCode() == 23000) {
|
if ($e->getCode() == 23000) {
|
||||||
@ -116,10 +118,21 @@ if (isset($_GET['action']) && $_GET['action'] === 'delete' && isset($_GET['id'])
|
|||||||
$id = $_GET['id'];
|
$id = $_GET['id'];
|
||||||
$stmt = db()->prepare("DELETE FROM mailbox WHERE id = ? AND type = 'inbound'");
|
$stmt = db()->prepare("DELETE FROM mailbox WHERE id = ? AND type = 'inbound'");
|
||||||
$stmt->execute([$id]);
|
$stmt->execute([$id]);
|
||||||
$success = 'تم حذف البريد بنجاح';
|
$_SESSION['success'] = 'تم حذف البريد بنجاح';
|
||||||
|
redirect('inbound.php');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get session messages
|
||||||
|
if (isset($_SESSION['success'])) {
|
||||||
|
$success = $_SESSION['success'];
|
||||||
|
unset($_SESSION['success']);
|
||||||
|
}
|
||||||
|
if (isset($_SESSION['error'])) {
|
||||||
|
$error = $_SESSION['error'];
|
||||||
|
unset($_SESSION['error']);
|
||||||
|
}
|
||||||
|
|
||||||
$search = $_GET['search'] ?? '';
|
$search = $_GET['search'] ?? '';
|
||||||
$my_tasks = isset($_GET['my_tasks']) && $_GET['my_tasks'] == 1;
|
$my_tasks = isset($_GET['my_tasks']) && $_GET['my_tasks'] == 1;
|
||||||
|
|
||||||
@ -345,7 +358,7 @@ function getStatusBadgeInList($mail) {
|
|||||||
<div class="row g-3">
|
<div class="row g-3">
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<label class="form-label fw-bold">رقم القيد <span class="text-danger">*</span></label>
|
<label class="form-label fw-bold">رقم القيد <span class="text-danger">*</span></label>
|
||||||
<input type="text" name="ref_no" id="modalRefNo" class="form-control" required>
|
<input type="text" name="ref_no" id="modalRefNo" class="form-control" required readonly>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<label class="form-label fw-bold">تاريخ التسجيل</label>
|
<label class="form-label fw-bold">تاريخ التسجيل</label>
|
||||||
@ -443,6 +456,7 @@ function openMailModal(action, data = null) {
|
|||||||
Object.keys(fields).forEach(key => {
|
Object.keys(fields).forEach(key => {
|
||||||
if (key === 'date_registered') fields[key].value = '<?= date('Y-m-d') ?>';
|
if (key === 'date_registered') fields[key].value = '<?= date('Y-m-d') ?>';
|
||||||
else if (key === 'status_id') fields[key].value = '<?= $default_status_id ?>';
|
else if (key === 'status_id') fields[key].value = '<?= $default_status_id ?>';
|
||||||
|
else if (key === 'ref_no') fields[key].value = '<?= generateRefNo('inbound') ?>';
|
||||||
else fields[key].value = '';
|
else fields[key].value = '';
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@ -513,4 +527,4 @@ function confirmDelete(id) {
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<?php require_once __DIR__ . '/includes/footer.php'; ?>
|
<?php require_once __DIR__ . '/includes/footer.php'; ?>
|
||||||
|
|||||||
@ -53,10 +53,10 @@ if (isLoggedIn()) {
|
|||||||
$current_user = $stmt->fetch();
|
$current_user = $stmt->fetch();
|
||||||
|
|
||||||
// Update session permissions
|
// Update session permissions
|
||||||
$_SESSION['can_view'] = $current_user['can_view'];
|
$_SESSION['can_view'] = $current_user['can_view'] ?? 1;
|
||||||
$_SESSION['can_add'] = $current_user['can_add'];
|
$_SESSION['can_add'] = $current_user['can_add'] ?? 0;
|
||||||
$_SESSION['can_edit'] = $current_user['can_edit'];
|
$_SESSION['can_edit'] = $current_user['can_edit'] ?? 0;
|
||||||
$_SESSION['can_delete'] = $current_user['can_delete'];
|
$_SESSION['can_delete'] = $current_user['can_delete'] ?? 0;
|
||||||
}
|
}
|
||||||
$user_theme = $current_user['theme'] ?? 'light';
|
$user_theme = $current_user['theme'] ?? 'light';
|
||||||
?>
|
?>
|
||||||
@ -233,6 +233,16 @@ $user_theme = $current_user['theme'] ?? 'light';
|
|||||||
color: var(--text-color) !important;
|
color: var(--text-color) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sidebar-heading {
|
||||||
|
padding: 0.5rem 1.5rem;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.05rem;
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--muted-text);
|
||||||
|
margin-top: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
/* Theme Switcher Styles */
|
/* Theme Switcher Styles */
|
||||||
.theme-switcher {
|
.theme-switcher {
|
||||||
padding: 1rem 1.5rem;
|
padding: 1rem 1.5rem;
|
||||||
@ -274,10 +284,12 @@ $user_theme = $current_user['theme'] ?? 'light';
|
|||||||
<nav class="col-md-3 col-lg-2 d-md-block sidebar">
|
<nav class="col-md-3 col-lg-2 d-md-block sidebar">
|
||||||
<div class="position-sticky">
|
<div class="position-sticky">
|
||||||
<div class="text-center mb-4">
|
<div class="text-center mb-4">
|
||||||
<?php if ($charity_logo): ?>
|
<a href="index.php" class="text-decoration-none text-dark">
|
||||||
<img src="<?= $charity_logo ?>?v=<?= time() ?>" alt="Logo" class="charity-logo mb-2">
|
<?php if ($charity_logo): ?>
|
||||||
<?php endif; ?>
|
<img src="<?= $charity_logo ?>?v=<?= time() ?>" alt="Logo" class="charity-logo mb-2">
|
||||||
<h5 class="fw-bold mt-2"><?= htmlspecialchars($charity_name) ?></h5>
|
<?php endif; ?>
|
||||||
|
<h5 class="fw-bold mt-2"><?= htmlspecialchars($charity_name) ?></h5>
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="user-info text-center mb-4 py-3 border-bottom border-top">
|
<div class="user-info text-center mb-4 py-3 border-bottom border-top">
|
||||||
@ -304,6 +316,8 @@ $user_theme = $current_user['theme'] ?? 'light';
|
|||||||
<i class="fas fa-home me-2"></i> لوحة التحكم
|
<i class="fas fa-home me-2"></i> لوحة التحكم
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
<div class="sidebar-heading">المراسلات الرسمية</div>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link <?= basename($_SERVER['PHP_SELF']) == 'inbound.php' ? 'active' : '' ?>" href="inbound.php">
|
<a class="nav-link <?= basename($_SERVER['PHP_SELF']) == 'inbound.php' ? 'active' : '' ?>" href="inbound.php">
|
||||||
<i class="fas fa-download me-2"></i> البريد الوارد
|
<i class="fas fa-download me-2"></i> البريد الوارد
|
||||||
@ -314,7 +328,21 @@ $user_theme = $current_user['theme'] ?? 'light';
|
|||||||
<i class="fas fa-upload me-2"></i> البريد الصادر
|
<i class="fas fa-upload me-2"></i> البريد الصادر
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
<div class="sidebar-heading">بريد الموظفين</div>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link <?= basename($_SERVER['PHP_SELF']) == 'internal_inbox.php' ? 'active' : '' ?>" href="internal_inbox.php">
|
||||||
|
<i class="fas fa-inbox me-2"></i> صندوق الوارد
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link <?= basename($_SERVER['PHP_SELF']) == 'internal_outbox.php' ? 'active' : '' ?>" href="internal_outbox.php">
|
||||||
|
<i class="fas fa-paper-plane me-2"></i> صندوق الصادر
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
<?php if (isAdmin()): ?>
|
<?php if (isAdmin()): ?>
|
||||||
|
<div class="sidebar-heading">الإدارة والنظام</div>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link <?= basename($_SERVER['PHP_SELF']) == 'overdue_report.php' ? 'active' : '' ?>" href="overdue_report.php">
|
<a class="nav-link <?= basename($_SERVER['PHP_SELF']) == 'overdue_report.php' ? 'active' : '' ?>" href="overdue_report.php">
|
||||||
<i class="fas fa-chart-line me-2"></i> تقرير التأخير
|
<i class="fas fa-chart-line me-2"></i> تقرير التأخير
|
||||||
@ -331,6 +359,8 @@ $user_theme = $current_user['theme'] ?? 'light';
|
|||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<div class="sidebar-heading">الحساب</div>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link <?= basename($_SERVER['PHP_SELF']) == 'profile.php' ? 'active' : '' ?>" href="profile.php">
|
<a class="nav-link <?= basename($_SERVER['PHP_SELF']) == 'profile.php' ? 'active' : '' ?>" href="profile.php">
|
||||||
<i class="fas fa-user-circle me-2"></i> الملف الشخصي
|
<i class="fas fa-user-circle me-2"></i> الملف الشخصي
|
||||||
@ -384,4 +414,4 @@ $user_theme = $current_user['theme'] ?? 'light';
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<main class="<?= isLoggedIn() ? 'col-md-9 ms-sm-auto col-lg-10' : 'col-12' ?> px-md-4 py-4">
|
<main class="<?= isLoggedIn() ? 'col-md-9 ms-sm-auto col-lg-10' : 'col-12' ?> px-md-4 py-4">
|
||||||
164
internal_inbox.php
Normal file
164
internal_inbox.php
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
<?php
|
||||||
|
require_once __DIR__ . '/includes/header.php';
|
||||||
|
|
||||||
|
// Every logged-in user can access their own internal mail
|
||||||
|
if (!isLoggedIn()) {
|
||||||
|
redirect('login.php');
|
||||||
|
}
|
||||||
|
|
||||||
|
$user_id = $_SESSION['user_id'];
|
||||||
|
$success = $_GET['success'] ?? '';
|
||||||
|
$error = $_GET['error'] ?? '';
|
||||||
|
|
||||||
|
// Search and filtering
|
||||||
|
$search = $_GET['search'] ?? '';
|
||||||
|
$page = isset($_GET['page']) && is_numeric($_GET['page']) ? (int)$_GET['page'] : 1;
|
||||||
|
$limit = 10;
|
||||||
|
$offset = ($page - 1) * $limit;
|
||||||
|
|
||||||
|
$params = [$user_id];
|
||||||
|
$where = "m.type = 'internal' AND m.assigned_to = ?";
|
||||||
|
|
||||||
|
if ($search) {
|
||||||
|
$where .= " AND (m.subject LIKE ? OR m.description LIKE ? OR u_sender.full_name LIKE ?)";
|
||||||
|
$params[] = "%$search%";
|
||||||
|
$params[] = "%$search%";
|
||||||
|
$params[] = "%$search%";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get total for pagination
|
||||||
|
$count_stmt = db()->prepare("SELECT COUNT(*) FROM mailbox m LEFT JOIN users u_sender ON m.created_by = u_sender.id WHERE $where");
|
||||||
|
$count_stmt->execute($params);
|
||||||
|
$total_records = $count_stmt->fetchColumn();
|
||||||
|
$total_pages = ceil($total_records / $limit);
|
||||||
|
|
||||||
|
// Fetch messages
|
||||||
|
$query = "SELECT m.*, u_sender.full_name as sender_name, u_sender.profile_image as sender_image, s.name as status_name, s.color as status_color
|
||||||
|
FROM mailbox m
|
||||||
|
LEFT JOIN users u_sender ON m.created_by = u_sender.id
|
||||||
|
LEFT JOIN mailbox_statuses s ON m.status_id = s.id
|
||||||
|
WHERE $where
|
||||||
|
ORDER BY m.created_at DESC
|
||||||
|
LIMIT $limit OFFSET $offset";
|
||||||
|
|
||||||
|
$stmt = db()->prepare($query);
|
||||||
|
$stmt->execute($params);
|
||||||
|
$messages = $stmt->fetchAll();
|
||||||
|
|
||||||
|
function getStatusBadgeInternal($mail) {
|
||||||
|
$status_name = $mail['status_name'] ?? 'received';
|
||||||
|
$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"><i class="fas fa-inbox me-2 text-primary"></i> بريد الموظفين - الوارد</h1>
|
||||||
|
<div class="btn-toolbar mb-2 mb-md-0">
|
||||||
|
<a href="internal_outbox.php?action=compose" class="btn btn-primary shadow-sm">
|
||||||
|
<i class="fas fa-paper-plane me-1"></i> إرسال رسالة جديدة
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php if ($success): ?>
|
||||||
|
<div class="alert alert-success alert-dismissible fade show" role="alert">
|
||||||
|
<?= htmlspecialchars($success) ?>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<div class="card shadow-sm border-0 mb-4">
|
||||||
|
<div class="card-header bg-white py-3">
|
||||||
|
<form class="row g-3">
|
||||||
|
<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) ?>">
|
||||||
|
<button type="submit" class="btn btn-primary">بحث</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php if ($search): ?>
|
||||||
|
<div class="col-auto">
|
||||||
|
<a href="internal_inbox.php" class="btn btn-outline-secondary">إعادة تعيين</a>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
</form>
|
||||||
|
</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 class="pe-4 text-center">الإجراء</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php if ($messages): ?>
|
||||||
|
<?php foreach ($messages as $msg): ?>
|
||||||
|
<tr style="cursor: pointer;" onclick="window.location='view_mail.php?id=<?= $msg['id'] ?>'">
|
||||||
|
<td class="ps-4">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<?php if ($msg['sender_image']): ?>
|
||||||
|
<img src="<?= $msg['sender_image'] ?>" class="rounded-circle me-2" width="32" height="32" style="object-fit: cover;">
|
||||||
|
<?php else: ?>
|
||||||
|
<div class="rounded-circle bg-light d-flex align-items-center justify-content-center me-2" width="32" height="32" style="width:32px; height:32px;">
|
||||||
|
<i class="fas fa-user text-secondary small"></i>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
<span class="fw-bold"><?= htmlspecialchars($msg['sender_name'] ?: 'مستخدم غير معروف') ?></span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<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>
|
||||||
|
<small class="text-muted"><?= date('Y-m-d H:i', strtotime($msg['created_at'])) ?></small>
|
||||||
|
</td>
|
||||||
|
<td><?= getStatusBadgeInternal($msg) ?></td>
|
||||||
|
<td class="pe-4 text-center">
|
||||||
|
<a href="view_mail.php?id=<?= $msg['id'] ?>" class="btn btn-sm btn-light rounded-pill px-3">عرض</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
<?php else: ?>
|
||||||
|
<tr>
|
||||||
|
<td colspan="5" class="text-center py-5 text-muted">
|
||||||
|
<i class="fas fa-envelope-open fa-3x mb-3 opacity-25"></i>
|
||||||
|
<p>لا توجد رسائل واردة حالياً</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php endif; ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php if ($total_pages > 1): ?>
|
||||||
|
<div class="card-footer bg-white border-0 py-3">
|
||||||
|
<nav>
|
||||||
|
<ul class="pagination justify-content-center mb-0">
|
||||||
|
<?php for ($i = 1; $i <= $total_pages; $i++): ?>
|
||||||
|
<li class="page-item <?= ($page == $i) ? 'active' : '' ?>">
|
||||||
|
<a class="page-link" href="?page=<?= $i ?><?= $search ? '&search='.urlencode($search) : '' ?>"><?= $i ?></a>
|
||||||
|
</li>
|
||||||
|
<?php endfor; ?>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php require_once __DIR__ . '/includes/footer.php'; ?>
|
||||||
296
internal_outbox.php
Normal file
296
internal_outbox.php
Normal file
@ -0,0 +1,296 @@
|
|||||||
|
<?php
|
||||||
|
require_once __DIR__ . '/includes/header.php';
|
||||||
|
require_once __DIR__ . '/mail/MailService.php';
|
||||||
|
|
||||||
|
if (!isLoggedIn()) {
|
||||||
|
redirect('login.php');
|
||||||
|
}
|
||||||
|
|
||||||
|
$user_id = $_SESSION['user_id'];
|
||||||
|
$success = '';
|
||||||
|
$error = '';
|
||||||
|
|
||||||
|
// Handle composing a new message
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'compose') {
|
||||||
|
$recipient_id = $_POST['recipient_id'] ?? null;
|
||||||
|
$subject = $_POST['subject'] ?? '';
|
||||||
|
$description = $_POST['description'] ?? '';
|
||||||
|
$type = 'internal';
|
||||||
|
$ref_no = generateRefNo('internal');
|
||||||
|
$date_registered = date('Y-m-d');
|
||||||
|
$default_status_id = db()->query("SELECT id FROM mailbox_statuses WHERE is_default = 1 LIMIT 1")->fetchColumn() ?: 1;
|
||||||
|
|
||||||
|
if ($recipient_id && $subject) {
|
||||||
|
try {
|
||||||
|
$stmt = db()->prepare("INSERT INTO mailbox (type, ref_no, date_registered, subject, description, status_id, assigned_to, created_by) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
|
||||||
|
$stmt->execute([$type, $ref_no, $date_registered, $subject, $description, $default_status_id, $recipient_id, $user_id]);
|
||||||
|
|
||||||
|
// Notify recipient
|
||||||
|
$stmt_recp = db()->prepare("SELECT full_name, email FROM users WHERE id = ?");
|
||||||
|
$stmt_recp->execute([$recipient_id]);
|
||||||
|
$recipient = $stmt_recp->fetch();
|
||||||
|
|
||||||
|
if ($recipient && !empty($recipient['email'])) {
|
||||||
|
$email_subject = "رسالة داخلية جديدة من " . $_SESSION['username'];
|
||||||
|
$htmlBody = "
|
||||||
|
<div dir='rtl' style='font-family: Arial, sans-serif;'>
|
||||||
|
<h3>لديك رسالة داخلية جديدة</h3>
|
||||||
|
<p><strong>الموضوع:</strong> " . htmlspecialchars($subject) . "</p>
|
||||||
|
<p><strong>المرسل:</strong> " . htmlspecialchars($_SESSION['username']) . "</p>
|
||||||
|
<hr>
|
||||||
|
<div>" . $description . "</div>
|
||||||
|
<br>
|
||||||
|
<p>يمكنك الرد من خلال النظام.</p>
|
||||||
|
</div>
|
||||||
|
";
|
||||||
|
MailService::sendMail($recipient['email'], $email_subject, $htmlBody);
|
||||||
|
}
|
||||||
|
|
||||||
|
$_SESSION['success'] = 'تم إرسال الرسالة بنجاح';
|
||||||
|
redirect('internal_outbox.php');
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
$error = 'حدث خطأ: ' . $e->getMessage();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$error = 'يرجى اختيار المرسل إليه وكتابة الموضوع';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get session messages
|
||||||
|
if (isset($_SESSION['success'])) {
|
||||||
|
$success = $_SESSION['success'];
|
||||||
|
unset($_SESSION['success']);
|
||||||
|
}
|
||||||
|
if (isset($_SESSION['error'])) {
|
||||||
|
$error = $_SESSION['error'];
|
||||||
|
unset($_SESSION['error']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search and filtering
|
||||||
|
$search = $_GET['search'] ?? '';
|
||||||
|
$page = isset($_GET['page']) && is_numeric($_GET['page']) ? (int)$_GET['page'] : 1;
|
||||||
|
$limit = 10;
|
||||||
|
$offset = ($page - 1) * $limit;
|
||||||
|
|
||||||
|
$params = [$user_id];
|
||||||
|
$where = "m.type = 'internal' AND m.created_by = ?";
|
||||||
|
|
||||||
|
if ($search) {
|
||||||
|
$where .= " AND (m.subject LIKE ? OR m.description LIKE ? OR u_recp.full_name LIKE ?)";
|
||||||
|
$params[] = "%$search%";
|
||||||
|
$params[] = "%$search%";
|
||||||
|
$params[] = "%$search%";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get total for pagination
|
||||||
|
$count_stmt = db()->prepare("SELECT COUNT(*) FROM mailbox m LEFT JOIN users u_recp ON m.assigned_to = u_recp.id WHERE $where");
|
||||||
|
$count_stmt->execute($params);
|
||||||
|
$total_records = $count_stmt->fetchColumn();
|
||||||
|
$total_pages = ceil($total_records / $limit);
|
||||||
|
|
||||||
|
// Fetch messages
|
||||||
|
$query = "SELECT m.*, u_recp.full_name as recipient_name, u_recp.profile_image as recipient_image, s.name as status_name, s.color as status_color
|
||||||
|
FROM mailbox m
|
||||||
|
LEFT JOIN users u_recp ON m.assigned_to = u_recp.id
|
||||||
|
LEFT JOIN mailbox_statuses s ON m.status_id = s.id
|
||||||
|
WHERE $where
|
||||||
|
ORDER BY m.created_at DESC
|
||||||
|
LIMIT $limit OFFSET $offset";
|
||||||
|
|
||||||
|
$stmt = db()->prepare($query);
|
||||||
|
$stmt->execute($params);
|
||||||
|
$messages = $stmt->fetchAll();
|
||||||
|
|
||||||
|
// Users for compose
|
||||||
|
$users_list = db()->prepare("SELECT id, full_name, username FROM users WHERE id != ? ORDER BY full_name");
|
||||||
|
$users_list->execute([$user_id]);
|
||||||
|
$users_list = $users_list->fetchAll();
|
||||||
|
|
||||||
|
function getStatusBadgeInternal($mail) {
|
||||||
|
$status_name = $mail['status_name'] ?? 'received';
|
||||||
|
$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"><i class="fas fa-paper-plane me-2 text-success"></i> بريد الموظفين - الصادر</h1>
|
||||||
|
<div class="btn-toolbar mb-2 mb-md-0">
|
||||||
|
<button type="button" class="btn btn-primary shadow-sm" data-bs-toggle="modal" data-bs-target="#composeModal">
|
||||||
|
<i class="fas fa-plus-circle me-1"></i> إنشاء رسالة جديدة
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php if ($success): ?>
|
||||||
|
<div class="alert alert-success alert-dismissible fade show" role="alert">
|
||||||
|
<?= 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) ?>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<div class="card shadow-sm border-0 mb-4">
|
||||||
|
<div class="card-header bg-white py-3">
|
||||||
|
<form class="row g-3">
|
||||||
|
<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) ?>">
|
||||||
|
<button type="submit" class="btn btn-primary">بحث</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php if ($search): ?>
|
||||||
|
<div class="col-auto">
|
||||||
|
<a href="internal_outbox.php" class="btn btn-outline-secondary">إعادة تعيين</a>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
</form>
|
||||||
|
</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 class="pe-4 text-center">الإجراء</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php if ($messages): ?>
|
||||||
|
<?php foreach ($messages as $msg): ?>
|
||||||
|
<tr style="cursor: pointer;" onclick="window.location='view_mail.php?id=<?= $msg['id'] ?>'">
|
||||||
|
<td class="ps-4">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<?php if ($msg['recipient_image']): ?>
|
||||||
|
<img src="<?= $msg['recipient_image'] ?>" class="rounded-circle me-2" width="32" height="32" style="object-fit: cover;">
|
||||||
|
<?php else: ?>
|
||||||
|
<div class="rounded-circle bg-light d-flex align-items-center justify-content-center me-2" width="32" height="32" style="width:32px; height:32px;">
|
||||||
|
<i class="fas fa-user text-secondary small"></i>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
<span class="fw-bold"><?= htmlspecialchars($msg['recipient_name'] ?: 'مستخدم غير معروف') ?></span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<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>
|
||||||
|
<small class="text-muted"><?= date('Y-m-d H:i', strtotime($msg['created_at'])) ?></small>
|
||||||
|
</td>
|
||||||
|
<td><?= getStatusBadgeInternal($msg) ?></td>
|
||||||
|
<td class="pe-4 text-center">
|
||||||
|
<a href="view_mail.php?id=<?= $msg['id'] ?>" class="btn btn-sm btn-light rounded-pill px-3">عرض</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
<?php else: ?>
|
||||||
|
<tr>
|
||||||
|
<td colspan="5" class="text-center py-5 text-muted">
|
||||||
|
<i class="fas fa-paper-plane fa-3x mb-3 opacity-25"></i>
|
||||||
|
<p>لم يتم إرسال أي رسائل حالياً</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php endif; ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php if ($total_pages > 1): ?>
|
||||||
|
<div class="card-footer bg-white border-0 py-3">
|
||||||
|
<nav>
|
||||||
|
<ul class="pagination justify-content-center mb-0">
|
||||||
|
<?php for ($i = 1; $i <= $total_pages; $i++): ?>
|
||||||
|
<li class="page-item <?= ($page == $i) ? 'active' : '' ?>">
|
||||||
|
<a class="page-link" href="?page=<?= $i ?><?= $search ? '&search='.urlencode($search) : '' ?>"><?= $i ?></a>
|
||||||
|
</li>
|
||||||
|
<?php endfor; ?>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Compose Modal -->
|
||||||
|
<div class="modal fade" id="composeModal" tabindex="-1" aria-labelledby="composeModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog modal-lg">
|
||||||
|
<div class="modal-content border-0 shadow-lg">
|
||||||
|
<div class="modal-header bg-dark text-white border-0">
|
||||||
|
<h5 class="modal-title fw-bold" id="composeModalLabel">إنشاء رسالة جديدة للموظفين</h5>
|
||||||
|
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<form id="composeForm" method="POST">
|
||||||
|
<div class="modal-body p-4">
|
||||||
|
<input type="hidden" name="action" value="compose">
|
||||||
|
<div class="row g-3">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<label class="form-label fw-bold">إلى <span class="text-danger">*</span></label>
|
||||||
|
<select name="recipient_id" class="form-select border-2" required>
|
||||||
|
<option value="">-- اختر الموظف --</option>
|
||||||
|
<?php foreach ($users_list as $u): ?>
|
||||||
|
<option value="<?= $u['id'] ?>"><?= htmlspecialchars($u['full_name'] . ' (@' . $u['username'] . ')') ?></option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-12">
|
||||||
|
<label class="form-label fw-bold">الموضوع <span class="text-danger">*</span></label>
|
||||||
|
<input type="text" name="subject" class="form-control border-2" required placeholder="عنوان الرسالة">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-12">
|
||||||
|
<label class="form-label fw-bold">الرسالة</label>
|
||||||
|
<textarea name="description" id="composeEditor" class="form-control border-2" rows="10"></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer border-top-0 bg-light p-3">
|
||||||
|
<button type="button" class="btn btn-secondary px-4 py-2" data-bs-dismiss="modal">إلغاء</button>
|
||||||
|
<button type="submit" class="btn btn-primary px-5 py-2 fw-bold">إرسال الآن <i class="fas fa-paper-plane ms-2"></i></button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
ClassicEditor
|
||||||
|
.create(document.querySelector('#composeEditor'), {
|
||||||
|
language: 'ar',
|
||||||
|
toolbar: ['heading', '|', 'bold', 'italic', 'link', 'bulletedList', 'numberedList', 'blockQuote', 'undo', 'redo'],
|
||||||
|
direction: 'rtl'
|
||||||
|
})
|
||||||
|
.then(editor => {
|
||||||
|
// Force RTL style on editable area
|
||||||
|
editor.ui.view.editable.element.style.direction = 'rtl';
|
||||||
|
editor.ui.view.editable.element.style.textAlign = 'right';
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error(error);
|
||||||
|
});
|
||||||
|
|
||||||
|
<?php if (isset($_GET['action']) && $_GET['action'] === 'compose'): ?>
|
||||||
|
var myModal = new bootstrap.Modal(document.getElementById('composeModal'));
|
||||||
|
myModal.show();
|
||||||
|
<?php endif; ?>
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<?php require_once __DIR__ . '/includes/footer.php'; ?>
|
||||||
30
outbound.php
30
outbound.php
@ -93,7 +93,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
sendAssignmentNotification($assigned_to, $ref_no, $subject);
|
sendAssignmentNotification($assigned_to, $ref_no, $subject);
|
||||||
}
|
}
|
||||||
|
|
||||||
$success = 'تمت إضافة البريد الصادر بنجاح';
|
$_SESSION['success'] = 'تمت إضافة البريد الصادر بنجاح';
|
||||||
} elseif ($action === 'edit') {
|
} elseif ($action === 'edit') {
|
||||||
$mail_id = $id;
|
$mail_id = $id;
|
||||||
|
|
||||||
@ -109,7 +109,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
sendAssignmentNotification($assigned_to, $ref_no, $subject);
|
sendAssignmentNotification($assigned_to, $ref_no, $subject);
|
||||||
}
|
}
|
||||||
|
|
||||||
$success = 'تم تحديث البيانات بنجاح';
|
$_SESSION['success'] = 'تم تحديث البيانات بنجاح';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle Attachments
|
// Handle Attachments
|
||||||
@ -130,6 +130,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
db()->commit();
|
db()->commit();
|
||||||
|
redirect('outbound.php');
|
||||||
} catch (PDOException $e) {
|
} catch (PDOException $e) {
|
||||||
db()->rollBack();
|
db()->rollBack();
|
||||||
if ($e->getCode() == 23000) {
|
if ($e->getCode() == 23000) {
|
||||||
@ -152,10 +153,21 @@ if (isset($_GET['action']) && $_GET['action'] === 'delete' && isset($_GET['id'])
|
|||||||
$id = $_GET['id'];
|
$id = $_GET['id'];
|
||||||
$stmt = db()->prepare("DELETE FROM mailbox WHERE id = ? AND type = 'outbound'");
|
$stmt = db()->prepare("DELETE FROM mailbox WHERE id = ? AND type = 'outbound'");
|
||||||
$stmt->execute([$id]);
|
$stmt->execute([$id]);
|
||||||
$success = 'تم حذف البريد بنجاح';
|
$_SESSION['success'] = 'تم حذف البريد بنجاح';
|
||||||
|
redirect('outbound.php');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get session messages
|
||||||
|
if (isset($_SESSION['success'])) {
|
||||||
|
$success = $_SESSION['success'];
|
||||||
|
unset($_SESSION['success']);
|
||||||
|
}
|
||||||
|
if (isset($_SESSION['error'])) {
|
||||||
|
$error = $_SESSION['error'];
|
||||||
|
unset($_SESSION['error']);
|
||||||
|
}
|
||||||
|
|
||||||
$search = $_GET['search'] ?? '';
|
$search = $_GET['search'] ?? '';
|
||||||
$my_tasks = isset($_GET['my_tasks']) && $_GET['my_tasks'] == 1;
|
$my_tasks = isset($_GET['my_tasks']) && $_GET['my_tasks'] == 1;
|
||||||
|
|
||||||
@ -367,7 +379,7 @@ function getStatusBadgeInList($mail) {
|
|||||||
<?php if (canAdd() || canEdit()): ?>
|
<?php if (canAdd() || canEdit()): ?>
|
||||||
<!-- Mail Modal -->
|
<!-- Mail Modal -->
|
||||||
<div class="modal fade" id="mailModal" tabindex="-1" aria-labelledby="mailModalLabel" aria-hidden="true">
|
<div class="modal fade" id="mailModal" tabindex="-1" aria-labelledby="mailModalLabel" aria-hidden="true">
|
||||||
<div class="modal-dialog modal-xl">
|
<div class="modal-dialog modal-lg">
|
||||||
<div class="modal-content border-0 shadow">
|
<div class="modal-content border-0 shadow">
|
||||||
<div class="modal-header bg-success text-white">
|
<div class="modal-header bg-success text-white">
|
||||||
<h5 class="modal-title fw-bold" id="mailModalLabel">إضافة بريد صادر جديد</h5>
|
<h5 class="modal-title fw-bold" id="mailModalLabel">إضافة بريد صادر جديد</h5>
|
||||||
@ -381,7 +393,7 @@ function getStatusBadgeInList($mail) {
|
|||||||
<div class="row g-3">
|
<div class="row g-3">
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<label class="form-label fw-bold">رقم القيد <span class="text-danger">*</span></label>
|
<label class="form-label fw-bold">رقم القيد <span class="text-danger">*</span></label>
|
||||||
<input type="text" name="ref_no" id="modalRefNo" class="form-control" required>
|
<input type="text" name="ref_no" id="modalRefNo" class="form-control" required readonly>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<label class="form-label fw-bold">تاريخ التسجيل</label>
|
<label class="form-label fw-bold">تاريخ التسجيل</label>
|
||||||
@ -456,6 +468,7 @@ function initEditors() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const config = {
|
const config = {
|
||||||
|
language: 'ar',
|
||||||
toolbar: ['heading', '|', 'bold', 'italic', 'link', 'bulletedList', 'numberedList', 'undo', 'redo']
|
toolbar: ['heading', '|', 'bold', 'italic', 'link', 'bulletedList', 'numberedList', 'undo', 'redo']
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -501,6 +514,7 @@ function openMailModal(action, data = null) {
|
|||||||
if (fields[key]) {
|
if (fields[key]) {
|
||||||
if (key === 'date_registered') fields[key].value = '<?= date('Y-m-d') ?>';
|
if (key === 'date_registered') fields[key].value = '<?= date('Y-m-d') ?>';
|
||||||
else if (key === 'status_id') fields[key].value = '<?= $default_status_id ?>';
|
else if (key === 'status_id') fields[key].value = '<?= $default_status_id ?>';
|
||||||
|
else if (key === 'ref_no') fields[key].value = '<?= generateRefNo('outbound') ?>';
|
||||||
else fields[key].value = '';
|
else fields[key].value = '';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -508,7 +522,7 @@ function openMailModal(action, data = null) {
|
|||||||
if (descriptionEditor) descriptionEditor.setData('');
|
if (descriptionEditor) descriptionEditor.setData('');
|
||||||
else document.getElementById('description_editor').value = '';
|
else document.getElementById('description_editor').value = '';
|
||||||
} else {
|
} else {
|
||||||
label.textContent = 'تعديل البريد الصادر';
|
label.textContent = 'تعديل البريد صادر';
|
||||||
modalId.value = data.id;
|
modalId.value = data.id;
|
||||||
Object.keys(fields).forEach(key => {
|
Object.keys(fields).forEach(key => {
|
||||||
if (fields[key]) fields[key].value = data[key] || '';
|
if (fields[key]) fields[key].value = data[key] || '';
|
||||||
@ -577,6 +591,8 @@ function confirmDelete(id) {
|
|||||||
<style>
|
<style>
|
||||||
.ck-editor__editable_inline {
|
.ck-editor__editable_inline {
|
||||||
min-height: 250px;
|
min-height: 250px;
|
||||||
|
direction: rtl;
|
||||||
|
text-align: right;
|
||||||
}
|
}
|
||||||
.modal-content {
|
.modal-content {
|
||||||
border-radius: 15px;
|
border-radius: 15px;
|
||||||
@ -587,4 +603,4 @@ function confirmDelete(id) {
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<?php require_once __DIR__ . '/includes/footer.php'; ?>
|
<?php require_once __DIR__ . '/includes/footer.php'; ?>
|
||||||
|
|||||||
15
profile.php
15
profile.php
@ -41,13 +41,16 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
$stmt = db()->prepare("UPDATE users SET full_name = ?, email = ?, phone = ?, address = ?, profile_image = ? WHERE id = ?");
|
$stmt = db()->prepare("UPDATE users SET full_name = ?, email = ?, phone = ?, address = ?, profile_image = ? WHERE id = ?");
|
||||||
$stmt->execute([$full_name, $email, $phone, $address, $profile_image, $user_id]);
|
$stmt->execute([$full_name, $email, $phone, $address, $profile_image, $user_id]);
|
||||||
}
|
}
|
||||||
$success_msg = 'تم تحديث الملف الشخصي بنجاح';
|
$_SESSION['success'] = 'تم تحديث الملف الشخصي بنجاح';
|
||||||
// Refresh user data
|
redirect('profile.php');
|
||||||
$stmt = db()->prepare("SELECT * FROM users WHERE id = ?");
|
|
||||||
$stmt->execute([$user_id]);
|
|
||||||
$user = $stmt->fetch();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get session messages
|
||||||
|
if (isset($_SESSION['success'])) {
|
||||||
|
$success_msg = $_SESSION['success'];
|
||||||
|
unset($_SESSION['success']);
|
||||||
|
}
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@ -111,4 +114,4 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php require_once __DIR__ . '/includes/footer.php'; ?>
|
<?php require_once __DIR__ . '/includes/footer.php'; ?>
|
||||||
|
|||||||
21
users.php
21
users.php
@ -28,7 +28,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
try {
|
try {
|
||||||
$stmt = db()->prepare("INSERT INTO users (username, password, full_name, role, can_view, can_add, can_edit, can_delete) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
|
$stmt = db()->prepare("INSERT INTO users (username, password, full_name, role, can_view, can_add, can_edit, can_delete) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
|
||||||
$stmt->execute([$username, $hashed_password, $full_name, $role, $can_view, $can_add, $can_edit, $can_delete]);
|
$stmt->execute([$username, $hashed_password, $full_name, $role, $can_view, $can_add, $can_edit, $can_delete]);
|
||||||
$success = 'تم إضافة المستخدم بنجاح';
|
$_SESSION['success'] = 'تم إضافة المستخدم بنجاح';
|
||||||
|
redirect('users.php');
|
||||||
} catch (PDOException $e) {
|
} catch (PDOException $e) {
|
||||||
if ($e->getCode() == 23000) {
|
if ($e->getCode() == 23000) {
|
||||||
$error = 'اسم المستخدم موجود مسبقاً';
|
$error = 'اسم المستخدم موجود مسبقاً';
|
||||||
@ -50,7 +51,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
$stmt = db()->prepare("UPDATE users SET username = ?, full_name = ?, role = ?, can_view = ?, can_add = ?, can_edit = ?, can_delete = ? WHERE id = ?");
|
$stmt = db()->prepare("UPDATE users SET username = ?, full_name = ?, role = ?, can_view = ?, can_add = ?, can_edit = ?, can_delete = ? WHERE id = ?");
|
||||||
$stmt->execute([$username, $full_name, $role, $can_view, $can_add, $can_edit, $can_delete, $id]);
|
$stmt->execute([$username, $full_name, $role, $can_view, $can_add, $can_edit, $can_delete, $id]);
|
||||||
}
|
}
|
||||||
$success = 'تم تحديث بيانات المستخدم بنجاح';
|
$_SESSION['success'] = 'تم تحديث بيانات المستخدم بنجاح';
|
||||||
|
redirect('users.php');
|
||||||
} catch (PDOException $e) {
|
} catch (PDOException $e) {
|
||||||
$error = 'حدث خطأ: ' . $e->getMessage();
|
$error = 'حدث خطأ: ' . $e->getMessage();
|
||||||
}
|
}
|
||||||
@ -64,12 +66,23 @@ if (isset($_GET['action']) && $_GET['action'] === 'delete' && isset($_GET['id'])
|
|||||||
if ($_GET['id'] != $_SESSION['user_id']) {
|
if ($_GET['id'] != $_SESSION['user_id']) {
|
||||||
$stmt = db()->prepare("DELETE FROM users WHERE id = ?");
|
$stmt = db()->prepare("DELETE FROM users WHERE id = ?");
|
||||||
$stmt->execute([$_GET['id']]);
|
$stmt->execute([$_GET['id']]);
|
||||||
$success = 'تم حذف المستخدم بنجاح';
|
$_SESSION['success'] = 'تم حذف المستخدم بنجاح';
|
||||||
|
redirect('users.php');
|
||||||
} else {
|
} else {
|
||||||
$error = 'لا يمكنك حذف حسابك الحالي';
|
$error = 'لا يمكنك حذف حسابك الحالي';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get session messages
|
||||||
|
if (isset($_SESSION['success'])) {
|
||||||
|
$success = $_SESSION['success'];
|
||||||
|
unset($_SESSION['success']);
|
||||||
|
}
|
||||||
|
if (isset($_SESSION['error'])) {
|
||||||
|
$error = $_SESSION['error'];
|
||||||
|
unset($_SESSION['error']);
|
||||||
|
}
|
||||||
|
|
||||||
$stmt = db()->query("SELECT * FROM users ORDER BY created_at DESC");
|
$stmt = db()->query("SELECT * FROM users ORDER BY created_at DESC");
|
||||||
$users = $stmt->fetchAll();
|
$users = $stmt->fetchAll();
|
||||||
|
|
||||||
@ -370,4 +383,4 @@ function confirmDelete(id) {
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<?php require_once __DIR__ . '/includes/footer.php'; ?>
|
<?php require_once __DIR__ . '/includes/footer.php'; ?>
|
||||||
108
view_mail.php
108
view_mail.php
@ -22,12 +22,19 @@ $mail = $stmt->fetch();
|
|||||||
|
|
||||||
if (!$mail) redirect('index.php');
|
if (!$mail) redirect('index.php');
|
||||||
|
|
||||||
|
// Security check for internal mail: only sender or recipient can view
|
||||||
|
if ($mail['type'] === 'internal') {
|
||||||
|
if ($mail['created_by'] != $_SESSION['user_id'] && $mail['assigned_to'] != $_SESSION['user_id'] && !isAdmin()) {
|
||||||
|
redirect('internal_inbox.php');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$success = '';
|
$success = '';
|
||||||
$error = '';
|
$error = '';
|
||||||
|
|
||||||
// Handle Comment submission
|
// Handle Comment submission
|
||||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_comment'])) {
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_comment'])) {
|
||||||
if (!canEdit()) {
|
if (!canEdit() && $mail['type'] !== 'internal') {
|
||||||
$error = 'عذراً، ليس لديك الصلاحية لإضافة تعليقات';
|
$error = 'عذراً، ليس لديك الصلاحية لإضافة تعليقات';
|
||||||
} else {
|
} else {
|
||||||
$comment = $_POST['comment'] ?? '';
|
$comment = $_POST['comment'] ?? '';
|
||||||
@ -68,14 +75,15 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_comment'])) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$success = 'تم إضافة التعليق بنجاح';
|
$_SESSION['success'] = 'تم إضافة التعليق بنجاح';
|
||||||
|
redirect("view_mail.php?id=$id");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle Attachment upload
|
// Handle Attachment upload
|
||||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['attachment'])) {
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['attachment'])) {
|
||||||
if (!canEdit()) {
|
if (!canEdit() && $mail['type'] !== 'internal') {
|
||||||
$error = 'عذراً، ليس لديك الصلاحية لرفع مرفقات';
|
$error = 'عذراً، ليس لديك الصلاحية لرفع مرفقات';
|
||||||
} else {
|
} else {
|
||||||
$file = $_FILES['attachment'];
|
$file = $_FILES['attachment'];
|
||||||
@ -90,7 +98,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['attachment'])) {
|
|||||||
if (move_uploaded_file($file['tmp_name'], $target_path)) {
|
if (move_uploaded_file($file['tmp_name'], $target_path)) {
|
||||||
$stmt = db()->prepare("INSERT INTO attachments (mail_id, display_name, file_path, file_name, file_size) VALUES (?, ?, ?, ?, ?)");
|
$stmt = db()->prepare("INSERT INTO attachments (mail_id, display_name, file_path, file_name, file_size) VALUES (?, ?, ?, ?, ?)");
|
||||||
$stmt->execute([$id, $display_name, $target_path, $file['name'], $file['size']]);
|
$stmt->execute([$id, $display_name, $target_path, $file['name'], $file['size']]);
|
||||||
$success = 'تم رفع الملف بنجاح';
|
$_SESSION['success'] = 'تم رفع الملف بنجاح';
|
||||||
|
redirect("view_mail.php?id=$id");
|
||||||
} else {
|
} else {
|
||||||
$error = 'فشل في رفع الملف';
|
$error = 'فشل في رفع الملف';
|
||||||
}
|
}
|
||||||
@ -100,7 +109,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['attachment'])) {
|
|||||||
|
|
||||||
// Handle Attachment deletion
|
// Handle Attachment deletion
|
||||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['delete_attachment'])) {
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['delete_attachment'])) {
|
||||||
if (!canDelete()) {
|
if (!canDelete() && $mail['type'] !== 'internal') {
|
||||||
$error = 'عذراً، ليس لديك الصلاحية لحذف المرفقات';
|
$error = 'عذراً، ليس لديك الصلاحية لحذف المرفقات';
|
||||||
} else {
|
} else {
|
||||||
$attachment_id = $_POST['attachment_id'] ?? 0;
|
$attachment_id = $_POST['attachment_id'] ?? 0;
|
||||||
@ -118,12 +127,23 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['delete_attachment']))
|
|||||||
// Delete record from DB
|
// Delete record from DB
|
||||||
$stmt = db()->prepare("DELETE FROM attachments WHERE id = ?");
|
$stmt = db()->prepare("DELETE FROM attachments WHERE id = ?");
|
||||||
$stmt->execute([$attachment_id]);
|
$stmt->execute([$attachment_id]);
|
||||||
$success = 'تم حذف المرفق بنجاح';
|
$_SESSION['success'] = 'تم حذف المرفق بنجاح';
|
||||||
|
redirect("view_mail.php?id=$id");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get session messages
|
||||||
|
if (isset($_SESSION['success'])) {
|
||||||
|
$success = $_SESSION['success'];
|
||||||
|
unset($_SESSION['success']);
|
||||||
|
}
|
||||||
|
if (isset($_SESSION['error'])) {
|
||||||
|
$error = $_SESSION['error'];
|
||||||
|
unset($_SESSION['error']);
|
||||||
|
}
|
||||||
|
|
||||||
$comments = db()->prepare("SELECT c.*, u.full_name, ru.full_name as referred_name
|
$comments = db()->prepare("SELECT c.*, u.full_name, ru.full_name as referred_name
|
||||||
FROM comments c
|
FROM comments c
|
||||||
LEFT JOIN users u ON c.user_id = u.id
|
LEFT JOIN users u ON c.user_id = u.id
|
||||||
@ -146,13 +166,22 @@ function isPreviewable($fileName) {
|
|||||||
$ext = strtolower(pathinfo($fileName, PATHINFO_EXTENSION));
|
$ext = strtolower(pathinfo($fileName, PATHINFO_EXTENSION));
|
||||||
return in_array($ext, ['pdf', 'png', 'jpg', 'jpeg', 'gif', 'webp']);
|
return in_array($ext, ['pdf', 'png', 'jpg', 'jpeg', 'gif', 'webp']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$type_label = 'بريد وارد';
|
||||||
|
if ($mail['type'] == 'outbound') $type_label = 'بريد صادر';
|
||||||
|
if ($mail['type'] == 'internal') $type_label = 'رسالة داخلية';
|
||||||
|
|
||||||
|
$back_link = $mail['type'] . '.php';
|
||||||
|
if ($mail['type'] == 'internal') {
|
||||||
|
$back_link = ($mail['created_by'] == $_SESSION['user_id']) ? 'internal_outbox.php' : 'internal_inbox.php';
|
||||||
|
}
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
|
<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">تفاصيل <?= $mail['type'] == 'inbound' ? 'البريد الوارد' : 'البريد الصادر' ?></h1>
|
<h1 class="h2">تفاصيل <?= $type_label ?></h1>
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
<a href="<?= $mail['type'] ?>.php" class="btn btn-outline-secondary">عودة للقائمة</a>
|
<a href="<?= $back_link ?>" class="btn btn-outline-secondary">عودة للقائمة</a>
|
||||||
<?php if (canEdit()): ?>
|
<?php if (canEdit() && $mail['type'] !== 'internal'): ?>
|
||||||
<a href="<?= $mail['type'] ?>.php?action=edit&id=<?= $mail['id'] ?>" class="btn btn-outline-primary">تعديل البيانات</a>
|
<a href="<?= $mail['type'] ?>.php?action=edit&id=<?= $mail['id'] ?>" class="btn btn-outline-primary">تعديل البيانات</a>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
@ -208,12 +237,12 @@ function isPreviewable($fileName) {
|
|||||||
<label class="text-muted small">الحالة</label>
|
<label class="text-muted small">الحالة</label>
|
||||||
<p>
|
<p>
|
||||||
<?php
|
<?php
|
||||||
$s_name = $mail['status_name'] ?? 'غير معروف';
|
$s_name = $mail['status_name'] ?? 'received';
|
||||||
$s_color = $mail['status_color'] ?? '#6c757d';
|
$s_color = $mail['status_color'] ?? '#6c757d';
|
||||||
$d_name = $s_name;
|
$d_name = $s_name;
|
||||||
if ($s_name == 'received') $d_name = 'تم الاستلام';
|
if ($s_name == 'received') $d_name = ($mail['type'] == 'internal' ? 'جديد / مرسل' : 'تم الاستلام');
|
||||||
if ($s_name == 'in_progress') $d_name = 'قيد المعالجة';
|
if ($s_name == 'in_progress') $d_name = 'قيد المعالجة';
|
||||||
if ($s_name == 'closed') $d_name = 'مكتمل';
|
if ($s_name == 'closed') $d_name = ($mail['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>
|
</p>
|
||||||
@ -222,7 +251,7 @@ function isPreviewable($fileName) {
|
|||||||
<label class="text-muted small">الموضوع</label>
|
<label class="text-muted small">الموضوع</label>
|
||||||
<div class="fw-bold">
|
<div class="fw-bold">
|
||||||
<?php
|
<?php
|
||||||
if ($mail['type'] == 'outbound') {
|
if ($mail['type'] == 'outbound' || $mail['type'] == 'internal') {
|
||||||
echo $mail['subject'];
|
echo $mail['subject'];
|
||||||
} else {
|
} else {
|
||||||
echo htmlspecialchars($mail['subject']);
|
echo htmlspecialchars($mail['subject']);
|
||||||
@ -230,6 +259,17 @@ function isPreviewable($fileName) {
|
|||||||
?>
|
?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<?php if ($mail['type'] == 'internal'): ?>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label class="text-muted small">المرسل</label>
|
||||||
|
<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>
|
||||||
|
</div>
|
||||||
|
<?php else: ?>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<label class="text-muted small"><?= $mail['type'] == 'inbound' ? 'المرسل' : 'المرسل الداخلي' ?></label>
|
<label class="text-muted small"><?= $mail['type'] == 'inbound' ? 'المرسل' : 'المرسل الداخلي' ?></label>
|
||||||
<p><?= htmlspecialchars($mail['sender'] ?: 'غير محدد') ?></p>
|
<p><?= htmlspecialchars($mail['sender'] ?: 'غير محدد') ?></p>
|
||||||
@ -238,25 +278,31 @@ function isPreviewable($fileName) {
|
|||||||
<label class="text-muted small"><?= $mail['type'] == 'inbound' ? 'المستلم الداخلي' : 'الجهة المستلمة' ?></label>
|
<label class="text-muted small"><?= $mail['type'] == 'inbound' ? 'المستلم الداخلي' : 'الجهة المستلمة' ?></label>
|
||||||
<p><?= htmlspecialchars($mail['recipient'] ?: 'غير محدد') ?></p>
|
<p><?= htmlspecialchars($mail['recipient'] ?: 'غير محدد') ?></p>
|
||||||
</div>
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<label class="text-muted small">الوصف / ملاحظات</label>
|
<label class="text-muted small">الرسالة / الوصف</label>
|
||||||
<div class="bg-light p-3 rounded border">
|
<div class="bg-light p-3 rounded border">
|
||||||
<?php
|
<?php
|
||||||
if ($mail['type'] == 'outbound') {
|
if ($mail['type'] == 'outbound' || $mail['type'] == 'internal') {
|
||||||
echo $mail['description'] ?: '<span class="text-muted">لا يوجد وصف إضافي</span>';
|
echo $mail['description'] ?: '<span class="text-muted">لا يوجد محتوى إضافي</span>';
|
||||||
} else {
|
} else {
|
||||||
echo nl2br(htmlspecialchars($mail['description'] ?: 'لا يوجد وصف إضافي'));
|
echo nl2br(htmlspecialchars($mail['description'] ?: 'لا يوجد محتوى إضافي'));
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<?php if ($mail['type'] != 'internal'): ?>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<label class="text-muted small">الموظف المسؤول</label>
|
<label class="text-muted small">الموظف المسؤول</label>
|
||||||
<p><?= htmlspecialchars($mail['assigned_name'] ?: 'غير معين') ?></p>
|
<p><?= htmlspecialchars($mail['assigned_name'] ?: 'غير معين') ?></p>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6 text-end">
|
<?php endif; ?>
|
||||||
<label class="text-muted small">بواسطة / التاريخ</label>
|
|
||||||
<p class="text-muted small"><?= htmlspecialchars($mail['creator_name']) ?> | <?= $mail['created_at'] ?></p>
|
<div class="col-md-6 <?= $mail['type'] == 'internal' ? 'col-md-12' : '' ?> text-end">
|
||||||
|
<label class="text-muted small">تاريخ الإنشاء</label>
|
||||||
|
<p class="text-muted small"><?= $mail['created_at'] ?></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -265,15 +311,15 @@ function isPreviewable($fileName) {
|
|||||||
<!-- Comments -->
|
<!-- Comments -->
|
||||||
<div class="card shadow-sm border-0 mb-4">
|
<div class="card shadow-sm border-0 mb-4">
|
||||||
<div class="card-header bg-white py-3">
|
<div class="card-header bg-white py-3">
|
||||||
<h5 class="mb-0 fw-bold">التعليقات والمتابعة</h5>
|
<h5 class="mb-0 fw-bold">الردود والمتابعة</h5>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<?php if (canEdit()): ?>
|
|
||||||
<form method="POST" class="mb-4 bg-light p-3 rounded border">
|
<form method="POST" class="mb-4 bg-light p-3 rounded border">
|
||||||
<div class="mb-2">
|
<div class="mb-2">
|
||||||
<label class="form-label small fw-bold">إضافة تعليق</label>
|
<label class="form-label small fw-bold">إضافة <?= $mail['type'] == 'internal' ? 'رد' : 'تعليق' ?></label>
|
||||||
<textarea name="comment" class="form-control" rows="2" placeholder="أضف تعليقاً أو ملاحظة متابعة..." required></textarea>
|
<textarea name="comment" class="form-control" rows="2" placeholder="اكتب ردك هنا..." required></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
<?php if ($mail['type'] != 'internal'): ?>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label class="form-label small fw-bold">إحالة إلى موظف (اختياري)</label>
|
<label class="form-label small fw-bold">إحالة إلى موظف (اختياري)</label>
|
||||||
<select name="referred_user_id" class="form-select form-select-sm">
|
<select name="referred_user_id" class="form-select form-select-sm">
|
||||||
@ -284,9 +330,9 @@ function isPreviewable($fileName) {
|
|||||||
</select>
|
</select>
|
||||||
<div class="form-text small">سيتم إرسال تنبيه عبر البريد الإلكتروني للموظف المحال إليه.</div>
|
<div class="form-text small">سيتم إرسال تنبيه عبر البريد الإلكتروني للموظف المحال إليه.</div>
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" name="add_comment" class="btn btn-sm btn-primary">إرسال تعليق وإحالة</button>
|
<?php endif; ?>
|
||||||
|
<button type="submit" name="add_comment" class="btn btn-sm btn-primary">إرسال <?= $mail['type'] == 'internal' ? 'الرد' : 'التعليق' ?></button>
|
||||||
</form>
|
</form>
|
||||||
<?php endif; ?>
|
|
||||||
|
|
||||||
<div class="comment-list">
|
<div class="comment-list">
|
||||||
<?php if ($mail_comments): foreach ($mail_comments as $c): ?>
|
<?php if ($mail_comments): foreach ($mail_comments as $c): ?>
|
||||||
@ -305,7 +351,7 @@ function isPreviewable($fileName) {
|
|||||||
<p class="mb-0 small"><?= nl2br(htmlspecialchars($c['comment'])) ?></p>
|
<p class="mb-0 small"><?= nl2br(htmlspecialchars($c['comment'])) ?></p>
|
||||||
</div>
|
</div>
|
||||||
<?php endforeach; else: ?>
|
<?php endforeach; else: ?>
|
||||||
<p class="text-center text-muted small">لا توجد تعليقات بعد</p>
|
<p class="text-center text-muted small">لا توجد ردود بعد</p>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -319,17 +365,15 @@ function isPreviewable($fileName) {
|
|||||||
<h5 class="mb-0 fw-bold">المرفقات</h5>
|
<h5 class="mb-0 fw-bold">المرفقات</h5>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<?php if (canEdit()): ?>
|
|
||||||
<form method="POST" enctype="multipart/form-data" class="mb-4">
|
<form method="POST" enctype="multipart/form-data" class="mb-4">
|
||||||
<div class="mb-2">
|
<div class="mb-2">
|
||||||
<label class="form-label small mb-1">اسم المرفق (يظهر في القائمة)</label>
|
<label class="form-label small mb-1">اسم المرفق (يظهر في القائمة)</label>
|
||||||
<input type="text" name="display_name" class="form-control form-control-sm mb-2" placeholder="مثال: فاتورة، صورة العقد...">
|
<input type="text" name="display_name" class="form-control form-control-sm mb-2" placeholder="مثال: صورة، مستند...">
|
||||||
<label class="form-label small mb-1">اختر الملف</label>
|
<label class="form-label small mb-1">اختر الملف</label>
|
||||||
<input type="file" name="attachment" class="form-control form-control-sm" required>
|
<input type="file" name="attachment" class="form-control form-control-sm" required>
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" class="btn btn-sm btn-secondary w-100">رفع ملف</button>
|
<button type="submit" class="btn btn-sm btn-secondary w-100">رفع ملف</button>
|
||||||
</form>
|
</form>
|
||||||
<?php endif; ?>
|
|
||||||
|
|
||||||
<div class="list-group list-group-flush">
|
<div class="list-group list-group-flush">
|
||||||
<?php if ($mail_attachments): foreach ($mail_attachments as $a): ?>
|
<?php if ($mail_attachments): foreach ($mail_attachments as $a): ?>
|
||||||
@ -352,7 +396,7 @@ function isPreviewable($fileName) {
|
|||||||
</button>
|
</button>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<?php if (canDelete()): ?>
|
<?php if (canDelete() || $mail['type'] == 'internal'): ?>
|
||||||
<form method="POST" class="d-inline delete-attachment-form">
|
<form method="POST" class="d-inline delete-attachment-form">
|
||||||
<input type="hidden" name="attachment_id" value="<?= $a['id'] ?>">
|
<input type="hidden" name="attachment_id" value="<?= $a['id'] ?>">
|
||||||
<input type="hidden" name="delete_attachment" value="1">
|
<input type="hidden" name="delete_attachment" value="1">
|
||||||
@ -388,7 +432,7 @@ function isPreviewable($fileName) {
|
|||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<a id="downloadBtn" href="#" class="btn btn-primary" download>تحميل الملف</a>
|
<a id="downloadBtn" href="#" class="btn btn-primary" download>تحميل الملف</a>
|
||||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">إإغلاق</button>
|
<button type="button" class="btn btn-secondary" data-bs-modal="modal">إغلاق</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user