v1
This commit is contained in:
parent
2a30fbdcdb
commit
c993331930
52
assets/css/custom.css
Normal file
52
assets/css/custom.css
Normal file
@ -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;
|
||||
}
|
||||
182
assets/js/main.js
Normal file
182
assets/js/main.js
Normal file
@ -0,0 +1,182 @@
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
|
||||
// --- DUMMY DATA ---
|
||||
const emails = [
|
||||
{
|
||||
id: 1,
|
||||
sender: 'إدارة شؤون الموظفين',
|
||||
subject: 'عاجل: تحديث بيانات الحضور والغياب',
|
||||
snippet: 'يرجى من جميع الموظفين مراجعة وتحديث بيانات الحضور الخاصة بهم قبل نهاية الأسبوع...',
|
||||
body: `<h6>الزملاء الكرام،</h6><p>نود تذكيركم بضرورة مراجعة وتحديث بيانات الحضور والغياب الخاصة بكم على النظام الإلكتروني في موعد أقصاه نهاية دوام يوم الخميس الموافق 30 أكتوبر 2025.</p><p>يأتي هذا الإجراء لضمان دقة صرف الرواتب والمستحقات. في حال وجود أي مشكلة تقنية، يرجى التواصل مع قسم الدعم الفني.</p><p>شكرًا لتعاونكم.</p><strong>إدارة شؤون الموظفين</strong>`,
|
||||
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: `<h6>السيد/ مدير المدرسة المحترم،</h6><p>يسرنا في شركة التوريدات الحديثة أن نقدم لكم عروض الأسعار المحدثة لأجهزة الحاسوب المحمولة والطابعات للعام الدراسي الجديد.</p><p>تجدون في المرفقات كتالوج المنتجات والأسعار. نقدم خصمًا خاصًا للمدارس بنسبة 15% على الطلبات التي تتجاوز 10 وحدات.</p><p>نتطلع للتعاون معكم.</p><strong>فريق المبيعات</strong>`,
|
||||
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: `<h6>الأستاذ/ مدير المدرسة،</h6><p>تحية طيبة،</p><p>أنا ولي أمر الطالب كريم أحمد في الصف الثاني الإعدادي. أود الاستفسار عن مستواه الدراسي وسلوكه في الفترة الأخيرة. هل هناك أي ملاحظات من المعلمين؟ وكيف يمكننا كأهل المساعدة في المنزل لتحسين أدائه؟</p><p>نقدر لكم اهتمامكم.</p><strong>والد الطالب</strong>`,
|
||||
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 = `
|
||||
<div class="d-flex w-100 justify-content-between">
|
||||
<h6 class="mb-1">${email.sender}</h6>
|
||||
<small><span class="badge ${email.tag === 'urgent' ? 'bg-urgent' : 'bg-normal'} rounded-pill">${email.tag === 'urgent' ? 'عاجل' : 'عادي'}</span></small>
|
||||
</div>
|
||||
<p class="mb-1">${email.subject}</p>
|
||||
<small class="text-muted">${email.snippet}</small>
|
||||
`;
|
||||
|
||||
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 = `من: <strong>${email.sender}</strong>`;
|
||||
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 = `<i class="bi bi-paperclip me-1"></i> المرفقات (${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 = `<i class="bi ${att.icon} me-1"></i> ${att.name}`;
|
||||
attachmentsWrapper.appendChild(attachmentChip);
|
||||
});
|
||||
emailAttachmentsContainer.appendChild(attachmentsWrapper);
|
||||
} else {
|
||||
emailAttachmentsContainer.innerHTML = `<small class="text-muted">لا توجد مرفقات.</small>`;
|
||||
}
|
||||
|
||||
// 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 = `<i class="bi ${action.icon} me-1"></i> ${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 = `
|
||||
<div class="d-flex w-100 justify-content-between">
|
||||
<h6 class="mb-1">${reply.title}</h6>
|
||||
</div>
|
||||
<small class="text-muted">${reply.content.substring(0, 100)}...</small>
|
||||
`;
|
||||
aiReplies.appendChild(replyItem);
|
||||
});
|
||||
}
|
||||
|
||||
// --- INITIALIZATION ---
|
||||
displayEmailList();
|
||||
|
||||
});
|
||||
28
db/migrate.php
Normal file
28
db/migrate.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/config.php';
|
||||
|
||||
try {
|
||||
// Connect to MySQL server without specifying a database
|
||||
$pdo = new PDO('mysql:host='.DB_HOST, DB_USER, DB_PASS, [
|
||||
PDO::ATTR_ERRMODE => 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());
|
||||
}
|
||||
8
db/migrations/001_create_manual_emails_table.sql
Normal file
8
db/migrations/001_create_manual_emails_table.sql
Normal file
@ -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
|
||||
);
|
||||
255
index.php
255
index.php
@ -1,150 +1,115 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
@ini_set('display_errors', '1');
|
||||
@error_reporting(E_ALL);
|
||||
@date_default_timezone_set('UTC');
|
||||
|
||||
$phpVersion = PHP_VERSION;
|
||||
$now = date('Y-m-d H:i:s');
|
||||
?>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<!DOCTYPE html>
|
||||
<html lang="ar" dir="rtl">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>New Style</title>
|
||||
<?php
|
||||
// Read project preview data from environment
|
||||
$projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? '';
|
||||
$projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
|
||||
?>
|
||||
<?php if ($projectDescription): ?>
|
||||
<!-- Meta description -->
|
||||
<meta name="description" content='<?= htmlspecialchars($projectDescription) ?>' />
|
||||
<!-- Open Graph meta tags -->
|
||||
<meta property="og:description" content="<?= htmlspecialchars($projectDescription) ?>" />
|
||||
<!-- Twitter meta tags -->
|
||||
<meta property="twitter:description" content="<?= htmlspecialchars($projectDescription) ?>" />
|
||||
<?php endif; ?>
|
||||
<?php if ($projectImageUrl): ?>
|
||||
<!-- Open Graph image -->
|
||||
<meta property="og:image" content="<?= htmlspecialchars($projectImageUrl) ?>" />
|
||||
<!-- Twitter image -->
|
||||
<meta property="twitter:image" content="<?= htmlspecialchars($projectImageUrl) ?>" />
|
||||
<?php endif; ?>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
:root {
|
||||
--bg-color-start: #6a11cb;
|
||||
--bg-color-end: #2575fc;
|
||||
--text-color: #ffffff;
|
||||
--card-bg-color: rgba(255, 255, 255, 0.01);
|
||||
--card-border-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: 'Inter', sans-serif;
|
||||
background: linear-gradient(45deg, var(--bg-color-start), var(--bg-color-end));
|
||||
color: var(--text-color);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 100vh;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
body::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"><path d="M-10 10L110 10M10 -10L10 110" stroke-width="1" stroke="rgba(255,255,255,0.05)"/></svg>');
|
||||
animation: bg-pan 20s linear infinite;
|
||||
z-index: -1;
|
||||
}
|
||||
@keyframes bg-pan {
|
||||
0% { background-position: 0% 0%; }
|
||||
100% { background-position: 100% 100%; }
|
||||
}
|
||||
main {
|
||||
padding: 2rem;
|
||||
}
|
||||
.card {
|
||||
background: var(--card-bg-color);
|
||||
border: 1px solid var(--card-border-color);
|
||||
border-radius: 16px;
|
||||
padding: 2rem;
|
||||
backdrop-filter: blur(20px);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
.loader {
|
||||
margin: 1.25rem auto 1.25rem;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border: 3px solid rgba(255, 255, 255, 0.25);
|
||||
border-top-color: #fff;
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
@keyframes spin {
|
||||
from { transform: rotate(0deg); }
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
.hint {
|
||||
opacity: 0.9;
|
||||
}
|
||||
.sr-only {
|
||||
position: absolute;
|
||||
width: 1px; height: 1px;
|
||||
padding: 0; margin: -1px;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
white-space: nowrap; border: 0;
|
||||
}
|
||||
h1 {
|
||||
font-size: 3rem;
|
||||
font-weight: 700;
|
||||
margin: 0 0 1rem;
|
||||
letter-spacing: -1px;
|
||||
}
|
||||
p {
|
||||
margin: 0.5rem 0;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
code {
|
||||
background: rgba(0,0,0,0.2);
|
||||
padding: 2px 6px;
|
||||
border-radius: 4px;
|
||||
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
||||
}
|
||||
footer {
|
||||
position: absolute;
|
||||
bottom: 1rem;
|
||||
font-size: 0.8rem;
|
||||
opacity: 0.7;
|
||||
}
|
||||
</style>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>مساعد البريد الذكي</title>
|
||||
<meta name="description" content="تطبيق داخلي لمدير المدرسة يقرأ الإيميلات ويقترح ردودًا. Built with Flatlogic Generator.">
|
||||
<meta name="keywords" content="إدارة المدرسة, مساعد بريد, ذكاء اصطناعي, ردود تلقائية, تنظيم الايميلات, التعليم, إدارة, إنتاجية, Built with Flatlogic Generator">
|
||||
<meta property="og:title" content="مساعد البريد الذكي">
|
||||
<meta property="og:description" content="تطبيق داخلي لمدير المدرسة يقرأ الإيميلات ويقترح ردودًا. Built with Flatlogic Generator.">
|
||||
<meta property="og:image" content="">
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="twitter:image" content="">
|
||||
|
||||
<!-- Bootstrap 5 RTL -->
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.rtl.min.css" rel="stylesheet" integrity="sha384-nU14brUcp6StFntEOOEBvcJm4huWjB0OcIeQ3fltAfSmuZFrkAif0T+UtNGlKKQv" crossorigin="anonymous">
|
||||
<!-- Bootstrap Icons -->
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css" rel="stylesheet">
|
||||
<!-- Google Fonts (Tajawal) -->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Tajawal:wght@400;500;700&display=swap" rel="stylesheet">
|
||||
<!-- Custom CSS -->
|
||||
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<div class="card">
|
||||
<h1>Analyzing your requirements and generating your website…</h1>
|
||||
<div class="loader" role="status" aria-live="polite" aria-label="Applying initial changes">
|
||||
<span class="sr-only">Loading…</span>
|
||||
</div>
|
||||
<p class="hint"><?= ($_SERVER['HTTP_HOST'] ?? '') === 'appwizzy.com' ? 'AppWizzy' : 'Flatlogic' ?> AI is collecting your requirements and applying the first changes.</p>
|
||||
<p class="hint">This page will update automatically as the plan is implemented.</p>
|
||||
<p>Runtime: PHP <code><?= htmlspecialchars($phpVersion) ?></code> — UTC <code><?= htmlspecialchars($now) ?></code></p>
|
||||
</div>
|
||||
</main>
|
||||
<footer>
|
||||
Page updated: <?= htmlspecialchars($now) ?> (UTC)
|
||||
</footer>
|
||||
|
||||
<main class="container-fluid vh-100 d-flex flex-column">
|
||||
<header class="row border-bottom py-2">
|
||||
<div class="col d-flex align-items-center">
|
||||
<i class="bi bi-robot fs-3 text-primary me-3"></i>
|
||||
<h4 class="mb-0">مساعد البريد الذكي</h4>
|
||||
</div>
|
||||
<div class="col-auto d-flex align-items-center">
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-outline-secondary dropdown-toggle" type="button" id="langDropdown" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
<i class="bi bi-translate me-1"></i> العربية
|
||||
</button>
|
||||
<ul class="dropdown-menu" aria-labelledby="langDropdown">
|
||||
<li><a class="dropdown-item active" href="#">العربية</a></li>
|
||||
<li><a class="dropdown-item" href="#">English</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<a href="manual_email.php" class="btn btn-outline-primary ms-2"><i class="bi bi-plus-circle me-1"></i> إدخال يدوي</a>
|
||||
<a href="settings.php" class="btn btn-light ms-2" title="الإعدادات"><i class="bi bi-gear"></i></a>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="row flex-grow-1 overflow-hidden">
|
||||
<!-- Email List Column -->
|
||||
<div id="email-list-col" class="col-md-3 border-end p-0 d-flex flex-column">
|
||||
<div class="p-3 border-bottom">
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" placeholder="بحث في البريد...">
|
||||
<button class="btn btn-outline-secondary" type="button"><i class="bi bi-search"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="email-list-container" class="flex-grow-1 overflow-auto">
|
||||
<!-- Email items will be injected here by JS -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Email Detail Column -->
|
||||
<div id="email-detail-col" class="col-md-5 p-0 d-flex flex-column">
|
||||
<div class="p-3 border-bottom bg-light">
|
||||
<h5 id="email-subject" class="mb-1">اختر رسالة لعرضها</h5>
|
||||
<small id="email-from" class="text-muted"></small>
|
||||
</div>
|
||||
<div id="email-body-container" class="flex-grow-1 p-4 overflow-auto">
|
||||
<p class="text-muted">محتوى الرسالة سيظهر هنا.</p>
|
||||
</div>
|
||||
<div id="email-attachments" class="p-3 border-top bg-light">
|
||||
<!-- Attachments will be injected here by JS -->
|
||||
</div>
|
||||
<div class="p-3 border-top d-flex gap-2">
|
||||
<button class="btn btn-primary"><i class="bi bi-reply-fill me-1"></i> رد</button>
|
||||
<button class="btn btn-outline-secondary"><i class="bi bi-reply-all-fill me-1"></i> رد على الكل</button>
|
||||
<button class="btn btn-outline-secondary"><i class="bi bi-arrow-right-short me-1"></i> تمرير</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- AI Assistant Column -->
|
||||
<div id="ai-assistant-col" class="col-md-4 border-start p-0 d-flex flex-column bg-light">
|
||||
<div class="p-3 border-bottom d-flex align-items-center">
|
||||
<i class="bi bi-magic fs-5 text-primary me-2"></i>
|
||||
<h5 class="mb-0">المساعد الذكي</h5>
|
||||
</div>
|
||||
<div id="ai-assistant-body" class="flex-grow-1 p-4 overflow-auto">
|
||||
<div class="mb-4">
|
||||
<h6><i class="bi bi-card-text me-2"></i>ملخص الرسالة</h6>
|
||||
<p id="ai-summary" class="text-muted small">اختر رسالة ليقوم المساعد بتلخيصها.</p>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<h6><i class="bi bi-lightbulb me-2"></i>إجراءات مقترحة</h6>
|
||||
<div id="ai-actions" class="d-flex flex-wrap gap-2">
|
||||
<span class="badge bg-secondary bg-opacity-25 text-dark-emphasis">لا إجراءات مقترحة</span>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h6><i class="bi bi-pencil-square me-2"></i>الردود المقترحة</h6>
|
||||
<div id="ai-replies" class="list-group list-group-flush">
|
||||
<div class="list-group-item text-muted small">اختر رسالة لعرض الردود المقترحة.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<!-- Bootstrap 5 JS -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script>
|
||||
<!-- Custom JS -->
|
||||
<script src="assets/js/main.js?v=<?php echo time(); ?>"></script>
|
||||
</body>
|
||||
</html>
|
||||
@ -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) {
|
||||
|
||||
112
manual_email.php
Normal file
112
manual_email.php
Normal file
@ -0,0 +1,112 @@
|
||||
<?php
|
||||
require_once 'db/config.php';
|
||||
|
||||
$page_title = 'Manual Email Entry';
|
||||
$page_description = 'A page to manually enter email content.';
|
||||
$from = '';
|
||||
$subject = '';
|
||||
$message = '';
|
||||
$success_message = '';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$from = isset($_POST['from']) ? $_POST['from'] : '';
|
||||
$subject = isset($_POST['subject']) ? $_POST['subject'] : '';
|
||||
$message = isset($_POST['message']) ? $_POST['message'] : '';
|
||||
|
||||
if ($from && $subject && $message) {
|
||||
try {
|
||||
$pdo = db();
|
||||
$stmt = $pdo->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();
|
||||
}
|
||||
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="ar" dir="rtl">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title><?php echo htmlspecialchars($page_title); ?></title>
|
||||
<meta name="description" content="<?php echo htmlspecialchars($page_description); ?>">
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<style>
|
||||
body { background-color: #f8f9fa; }
|
||||
.container { max-width: 800px; }
|
||||
.card { margin-top: 2rem; }
|
||||
.card-header { background-color: #0d6efd; color: white; }
|
||||
.result-box { margin-top: 2rem; padding: 1.5rem; border: 1px solid #dee2e6; border-radius: .25rem; background-color: #fff; }
|
||||
.email-item { border-bottom: 1px solid #eee; padding-bottom: 1rem; margin-bottom: 1rem; }
|
||||
.email-item:last-child { border-bottom: none; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<header class="d-flex justify-content-between align-items-center py-3 mb-4 border-bottom">
|
||||
<h1 class="h4">إدخال البريد الإلكتروني يدوياً</h1>
|
||||
<a href="index.php" class="btn btn-sm btn-outline-secondary">العودة للرئيسية</a>
|
||||
</header>
|
||||
|
||||
<?php if ($success_message): ?>
|
||||
<div class="alert alert-success"><?php echo $success_message; ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header">نموذج إدخال البريد</div>
|
||||
<div class="card-body">
|
||||
<form action="manual_email.php" method="POST">
|
||||
<div class="mb-3">
|
||||
<label for="from" class="form-label">من:</label>
|
||||
<input type="email" class="form-control" id="from" name="from" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="subject" class="form-label">الموضوع:</label>
|
||||
<input type="text" class="form-control" id="subject" name="subject" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="message" class="form-label">نص الرسالة:</label>
|
||||
<textarea class.form-control" id="message" name="message" rows="8" required></textarea>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">حفظ البريد</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="result-box">
|
||||
<h2 class="h5 mb-4">الرسائل المحفوظة</h2>
|
||||
<?php if (isset($db_error)): ?>
|
||||
<div class="alert alert-danger"><?php echo $db_error; ?></div>
|
||||
<?php elseif (empty($saved_emails)): ?>
|
||||
<p>لا توجد رسائل محفوظة حتى الآن.</p>
|
||||
<?php else: ?>
|
||||
<?php foreach ($saved_emails as $email): ?>
|
||||
<div class="email-item">
|
||||
<p><strong>من:</strong> <?php echo htmlspecialchars($email['sender']); ?></p>
|
||||
<p><strong>الموضوع:</strong> <?php echo htmlspecialchars($email['subject']); ?></p>
|
||||
<p><strong>الرسالة:</strong></p>
|
||||
<pre style="white-space: pre-wrap; background-color: #f1f1f1; padding: 1rem; border-radius: .25rem;"><?php echo htmlspecialchars($email['message']); ?></pre>
|
||||
<small class="text-muted">تم الاستلام في: <?php echo $email['created_at']; ?></small>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
49
settings.php
Normal file
49
settings.php
Normal file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
// settings.php
|
||||
// You can add PHP logic here for handling settings in the future.
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="ar" dir="rtl">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>الإعدادات</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||||
<style>
|
||||
body {
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
.container {
|
||||
max-width: 800px;
|
||||
}
|
||||
.header {
|
||||
background-color: #ffffff;
|
||||
padding: 1rem;
|
||||
border-bottom: 1px solid #dee2e6;
|
||||
margin-bottom: 2rem;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="header">
|
||||
<h1 class="h4">الإعدادات</h1>
|
||||
<a href="index.php" class="btn btn-secondary">العودة للرئيسية</a>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">إعدادات التطبيق</h5>
|
||||
<p class="card-text">هذه الصفحة مخصصة لإعدادات التطبيق المستقبلية.</p>
|
||||
<!-- Add settings form or options here later -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
x
Reference in New Issue
Block a user