muzakkirhussain011 commited on
Commit
3e51085
·
1 Parent(s): 3d1c511

Add application files

Browse files
Files changed (1) hide show
  1. app.py +324 -6
app.py CHANGED
@@ -17,6 +17,7 @@ import gradio as gr
17
  import asyncio
18
  import logging
19
  import json
 
20
  from pathlib import Path
21
  from dotenv import load_dotenv
22
  from datetime import datetime
@@ -512,6 +513,296 @@ input[type="text"], textarea {
512
 
513
  .dark input, .dark textarea { background: var(--input-bg) !important; color: var(--text-primary) !important; }
514
  .dark label, .dark .prose, .dark .prose p { color: var(--text-primary) !important; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
515
  """
516
 
517
 
@@ -2203,13 +2494,38 @@ def get_prospect_choices():
2203
  # ============================================================================
2204
  # GRADIO UI
2205
  # ============================================================================
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2206
  def create_app():
2207
 
 
 
 
 
2208
  # Custom head HTML for favicon and meta tags
2209
- head_html = """
2210
- <link rel="icon" type="image/png" sizes="32x32" href="/file=assets/cx_ai_agent_favicon_32.png">
2211
- <link rel="apple-touch-icon" sizes="192x192" href="/file=assets/cx_ai_agent_appicon_192.png">
 
 
 
2212
  <meta name="theme-color" content="#2563eb">
 
2213
  """
2214
 
2215
  with gr.Blocks(
@@ -2219,11 +2535,13 @@ def create_app():
2219
  head=head_html
2220
  ) as demo:
2221
 
2222
- # Header with logo
2223
- gr.HTML("""
 
 
2224
  <div class="main-header">
2225
  <div class="header-logo">
2226
- <img src="/file=assets/cx_ai_agent_logo_512.png" alt="CX AI Agent" style="width: 48px; height: 48px; border-radius: 8px;">
2227
  </div>
2228
  <div class="header-content">
2229
  <h1>CX AI Agent</h1>
 
17
  import asyncio
18
  import logging
19
  import json
20
+ import base64
21
  from pathlib import Path
22
  from dotenv import load_dotenv
23
  from datetime import datetime
 
513
 
514
  .dark input, .dark textarea { background: var(--input-bg) !important; color: var(--text-primary) !important; }
515
  .dark label, .dark .prose, .dark .prose p { color: var(--text-primary) !important; }
516
+
517
+ /* ============== RESPONSIVE DESIGN ============== */
518
+
519
+ /* Tablet and below (max-width: 1024px) */
520
+ @media (max-width: 1024px) {
521
+ .main-header {
522
+ padding: 16px 20px;
523
+ flex-wrap: wrap;
524
+ gap: 12px;
525
+ }
526
+
527
+ .header-content h1 {
528
+ font-size: 22px;
529
+ }
530
+
531
+ .header-content p {
532
+ font-size: 12px;
533
+ }
534
+
535
+ .header-badge {
536
+ font-size: 11px;
537
+ padding: 4px 10px;
538
+ }
539
+
540
+ .stat-card {
541
+ padding: 16px;
542
+ }
543
+
544
+ .stat-value {
545
+ font-size: 28px;
546
+ }
547
+
548
+ .action-card {
549
+ padding: 16px;
550
+ }
551
+
552
+ .prospect-card-header {
553
+ padding: 14px;
554
+ }
555
+ }
556
+
557
+ /* Mobile (max-width: 768px) */
558
+ @media (max-width: 768px) {
559
+ .main-header {
560
+ padding: 14px 16px;
561
+ flex-direction: column;
562
+ text-align: center;
563
+ gap: 10px;
564
+ }
565
+
566
+ .header-logo {
567
+ width: 48px;
568
+ height: 48px;
569
+ }
570
+
571
+ .header-logo img {
572
+ width: 40px !important;
573
+ height: 40px !important;
574
+ }
575
+
576
+ .header-content h1 {
577
+ font-size: 20px;
578
+ margin-bottom: 4px;
579
+ }
580
+
581
+ .header-content p {
582
+ font-size: 11px;
583
+ line-height: 1.3;
584
+ }
585
+
586
+ .header-badge {
587
+ font-size: 10px;
588
+ padding: 4px 8px;
589
+ }
590
+
591
+ .stat-card {
592
+ padding: 12px;
593
+ border-left-width: 3px;
594
+ }
595
+
596
+ .stat-value {
597
+ font-size: 24px;
598
+ }
599
+
600
+ .stat-label {
601
+ font-size: 11px;
602
+ }
603
+
604
+ .action-card {
605
+ padding: 12px;
606
+ }
607
+
608
+ .action-card h3 {
609
+ font-size: 15px;
610
+ }
611
+
612
+ .action-card p {
613
+ font-size: 12px;
614
+ }
615
+
616
+ .prospect-card {
617
+ border-radius: 10px;
618
+ }
619
+
620
+ .prospect-card-header {
621
+ padding: 12px;
622
+ flex-wrap: wrap;
623
+ gap: 8px;
624
+ }
625
+
626
+ .prospect-card-title {
627
+ font-size: 14px;
628
+ }
629
+
630
+ .prospect-card-badge {
631
+ font-size: 10px;
632
+ padding: 3px 8px;
633
+ }
634
+
635
+ .prospect-card-details {
636
+ padding: 12px;
637
+ }
638
+
639
+ .detail-section h4 {
640
+ font-size: 12px;
641
+ }
642
+
643
+ .detail-section p, .detail-section li {
644
+ font-size: 13px;
645
+ }
646
+
647
+ /* Progress container mobile */
648
+ .progress-container {
649
+ padding: 12px;
650
+ margin: 8px 0;
651
+ }
652
+
653
+ .progress-header {
654
+ font-size: 16px;
655
+ margin-bottom: 12px;
656
+ padding-bottom: 10px;
657
+ }
658
+
659
+ .progress-section {
660
+ padding: 10px 12px;
661
+ }
662
+
663
+ .progress-item {
664
+ font-size: 13px;
665
+ padding: 5px 0;
666
+ }
667
+
668
+ .progress-detail {
669
+ font-size: 11px;
670
+ margin-left: 24px;
671
+ }
672
+
673
+ .progress-summary {
674
+ padding: 12px;
675
+ }
676
+
677
+ .progress-summary h3 {
678
+ font-size: 14px;
679
+ }
680
+
681
+ .progress-summary td {
682
+ padding: 5px 6px;
683
+ font-size: 13px;
684
+ }
685
+
686
+ /* Chat section mobile */
687
+ .chatbot {
688
+ height: 350px !important;
689
+ }
690
+
691
+ /* Footer mobile */
692
+ .footer {
693
+ padding: 16px;
694
+ margin-top: 20px;
695
+ }
696
+
697
+ .footer p {
698
+ font-size: 12px;
699
+ }
700
+
701
+ /* Tab labels mobile */
702
+ .tab-nav button {
703
+ font-size: 12px !important;
704
+ padding: 8px 12px !important;
705
+ }
706
+ }
707
+
708
+ /* Small mobile (max-width: 480px) */
709
+ @media (max-width: 480px) {
710
+ .main-header {
711
+ padding: 12px;
712
+ border-radius: 10px;
713
+ margin-bottom: 12px;
714
+ }
715
+
716
+ .header-logo {
717
+ width: 40px;
718
+ height: 40px;
719
+ }
720
+
721
+ .header-logo img {
722
+ width: 32px !important;
723
+ height: 32px !important;
724
+ }
725
+
726
+ .header-content h1 {
727
+ font-size: 18px;
728
+ }
729
+
730
+ .header-content p {
731
+ font-size: 10px;
732
+ }
733
+
734
+ .stat-card {
735
+ padding: 10px;
736
+ }
737
+
738
+ .stat-value {
739
+ font-size: 20px;
740
+ }
741
+
742
+ .stat-label {
743
+ font-size: 10px;
744
+ }
745
+
746
+ .action-card {
747
+ padding: 10px;
748
+ }
749
+
750
+ .action-card h3 {
751
+ font-size: 14px;
752
+ }
753
+
754
+ .prospect-card-header {
755
+ padding: 10px;
756
+ }
757
+
758
+ .prospect-card-title {
759
+ font-size: 13px;
760
+ }
761
+
762
+ .progress-header {
763
+ font-size: 14px;
764
+ }
765
+
766
+ .progress-item {
767
+ font-size: 12px;
768
+ }
769
+
770
+ /* Example prompts mobile - make them scrollable */
771
+ .action-card ul {
772
+ max-height: 200px;
773
+ overflow-y: auto;
774
+ }
775
+
776
+ .action-card li {
777
+ font-size: 11px;
778
+ line-height: 1.6;
779
+ }
780
+ }
781
+
782
+ /* Ensure Gradio rows stack on mobile */
783
+ @media (max-width: 768px) {
784
+ .gr-row {
785
+ flex-direction: column !important;
786
+ }
787
+
788
+ .gr-column {
789
+ width: 100% !important;
790
+ max-width: 100% !important;
791
+ }
792
+ }
793
+
794
+ /* Fix Gradio tab overflow on mobile */
795
+ @media (max-width: 768px) {
796
+ .tabs {
797
+ overflow-x: auto;
798
+ }
799
+
800
+ .tab-nav {
801
+ flex-wrap: nowrap;
802
+ overflow-x: auto;
803
+ -webkit-overflow-scrolling: touch;
804
+ }
805
+ }
806
  """
807
 
808
 
 
2494
  # ============================================================================
2495
  # GRADIO UI
2496
  # ============================================================================
2497
+ def get_logo_base64():
2498
+ """Load logo image as base64 for embedding in HTML"""
2499
+ logo_path = Path(__file__).parent / "assets" / "cx_ai_agent_logo_512.png"
2500
+ if logo_path.exists():
2501
+ with open(logo_path, "rb") as f:
2502
+ return base64.b64encode(f.read()).decode("utf-8")
2503
+ return None
2504
+
2505
+ def get_favicon_base64():
2506
+ """Load favicon as base64 for embedding"""
2507
+ favicon_path = Path(__file__).parent / "assets" / "cx_ai_agent_favicon_32.png"
2508
+ if favicon_path.exists():
2509
+ with open(favicon_path, "rb") as f:
2510
+ return base64.b64encode(f.read()).decode("utf-8")
2511
+ return None
2512
+
2513
+
2514
  def create_app():
2515
 
2516
+ # Load logo as base64
2517
+ logo_b64 = get_logo_base64()
2518
+ favicon_b64 = get_favicon_base64()
2519
+
2520
  # Custom head HTML for favicon and meta tags
2521
+ favicon_html = ""
2522
+ if favicon_b64:
2523
+ favicon_html = f'<link rel="icon" type="image/png" href="data:image/png;base64,{favicon_b64}">'
2524
+
2525
+ head_html = f"""
2526
+ {favicon_html}
2527
  <meta name="theme-color" content="#2563eb">
2528
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
2529
  """
2530
 
2531
  with gr.Blocks(
 
2535
  head=head_html
2536
  ) as demo:
2537
 
2538
+ # Header with logo (using base64 encoded image)
2539
+ logo_img = f'<img src="data:image/png;base64,{logo_b64}" alt="CX AI Agent" style="width: 48px; height: 48px; border-radius: 8px;">' if logo_b64 else '<div style="width:48px;height:48px;background:rgba(255,255,255,0.3);border-radius:8px;display:flex;align-items:center;justify-content:center;font-size:24px;">🤖</div>'
2540
+
2541
+ gr.HTML(f"""
2542
  <div class="main-header">
2543
  <div class="header-logo">
2544
+ {logo_img}
2545
  </div>
2546
  <div class="header-content">
2547
  <h1>CX AI Agent</h1>