| """ |
| مكون الهيدر لنظام واهبي لتحليل العقود والمناقصات |
| Header component for WAHBI Tender Analysis System |
| """ |
|
|
| import streamlit as st |
| import os |
| import base64 |
|
|
| def render_header(subtitle=None): |
| """ |
| عرض شريط العنوان في التطبيق مع الشعار |
| """ |
| |
| logo_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), "assets", "logo.svg") |
| |
| |
| if os.path.exists(logo_path): |
| with open(logo_path, "r", encoding="utf-8") as f: |
| svg_content = f.read() |
| |
| |
| st.markdown(f""" |
| <div style="display: flex; align-items: center; margin-bottom: 1rem; padding: 1rem; background-color: #f8f9fa; border-radius: 10px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);"> |
| <div style="width: 260px; height: 80px;"> |
| {svg_content} |
| </div> |
| <div style="margin-right: 1.5rem; flex: 1; text-align: center;"> |
| <h1 style="margin: 0; color: #1E88E5; font-size: 1.8rem;">نظام واهبي للذكاء الاصطناعي</h1> |
| <p style="margin: 0; color: #666; font-size: 1.1rem;">{subtitle if subtitle else "لتحليل العقود والمناقصات"}</p> |
| </div> |
| </div> |
| """, unsafe_allow_html=True) |
| else: |
| |
| st.markdown(f""" |
| <div style="margin-bottom: 1rem; padding: 1rem; background-color: #f8f9fa; border-radius: 10px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); text-align: center;"> |
| <h1 style="margin: 0; color: #1E88E5; font-size: 1.8rem;">نظام واهبي للذكاء الاصطناعي</h1> |
| <p style="margin: 0; color: #666; font-size: 1.1rem;">{subtitle if subtitle else "لتحليل العقود والمناقصات"}</p> |
| </div> |
| """, unsafe_allow_html=True) |
| print(f"تحذير: لم يتم العثور على ملف الشعار في المسار: {logo_path}") |
|
|
| def render_app_header(): |
| """ |
| عرض هيدر التطبيق الرئيسي مع الشعار والعنوان |
| """ |
| render_header("النظام المتكامل لتحليل العقود والمناقصات باستخدام الذكاء الاصطناعي") |
| |
| def render_section_header(title, description=None, icon=None): |
| """ |
| عرض عنوان قسم مع وصف اختياري وأيقونة |
| """ |
| icon_html = f'<i class="fas fa-{icon}" style="font-size: 1.3rem; color: #1E88E5; margin-left: 0.5rem;"></i>' if icon else '' |
| |
| st.markdown(f""" |
| <div style="margin-bottom: 1.5rem; padding: 1rem; background: linear-gradient(135deg, #f0f7ff, #e8f1fb); border-radius: 10px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);"> |
| <h2 style="margin: 0; display: flex; align-items: center; color: #1E88E5; font-size: 1.5rem;"> |
| {icon_html}{title} |
| </h2> |
| {f'<p style="margin-top: 0.5rem; margin-bottom: 0; color: #666;">{description}</p>' if description else ''} |
| </div> |
| """, unsafe_allow_html=True) |
|
|
| def render_page_title(title, description=None, icon=None): |
| """ |
| عرض عنوان صفحة مع وصف اختياري وأيقونة |
| """ |
| st.markdown(f""" |
| <h1 style="font-size: 1.8rem; font-weight: bold; color: #1E88E5; margin-bottom: 0.5rem; display: flex; align-items: center;"> |
| {f'<i class="fas fa-{icon}" style="margin-left: 0.8rem;"></i>' if icon else ''}{title} |
| </h1> |
| {f'<p style="color: #666; margin-bottom: 1.5rem;">{description}</p>' if description else ''} |
| """, unsafe_allow_html=True) |
|
|
| def render_breadcrumbs(items): |
| """ |
| عرض مسار التنقل في الصفحة |
| |
| المعلمات: |
| items (list): قائمة بالعناصر، كل عنصر هو قاموس يحتوي على مفتاحين: "label" و"url" (اختياري) |
| """ |
| breadcrumbs_html = "" |
| for i, item in enumerate(items): |
| if i > 0: |
| breadcrumbs_html += f'<span style="margin: 0 0.5rem; color: #ccc;"><i class="fas fa-chevron-left"></i></span>' |
| |
| if "url" in item and item["url"]: |
| breadcrumbs_html += f'<a href="{item["url"]}" style="color: {"#1E88E5" if i == len(items) - 1 else "#666"}; text-decoration: {"none" if i == len(items) - 1 else "underline"};">{item["label"]}</a>' |
| else: |
| breadcrumbs_html += f'<span style="color: {"#1E88E5" if i == len(items) - 1 else "#666"};">{item["label"]}</span>' |
| |
| st.markdown(f""" |
| <div style="margin-bottom: 1.5rem; padding: 0.5rem 1rem; background-color: #f8f9fa; border-radius: 5px; font-size: 0.9rem;"> |
| {breadcrumbs_html} |
| </div> |
| """, unsafe_allow_html=True) |
|
|
| def render_notice(message, type="info"): |
| """ |
| عرض إشعار للمستخدم |
| |
| المعلمات: |
| message (str): نص الإشعار |
| type (str): نوع الإشعار "info", "success", "warning", "error" |
| """ |
| icon_map = { |
| "info": "info-circle", |
| "success": "check-circle", |
| "warning": "exclamation-triangle", |
| "error": "times-circle" |
| } |
| |
| color_map = { |
| "info": "#1E88E5", |
| "success": "#4CAF50", |
| "warning": "#FFC107", |
| "error": "#F44336" |
| } |
| |
| bg_color_map = { |
| "info": "#E3F2FD", |
| "success": "#E8F5E9", |
| "warning": "#FFF8E1", |
| "error": "#FFEBEE" |
| } |
| |
| st.markdown(f""" |
| <div style="padding: 1rem; margin-bottom: 1.5rem; background-color: {bg_color_map.get(type, "#E3F2FD")}; border-right: 4px solid {color_map.get(type, "#1E88E5")}; border-radius: 5px; display: flex; align-items: flex-start;"> |
| <i class="fas fa-{icon_map.get(type, 'info-circle')}" style="color: {color_map.get(type, "#1E88E5")}; margin-left: 1rem; font-size: 1.2rem;"></i> |
| <div style="flex: 1;"> |
| <p style="margin: 0; color: #333;">{message}</p> |
| </div> |
| </div> |
| """, unsafe_allow_html=True) |