Nischal Subedi commited on
Commit
fd79167
·
1 Parent(s): 4d38bdb
Files changed (1) hide show
  1. app.py +32 -28
app.py CHANGED
@@ -248,7 +248,7 @@ Answer:"""
248
  # Basic client-side validation for immediate feedback (redundant but good UX)
249
  if not api_key or not api_key.strip() or not api_key.startswith("sk-"):
250
  return "<div class='error-message'><span class='error-icon'>⚠️</span>Please provide a valid OpenAI API key (starting with 'sk-'). <a href='https://platform.openai.com/api-keys' target='_blank'>OpenAI</a>.</div>"
251
- if not state or state == "Select a state..." or "Error" in state:
252
  return "<div class='error-message'><span class='error-icon'>⚠️</span>Please select a valid state from the list.</div>"
253
  if not query or not query.strip():
254
  return "<div class='error-message'><span class='error-icon'>⚠️</span>Please enter your question in the text box.</div>"
@@ -270,13 +270,13 @@ Answer:"""
270
  available_states_list = self.get_states()
271
  # DEBUG: Print states to console to verify if data is loaded
272
  print(f"DEBUG: States loaded for selection: {available_states_list}")
273
- # Ensure "Select a state..." is always the first option
274
- radio_choices = ["Select a state..."] + (available_states_list if available_states_list and "Error" not in available_states_list[0] else ["Error: States unavailable"])
275
- initial_value_radio = radio_choices[0] # Set initial value to the prompt
276
  except Exception as e: # Catch-all for safety
277
  print(f"DEBUG: Error loading states for selection: {e}")
278
  radio_choices = ["Error: Critical failure loading states"]
279
- initial_value_radio = radio_choices[0]
280
 
281
 
282
  # Define example queries, filtering based on available states
@@ -309,8 +309,8 @@ Answer:"""
309
  :root {
310
  --primary-color: #FF8C00; /* Darker Orange for buttons/accents */
311
  --primary-hover: #E07B00; /* Slightly darker orange for hover */
312
- --background-primary: hsl(30, 100%, 99.5%); /* Very bright, almost white, distinctly warm cream */
313
- --background-secondary: hsl(30, 100%, 96%); /* Slightly deeper, yet still very light, warm peach/cream */
314
  --text-primary: #4A3C32; /* Dark warm brown/charcoal for main text */
315
  --text-secondary: #8C7B6F; /* Muted warm gray/brown for secondary text */
316
  --border-color: hsl(30, 70%, 85%); /* Light, warm orange-brown for borders */
@@ -377,15 +377,15 @@ Answer:"""
377
  left: 0;
378
  width: 100%;
379
  height: 100%;
380
- background: radial-gradient(circle at top left, rgba(255,140,0,0.25) 0%, transparent 60%), /* More vibrant orange tint */
381
- radial-gradient(circle at bottom right, rgba(255,140,0,0.25) 0%, transparent 60%);
382
  z-index: 0;
383
  opacity: 0.8;
384
  pointer-events: none;
385
  }
386
 
387
  .app-header-logo {
388
- font-size: 8rem !important; /* Significantly larger icon */
389
  margin-bottom: 0.75rem !important;
390
  display: block !important;
391
  color: var(--primary-color) !important; /* Theme color */
@@ -471,17 +471,25 @@ Answer:"""
471
  letter-spacing: -0.01em !important;
472
  }
473
 
474
- /* Specific styling for the welcome/disclaimer markdown content */
475
  .dashboard-card-section p {
476
  line-height: 1.7 !important;
477
  color: var(--text-primary) !important;
478
  font-size: 1rem !important;
479
  text-align: left !important; /* Ensure content text is left-aligned */
 
480
  }
481
  .dashboard-card-section strong {
482
  color: var(--primary-color) !important; /* Highlight strong text with primary color */
483
  }
484
 
 
 
 
 
 
 
 
485
  /* Improved input styling with clear boundaries and focus */
486
  /* Target the main textbox container to remove any default background */
487
  .gradio-textbox {
@@ -539,7 +547,7 @@ Answer:"""
539
  cursor: pointer !important;
540
  transition: all 0.2s ease-out !important;
541
  box-shadow: var(--shadow-sm) !important;
542
- margin: 0.25rem 0 !important; /* Small vertical margin between options */
543
  width: 100% !important; /* Ensure options take full width of their column */
544
  box-sizing: border-box !important; /* Include padding/border in width */
545
  }
@@ -800,6 +808,7 @@ Answer:"""
800
  font-size: 0.95rem !important;
801
  color: var(--text-secondary) !important;
802
  line-height: 1.6 !important;
 
803
  }
804
  .app-footer a {
805
  color: var(--primary-color) !important;
@@ -864,21 +873,18 @@ Answer:"""
864
  # Main Dashboard Container - acts as a column to stack various sections
865
  with gr.Column(elem_classes="main-dashboard-container"):
866
 
867
- # Introduction and Disclaimer Card
868
  with gr.Group(elem_classes="dashboard-card-section"):
869
- # Apply 'full-width-center' for section titles
870
- gr.Markdown("<h3 class='section-title'>Welcome & Disclaimer</h3>", elem_classes="full-width-center")
871
  gr.Markdown(
872
  """
873
- Navigate landlord-tenant laws with ease. This assistant provides detailed, state-specific answers grounded in legal authority.
874
-
875
- **Disclaimer:** This tool is for informational purposes only and does not constitute legal advice. For specific legal guidance, always consult a licensed attorney in your jurisdiction.
876
  """
 
877
  )
878
 
879
  # OpenAI API Key Input Card
880
  with gr.Group(elem_classes="dashboard-card-section"):
881
- # Apply 'full-width-center' for section titles
882
  gr.Markdown("<h3 class='section-title'>OpenAI API Key</h3>", elem_classes="full-width-center")
883
  api_key_input = gr.Textbox(
884
  label="API Key",
@@ -891,7 +897,6 @@ Answer:"""
891
 
892
  # Query Input and State Selection Card
893
  with gr.Group(elem_classes="dashboard-card-section"):
894
- # Apply 'full-width-center' for section titles
895
  gr.Markdown("<h3 class='section-title'>Ask Your Question</h3>", elem_classes="full-width-center")
896
 
897
  # Changed from gr.Row to gr.Column for vertical stacking
@@ -908,8 +913,9 @@ Answer:"""
908
  state_input = gr.Radio(
909
  label="Select State",
910
  choices=radio_choices,
911
- value=initial_value_radio,
912
- elem_classes=["input-field-group", "gradio-radio-custom"] # Added custom class for specific styling
 
913
  )
914
 
915
  with gr.Row(elem_classes="button-row"): # Row for action buttons
@@ -918,7 +924,6 @@ Answer:"""
918
 
919
  # Output Display Card - Using gr.HTML for better animation control
920
  with gr.Group(elem_classes="dashboard-card-section"):
921
- # Apply 'full-width-center' for section titles
922
  gr.Markdown("<h3 class='section-title'>Legal Assistant's Response</h3>", elem_classes="full-width-center")
923
  output = gr.HTML( # Changed to gr.HTML to wrap content with animation class
924
  value="<div class='placeholder'>The answer will appear here after submitting your query.</div>",
@@ -927,7 +932,6 @@ Answer:"""
927
 
928
  # Example Questions Section
929
  with gr.Group(elem_classes="dashboard-card-section examples-section"):
930
- # Apply 'full-width-center' for section titles
931
  gr.Markdown("<h3 class='section-title'>Example Questions</h3>", elem_classes="full-width-center")
932
  if example_queries:
933
  gr.Examples(
@@ -939,12 +943,12 @@ Answer:"""
939
  else:
940
  gr.Markdown("<div class='placeholder'>Sample questions could not be loaded. Please ensure the vector database is populated.</div>")
941
 
942
- # Footer Section - contains disclaimer and developer info
943
  with gr.Group(elem_classes="app-footer-wrapper"):
944
  gr.Markdown(
945
  """
946
- This tool is for informational purposes only and does not constitute legal advice. For legal guidance, always consult with a licensed attorney in your jurisdiction.
947
- Developed by **Nischal Subedi**. Connect on [LinkedIn](https://www.linkedin.com/in/nischal1/) or explore insights at [Substack](https://datascientistinsights.substack.com/).
948
  """
949
  )
950
 
@@ -960,7 +964,7 @@ Answer:"""
960
  fn=lambda: (
961
  "", # Clear API key input
962
  "", # Clear query input
963
- initial_value_radio, # Reset state radio to default prompt
964
  "<div class='placeholder'>Inputs cleared. Ready for your next question.</div>" # Reset output message
965
  ),
966
  inputs=[],
 
248
  # Basic client-side validation for immediate feedback (redundant but good UX)
249
  if not api_key or not api_key.strip() or not api_key.startswith("sk-"):
250
  return "<div class='error-message'><span class='error-icon'>⚠️</span>Please provide a valid OpenAI API key (starting with 'sk-'). <a href='https://platform.openai.com/api-keys' target='_blank'>OpenAI</a>.</div>"
251
+ if not state or state == "Select a state..." or "Error" in state or state is None: # Added check for None
252
  return "<div class='error-message'><span class='error-icon'>⚠️</span>Please select a valid state from the list.</div>"
253
  if not query or not query.strip():
254
  return "<div class='error-message'><span class='error-icon'>⚠️</span>Please enter your question in the text box.</div>"
 
270
  available_states_list = self.get_states()
271
  # DEBUG: Print states to console to verify if data is loaded
272
  print(f"DEBUG: States loaded for selection: {available_states_list}")
273
+ # For Radio, remove "Select a state..." from choices, initial value will be None
274
+ radio_choices = available_states_list if available_states_list and "Error" not in available_states_list[0] else ["Error: States unavailable"]
275
+ initial_value_radio = None # Set initial value to None, forcing user to pick
276
  except Exception as e: # Catch-all for safety
277
  print(f"DEBUG: Error loading states for selection: {e}")
278
  radio_choices = ["Error: Critical failure loading states"]
279
+ initial_value_radio = None
280
 
281
 
282
  # Define example queries, filtering based on available states
 
309
  :root {
310
  --primary-color: #FF8C00; /* Darker Orange for buttons/accents */
311
  --primary-hover: #E07B00; /* Slightly darker orange for hover */
312
+ --background-primary: hsl(30, 100%, 99.8%); /* Almost pure white, with a very subtle warm tint */
313
+ --background-secondary: hsl(30, 100%, 96%); /* Clear, light, warm peach/cream */
314
  --text-primary: #4A3C32; /* Dark warm brown/charcoal for main text */
315
  --text-secondary: #8C7B6F; /* Muted warm gray/brown for secondary text */
316
  --border-color: hsl(30, 70%, 85%); /* Light, warm orange-brown for borders */
 
377
  left: 0;
378
  width: 100%;
379
  height: 100%;
380
+ background: radial-gradient(circle at top left, rgba(255,140,0,0.3) 0%, transparent 60%), /* More vibrant orange tint */
381
+ radial-gradient(circle at bottom right, rgba(255,140,0,0.3) 0%, transparent 60%);
382
  z-index: 0;
383
  opacity: 0.8;
384
  pointer-events: none;
385
  }
386
 
387
  .app-header-logo {
388
+ font-size: 8.5rem !important; /* Significantly larger icon */
389
  margin-bottom: 0.75rem !important;
390
  display: block !important;
391
  color: var(--primary-color) !important; /* Theme color */
 
471
  letter-spacing: -0.01em !important;
472
  }
473
 
474
+ /* Specific styling for all paragraph content within dashboard sections */
475
  .dashboard-card-section p {
476
  line-height: 1.7 !important;
477
  color: var(--text-primary) !important;
478
  font-size: 1rem !important;
479
  text-align: left !important; /* Ensure content text is left-aligned */
480
+ background-color: transparent !important; /* Ensure p tags don't have unexpected backgrounds */
481
  }
482
  .dashboard-card-section strong {
483
  color: var(--primary-color) !important; /* Highlight strong text with primary color */
484
  }
485
 
486
+ /* Overrides for common Gradio internal elements that might have default backgrounds */
487
+ .gr-box, .gr-prose, .gr-form, .gr-panel, .gr-block {
488
+ background-color: transparent !important; /* Ensure these are transparent to show parent's gradient */
489
+ color: var(--text-primary) !important; /* Ensure text color is consistent */
490
+ }
491
+
492
+
493
  /* Improved input styling with clear boundaries and focus */
494
  /* Target the main textbox container to remove any default background */
495
  .gradio-textbox {
 
547
  cursor: pointer !important;
548
  transition: all 0.2s ease-out !important;
549
  box-shadow: var(--shadow-sm) !important;
550
+ margin: 0.4rem 0 !important; /* Increased vertical margin between options */
551
  width: 100% !important; /* Ensure options take full width of their column */
552
  box-sizing: border-box !important; /* Include padding/border in width */
553
  }
 
808
  font-size: 0.95rem !important;
809
  color: var(--text-secondary) !important;
810
  line-height: 1.6 !important;
811
+ background-color: transparent !important; /* Ensure paragraph in footer does not get unexpected background */
812
  }
813
  .app-footer a {
814
  color: var(--primary-color) !important;
 
873
  # Main Dashboard Container - acts as a column to stack various sections
874
  with gr.Column(elem_classes="main-dashboard-container"):
875
 
876
+ # How It Works Box (formerly Welcome & Disclaimer)
877
  with gr.Group(elem_classes="dashboard-card-section"):
878
+ gr.Markdown("<h3 class='section-title'>How This Assistant Works</h3>", elem_classes="full-width-center")
 
879
  gr.Markdown(
880
  """
881
+ This AI-powered assistant helps navigate complex landlord-tenant laws. Simply ask a question about your state's regulations, and it will provide detailed, legally-grounded insights.
 
 
882
  """
883
+ # Disclaimer text removed from here.
884
  )
885
 
886
  # OpenAI API Key Input Card
887
  with gr.Group(elem_classes="dashboard-card-section"):
 
888
  gr.Markdown("<h3 class='section-title'>OpenAI API Key</h3>", elem_classes="full-width-center")
889
  api_key_input = gr.Textbox(
890
  label="API Key",
 
897
 
898
  # Query Input and State Selection Card
899
  with gr.Group(elem_classes="dashboard-card-section"):
 
900
  gr.Markdown("<h3 class='section-title'>Ask Your Question</h3>", elem_classes="full-width-center")
901
 
902
  # Changed from gr.Row to gr.Column for vertical stacking
 
913
  state_input = gr.Radio(
914
  label="Select State",
915
  choices=radio_choices,
916
+ value=initial_value_radio, # Set initial value to None
917
+ elem_classes=["input-field-group", "gradio-radio-custom"], # Added custom class for specific styling
918
+ interactive=True # Ensure it's interactive
919
  )
920
 
921
  with gr.Row(elem_classes="button-row"): # Row for action buttons
 
924
 
925
  # Output Display Card - Using gr.HTML for better animation control
926
  with gr.Group(elem_classes="dashboard-card-section"):
 
927
  gr.Markdown("<h3 class='section-title'>Legal Assistant's Response</h3>", elem_classes="full-width-center")
928
  output = gr.HTML( # Changed to gr.HTML to wrap content with animation class
929
  value="<div class='placeholder'>The answer will appear here after submitting your query.</div>",
 
932
 
933
  # Example Questions Section
934
  with gr.Group(elem_classes="dashboard-card-section examples-section"):
 
935
  gr.Markdown("<h3 class='section-title'>Example Questions</h3>", elem_classes="full-width-center")
936
  if example_queries:
937
  gr.Examples(
 
943
  else:
944
  gr.Markdown("<div class='placeholder'>Sample questions could not be loaded. Please ensure the vector database is populated.</div>")
945
 
946
+ # Footer Section - contains disclaimer and developer info (now including the full disclaimer)
947
  with gr.Group(elem_classes="app-footer-wrapper"):
948
  gr.Markdown(
949
  """
950
+ **Disclaimer:** This tool is for informational purposes only and does not constitute legal advice. For specific legal guidance, always consult with a licensed attorney in your jurisdiction.
951
+ \nDeveloped by **Nischal Subedi**. Connect on [LinkedIn](https://www.linkedin.com/in/nischal1/) or explore insights at [Substack](https://datascientistinsights.substack.com/).
952
  """
953
  )
954
 
 
964
  fn=lambda: (
965
  "", # Clear API key input
966
  "", # Clear query input
967
+ initial_value_radio, # Reset state radio to default (None)
968
  "<div class='placeholder'>Inputs cleared. Ready for your next question.</div>" # Reset output message
969
  ),
970
  inputs=[],