|
""" |
|
مكون الشريط الجانبي لنظام واهبي لتحليل العقود والمناقصات |
|
Sidebar component for WAHBI Tender Analysis System |
|
""" |
|
|
|
import streamlit as st |
|
import os |
|
from pathlib import Path |
|
import streamlit_option_menu as option_menu |
|
import json |
|
import datetime |
|
|
|
|
|
COLORS = { |
|
"primary": "#0B6E4F", |
|
"secondary": "#08603a", |
|
"accent": "#FFB100", |
|
"tertiary": "#5754FF", |
|
"quaternary": "#f43f5e", |
|
"success": "#10b981", |
|
"warning": "#f59e0b", |
|
"danger": "#ef4444", |
|
"light_bg": "#f8fafc", |
|
"text": "#334155", |
|
"heading": "#1e293b", |
|
"muted": "#64748b", |
|
"border": "#e2e8f0", |
|
} |
|
|
|
|
|
SECTION_ICONS = { |
|
"الرئيسية": {"icon": "house-fill", "color": COLORS["primary"]}, |
|
"تحليل العقود": {"icon": "file-earmark-text-fill", "color": COLORS["primary"]}, |
|
"حاسبة التكاليف": {"icon": "calculator-fill", "color": COLORS["tertiary"]}, |
|
"إدارة المشاريع": {"icon": "clipboard2-data-fill", "color": COLORS["primary"]}, |
|
"الخريطة التفاعلية": {"icon": "geo-alt-fill", "color": COLORS["quaternary"]}, |
|
"المساعد الذكي": {"icon": "robot", "color": COLORS["accent"]}, |
|
"التقارير": {"icon": "bar-chart-fill", "color": COLORS["tertiary"]}, |
|
"المحتوى المحلي": {"icon": "flag-fill", "color": COLORS["success"]}, |
|
"تحليل المخاطر": {"icon": "shield-fill-exclamation", "color": COLORS["warning"]}, |
|
"الإعدادات": {"icon": "gear-fill", "color": COLORS["muted"]}, |
|
} |
|
|
|
def get_user_info(): |
|
""" |
|
استرجاع معلومات المستخدم الحالي (يُستخدم كمثال بسيط) |
|
""" |
|
|
|
return { |
|
"name": "محمد أحمد", |
|
"role": "محلل عقود", |
|
"organization": "شركة المشاريع المتطورة", |
|
"last_login": datetime.datetime.now().strftime("%Y-%m-%d %H:%M"), |
|
"image": None |
|
} |
|
|
|
def render_wahbi_logo(): |
|
""" |
|
عرض شعار نظام واهبي بتصميم SVG متقدم |
|
""" |
|
logo_html = """ |
|
<div style="text-align: center; margin-bottom: 1.5rem; margin-top: 0.5rem;"> |
|
<svg width="120" height="60" viewBox="0 0 240 120" xmlns="http://www.w3.org/2000/svg"> |
|
<style> |
|
.logo-text { font-family: 'Almarai', sans-serif; font-weight: 800; } |
|
.logo-accent { fill: #FFB100; } |
|
.logo-primary { fill: #0B6E4F; } |
|
.logo-secondary { fill: #08603a; } |
|
@keyframes pulse { |
|
0% { opacity: 0.8; } |
|
50% { opacity: 1; } |
|
100% { opacity: 0.8; } |
|
} |
|
.pulse { animation: pulse 2s infinite ease-in-out; } |
|
</style> |
|
<g> |
|
<!-- الشكل الخارجي --> |
|
<path class="logo-primary" d="M40,20 L200,20 C220,20 230,30 230,50 L230,70 C230,90 220,100 200,100 L40,100 C20,100 10,90 10,70 L10,50 C10,30 20,20 40,20 Z" /> |
|
|
|
<!-- الشكل الداخلي --> |
|
<path class="logo-secondary" d="M45,30 L195,30 C210,30 220,40 220,55 L220,65 C220,80 210,90 195,90 L45,90 C30,90 20,80 20,65 L20,55 C20,40 30,30 45,30 Z" /> |
|
|
|
<!-- الشكل الثالث (الهالة) --> |
|
<circle class="pulse logo-accent" cx="120" cy="60" r="35" opacity="0.2" /> |
|
|
|
<!-- نص "واهبي" --> |
|
<text class="logo-text" x="120" y="70" font-size="40" text-anchor="middle" fill="white">واهبي</text> |
|
|
|
<!-- نص "AI" --> |
|
<text class="logo-text logo-accent" x="175" y="70" font-size="30" text-anchor="middle">AI</text> |
|
</g> |
|
</svg> |
|
</div> |
|
""" |
|
return logo_html |
|
|
|
def render_sidebar(): |
|
""" |
|
عرض الشريط الجانبي الرئيسي للتطبيق |
|
""" |
|
with st.sidebar: |
|
|
|
st.markdown(render_wahbi_logo(), unsafe_allow_html=True) |
|
|
|
|
|
user = get_user_info() |
|
|
|
|
|
st.markdown(f""" |
|
<div class="user-profile-card"> |
|
<div class="user-avatar"> |
|
{user["name"][0] if user["name"] else "م"} |
|
</div> |
|
<h3 class="user-name">{user["name"]}</h3> |
|
<p class="user-role">{user["role"]}</p> |
|
<p class="user-organization">{user["organization"]}</p> |
|
|
|
<div class="user-last-login"> |
|
<i class="fas fa-clock"></i> |
|
آخر دخول: {user["last_login"]} |
|
</div> |
|
</div> |
|
|
|
<style> |
|
.user-profile-card {{ |
|
padding: var(--spacing-lg); |
|
background: linear-gradient(135deg, rgba(11, 110, 79, 0.08), rgba(11, 110, 79, 0.03)); |
|
border-radius: var(--border-radius); |
|
margin-bottom: var(--spacing-lg); |
|
text-align: center; |
|
border: 1px solid rgba(11, 110, 79, 0.12); |
|
box-shadow: var(--shadow-sm); |
|
}} |
|
|
|
.user-avatar {{ |
|
width: 85px; |
|
height: 85px; |
|
background: var(--primary-gradient); |
|
border-radius: var(--border-radius-circle); |
|
margin: 0 auto var(--spacing-md) auto; |
|
display: flex; |
|
justify-content: center; |
|
align-items: center; |
|
color: white; |
|
font-size: 2.2rem; |
|
font-weight: var(--font-weight-bold); |
|
box-shadow: 0 4px 10px rgba(11, 110, 79, 0.3); |
|
}} |
|
|
|
.user-name {{ |
|
margin: 0; |
|
font-size: var(--font-size-xl); |
|
color: var(--gray-800); |
|
font-weight: var(--font-weight-bold); |
|
}} |
|
|
|
.user-role {{ |
|
margin: var(--spacing-xs) 0 var(--spacing-xs) 0; |
|
color: var(--primary-color); |
|
font-size: var(--font-size-sm); |
|
font-weight: var(--font-weight-semibold); |
|
}} |
|
|
|
.user-organization {{ |
|
margin: 0; |
|
color: var(--gray-600); |
|
font-size: var(--font-size-xs); |
|
}} |
|
|
|
.user-last-login {{ |
|
margin-top: var(--spacing-md); |
|
padding-top: var(--spacing-md); |
|
border-top: 1px dashed rgba(11, 110, 79, 0.15); |
|
text-align: center; |
|
font-size: var(--font-size-xs); |
|
color: var(--gray-500); |
|
display: flex; |
|
align-items: center; |
|
justify-content: center; |
|
}} |
|
|
|
.user-last-login i {{ |
|
margin-left: 5px; |
|
}} |
|
</style> |
|
""", unsafe_allow_html=True) |
|
|
|
|
|
menu_options = [ |
|
"الرئيسية", |
|
"تحليل العقود", |
|
"حاسبة التكاليف", |
|
"إدارة المشاريع", |
|
"الخريطة التفاعلية", |
|
"المساعد الذكي", |
|
"التقارير", |
|
"المحتوى المحلي", |
|
"تحليل المخاطر", |
|
"الإعدادات" |
|
] |
|
|
|
icons = [SECTION_ICONS[option]["icon"] for option in menu_options] |
|
|
|
|
|
icon_colors = [SECTION_ICONS[option]["color"] for option in menu_options] |
|
|
|
|
|
menu_style = """ |
|
<style> |
|
/* تحسين تنسيق القائمة الرئيسية */ |
|
.nav-link { |
|
position: relative !important; |
|
overflow: hidden !important; |
|
white-space: nowrap !important; |
|
} |
|
|
|
/* تأثير التوهج للعنصر المحدد */ |
|
.nav-link.active::before { |
|
content: ''; |
|
position: absolute; |
|
top: 0; |
|
right: 0; |
|
width: 4px; |
|
height: 100%; |
|
background: linear-gradient(to bottom, rgba(255, 177, 0, 0.8), rgba(255, 177, 0, 0.3)); |
|
z-index: 5; |
|
animation: pulse-border 1.5s infinite alternate; |
|
} |
|
|
|
/* تأثير الخلفية للعنصر المحدد */ |
|
.nav-link.active::after { |
|
content: ''; |
|
position: absolute; |
|
top: 0; |
|
right: 0; |
|
width: 100%; |
|
height: 100%; |
|
background: linear-gradient(135deg, rgba(11, 110, 79, 0.95), rgba(8, 96, 58, 0.95)); |
|
z-index: -1; |
|
animation: gradient-shift 8s infinite alternate; |
|
} |
|
|
|
/* تنسيق الأيقونات بالألوان المخصصة */ |
|
.section-icon-0 { color: #0B6E4F !important; } |
|
.section-icon-1 { color: #0B6E4F !important; } |
|
.section-icon-2 { color: #5754FF !important; } |
|
.section-icon-3 { color: #0B6E4F !important; } |
|
.section-icon-4 { color: #f43f5e !important; } |
|
.section-icon-5 { color: #FFB100 !important; } |
|
.section-icon-6 { color: #5754FF !important; } |
|
.section-icon-7 { color: #10b981 !important; } |
|
.section-icon-8 { color: #f59e0b !important; } |
|
.section-icon-9 { color: #64748b !important; } |
|
|
|
/* إظهار الأيقونات بالأبيض للعنصر المحدد */ |
|
.nav-link.active i { |
|
color: white !important; |
|
animation: icon-pop 0.3s ease-out; |
|
} |
|
|
|
/* تأثيرات الحركة */ |
|
@keyframes pulse-border { |
|
0% { opacity: 0.7; } |
|
100% { opacity: 1; } |
|
} |
|
|
|
@keyframes gradient-shift { |
|
0% { background-position: 0% 50%; } |
|
50% { background-position: 100% 50%; } |
|
100% { background-position: 0% 50%; } |
|
} |
|
|
|
@keyframes icon-pop { |
|
0% { transform: scale(1); } |
|
50% { transform: scale(1.2); } |
|
100% { transform: scale(1); } |
|
} |
|
|
|
/* تأثير التحويم */ |
|
.nav-link:not(.active):hover { |
|
background-color: rgba(11, 110, 79, 0.08) !important; |
|
transform: translateX(-3px) !important; |
|
} |
|
|
|
/* تنعيم عملية الانتقال */ |
|
.nav-link { |
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important; |
|
} |
|
</style> |
|
""" |
|
st.markdown(menu_style, unsafe_allow_html=True) |
|
|
|
|
|
for i, option in enumerate(menu_options): |
|
st.markdown(f""" |
|
<style> |
|
div[data-testid="stVerticalBlock"] div.stButton:nth-child({i+1}) button i {{ |
|
color: {SECTION_ICONS[option]["color"]} !important; |
|
}} |
|
</style> |
|
""", unsafe_allow_html=True) |
|
|
|
selected = option_menu.option_menu( |
|
menu_title="نظام WAHBi AI", |
|
options=menu_options, |
|
icons=icons, |
|
menu_icon="grid-fill", |
|
default_index=0, |
|
styles={ |
|
"container": { |
|
"padding": "0.5rem !important", |
|
"background-color": "transparent", |
|
"direction": "rtl", |
|
"border-radius": "var(--border-radius)", |
|
"margin-bottom": "var(--spacing-md)", |
|
"border": "1px solid rgba(11, 110, 79, 0.1)", |
|
"backdrop-filter": "blur(10px)", |
|
"background": "rgba(255, 255, 255, 0.6)", |
|
}, |
|
"icon": { |
|
"font-size": "1.2rem", |
|
"float": "right", |
|
"margin-left": "15px", |
|
"vertical-align": "middle", |
|
}, |
|
"nav-link": { |
|
"font-size": "0.95rem", |
|
"text-align": "right", |
|
"direction": "rtl", |
|
"padding": "0.8rem 1rem", |
|
"margin-bottom": "0.5rem", |
|
"border-radius": "8px", |
|
"font-weight": "500", |
|
"display": "flex", |
|
"align-items": "center", |
|
"justify-content": "flex-start", |
|
"position": "relative", |
|
"overflow": "hidden", |
|
"z-index": "1", |
|
"transition": "all 0.3s ease", |
|
"background": "rgba(255, 255, 255, 0.7)", |
|
"border": "1px solid rgba(226, 232, 240, 0.7)", |
|
}, |
|
"nav-link-selected": { |
|
"background": "var(--primary-gradient)", |
|
"color": "white", |
|
"text-align": "right", |
|
"font-weight": "600", |
|
"box-shadow": "0 4px 12px rgba(11, 110, 79, 0.2)", |
|
"border": "none", |
|
}, |
|
} |
|
) |
|
|
|
|
|
st.session_state["sidebar_selected"] = selected |
|
|
|
|
|
st.markdown(f""" |
|
<div class="system-status-card"> |
|
<h4 class="status-title">حالة النظام</h4> |
|
|
|
<div class="status-item"> |
|
<div class="status-indicator active"></div> |
|
<span class="status-text">قاعدة البيانات متصلة</span> |
|
</div> |
|
|
|
<div class="status-item"> |
|
<div class="status-indicator active"></div> |
|
<span class="status-text">واجهة برمجة التطبيقات</span> |
|
</div> |
|
|
|
<div class="status-item"> |
|
<div class="status-indicator active"></div> |
|
<span class="status-text">الذكاء الاصطناعي</span> |
|
</div> |
|
|
|
<div class="status-footer"> |
|
آخر تحديث: {datetime.datetime.now().strftime("%H:%M:%S")} |
|
</div> |
|
</div> |
|
|
|
<style> |
|
.system-status-card {{ |
|
padding: var(--spacing-lg); |
|
background-color: white; |
|
border-radius: var(--border-radius); |
|
margin-top: var(--spacing-lg); |
|
border: 1px solid var(--gray-200); |
|
box-shadow: var(--shadow-card); |
|
}} |
|
|
|
.status-title {{ |
|
margin: 0 0 var(--spacing-md) 0; |
|
font-size: var(--font-size-md); |
|
color: var(--gray-800); |
|
font-weight: var(--font-weight-semibold); |
|
border-right: 3px solid var(--primary-color); |
|
padding-right: var(--spacing-sm); |
|
}} |
|
|
|
.status-item {{ |
|
display: flex; |
|
align-items: center; |
|
margin-bottom: var(--spacing-sm); |
|
justify-content: flex-start; |
|
}} |
|
|
|
.status-indicator {{ |
|
min-width: 10px; |
|
height: 10px; |
|
border-radius: 50%; |
|
margin-left: var(--spacing-sm); |
|
}} |
|
|
|
.status-indicator.active {{ |
|
background-color: var(--success-color); |
|
box-shadow: 0 0 5px var(--success-color); |
|
}} |
|
|
|
.status-indicator.warning {{ |
|
background-color: var(--warning-color); |
|
box-shadow: 0 0 5px var(--warning-color); |
|
}} |
|
|
|
.status-indicator.error {{ |
|
background-color: var(--danger-color); |
|
box-shadow: 0 0 5px var(--danger-color); |
|
}} |
|
|
|
.status-text {{ |
|
font-size: var(--font-size-sm); |
|
color: var(--gray-700); |
|
}} |
|
|
|
.status-footer {{ |
|
margin-top: var(--spacing-md); |
|
padding-top: var(--spacing-md); |
|
border-top: 1px solid var(--gray-200); |
|
font-size: var(--font-size-xs); |
|
color: var(--gray-500); |
|
text-align: center; |
|
}} |
|
</style> |
|
""", unsafe_allow_html=True) |
|
|
|
|
|
with st.expander("حول النظام", expanded=False): |
|
st.markdown(f""" |
|
<div class="about-system"> |
|
<div class="about-item"> |
|
<i class="fas fa-info-circle about-icon"></i> |
|
<span class="about-text about-title">نظام واهبي للذكاء الاصطناعي - إصدار 2.0</span> |
|
</div> |
|
<div class="about-item"> |
|
<i class="fas fa-file-contract about-icon"></i> |
|
<span class="about-text">تحليل العقود والمناقصات</span> |
|
</div> |
|
<div class="about-item"> |
|
<i class="fas fa-brain about-icon"></i> |
|
<span class="about-text">بواسطة نماذج الذكاء الاصطناعي المتقدمة</span> |
|
</div> |
|
<div class="about-item"> |
|
<i class="fas fa-copyright about-icon"></i> |
|
<span class="about-text">© 2025 جميع الحقوق محفوظة</span> |
|
</div> |
|
</div> |
|
|
|
<style> |
|
.about-system {{ |
|
font-size: var(--font-size-sm); |
|
color: var(--gray-700); |
|
}} |
|
|
|
.about-item {{ |
|
display: flex; |
|
align-items: center; |
|
margin-bottom: var(--spacing-sm); |
|
}} |
|
|
|
.about-icon {{ |
|
color: var(--primary-color); |
|
font-size: 1rem; |
|
margin-left: var(--spacing-sm); |
|
}} |
|
|
|
.about-text {{ |
|
flex: 1; |
|
}} |
|
|
|
.about-title {{ |
|
font-weight: var(--font-weight-semibold); |
|
}} |
|
</style> |
|
""", unsafe_allow_html=True) |
|
|
|
def get_sidebar_selection(): |
|
""" |
|
الحصول على العنصر المحدد في القائمة الجانبية |
|
""" |
|
return st.session_state.get("sidebar_selected", "الرئيسية") |
|
|
|
def render_module_sidebar(module_name, options=[]): |
|
""" |
|
عرض شريط جانبي مخصص للوحدة |
|
|
|
المعلمات: |
|
module_name (str): اسم الوحدة |
|
options (list): قائمة بالخيارات المتاحة في الوحدة |
|
""" |
|
with st.sidebar: |
|
|
|
st.markdown(f""" |
|
<div class="module-title"> |
|
{module_name} |
|
</div> |
|
|
|
<style> |
|
.module-title {{ |
|
margin-bottom: var(--spacing-md); |
|
color: var(--primary-color); |
|
font-size: var(--font-size-lg); |
|
font-weight: var(--font-weight-semibold); |
|
padding-bottom: var(--spacing-sm); |
|
border-bottom: 1px solid var(--gray-200); |
|
}} |
|
</style> |
|
""", unsafe_allow_html=True) |
|
|
|
|
|
if options: |
|
|
|
module_menu_style = """ |
|
<style> |
|
/* تحسين تنسيق قائمة الوحدة الفرعية */ |
|
.module-menu .nav-link { |
|
position: relative !important; |
|
overflow: hidden !important; |
|
white-space: nowrap !important; |
|
background: rgba(250, 250, 250, 0.5) !important; |
|
border: 1px solid rgba(226, 232, 240, 0.5) !important; |
|
border-radius: 6px !important; |
|
margin-bottom: 0.4rem !important; |
|
padding: 0.6rem 1rem !important; |
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important; |
|
} |
|
|
|
/* تأثير التحويم */ |
|
.module-menu .nav-link:not(.active):hover { |
|
background-color: rgba(11, 110, 79, 0.05) !important; |
|
transform: translateX(-2px) !important; |
|
border-color: rgba(11, 110, 79, 0.15) !important; |
|
} |
|
|
|
/* تنسيق العنصر النشط */ |
|
.module-menu .nav-link.active { |
|
background: linear-gradient(135deg, rgba(11, 110, 79, 0.9), rgba(8, 96, 58, 0.9)) !important; |
|
color: white !important; |
|
box-shadow: 0 4px 10px rgba(11, 110, 79, 0.15) !important; |
|
font-weight: 600 !important; |
|
border: none !important; |
|
} |
|
|
|
/* ترتيب العناصر */ |
|
.module-menu .nav-link::before { |
|
content: ''; |
|
position: absolute; |
|
width: 4px; |
|
height: 0; |
|
right: 0; |
|
top: 50%; |
|
transform: translateY(-50%); |
|
background-color: var(--primary-color); |
|
transition: height 0.3s ease; |
|
} |
|
|
|
.module-menu .nav-link:hover::before { |
|
height: 70%; |
|
} |
|
|
|
.module-menu .nav-link.active::before { |
|
height: 100%; |
|
background: linear-gradient(to bottom, var(--accent-color), rgba(255, 177, 0, 0.5)); |
|
animation: pulse-height 1.5s infinite alternate; |
|
} |
|
|
|
@keyframes pulse-height { |
|
0% { opacity: 0.7; } |
|
100% { opacity: 1; } |
|
} |
|
</style> |
|
""" |
|
st.markdown(module_menu_style, unsafe_allow_html=True) |
|
|
|
|
|
menu_container = st.container() |
|
with menu_container: |
|
st.markdown('<div class="module-menu">', unsafe_allow_html=True) |
|
|
|
selected = option_menu.option_menu( |
|
menu_title=None, |
|
options=options, |
|
menu_icon=None, |
|
default_index=0, |
|
styles={ |
|
"container": { |
|
"padding": "0!important", |
|
"background-color": "transparent", |
|
"direction": "rtl" |
|
}, |
|
"icon": { |
|
"color": "var(--primary-color)", |
|
"font-size": "1rem", |
|
"float": "right", |
|
"margin-left": "12px" |
|
}, |
|
"nav-link": { |
|
"font-size": "0.9rem", |
|
"text-align": "right", |
|
"direction": "rtl", |
|
"margin-bottom": "0.35rem", |
|
"padding": "0.7rem 1rem", |
|
"border-radius": "6px" |
|
}, |
|
"nav-link-selected": { |
|
"background-color": "var(--primary-color)", |
|
"color": "white", |
|
"text-align": "right", |
|
"font-weight": "600" |
|
}, |
|
} |
|
) |
|
|
|
|
|
st.markdown('</div>', unsafe_allow_html=True) |
|
|
|
|
|
st.session_state[f"{module_name}_selected"] = selected |
|
|
|
return selected |
|
|
|
|
|
back_button_container = st.container() |
|
with back_button_container: |
|
st.markdown(f""" |
|
<style> |
|
/* تنسيق زر العودة للقائمة الرئيسية */ |
|
div[data-testid="stButton"][data-testid*="back_btn_{module_name}"] button {{ |
|
background: linear-gradient(135deg, rgba(11, 110, 79, 0.05), rgba(11, 110, 79, 0.1)); |
|
color: var(--primary-color); |
|
border: 1px solid rgba(11, 110, 79, 0.15); |
|
padding: 0.7rem; |
|
border-radius: 8px; |
|
font-size: 0.95rem; |
|
font-weight: 500; |
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); |
|
width: 100%; |
|
text-align: center; |
|
margin-top: 1.5rem; |
|
position: relative; |
|
overflow: hidden; |
|
}} |
|
|
|
div[data-testid="stButton"][data-testid*="back_btn_{module_name}"] button:hover {{ |
|
background: linear-gradient(135deg, rgba(11, 110, 79, 0.1), rgba(11, 110, 79, 0.15)); |
|
border-color: rgba(11, 110, 79, 0.25); |
|
transform: translateY(-2px); |
|
box-shadow: 0 4px 12px rgba(11, 110, 79, 0.1); |
|
}} |
|
|
|
div[data-testid="stButton"][data-testid*="back_btn_{module_name}"] button:active {{ |
|
transform: translateY(0); |
|
box-shadow: none; |
|
}} |
|
|
|
/* إضافة أيقونة للزر */ |
|
div[data-testid="stButton"][data-testid*="back_btn_{module_name}"] button::before {{ |
|
content: "⟸"; |
|
margin-left: 8px; |
|
font-size: 1.1rem; |
|
display: inline-block; |
|
vertical-align: middle; |
|
}} |
|
|
|
/* إضافة تأثير متموج عند النقر */ |
|
@keyframes ripple {{ |
|
0% {{ |
|
transform: scale(0); |
|
opacity: 0.5; |
|
}} |
|
100% {{ |
|
transform: scale(4); |
|
opacity: 0; |
|
}} |
|
}} |
|
|
|
div[data-testid="stButton"][data-testid*="back_btn_{module_name}"] button::after {{ |
|
content: ""; |
|
position: absolute; |
|
width: 30px; |
|
height: 30px; |
|
background: rgba(255, 255, 255, 0.4); |
|
border-radius: 50%; |
|
left: 50%; |
|
top: 50%; |
|
transform: scale(0); |
|
transform-origin: center; |
|
pointer-events: none; |
|
}} |
|
|
|
div[data-testid="stButton"][data-testid*="back_btn_{module_name}"] button:active::after {{ |
|
animation: ripple 0.6s ease-out; |
|
}} |
|
</style> |
|
""", unsafe_allow_html=True) |
|
|
|
|
|
st.markdown(""" |
|
<div class="back-button-card"> |
|
<style> |
|
.back-button-card { |
|
margin-top: 1.5rem; |
|
margin-bottom: 1rem; |
|
} |
|
</style> |
|
</div> |
|
""", unsafe_allow_html=True) |
|
|
|
if st.button("العودة للقائمة الرئيسية", key=f"back_btn_{module_name}"): |
|
st.session_state["sidebar_selected"] = "الرئيسية" |
|
st.rerun() |
|
|
|
def get_module_selection(module_name): |
|
""" |
|
الحصول على العنصر المحدد في قائمة الوحدة |
|
|
|
المعلمات: |
|
module_name (str): اسم الوحدة |
|
""" |
|
return st.session_state.get(f"{module_name}_selected", None) |