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