|
""" |
|
مكون الهيدر لنظام واهبي لتحليل العقود والمناقصات |
|
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) |