""" وحدة الإشعارات المتكاملة """ 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