Spaces:
Runtime error
Runtime error
| """ | |
| وحدة الإشعارات المتكاملة | |
| """ | |
| 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("<h2 class='module-title'>وحدة الإشعارات المتكاملة</h2>", 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"<small>{notification['date']}</small>", 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 | |