EGYADMIN commited on
Commit
e6c6e90
·
verified ·
1 Parent(s): a1bf31f

Update styling/enhanced_ui.py

Browse files
Files changed (1) hide show
  1. styling/enhanced_ui.py +156 -182
styling/enhanced_ui.py CHANGED
@@ -300,6 +300,9 @@ class UIEnhancer:
300
 
301
  def create_sidebar(self, menu_items):
302
  """إنشاء الشريط الجانبي مع قائمة العناصر"""
 
 
 
303
  with st.sidebar:
304
  # إضافة الشعار
305
  st.markdown(
@@ -337,8 +340,8 @@ class UIEnhancer:
337
 
338
  st.divider()
339
 
340
- # إضافة زر تبديل السمة
341
- if st.button("تبديل السمة 🌓"):
342
  self.toggle_theme()
343
  st.experimental_rerun()
344
 
@@ -357,6 +360,10 @@ class UIEnhancer:
357
 
358
  def create_header(self, title, subtitle=None, show_actions=True):
359
  """إنشاء ترويسة الصفحة"""
 
 
 
 
360
  col1, col2 = st.columns([3, 1])
361
 
362
  with col1:
@@ -366,15 +373,11 @@ class UIEnhancer:
366
 
367
  if show_actions:
368
  with col2:
369
- st.markdown(
370
- """
371
- <div class="header-actions" style="display: flex; justify-content: flex-end; gap: 10px;">
372
- <button class="custom-button" style="background-color: #43A047;">إضافة جديد</button>
373
- <button class="custom-button" style="background-color: #1E88E5;">تحديث</button>
374
- </div>
375
- """,
376
- unsafe_allow_html=True
377
- )
378
 
379
  st.divider()
380
 
@@ -408,205 +411,176 @@ class UIEnhancer:
408
  unsafe_allow_html=True
409
  )
410
 
411
- def create_card(self, title, content, footer=None, color=None):
412
  """إنشاء بطاقة عامة"""
413
  if color is None:
414
  color = self.COLORS['primary']
415
 
416
- footer_html = ""
417
- if footer is not None:
418
- footer_html = f'<div style="margin-top: 15px; padding-top: 10px; border-top: 1px solid {self.COLORS["border"]}; font-size: 0.9rem; color: #666;">{footer}</div>'
419
-
420
  st.markdown(
421
  f"""
422
  <div class="custom-card" style="border-top: 4px solid {color};">
423
  <h3 style="color: {color}; margin-top: 0;">{title}</h3>
424
  <div>{content}</div>
425
- {footer_html}
426
  </div>
427
  """,
428
  unsafe_allow_html=True
429
  )
430
 
431
- def create_status_badge(self, status):
432
- """إنشاء شارة حالة"""
433
- status_colors = {
434
- "جديد": self.COLORS['info'],
435
- "قيد التسعير": self.COLORS['warning'],
436
- "تم التقديم": self.COLORS['primary'],
437
- "تمت الترسية": self.COLORS['success'],
438
- "قيد التنفيذ": self.COLORS['accent'],
439
- "منتهي": self.COLORS['secondary'],
440
- "ملغي": self.COLORS['danger']
441
- }
442
-
443
- color = status_colors.get(status, self.COLORS['primary'])
444
-
445
- return f"""
446
- <span style="background-color: {color}; color: white; padding: 3px 8px; border-radius: 12px; font-size: 0.8rem;">
447
- {status}
448
- </span>
449
- """
450
 
451
- def create_progress_bar(self, percent, label=None):
452
- """إنشاء شريط تقدم"""
453
- if label is None:
454
- label = f"{percent}%"
455
-
456
- # تحديد لون شريط التقدم بناءً على النسبة
457
- if percent < 30:
458
- color = self.COLORS['danger']
459
- elif percent < 70:
460
- color = self.COLORS['warning']
 
 
 
 
 
 
 
 
 
 
 
 
 
 
461
  else:
462
- color = self.COLORS['success']
 
 
 
 
 
 
463
 
464
- st.markdown(
465
- f"""
466
- <div style="margin-bottom: 10px;">
467
- <div style="display: flex; justify-content: space-between; margin-bottom: 5px;">
468
- <span>{label}</span>
469
- <span>{percent}%</span>
470
- </div>
471
- <div style="background-color: {self.COLORS['light']}; border-radius: 5px; height: 10px;">
472
- <div style="background-color: {color}; width: {percent}%; height: 100%; border-radius: 5px;"></div>
473
- </div>
474
- </div>
475
- """,
476
- unsafe_allow_html=True
477
- )
478
 
479
- def create_tabs_container(self, tabs_data):
480
- """إنشاء حاوية تبويبات مخصصة"""
481
- # إنشاء أزرار التبويب
482
- tab_buttons_html = ""
483
- for i, tab in enumerate(tabs_data):
484
- active_class = "active" if i == 0 else ""
485
- tab_buttons_html += f"""
486
- <button class="tablinks {active_class}" onclick="openTab(event, 'tab{i}')">{tab['title']}</button>
487
- """
488
-
489
- # إنشاء محتوى التبويبات
490
- tab_content_html = ""
491
- for i, tab in enumerate(tabs_data):
492
- display_style = "block" if i == 0 else "none"
493
- tab_content_html += f"""
494
- <div id="tab{i}" class="tabcontent" style="display: {display_style};">
495
- {tab['content']}
496
- </div>
497
- """
498
-
499
- # إنشاء JavaScript للتبديل بين التبويبات
500
- js = """
501
- <script>
502
- function openTab(evt, tabName) {
503
- var i, tabcontent, tablinks;
504
- tabcontent = document.getElementsByClassName("tabcontent");
505
- for (i = 0; i < tabcontent.length; i++) {
506
- tabcontent[i].style.display = "none";
507
- }
508
- tablinks = document.getElementsByClassName("tablinks");
509
- for (i = 0; i < tablinks.length; i++) {
510
- tablinks[i].className = tablinks[i].className.replace(" active", "");
511
- }
512
- document.getElementById(tabName).style.display = "block";
513
- evt.currentTarget.className += " active";
514
- }
515
- </script>
516
- """
517
 
518
- # إنشاء CSS للتبويبات
519
- css = f"""
520
- <style>
521
- .tab {{
522
- overflow: hidden;
523
- border: 1px solid {self.COLORS['border']};
524
- background-color: {self.COLORS['light']};
525
- border-radius: 5px 5px 0 0;
526
- }}
527
 
528
- .tab button {{
529
- background-color: inherit;
530
- float: right;
531
- border: none;
532
- outline: none;
533
- cursor: pointer;
534
- padding: 14px 16px;
535
- transition: 0.3s;
536
- font-size: 16px;
537
- font-family: 'Tajawal', sans-serif;
538
- }}
539
 
540
- .tab button:hover {{
541
- background-color: {self.COLORS['primary'] + '20'};
542
- }}
 
 
 
 
543
 
544
- .tab button.active {{
545
- background-color: {self.COLORS['primary']};
546
- color: white;
547
- }}
 
 
 
548
 
549
- .tabcontent {{
550
- display: none;
551
- padding: 20px;
552
- border: 1px solid {self.COLORS['border']};
553
- border-top: none;
554
- border-radius: 0 0 5px 5px;
555
- }}
556
- </style>
557
- """
 
 
 
 
 
 
558
 
559
- # تجميع HTML
560
- html = f"""
561
- {css}
562
- <div class="tab">
563
- {tab_buttons_html}
564
- </div>
 
565
 
566
- {tab_content_html}
 
 
 
 
 
 
567
 
568
- {js}
569
- """
 
 
 
 
 
570
 
571
- st.markdown(html, unsafe_allow_html=True)
572
 
573
- def get_icon_html(self, icon_name, size="1rem", color=None):
574
- """الحصول على HTML لأيقونة Bootstrap"""
575
- if color is None:
576
- color = self.COLORS['primary']
 
577
 
578
- return f"""
579
- <i class="bi bi-{icon_name}" style="font-size: {size}; color: {color};"></i>
580
- """
581
 
582
- def add_bootstrap_icons(self):
583
- """إضافة أيقونات Bootstrap"""
584
- st.markdown(
585
- """
586
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.css">
587
- """,
588
- unsafe_allow_html=True
589
- )
590
 
591
- def get_image_base64(self, image_path):
592
- """تحويل الصورة إلى تنسيق base64"""
593
- with open(image_path, "rb") as img_file:
594
- return base64.b64encode(img_file.read()).decode()
595
-
596
- def add_logo(self, logo_path, width="150px"):
597
- """إضافة شعار"""
598
- if os.path.exists(logo_path):
599
- try:
600
- base64_image = self.get_image_base64(logo_path)
601
- st.markdown(
602
- f"""
603
- <div style="text-align: center; margin-bottom: 20px;">
604
- <img src="data:image/png;base64,{base64_image}" width="{width}">
605
- </div>
606
- """,
607
- unsafe_allow_html=True
608
- )
609
- except Exception as e:
610
- st.error(f"خطأ في تحميل الشعار: {e}")
611
- else:
612
- st.warning(f"ملف الشعار غير موجود: {logo_path}")
 
300
 
301
  def create_sidebar(self, menu_items):
302
  """إنشاء الشريط الجانبي مع قائمة العناصر"""
303
+ # إنشاء معرف فريد للزر بناءً على عنوان الصفحة
304
+ button_key = f"toggle_theme_button_{self.page_title}"
305
+
306
  with st.sidebar:
307
  # إضافة الشعار
308
  st.markdown(
 
340
 
341
  st.divider()
342
 
343
+ # إضافة زر تبديل السمة مع معرف فريد
344
+ if st.button("تبديل السمة 🌓", key=button_key):
345
  self.toggle_theme()
346
  st.experimental_rerun()
347
 
 
360
 
361
  def create_header(self, title, subtitle=None, show_actions=True):
362
  """إنشاء ترويسة الصفحة"""
363
+ # إنشاء معرفات فريدة للأزرار
364
+ add_button_key = f"add_button_{title}"
365
+ update_button_key = f"update_button_{title}"
366
+
367
  col1, col2 = st.columns([3, 1])
368
 
369
  with col1:
 
373
 
374
  if show_actions:
375
  with col2:
376
+ col2_1, col2_2 = st.columns(2)
377
+ with col2_1:
378
+ st.button("إضافة جديد", key=add_button_key)
379
+ with col2_2:
380
+ st.button("تحديث", key=update_button_key)
 
 
 
 
381
 
382
  st.divider()
383
 
 
411
  unsafe_allow_html=True
412
  )
413
 
414
+ def create_card(self, title, content, color=None):
415
  """إنشاء بطاقة عامة"""
416
  if color is None:
417
  color = self.COLORS['primary']
418
 
 
 
 
 
419
  st.markdown(
420
  f"""
421
  <div class="custom-card" style="border-top: 4px solid {color};">
422
  <h3 style="color: {color}; margin-top: 0;">{title}</h3>
423
  <div>{content}</div>
 
424
  </div>
425
  """,
426
  unsafe_allow_html=True
427
  )
428
 
429
+ def create_button(self, label, color=None, icon=None, key=None):
430
+ """إنشاء زر مخصص"""
431
+ if color is None:
432
+ color = self.COLORS['primary']
433
+
434
+ # إنشاء معرف فريد للزر إذا لم يتم توفيره
435
+ if key is None:
436
+ key = f"button_{label}_{hash(label)}"
437
+
438
+ icon_html = f"{icon} " if icon else ""
439
+
440
+ return st.button(
441
+ f"{icon_html}{label}",
442
+ key=key
443
+ )
 
 
 
 
444
 
445
+ def create_tabs(self, tab_names):
446
+ """إنشاء تبويبات"""
447
+ return st.tabs(tab_names)
448
+
449
+ def create_expander(self, title, expanded=False, key=None):
450
+ """إنشاء عنصر قابل للتوسيع"""
451
+ # إنشاء معرف فريد للعنصر إذا لم يتم توفيره
452
+ if key is None:
453
+ key = f"expander_{title}_{hash(title)}"
454
+
455
+ return st.expander(title, expanded=expanded, key=key)
456
+
457
+ def create_data_table(self, data, use_container_width=True, hide_index=True):
458
+ """إنشاء جدول بيانات"""
459
+ return st.dataframe(data, use_container_width=use_container_width, hide_index=hide_index)
460
+
461
+ def create_chart(self, chart_type, data, **kwargs):
462
+ """إنشاء رسم بياني"""
463
+ if chart_type == "bar":
464
+ return st.bar_chart(data, **kwargs)
465
+ elif chart_type == "line":
466
+ return st.line_chart(data, **kwargs)
467
+ elif chart_type == "area":
468
+ return st.area_chart(data, **kwargs)
469
  else:
470
+ return st.bar_chart(data, **kwargs)
471
+
472
+ def create_form(self, title, key=None):
473
+ """إنشاء نموذج"""
474
+ # إنشاء معرف فريد للنموذج إذا لم يتم توفيره
475
+ if key is None:
476
+ key = f"form_{title}_{hash(title)}"
477
 
478
+ return st.form(key=key)
 
 
 
 
 
 
 
 
 
 
 
 
 
479
 
480
+ def create_file_uploader(self, label, types=None, key=None):
481
+ """إنشاء أداة رفع الملفات"""
482
+ # إنشاء معرف فريد لأداة رفع الملفات إذا لم يتم توفيره
483
+ if key is None:
484
+ key = f"file_uploader_{label}_{hash(label)}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
485
 
486
+ return st.file_uploader(label, type=types, key=key)
487
+
488
+ def create_date_input(self, label, value=None, key=None):
489
+ """إنشاء حقل إدخال تاريخ"""
490
+ # إنشاء معرف فريد لحقل إدخال التاريخ إذا لم يتم توفيره
491
+ if key is None:
492
+ key = f"date_input_{label}_{hash(label)}"
 
 
493
 
494
+ return st.date_input(label, value=value, key=key)
495
+
496
+ def create_select_box(self, label, options, index=0, key=None):
497
+ """إنشاء قائمة منسدلة"""
498
+ # إنشاء معرف فريد للقائمة المنسدلة إذا لم يتم توفيره
499
+ if key is None:
500
+ key = f"select_box_{label}_{hash(label)}"
 
 
 
 
501
 
502
+ return st.selectbox(label, options, index=index, key=key)
503
+
504
+ def create_multi_select(self, label, options, default=None, key=None):
505
+ """إنشاء قائمة اختيار متعدد"""
506
+ # إنشاء معرف فريد لقائمة الاختيار المتعدد إذا لم يتم توفيره
507
+ if key is None:
508
+ key = f"multi_select_{label}_{hash(label)}"
509
 
510
+ return st.multiselect(label, options, default=default, key=key)
511
+
512
+ def create_slider(self, label, min_value, max_value, value=None, step=1, key=None):
513
+ """إنشاء شريط تمرير"""
514
+ # إنشاء معرف فريد لشريط التمرير إذا لم يتم توفيره
515
+ if key is None:
516
+ key = f"slider_{label}_{hash(label)}"
517
 
518
+ return st.slider(label, min_value=min_value, max_value=max_value, value=value, step=step, key=key)
519
+
520
+ def create_text_input(self, label, value="", key=None):
521
+ """إنشاء حقل إدخال نصي"""
522
+ # إنشاء معرف فريد لحقل الإدخال النصي إذا لم يتم توفيره
523
+ if key is None:
524
+ key = f"text_input_{label}_{hash(label)}"
525
+
526
+ return st.text_input(label, value=value, key=key)
527
+
528
+ def create_text_area(self, label, value="", height=None, key=None):
529
+ """إنشاء منطقة نص"""
530
+ # إنشاء معرف فريد لمنطقة النص إذا لم يتم توفيره
531
+ if key is None:
532
+ key = f"text_area_{label}_{hash(label)}"
533
 
534
+ return st.text_area(label, value=value, height=height, key=key)
535
+
536
+ def create_number_input(self, label, min_value=None, max_value=None, value=0, step=1, key=None):
537
+ """إنشاء حقل إدخال رقمي"""
538
+ # إنشاء معرف فريد لحقل الإدخال الرقمي إذا لم يتم توفيره
539
+ if key is None:
540
+ key = f"number_input_{label}_{hash(label)}"
541
 
542
+ return st.number_input(label, min_value=min_value, max_value=max_value, value=value, step=step, key=key)
543
+
544
+ def create_checkbox(self, label, value=False, key=None):
545
+ """إنشاء خانة اختيار"""
546
+ # إنشاء معرف فريد لخانة الاختيار إذا لم يتم توفيره
547
+ if key is None:
548
+ key = f"checkbox_{label}_{hash(label)}"
549
 
550
+ return st.checkbox(label, value=value, key=key)
551
+
552
+ def create_radio(self, label, options, index=0, key=None):
553
+ """إنشاء أزرار راديو"""
554
+ # إنشاء معرف فريد لأزرار الراديو إذا لم يتم توفيره
555
+ if key is None:
556
+ key = f"radio_{label}_{hash(label)}"
557
 
558
+ return st.radio(label, options, index=index, key=key)
559
 
560
+ def create_progress_bar(self, value, key=None):
561
+ """إنشاء شريط تقدم"""
562
+ # إنشاء معرف فريد لشريط التقدم إذا لم يتم توفيره
563
+ if key is None:
564
+ key = f"progress_bar_{value}_{hash(str(value))}"
565
 
566
+ return st.progress(value, key=key)
 
 
567
 
568
+ def create_spinner(self, text="جاري التحميل..."):
569
+ """إنشاء مؤشر تحميل"""
570
+ return st.spinner(text)
 
 
 
 
 
571
 
572
+ def create_success_message(self, message):
573
+ """إنشاء رسالة نجاح"""
574
+ return st.success(message)
575
+
576
+ def create_error_message(self, message):
577
+ """إنشاء رسالة خطأ"""
578
+ return st.error(message)
579
+
580
+ def create_warning_message(self, message):
581
+ """إنشاء رسالة تحذير"""
582
+ return st.warning(message)
583
+
584
+ def create_info_message(self, message):
585
+ """إنشاء رسالة معلومات"""
586
+ return st.info(message)