From c99333193081ca8b999c587375720f33e800bc5c Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Sat, 25 Oct 2025 15:42:13 +0000 Subject: [PATCH] v1 --- assets/css/custom.css | 52 ++++ assets/js/main.js | 182 +++++++++++++ db/migrate.php | 28 ++ .../001_create_manual_emails_table.sql | 8 + index.php | 257 ++++++++---------- mail/config.php | 2 +- manual_email.php | 112 ++++++++ settings.php | 49 ++++ 8 files changed, 543 insertions(+), 147 deletions(-) create mode 100644 assets/css/custom.css create mode 100644 assets/js/main.js create mode 100644 db/migrate.php create mode 100644 db/migrations/001_create_manual_emails_table.sql create mode 100644 manual_email.php create mode 100644 settings.php diff --git a/assets/css/custom.css b/assets/css/custom.css new file mode 100644 index 0000000..97e5ad5 --- /dev/null +++ b/assets/css/custom.css @@ -0,0 +1,52 @@ +/* Custom Styles */ +body { + font-family: 'Tajawal', sans-serif; + background-color: #f8f9fa; +} + +.vh-100 { + height: 100vh; +} + +.overflow-hidden { + overflow: hidden; +} + +.overflow-auto { + overflow-y: auto; +} + +#email-list-container .list-group-item { + cursor: pointer; + transition: background-color 0.2s ease-in-out; +} + +#email-list-container .list-group-item:hover { + background-color: #e9ecef; +} + +#email-list-container .list-group-item.active { + background-color: #0d6efd; + border-color: #0d6efd; +} + +#email-list-container .list-group-item.urgent { + border-right: 4px solid #dc3545; +} + +#ai-replies .list-group-item { + cursor: pointer; + transition: background-color 0.2s ease-in-out; +} + +#ai-replies .list-group-item:hover { + background-color: #e9ecef; +} + +.badge.bg-urgent { + background-color: #dc3545 !important; +} + +.badge.bg-normal { + background-color: #0d6efd !important; +} diff --git a/assets/js/main.js b/assets/js/main.js new file mode 100644 index 0000000..8aeb5e2 --- /dev/null +++ b/assets/js/main.js @@ -0,0 +1,182 @@ +document.addEventListener('DOMContentLoaded', function () { + + // --- DUMMY DATA --- + const emails = [ + { + id: 1, + sender: 'إدارة شؤون الموظفين', + subject: 'عاجل: تحديث بيانات الحضور والغياب', + snippet: 'يرجى من جميع الموظفين مراجعة وتحديث بيانات الحضور الخاصة بهم قبل نهاية الأسبوع...', + body: `
الزملاء الكرام،

نود تذكيركم بضرورة مراجعة وتحديث بيانات الحضور والغياب الخاصة بكم على النظام الإلكتروني في موعد أقصاه نهاية دوام يوم الخميس الموافق 30 أكتوبر 2025.

يأتي هذا الإجراء لضمان دقة صرف الرواتب والمستحقات. في حال وجود أي مشكلة تقنية، يرجى التواصل مع قسم الدعم الفني.

شكرًا لتعاونكم.

إدارة شؤون الموظفين`, + attachments: [ + { name: 'تعليمات_التحديث.pdf', icon: 'bi-file-earmark-pdf-fill text-danger' }, + { name: 'نموذج_اعتراض.docx', icon: 'bi-file-earmark-word-fill text-primary' } + ], + tag: 'urgent', + ai: { + summary: 'تطلب إدارة شؤون الموظفين من الجميع تحديث بيانات الحضور والغياب على النظام الإلكتروني قبل نهاية يوم الخميس 30 أكتوبر، وذلك لضمان دقة الرواتب.', + actions: [ + { text: 'إنشاء تذكير', icon: 'bi-alarm-fill' }, + { text: 'طلب مساعدة', icon: 'bi-headset' } + ], + replies: [ + { title: 'رد رسمي (تأكيد)', content: 'السادة/ إدارة شؤون الموظفين،\n\nتحية طيبة وبعد،\n\nتم استلام تعميمكم بخصوص تحديث بيانات الحضور والغياب، وسيتم اتخاذ اللازم. خالص الشكر والتقدير.' }, + { title: 'استفسار', content: 'السادة/ إدارة شؤون الموظفين،\n\nتحية طيبة وبعد،\n\nبخصوص تحديث البيانات، أواجه مشكلة في الدخول إلى النظام. لمن يمكنني التوجه؟ مع الشكر.' } + ] + } + }, + { + id: 2, + sender: 'شركة التوريدات الحديثة', + subject: 'عروض أسعار جديدة لأجهزة الحاسوب', + snippet: 'يسرنا أن نقدم لكم عروض الأسعار الجديدة الخاصة بأجهزة الحاسوب المحمولة والطابعات...', + body: `
السيد/ مدير المدرسة المحترم،

يسرنا في شركة التوريدات الحديثة أن نقدم لكم عروض الأسعار المحدثة لأجهزة الحاسوب المحمولة والطابعات للعام الدراسي الجديد.

تجدون في المرفقات كتالوج المنتجات والأسعار. نقدم خصمًا خاصًا للمدارس بنسبة 15% على الطلبات التي تتجاوز 10 وحدات.

نتطلع للتعاون معكم.

فريق المبيعات`, + attachments: [ + { name: 'كتالوج_2025.pdf', icon: 'bi-file-earmark-pdf-fill text-danger' } + ], + tag: 'normal', + ai: { + summary: 'تقدم شركة التوريدات الحديثة عروض أسعار جديدة على أجهزة الحاسوب والطابعات مع خصم 15% للطلبات الكبيرة.', + actions: [ + { text: 'تمرير لقسم المشتريات', icon: 'bi-share-fill' }, + { text: 'طلب اجتماع', icon: 'bi-calendar-plus' } + ], + replies: [ + { title: 'طلب معلومات إضافية', content: 'السادة/ شركة التوريدات الحديثة،\n\nشكرًا على عروض الأسعار. هل يمكن تزويدنا بتفاصيل إضافية حول فترة الضمان وخدمات ما بعد البيع؟' }, + { title: 'رفض مهذب', content: 'السادة/ شركة التوريدات الحديثة،\n\nنشكركم على جهودكم، ولكننا لا نعتزم إجراء عمليات شراء جديدة في الوقت الحالي.' } + ] + } + }, + { + id: 3, + sender: 'ولي أمر الطالب/ة كريم أحمد', + subject: 'استفسار بخصوص مستوى الطالب الدراسي', + snippet: 'أود الاستفسار عن أداء ابني كريم في الفترة الأخيرة وكيف يمكننا المساعدة في تحسينه...', + body: `
الأستاذ/ مدير المدرسة،

تحية طيبة،

أنا ولي أمر الطالب كريم أحمد في الصف الثاني الإعدادي. أود الاستفسار عن مستواه الدراسي وسلوكه في الفترة الأخيرة. هل هناك أي ملاحظات من المعلمين؟ وكيف يمكننا كأهل المساعدة في المنزل لتحسين أدائه؟

نقدر لكم اهتمامكم.

والد الطالب`, + attachments: [], + tag: 'normal', + ai: { + summary: 'يستفسر ولي أمر الطالب كريم أحمد عن مستواه الدراسي والسلوكي، ويسأل عن طرق للمساعدة في تحسينه.', + actions: [ + { text: 'طلب تقرير من المعلمين', icon: 'bi-file-earmark-text' }, + { text: 'تحديد موعد اجتماع', icon: 'bi-calendar-plus' } + ], + replies: [ + { title: 'رد لطيف ومطمئن', content: 'السيد/ ولي أمر الطالب كريم،\n\nنشكركم على حرصكم ومتابعتكم. سيتم التواصل مع معلمي الطالب لجمع الملاحظات اللازمة والرد عليكم بتقرير مفصل في أقرب فرصة ممكنة. يمكننا بعدها تحديد موعد لمناقشة الأمر إذا لزم.' }, + { title: 'تحديد موعد مباشر', content: 'السيد/ ولي أمر الطالب كريم،\n\nشكرًا لتواصلكم. يسعدنا استقبالكم في المدرسة لمناقشة مستوى الطالب. هل يناسبكم يوم الثلاثاء القادم الساعة 11 صباحًا؟' } + ] + } + } + ]; + + // --- DOM ELEMENTS --- + const emailListContainer = document.getElementById('email-list-container'); + const emailSubject = document.getElementById('email-subject'); + const emailFrom = document.getElementById('email-from'); + const emailBodyContainer = document.getElementById('email-body-container'); + const emailAttachmentsContainer = document.getElementById('email-attachments'); + + const aiSummary = document.getElementById('ai-summary'); + const aiActions = document.getElementById('ai-actions'); + const aiReplies = document.getElementById('ai-replies'); + + // --- FUNCTIONS --- + + function displayEmailList() { + const listGroup = document.createElement('div'); + listGroup.className = 'list-group list-group-flush'; + + emails.forEach(email => { + const item = document.createElement('a'); + item.href = '#'; + item.className = `list-group-item list-group-item-action ${email.tag === 'urgent' ? 'urgent' : ''}`; + item.dataset.id = email.id; + + item.innerHTML = ` +
+
${email.sender}
+ ${email.tag === 'urgent' ? 'عاجل' : 'عادي'} +
+

${email.subject}

+ ${email.snippet} + `; + + item.addEventListener('click', (e) => { + e.preventDefault(); + displayEmailDetail(email.id); + + // Handle active state + document.querySelectorAll('#email-list-container .list-group-item').forEach(el => el.classList.remove('active')); + item.classList.add('active'); + }); + + listGroup.appendChild(item); + }); + emailListContainer.innerHTML = ''; + emailListContainer.appendChild(listGroup); + } + + function displayEmailDetail(id) { + const email = emails.find(e => e.id === id); + if (!email) return; + + emailSubject.textContent = email.subject; + emailFrom.innerHTML = `من: ${email.sender}`; + emailBodyContainer.innerHTML = email.body; + + // Display attachments + emailAttachmentsContainer.innerHTML = ''; + if (email.attachments.length > 0) { + const attachmentsTitle = document.createElement('h6'); + attachmentsTitle.className = 'mb-2 text-muted'; + attachmentsTitle.innerHTML = ` المرفقات (${email.attachments.length})`; + emailAttachmentsContainer.appendChild(attachmentsTitle); + + const attachmentsWrapper = document.createElement('div'); + attachmentsWrapper.className = 'd-flex flex-wrap gap-2'; + email.attachments.forEach(att => { + const attachmentChip = document.createElement('a'); + attachmentChip.href = '#'; + attachmentChip.className = 'btn btn-sm btn-outline-secondary'; + attachmentChip.innerHTML = ` ${att.name}`; + attachmentsWrapper.appendChild(attachmentChip); + }); + emailAttachmentsContainer.appendChild(attachmentsWrapper); + } else { + emailAttachmentsContainer.innerHTML = `لا توجد مرفقات.`; + } + + // Display AI Assistant content + displayAiAssistant(email.ai); + } + + function displayAiAssistant(ai) { + aiSummary.textContent = ai.summary; + + aiActions.innerHTML = ''; + ai.actions.forEach(action => { + const actionChip = document.createElement('button'); + actionChip.className = 'btn btn-sm btn-light border'; + actionChip.innerHTML = ` ${action.text}`; + aiActions.appendChild(actionChip); + }); + + aiReplies.innerHTML = ''; + ai.replies.forEach(reply => { + const replyItem = document.createElement('a'); + replyItem.href = '#'; + replyItem.className = 'list-group-item list-group-item-action'; + replyItem.innerHTML = ` +
+
${reply.title}
+
+ ${reply.content.substring(0, 100)}... + `; + aiReplies.appendChild(replyItem); + }); + } + + // --- INITIALIZATION --- + displayEmailList(); + +}); diff --git a/db/migrate.php b/db/migrate.php new file mode 100644 index 0000000..d4421bb --- /dev/null +++ b/db/migrate.php @@ -0,0 +1,28 @@ + PDO::ERRMODE_EXCEPTION, + ]); + + // Create the database if it doesn't exist + $pdo->exec('CREATE DATABASE IF NOT EXISTS `'.DB_NAME.'`'); + + // Now connect to the specific database + $pdo = db(); + + $migrations = glob(__DIR__ . '/migrations/*.sql'); + sort($migrations); + + foreach ($migrations as $migration) { + $sql = file_get_contents($migration); + $pdo->exec($sql); + echo "Executed migration: " . basename($migration) . "\n"; + } + + echo "Migrations completed successfully.\n"; +} catch (PDOException $e) { + die("Migration failed: " . $e->getMessage()); +} \ No newline at end of file diff --git a/db/migrations/001_create_manual_emails_table.sql b/db/migrations/001_create_manual_emails_table.sql new file mode 100644 index 0000000..ef7a294 --- /dev/null +++ b/db/migrations/001_create_manual_emails_table.sql @@ -0,0 +1,8 @@ + +CREATE TABLE IF NOT EXISTS manual_emails ( + id INT AUTO_INCREMENT PRIMARY KEY, + sender VARCHAR(255) NOT NULL, + subject VARCHAR(255) NOT NULL, + message TEXT NOT NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); diff --git a/index.php b/index.php index 7205f3d..4043d94 100644 --- a/index.php +++ b/index.php @@ -1,150 +1,115 @@ - - - + + - - - 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

-
-
- + +
+
+
+ +

مساعد البريد الذكي

+
+
+ + إدخال يدوي + +
+
+ +
+ +
+
+
+ + +
+
+
+ +
+
+ + +
+
+
اختر رسالة لعرضها
+ +
+
+

محتوى الرسالة سيظهر هنا.

+
+
+ +
+
+ + + +
+
+ + +
+
+ +
المساعد الذكي
+
+
+
+
ملخص الرسالة
+

اختر رسالة ليقوم المساعد بتلخيصها.

+
+
+
إجراءات مقترحة
+
+ لا إجراءات مقترحة +
+
+
+
الردود المقترحة
+
+
اختر رسالة لعرض الردود المقترحة.
+
+
+
+
+
+
+ + + + + - + \ No newline at end of file diff --git a/mail/config.php b/mail/config.php index 626cca1..30f925e 100644 --- a/mail/config.php +++ b/mail/config.php @@ -15,7 +15,7 @@ function load_dotenv_if_needed(array $keys): void { if (empty($missing)) return; static $loaded = false; if ($loaded) return; - $envPath = realpath(__DIR__ . '/../../.env'); // executor/.env + $envPath = realpath(__DIR__ . '/../.env'); // workspace/.env if ($envPath && is_readable($envPath)) { $lines = @file($envPath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) ?: []; foreach ($lines as $line) { diff --git a/manual_email.php b/manual_email.php new file mode 100644 index 0000000..5bf53e7 --- /dev/null +++ b/manual_email.php @@ -0,0 +1,112 @@ +prepare('INSERT INTO manual_emails (sender, subject, message) VALUES (?, ?, ?)'); + $stmt->execute([$from, $subject, $message]); + $success_message = 'تم حفظ البريد الإلكتروني بنجاح!'; + } catch (PDOException $e) { + // For development, it's useful to see the error. In production, you'd log this. + $success_message = 'خطأ في حفظ البريد: ' . $e->getMessage(); + } + } +} + +// Fetch all saved emails +$saved_emails = []; +try { + $pdo = db(); + $stmt = $pdo->query('SELECT sender, subject, message, created_at FROM manual_emails ORDER BY created_at DESC'); + $saved_emails = $stmt->fetchAll(); +} catch (PDOException $e) { + // Handle error, e.g., by showing a message + $db_error = 'خطأ في استرجاع رسائل البريد الإلكتروني: ' . $e->getMessage(); +} + +?> + + + + + + <?php echo htmlspecialchars($page_title); ?> + + + + + +
+
+

إدخال البريد الإلكتروني يدوياً

+ العودة للرئيسية +
+ + +
+ + +
+
نموذج إدخال البريد
+
+
+
+ + +
+
+ + +
+
+ + +
+ +
+
+
+ +
+

الرسائل المحفوظة

+ +
+ +

لا توجد رسائل محفوظة حتى الآن.

+ + + + + +
+ +
+ + \ No newline at end of file diff --git a/settings.php b/settings.php new file mode 100644 index 0000000..89d5b11 --- /dev/null +++ b/settings.php @@ -0,0 +1,49 @@ + + + + + + + الإعدادات + + + + + +
+

الإعدادات

+ العودة للرئيسية +
+ +
+
+
+
إعدادات التطبيق
+

هذه الصفحة مخصصة لإعدادات التطبيق المستقبلية.

+ +
+
+
+ + + +