EngReem85 commited on
Commit
76bec23
·
verified ·
1 Parent(s): 9fde9af

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +101 -63
app.py CHANGED
@@ -182,6 +182,19 @@ p, span, div {
182
  background: #3d3d5c !important;
183
  border-color: #6366f1 !important;
184
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
185
  """
186
 
187
  # ==================================================
@@ -305,6 +318,69 @@ def format_time(timestamp):
305
  except:
306
  return "غير معروف"
307
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
308
  # ==================================================
309
  # إضافة رأي
310
  # ==================================================
@@ -414,7 +490,7 @@ def add_testimonial(name, role, content, rating, request: gr.Request):
414
  # جلب الآراء
415
  # ==================================================
416
 
417
- def get_testimonials(filter_type="all", sort_by="newest", search_query="", page=1, per_page=5):
418
  conn = get_connection()
419
  c = conn.cursor()
420
 
@@ -422,16 +498,6 @@ def get_testimonials(filter_type="all", sort_by="newest", search_query="", page=
422
  conditions = []
423
  params = []
424
 
425
- # فلترة
426
- if filter_type == "highlight":
427
- conditions.append("is_highlighted = 1")
428
- elif filter_type == "rating_5":
429
- conditions.append("rating = 5")
430
- elif filter_type == "rating_4":
431
- conditions.append("rating = 4")
432
- elif filter_type == "rating_3":
433
- conditions.append("rating = 3")
434
-
435
  # بحث
436
  if search_query:
437
  conditions.append("(content LIKE ? OR name LIKE ?)")
@@ -440,11 +506,8 @@ def get_testimonials(filter_type="all", sort_by="newest", search_query="", page=
440
  if conditions:
441
  query += " WHERE " + " AND ".join(conditions)
442
 
443
- # ترتيب
444
- if sort_by == "newest":
445
- query += " ORDER BY timestamp DESC"
446
- else:
447
- query += " ORDER BY timestamp ASC"
448
 
449
  offset = (page - 1) * per_page
450
  query += " LIMIT ? OFFSET ?"
@@ -566,8 +629,8 @@ def render_card(row):
566
  # تحديث العرض
567
  # ==================================================
568
 
569
- def update_display(filter_type="all", sort_by="newest", search_query="", page=1):
570
- rows, total, total_pages = get_testimonials(filter_type, sort_by, search_query, page)
571
 
572
  if not rows:
573
  return """
@@ -783,6 +846,9 @@ def create_interface():
783
  </div>
784
  """)
785
 
 
 
 
786
  # ===== المحتوى الرئيسي =====
787
  with gr.Row(equal_height=False):
788
 
@@ -853,29 +919,6 @@ def create_interface():
853
  with gr.Column(scale=2, min_width=400):
854
  gr.Markdown("### 💬 آراء المستخدمين")
855
 
856
- with gr.Row():
857
- filter_dropdown = gr.Dropdown(
858
- choices=[
859
- ("الكل", "all"),
860
- ("المميزة", "highlight"),
861
- ("تقييم 5 نجوم", "rating_5"),
862
- ("تقييم 4 نجوم", "rating_4"),
863
- ("تقييم 3 نجوم", "rating_3"),
864
- ],
865
- value="all",
866
- label="🔍 فلترة",
867
- scale=1
868
- )
869
- sort_dropdown = gr.Dropdown(
870
- choices=[
871
- ("الأحدث", "newest"),
872
- ("الأقدم", "oldest")
873
- ],
874
- value="newest",
875
- label="📊 ترتيب",
876
- scale=1
877
- )
878
-
879
  # شريط البحث
880
  search_input = gr.Textbox(
881
  placeholder="🔎 بحث في الآراء...",
@@ -910,41 +953,36 @@ def create_interface():
910
 
911
  # ===== الأحداث =====
912
 
913
- def full_update(filter_type="all", sort_by="newest", search_query="", page=1):
914
- display = update_display(filter_type, sort_by, search_query, page)
915
- return display
 
 
 
 
916
 
917
  # زر النشر
918
  submit_btn.click(
919
  fn=add_testimonial,
920
  inputs=[name_input, role_input, content_input, rating_input],
921
  outputs=[status_output, name_input, role_input, testimonials_display, char_count]
 
 
 
922
  )
923
 
924
  # زر التحديث
925
  refresh_btn.click(
926
  fn=full_update,
927
- inputs=[filter_dropdown, sort_dropdown, search_input],
928
- outputs=[testimonials_display]
929
- )
930
-
931
- # تغيير الفلترة/الترتيب/البحث
932
- filter_dropdown.change(
933
- fn=full_update,
934
- inputs=[filter_dropdown, sort_dropdown, search_input],
935
- outputs=[testimonials_display]
936
- )
937
-
938
- sort_dropdown.change(
939
- fn=full_update,
940
- inputs=[filter_dropdown, sort_dropdown, search_input],
941
- outputs=[testimonials_display]
942
  )
943
 
 
944
  search_input.change(
945
  fn=full_update,
946
- inputs=[filter_dropdown, sort_dropdown, search_input],
947
- outputs=[testimonials_display]
948
  )
949
 
950
  # زر التصدير
@@ -966,8 +1004,8 @@ def create_interface():
966
  # تحميل أولي
967
  demo.load(
968
  fn=full_update,
969
- inputs=[filter_dropdown, sort_dropdown, search_input],
970
- outputs=[testimonials_display]
971
  )
972
 
973
  return demo
 
182
  background: #3d3d5c !important;
183
  border-color: #6366f1 !important;
184
  }
185
+
186
+ /* تحسين الإحصائيات */
187
+ .stat-card {
188
+ background: #1a1a2e !important;
189
+ border: 1px solid #2d2d44 !important;
190
+ transition: all 0.3s ease;
191
+ }
192
+
193
+ .stat-card:hover {
194
+ transform: translateY(-2px);
195
+ border-color: #6366f1 !important;
196
+ box-shadow: 0 4px 20px rgba(99, 102, 241, 0.1) !important;
197
+ }
198
  """
199
 
200
  # ==================================================
 
318
  except:
319
  return "غير معروف"
320
 
321
+ # ==================================================
322
+ # الإحصائيات
323
+ # ==================================================
324
+
325
+ def get_stats():
326
+ """جلب الإحصائيات"""
327
+ conn = get_connection()
328
+ c = conn.cursor()
329
+
330
+ try:
331
+ c.execute("SELECT COUNT(*) FROM testimonials")
332
+ total = c.fetchone()[0]
333
+
334
+ c.execute("SELECT AVG(rating) FROM testimonials")
335
+ avg = c.fetchone()[0]
336
+ avg_rating = round(avg, 1) if avg else 0
337
+
338
+ except Exception as e:
339
+ logger.error(f"خطأ في الإحصائيات: {e}")
340
+ return {"total": 0, "avg_rating": 0}
341
+ finally:
342
+ conn.close()
343
+
344
+ return {
345
+ "total": total,
346
+ "avg_rating": avg_rating
347
+ }
348
+
349
+ def render_stats(stats):
350
+ """عرض الإحصائيات"""
351
+ return f"""
352
+ <div style="
353
+ display:grid;
354
+ grid-template-columns:repeat(auto-fit, minmax(200px, 1fr));
355
+ gap:1rem;
356
+ margin-bottom:1.5rem;
357
+ ">
358
+ <div class="stat-card" style="
359
+ background:#1a1a2e;
360
+ padding:1.5rem;
361
+ border-radius:16px;
362
+ text-align:center;
363
+ border:1px solid #2d2d44;
364
+ transition: all 0.3s ease;
365
+ ">
366
+ <div style="font-size:3rem;font-weight:700;color:#818cf8;">{stats['total']}</div>
367
+ <div style="color:#94a3b8;font-size:0.95rem;">📝 عدد الآراء</div>
368
+ </div>
369
+
370
+ <div class="stat-card" style="
371
+ background:#1a1a2e;
372
+ padding:1.5rem;
373
+ border-radius:16px;
374
+ text-align:center;
375
+ border:1px solid #2d2d44;
376
+ transition: all 0.3s ease;
377
+ ">
378
+ <div style="font-size:3rem;font-weight:700;color:#fbbf24;">{stats['avg_rating']}</div>
379
+ <div style="color:#94a3b8;font-size:0.95rem;">⭐ متوسط التقييم</div>
380
+ </div>
381
+ </div>
382
+ """
383
+
384
  # ==================================================
385
  # إضافة رأي
386
  # ==================================================
 
490
  # جلب الآراء
491
  # ==================================================
492
 
493
+ def get_testimonials(search_query="", page=1, per_page=5):
494
  conn = get_connection()
495
  c = conn.cursor()
496
 
 
498
  conditions = []
499
  params = []
500
 
 
 
 
 
 
 
 
 
 
 
501
  # بحث
502
  if search_query:
503
  conditions.append("(content LIKE ? OR name LIKE ?)")
 
506
  if conditions:
507
  query += " WHERE " + " AND ".join(conditions)
508
 
509
+ # ترتيب من الأحدث
510
+ query += " ORDER BY timestamp DESC"
 
 
 
511
 
512
  offset = (page - 1) * per_page
513
  query += " LIMIT ? OFFSET ?"
 
629
  # تحديث العرض
630
  # ==================================================
631
 
632
+ def update_display(search_query="", page=1):
633
+ rows, total, total_pages = get_testimonials(search_query, page)
634
 
635
  if not rows:
636
  return """
 
846
  </div>
847
  """)
848
 
849
+ # ===== الإحصائيات =====
850
+ stats_display = gr.HTML()
851
+
852
  # ===== المحتوى الرئيسي =====
853
  with gr.Row(equal_height=False):
854
 
 
919
  with gr.Column(scale=2, min_width=400):
920
  gr.Markdown("### 💬 آراء المستخدمين")
921
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
922
  # شريط البحث
923
  search_input = gr.Textbox(
924
  placeholder="🔎 بحث في الآراء...",
 
953
 
954
  # ===== الأحداث =====
955
 
956
+ def update_stats():
957
+ return render_stats(get_stats())
958
+
959
+ def full_update(search_query="", page=1):
960
+ stats_html = render_stats(get_stats())
961
+ display = update_display(search_query, page)
962
+ return stats_html, display
963
 
964
  # زر النشر
965
  submit_btn.click(
966
  fn=add_testimonial,
967
  inputs=[name_input, role_input, content_input, rating_input],
968
  outputs=[status_output, name_input, role_input, testimonials_display, char_count]
969
+ ).then(
970
+ fn=update_stats,
971
+ outputs=[stats_display]
972
  )
973
 
974
  # زر التحديث
975
  refresh_btn.click(
976
  fn=full_update,
977
+ inputs=[search_input],
978
+ outputs=[stats_display, testimonials_display]
 
 
 
 
 
 
 
 
 
 
 
 
 
979
  )
980
 
981
+ # البحث
982
  search_input.change(
983
  fn=full_update,
984
+ inputs=[search_input],
985
+ outputs=[stats_display, testimonials_display]
986
  )
987
 
988
  # زر التصدير
 
1004
  # تحميل أولي
1005
  demo.load(
1006
  fn=full_update,
1007
+ inputs=[search_input],
1008
+ outputs=[stats_display, testimonials_display]
1009
  )
1010
 
1011
  return demo