diff --git a/db/migrations/001_initial_schema.sql b/db/migrations/001_initial_schema.sql new file mode 100644 index 0000000..eaf474f --- /dev/null +++ b/db/migrations/001_initial_schema.sql @@ -0,0 +1,52 @@ +-- Migration: Initial Schema +CREATE TABLE IF NOT EXISTS users ( + id INT AUTO_INCREMENT PRIMARY KEY, + username VARCHAR(50) NOT NULL UNIQUE, + password VARCHAR(255) NOT NULL, + full_name VARCHAR(100), + role ENUM('admin', 'clerk', 'staff') DEFAULT 'staff', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS mailbox ( + id INT AUTO_INCREMENT PRIMARY KEY, + type ENUM('inbound', 'outbound') NOT NULL, + ref_no VARCHAR(50) NOT NULL UNIQUE, + date_registered DATE NOT NULL, + sender VARCHAR(255), + recipient VARCHAR(255), + subject VARCHAR(255) NOT NULL, + description TEXT, + status ENUM('received', 'in_progress', 'closed') DEFAULT 'received', + assigned_to INT, + created_by INT, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + FOREIGN KEY (assigned_to) REFERENCES users(id) ON DELETE SET NULL, + FOREIGN KEY (created_by) REFERENCES users(id) ON DELETE SET NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS attachments ( + id INT AUTO_INCREMENT PRIMARY KEY, + mail_id INT NOT NULL, + file_path VARCHAR(255) NOT NULL, + file_name VARCHAR(255) NOT NULL, + file_size INT, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (mail_id) REFERENCES mailbox(id) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS comments ( + id INT AUTO_INCREMENT PRIMARY KEY, + mail_id INT NOT NULL, + user_id INT, + comment TEXT NOT NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (mail_id) REFERENCES mailbox(id) ON DELETE CASCADE, + FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- Initial Admin User (password: admin123) +INSERT INTO users (username, password, full_name, role) +VALUES ('admin', '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', 'مدير النظام', 'admin') +ON DUPLICATE KEY UPDATE username=username; diff --git a/db/migrations/migrate.php b/db/migrations/migrate.php new file mode 100644 index 0000000..7f47a3a --- /dev/null +++ b/db/migrations/migrate.php @@ -0,0 +1,21 @@ +exec($sql); + echo "Successfully applied migration: " . basename($file) . PHP_EOL; + } catch (PDOException $e) { + echo "Error applying migration " . basename($file) . ": " . $e->getMessage() . PHP_EOL; + } + } +} + +runMigrations(); diff --git a/inbound.php b/inbound.php new file mode 100644 index 0000000..2974ae3 --- /dev/null +++ b/inbound.php @@ -0,0 +1,301 @@ +prepare("INSERT INTO mailbox (type, ref_no, date_registered, sender, recipient, subject, description, status, assigned_to, created_by) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); + $stmt->execute([$type, $ref_no, $date_registered, $sender, $recipient, $subject, $description, $status, $assigned_to, $_SESSION['user_id']]); + $success = 'تمت إضافة البريد بنجاح'; + } elseif ($action === 'edit') { + $stmt = db()->prepare("UPDATE mailbox SET ref_no = ?, date_registered = ?, sender = ?, recipient = ?, subject = ?, description = ?, status = ?, assigned_to = ? WHERE id = ? AND type = 'inbound'"); + $stmt->execute([$ref_no, $date_registered, $sender, $recipient, $subject, $description, $status, $assigned_to, $id]); + $success = 'تم تحديث البيانات بنجاح'; + } + } catch (PDOException $e) { + if ($e->getCode() == 23000) { + $error = 'رقم القيد مستخدم مسبقاً'; + } else { + $error = 'حدث خطأ: ' . $e->getMessage(); + } + } + } else { + $error = 'يرجى ملء الحقول المطلوبة (رقم القيد، الموضوع)'; + } +} + +// Delete action +if (isset($_GET['action']) && $_GET['action'] === 'delete' && isset($_GET['id'])) { + $id = $_GET['id']; + $stmt = db()->prepare("DELETE FROM mailbox WHERE id = ? AND type = 'inbound'"); + $stmt->execute([$id]); + $success = 'تم حذف البريد بنجاح'; +} + +$search = $_GET['search'] ?? ''; +$query = "SELECT * FROM mailbox WHERE type = 'inbound'"; +$params = []; +if ($search) { + $query .= " AND (ref_no LIKE ? OR sender LIKE ? OR subject LIKE ?)"; + $params = ["%$search%", "%$search%", "%$search%"]; +} +$query .= " ORDER BY created_at DESC"; +$stmt = db()->prepare($query); +$stmt->execute($params); +$mails = $stmt->fetchAll(); + +$users_list = db()->query("SELECT id, full_name FROM users ORDER BY full_name")->fetchAll(); + +// Handle Deep Link for Edit +$deepLinkData = null; +if (isset($_GET['action']) && $_GET['action'] === 'edit' && isset($_GET['id'])) { + $stmt = db()->prepare("SELECT * FROM mailbox WHERE id = ? AND type = 'inbound'"); + $stmt->execute([$_GET['id']]); + $deepLinkData = $stmt->fetch(); +} +?> + +
+

البريد الوارد

+ +
+ + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
رقم القيدالتاريخالموضوعالمرسلالحالةالإجراءات
+ + تم الاستلام + + قيد المعالجة + + مكتمل + + + + + +
لا يوجد بريد وارد مسجل حالياً
+
+
+
+ + + + + + + \ No newline at end of file diff --git a/includes/footer.php b/includes/footer.php new file mode 100644 index 0000000..9dc65f4 --- /dev/null +++ b/includes/footer.php @@ -0,0 +1,13 @@ + + + + + + + + + + + diff --git a/includes/header.php b/includes/header.php new file mode 100644 index 0000000..a6fe0b9 --- /dev/null +++ b/includes/header.php @@ -0,0 +1,113 @@ + + + + + + + بريد الجمعية الخيرية + + + + + + + + + + +
+
+ + + + + +
diff --git a/index.php b/index.php index 7205f3d..850d680 100644 --- a/index.php +++ b/index.php @@ -1,150 +1,130 @@ query("SELECT COUNT(*) FROM mailbox WHERE type = 'inbound'")->fetchColumn(); +$total_outbound = db()->query("SELECT COUNT(*) FROM mailbox WHERE type = 'outbound'")->fetchColumn(); +$in_progress = db()->query("SELECT COUNT(*) FROM mailbox WHERE status = 'in_progress'")->fetchColumn(); +$recent_mail = db()->query("SELECT * FROM mailbox ORDER BY created_at DESC LIMIT 5")->fetchAll(); + +function getStatusBadge($status) { + switch ($status) { + case 'received': return 'تم الاستلام'; + case 'in_progress': return 'قيد المعالجة'; + case 'closed': return 'مكتمل'; + default: return 'غير معروف'; + } +} ?> - - - - - - New Style - - - - - - - - - - - - - - - - - - - - - -
-
-

Analyzing your requirements and generating your website…

-
- Loading… -
-

AI is collecting your requirements and applying the first changes.

-

This page will update automatically as the plan is implemented.

-

Runtime: PHP — UTC

+ +
+

لوحة التحكم

+ -
-
- Page updated: (UTC) -
- - +
+ + +
+
+
+
+
+
البريد الوارد
+

+
+
+ +
+
+
+
+
+
+
+
+
البريد الصادر
+

+
+
+ +
+
+
+
+
+
+
+
+
قيد المعالجة
+

+
+
+ +
+
+
+
+
+
+
+
+
المستخدمين
+

query("SELECT COUNT(*) FROM users")->fetchColumn() ?>

+
+
+ +
+
+
+
+
+ + +
+
+
+
البريد المضاف حديثاً
+ عرض الكل +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
رقم القيدالنوعالموضوعالمرسل/المستلمالحالةالتاريخ
لا يوجد بريد مسجل حالياً
+
+
+
+ + diff --git a/login.php b/login.php new file mode 100644 index 0000000..f433b90 --- /dev/null +++ b/login.php @@ -0,0 +1,63 @@ +prepare("SELECT * FROM users WHERE username = ?"); + $stmt->execute([$username]); + $user = $stmt->fetch(PDO::FETCH_ASSOC); + + if ($user && password_verify($password, $user['password'])) { + $_SESSION['user_id'] = $user['id']; + $_SESSION['username'] = $user['username']; + $_SESSION['full_name'] = $user['full_name']; + $_SESSION['user_role'] = $user['role']; + redirect('index.php'); + } else { + $error = 'اسم المستخدم أو كلمة المرور غير صحيحة'; + } + } else { + $error = 'يرجى إدخال جميع الحقول المطلوبة'; + } +} +?> + +
+
+
+
+

تسجيل الدخول

+

بريد الجمعية الخيرية

+
+ + +
+ + +
+
+ + +
+
+ + +
+
+ +
+
+
+
+
+ + diff --git a/logout.php b/logout.php new file mode 100644 index 0000000..766a593 --- /dev/null +++ b/logout.php @@ -0,0 +1,6 @@ +beginTransaction(); + if ($action === 'add') { + $stmt = db()->prepare("INSERT INTO mailbox (type, ref_no, date_registered, sender, recipient, subject, description, status, assigned_to, created_by) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); + $stmt->execute([$type, $ref_no, $date_registered, $sender, $recipient, $subject, $description, $status, $assigned_to, $_SESSION['user_id']]); + $mail_id = db()->lastInsertId(); + $success = 'تمت إضافة البريد الصادر بنجاح'; + } elseif ($action === 'edit') { + $mail_id = $id; + $stmt = db()->prepare("UPDATE mailbox SET ref_no = ?, date_registered = ?, sender = ?, recipient = ?, subject = ?, description = ?, status = ?, assigned_to = ? WHERE id = ? AND type = 'outbound'"); + $stmt->execute([$ref_no, $date_registered, $sender, $recipient, $subject, $description, $status, $assigned_to, $mail_id]); + $success = 'تم تحديث البيانات بنجاح'; + } + + // Handle Attachments + if (!empty($_FILES['attachments']['name'][0])) { + $upload_dir = 'uploads/attachments/'; + if (!is_dir($upload_dir)) mkdir($upload_dir, 0777, true); + + foreach ($_FILES['attachments']['name'] as $key => $name) { + if ($_FILES['attachments']['error'][$key] === 0) { + $file_name = time() . '_' . basename($name); + $target_path = $upload_dir . $file_name; + if (move_uploaded_file($_FILES['attachments']['tmp_name'][$key], $target_path)) { + $stmt = db()->prepare("INSERT INTO attachments (mail_id, file_path, file_name, file_size) VALUES (?, ?, ?, ?)"); + $stmt->execute([$mail_id, $target_path, $name, $_FILES['attachments']['size'][$key]]); + } + } + } + } + + db()->commit(); + } catch (PDOException $e) { + db()->rollBack(); + if ($e->getCode() == 23000) { + $error = 'رقم القيد مستخدم مسبقاً'; + } else { + $error = 'حدث خطأ: ' . $e->getMessage(); + } + } + } else { + $error = 'يرجى ملء الحقول المطلوبة (رقم القيد، الموضوع)'; + } +} + +// Delete action +if (isset($_GET['action']) && $_GET['action'] === 'delete' && isset($_GET['id'])) { + $id = $_GET['id']; + $stmt = db()->prepare("DELETE FROM mailbox WHERE id = ? AND type = 'outbound'"); + $stmt->execute([$id]); + $success = 'تم حذف البريد بنجاح'; +} + +$search = $_GET['search'] ?? ''; +$query = "SELECT * FROM mailbox WHERE type = 'outbound'"; +$params = []; +if ($search) { + $query .= " AND (ref_no LIKE ? OR recipient LIKE ? OR subject LIKE ?)"; + $params = ["%$search%", "%$search%", "%$search%"]; +} +$query .= " ORDER BY created_at DESC"; +$stmt = db()->prepare($query); +$stmt->execute($params); +$mails = $stmt->fetchAll(); + +$users_list = db()->query("SELECT id, full_name FROM users ORDER BY full_name")->fetchAll(); + +// Handle Deep Link for Edit +$deepLinkData = null; +if (isset($_GET['action']) && $_GET['action'] === 'edit' && isset($_GET['id'])) { + $stmt = db()->prepare("SELECT * FROM mailbox WHERE id = ? AND type = 'outbound'"); + $stmt->execute([$_GET['id']]); + $deepLinkData = $stmt->fetch(); +} +?> + +
+

البريد الصادر

+ +
+ + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
رقم القيدالتاريخالموضوعالمستلم الخارجىالحالةالإجراءات
+ + تم الاستلام + + قيد المعالجة + + مكتمل + + + + + +
لا يوجد بريد صادر مسجل حالياً
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/users.php b/users.php new file mode 100644 index 0000000..243a3a5 --- /dev/null +++ b/users.php @@ -0,0 +1,261 @@ +غير مصرح لك بالوصول لهذه الصفحة.
'; + require_once __DIR__ . '/includes/footer.php'; + exit; +} + +$error = ''; +$success = ''; + +// Handle actions +if ($_SERVER['REQUEST_METHOD'] === 'POST') { + $action = $_POST['action'] ?? ''; + $username = $_POST['username'] ?? ''; + $full_name = $_POST['full_name'] ?? ''; + $role = $_POST['role'] ?? 'staff'; + $password = $_POST['password'] ?? ''; + $id = $_POST['id'] ?? 0; + + if ($username && $full_name) { + try { + if ($action === 'add') { + if (!$password) { + $error = 'يرجى إدخال كلمة المرور للمستخدم الجديد'; + } else { + $hashed_password = password_hash($password, PASSWORD_DEFAULT); + $stmt = db()->prepare("INSERT INTO users (username, full_name, role, password) VALUES (?, ?, ?, ?)"); + $stmt->execute([$username, $full_name, $role, $hashed_password]); + $success = 'تمت إضافة المستخدم بنجاح'; + } + } elseif ($action === 'edit') { + if ($password) { + $hashed_password = password_hash($password, PASSWORD_DEFAULT); + $stmt = db()->prepare("UPDATE users SET username = ?, full_name = ?, role = ?, password = ? WHERE id = ?"); + $stmt->execute([$username, $full_name, $role, $hashed_password, $id]); + } else { + $stmt = db()->prepare("UPDATE users SET username = ?, full_name = ?, role = ? WHERE id = ?"); + $stmt->execute([$username, $full_name, $role, $id]); + } + $success = 'تم تحديث بيانات المستخدم بنجاح'; + } + } catch (PDOException $e) { + if ($e->getCode() == 23000) { + $error = 'اسم المستخدم موجود مسبقاً'; + } else { + $error = 'حدث خطأ: ' . $e->getMessage(); + } + } + } else { + $error = 'يرجى ملء الحقول المطلوبة'; + } +} + +// Delete action +if (isset($_GET['action']) && $_GET['action'] === 'delete' && isset($_GET['id'])) { + $id = $_GET['id']; + if ($id == $_SESSION['user_id']) { + $error = 'لا يمكنك حذف حسابك الحالي'; + } else { + $stmt = db()->prepare("DELETE FROM users WHERE id = ?"); + $stmt->execute([$id]); + $success = 'تم حذف المستخدم بنجاح'; + } +} + +$users = db()->query("SELECT * FROM users ORDER BY created_at DESC")->fetchAll(); + +// Handle Deep Link for Edit +$deepLinkData = null; +if (isset($_GET['action']) && $_GET['action'] === 'edit' && isset($_GET['id'])) { + $stmt = db()->prepare("SELECT * FROM users WHERE id = ?"); + $stmt->execute([$_GET['id']]); + $deepLinkData = $stmt->fetch(); +} +?> + +
+

إدارة المستخدمين

+ +
+ + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + +
اسم المستخدمالاسم الكاملالصلاحيةتاريخ الإنشاءالإجراءات
+ + + + + + + +
+
+
+
+ + + + + + + diff --git a/view_mail.php b/view_mail.php new file mode 100644 index 0000000..b0da229 --- /dev/null +++ b/view_mail.php @@ -0,0 +1,211 @@ +prepare("SELECT m.*, u1.full_name as assigned_name, u2.full_name as creator_name + FROM mailbox m + LEFT JOIN users u1 ON m.assigned_to = u1.id + LEFT JOIN users u2 ON m.created_by = u2.id + WHERE m.id = ?"); +$stmt->execute([$id]); +$mail = $stmt->fetch(); + +if (!$mail) redirect('index.php'); + +$success = ''; +$error = ''; + +// Handle Comment submission +if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_comment'])) { + $comment = $_POST['comment'] ?? ''; + if ($comment) { + $stmt = db()->prepare("INSERT INTO comments (mail_id, user_id, comment) VALUES (?, ?, ?)"); + $stmt->execute([$id, $_SESSION['user_id'], $comment]); + $success = 'تم إضافة التعليق بنجاح'; + } +} + +// Handle Attachment upload +if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['attachment'])) { + $file = $_FILES['attachment']; + if ($file['error'] === 0) { + $upload_dir = 'uploads/attachments/'; + if (!is_dir($upload_dir)) mkdir($upload_dir, 0777, true); + + $file_name = time() . '_' . basename($file['name']); + $target_path = $upload_dir . $file_name; + + if (move_uploaded_file($file['tmp_name'], $target_path)) { + $stmt = db()->prepare("INSERT INTO attachments (mail_id, file_path, file_name, file_size) VALUES (?, ?, ?, ?)"); + $stmt->execute([$id, $target_path, $file['name'], $file['size']]); + $success = 'تم رفع الملف بنجاح'; + } else { + $error = 'فشل في رفع الملف'; + } + } +} + +$comments = db()->prepare("SELECT c.*, u.full_name FROM comments c LEFT JOIN users u ON c.user_id = u.id WHERE c.mail_id = ? ORDER BY c.created_at DESC"); +$comments->execute([$id]); +$mail_comments = $comments->fetchAll(); + +$attachments = db()->prepare("SELECT * FROM attachments WHERE mail_id = ? ORDER BY created_at DESC"); +$attachments->execute([$id]); +$mail_attachments = $attachments->fetchAll(); +?> + +
+

تفاصيل

+
+ عودة للقائمة + تعديل البيانات +
+
+ + + + + +
+ +
+
+
+
المعلومات الأساسية
+
+
+
+
+ +

+
+
+ +

+
+
+ +

+ + تم الاستلام + + قيد المعالجة + + مكتمل + +

+
+
+ +
+ +
+
+
+ +

+
+
+ +

+
+
+ +
+ لا يوجد وصف إضافي'; + } else { + echo nl2br(htmlspecialchars($mail['description'] ?: 'لا يوجد وصف إضافي')); + } + ?> +
+
+
+ +

+
+
+ +

|

+
+
+
+
+ + +
+
+
التعليقات والمتابعة
+
+
+
+
+ +
+ +
+ +
+ +
+
+ + +
+

+
+ +

لا توجد تعليقات بعد

+ +
+
+
+
+ + +
+
+
+
المرفقات
+
+
+
+
+ +
+ +
+ +
+ +
+
+
+ + +
+ KB +
+
+ +

لا توجد مرفقات

+ +
+
+
+
+
+ +