"""
وحدة الإشعارات المتكاملة
"""
import streamlit as st
import pandas as pd
from datetime import datetime, timedelta
import random
class NotificationsApp:
"""
وحدة الإشعارات المتكاملة للنظام
"""
def __init__(self):
"""
تهيئة وحدة الإشعارات
"""
# تهيئة حالة الجلسة الخاصة بالإشعارات إذا لم تكن موجودة
if 'notifications' not in st.session_state:
# إنشاء بيانات تجريبية للإشعارات
st.session_state.notifications = self._generate_sample_notifications()
if 'notification_settings' not in st.session_state:
# إعدادات الإشعارات الافتراضية
st.session_state.notification_settings = {
'email_enabled': True,
'sms_enabled': True,
'app_enabled': True,
'frequency': 'daily',
'priority_only': False
}
def run(self):
"""
تشغيل وحدة الإشعارات
"""
st.markdown("
وحدة الإشعارات المتكاملة
", unsafe_allow_html=True)
# إنشاء تبويبات للإشعارات المختلفة
tabs = st.tabs(["الإشعارات الحالية", "إعدادات الإشعارات", "سجل الإشعارات"])
with tabs[0]:
self._render_current_notifications()
with tabs[1]:
self._render_notification_settings()
with tabs[2]:
self._render_notification_history()
def _render_current_notifications(self):
"""
عرض الإشعارات الحالية
"""
st.markdown("### الإشعارات الحالية")
# فلترة الإشعارات غير المقروءة
unread_notifications = [n for n in st.session_state.notifications if not n['read']]
if not unread_notifications:
st.info("لا توجد إشعارات جديدة", icon="ℹ️")
else:
st.success(f"لديك {len(unread_notifications)} إشعارات جديدة", icon="🔔")
# عرض الإشعارات غير المقروءة
for i, notification in enumerate(unread_notifications):
with st.container():
col1, col2 = st.columns([5, 1])
with col1:
# تحديد نوع الإشعار ولونه
if notification['type'] == 'تنبيه':
st.warning(f"**{notification['title']}**", icon="⚠️")
elif notification['type'] == 'معلومات':
st.info(f"**{notification['title']}**", icon="ℹ️")
elif notification['type'] == 'نجاح':
st.success(f"**{notification['title']}**", icon="✅")
else:
st.error(f"**{notification['title']}**", icon="❌")
st.markdown(f"{notification['message']}")
st.markdown(f"{notification['date']}", unsafe_allow_html=True)
with col2:
# زر لتحديد الإشعار كمقروء
if st.button("تحديد كمقروء", key=f"mark_read_{i}"):
notification_id = notification['id']
for n in st.session_state.notifications:
if n['id'] == notification_id:
n['read'] = True
st.rerun()
st.markdown("---")
# زر لتحديد جميع الإشعارات كمقروءة
if st.button("تحديد الكل كمقروء", key="mark_all_read"):
for n in st.session_state.notifications:
n['read'] = True
st.rerun()
def _render_notification_settings(self):
"""
عرض إعدادات الإشعارات
"""
st.markdown("### إعدادات الإشعارات")
st.markdown("تخصيص طريقة استلام الإشعارات وتكرارها")
settings = st.session_state.notification_settings
# قسم طرق الإشعارات
st.markdown("#### طرق الإشعارات")
col1, col2, col3 = st.columns(3)
with col1:
email_enabled = st.checkbox("إشعارات البريد الإلكتروني", value=settings['email_enabled'], key="email_enabled")
with col2:
sms_enabled = st.checkbox("إشعارات الرسائل النصية", value=settings['sms_enabled'], key="sms_enabled")
with col3:
app_enabled = st.checkbox("إشعارات التطبيق", value=settings['app_enabled'], key="app_enabled")
# قسم تكرار الإشعارات
st.markdown("#### تكرار الإشعارات")
frequency = st.radio(
"تكرار الإشعارات",
options=["فوري", "يومي", "أسبوعي"],
index=["فوري", "يومي", "أسبوعي"].index(settings['frequency']),
horizontal=True,
key="frequency"
)
# قسم أولوية الإشعارات
st.markdown("#### أولوية الإشعارات")
priority_only = st.checkbox(
"إظهار الإشعارات ذات الأولوية العالية فقط",
value=settings['priority_only'],
key="priority_only"
)
# قسم أنواع الإشعارات
st.markdown("#### أنواع الإشعارات")
notification_types = {
"مناقصات جديدة": True,
"تحديثات المشاريع": True,
"مواعيد نهائية": True,
"تنبيهات النظام": True,
"تقارير دورية": False
}
for ntype, default_value in notification_types.items():
st.checkbox(ntype, value=default_value, key=f"ntype_{ntype}")
# زر حفظ الإعدادات
if st.button("حفظ الإعدادات", key="save_settings"):
st.session_state.notification_settings = {
'email_enabled': email_enabled,
'sms_enabled': sms_enabled,
'app_enabled': app_enabled,
'frequency': frequency,
'priority_only': priority_only
}
st.success("تم حفظ الإعدادات بنجاح", icon="✅")
def _render_notification_history(self):
"""
عرض سجل الإشعارات
"""
st.markdown("### سجل الإشعارات")
st.markdown("عرض جميع الإشعارات السابقة مع إمكانية البحث والتصفية")
# خيارات التصفية
col1, col2 = st.columns(2)
with col1:
filter_type = st.multiselect(
"نوع الإشعار",
options=["الكل", "تنبيه", "معلومات", "نجاح", "خطأ"],
default=["الكل"]
)
with col2:
filter_read = st.multiselect(
"حالة القراءة",
options=["الكل", "مقروء", "غير مقروء"],
default=["الكل"]
)
# تطبيق التصفية
filtered_notifications = st.session_state.notifications
if "الكل" not in filter_type:
filtered_notifications = [n for n in filtered_notifications if n['type'] in filter_type]
if "الكل" not in filter_read:
if "مقروء" in filter_read and "غير مقروء" not in filter_read:
filtered_notifications = [n for n in filtered_notifications if n['read']]
elif "غير مقروء" in filter_read and "مقروء" not in filter_read:
filtered_notifications = [n for n in filtered_notifications if not n['read']]
# تحويل البيانات إلى DataFrame
if filtered_notifications:
df = pd.DataFrame(filtered_notifications)
df = df[['date', 'type', 'title', 'read']]
df.columns = ['التاريخ', 'النوع', 'العنوان', 'مقروء']
df['مقروء'] = df['مقروء'].map({True: 'نعم', False: 'لا'})
# عرض الجدول
st.dataframe(df, use_container_width=True)
else:
st.info("لا توجد إشعارات تطابق معايير التصفية", icon="ℹ️")
def _generate_sample_notifications(self):
"""
إنشاء بيانات تجريبية للإشعارات
"""
notification_types = ['تنبيه', 'معلومات', 'نجاح', 'خطأ']
notifications = []
now = datetime.now()
# إنشاء 20 إشعار تجريبي
for i in range(20):
notification_type = random.choice(notification_types)
# تحديد العنوان والرسالة بناءً على النوع
if notification_type == 'تنبيه':
title = random.choice([
"موعد نهائي قريب",
"تحديث هام في المناقصة",
"تغيير في متطلبات المشروع"
])
message = random.choice([
"يجب تقديم عرض المناقصة خلال 3 أيام",
"تم تحديث وثائق المناقصة، يرجى مراجعتها",
"تم تغيير بعض متطلبات المشروع، يرجى الاطلاع على التفاصيل"
])
elif notification_type == 'معلومات':
title = random.choice([
"مناقصة جديدة متاحة",
"تحديث في النظام",
"اجتماع قادم"
])
message = random.choice([
"تم إضافة مناقصة جديدة في قطاع البنية التحتية",
"تم تحديث النظام إلى الإصدار 2.0.1",
"اجتماع مراجعة المشروع يوم الخميس القادم الساعة 10 صباحاً"
])
elif notification_type == 'نجاح':
title = random.choice([
"تم ترسية المناقصة",
"تم إكمال المشروع بنجاح",
"تم قبول العرض الفني"
])
message = random.choice([
"تمت ترسية المناقصة رقم 2025/123 على شركتكم",
"تم إكمال مشروع تطوير البنية التحتية بنجاح",
"تم قبول العرض الفني للمناقصة رقم 2025/456"
])
else: # خطأ
title = random.choice([
"خطأ في تقديم العرض",
"مشكلة في النظام",
"تأخير في المشروع"
])
message = random.choice([
"حدث خطأ أثناء تقديم العرض، يرجى المحاولة مرة أخرى",
"يواجه النظام مشكلة في وحدة التسعير، جاري العمل على إصلاحها",
"هناك تأخير في تنفيذ المشروع بسبب ظروف خارجية"
])
# تحديد تاريخ عشوائي خلال الأسبوعين الماضيين
days_ago = random.randint(0, 14)
notification_date = (now - timedelta(days=days_ago)).strftime("%Y-%m-%d %H:%M")
# تحديد حالة القراءة (الإشعارات الأقدم أكثر احتمالاً أن تكون مقروءة)
read_probability = days_ago / 14.0
is_read = random.random() < read_probability
notification = {
'id': i + 1,
'type': notification_type,
'title': title,
'message': message,
'date': notification_date,
'read': is_read
}
notifications.append(notification)
# ترتيب الإشعارات حسب التاريخ (الأحدث أولاً)
notifications.sort(key=lambda x: x['date'], reverse=True)
return notifications