Spaces:
Sleeping
Sleeping
import gradio as gr | |
from typing import List, Optional | |
from services.llm_factory import get_default_model | |
def create_provider_dropdown(providers: List[str], default_value: str = "mistral") -> gr.Dropdown: | |
"""Creates a standardized LLM provider dropdown.""" | |
return gr.Dropdown(providers, value=default_value, label="AI Provider") | |
def create_llm_config_inputs(providers: List[str], default_provider: str = "mistral", initial_api_key: str = "") -> dict: | |
"""Creates a 3-column AI provider configuration with Provider, Model Name, and API Key.""" | |
with gr.Row(): | |
provider_dropdown = gr.Dropdown( | |
choices=providers, | |
value=default_provider, | |
label="AI Provider", | |
interactive=True | |
) | |
model_textbox = gr.Textbox( | |
label="Model Name", | |
placeholder=f"Default: {get_default_model(default_provider)}", | |
value="", | |
interactive=True, | |
) | |
api_key_textbox = gr.Textbox( | |
label="API Key", | |
placeholder="Default: from .env file (if ran locally)", | |
value=initial_api_key, | |
type="password", | |
interactive=True, | |
) | |
# Update model placeholder when provider changes | |
def update_model_placeholder(provider): | |
default_model = get_default_model(provider) | |
return gr.update(placeholder=f"Default: {default_model}") | |
provider_dropdown.change( | |
fn=update_model_placeholder, | |
inputs=[provider_dropdown], | |
outputs=[model_textbox] | |
) | |
return { | |
"provider": provider_dropdown, | |
"model": model_textbox, | |
"api_key": api_key_textbox, | |
"provider_dropdown_component": provider_dropdown, | |
"api_key_textbox_component": api_key_textbox | |
} | |
def create_unit_dropdown(default_label: str = "Select Generated Unit") -> gr.Dropdown: | |
"""Creates a standardized unit selection dropdown.""" | |
return gr.Dropdown( | |
choices=["Select Generated Unit"], | |
value="Select Generated Unit", | |
label=default_label, | |
interactive=True | |
) | |
def create_file_upload() -> gr.File: | |
"""Creates a standardized file upload component.""" | |
return gr.File( | |
label="", | |
file_types=[".pdf", ".doc", ".txt", ".pptx", ".md"], | |
height=200 | |
) | |
def create_text_input(label: str = "Text Input", lines: int = 4) -> gr.Textbox: | |
"""Creates a standardized text input component.""" | |
return gr.Textbox( | |
placeholder="Paste your learning content here...", | |
lines=lines, | |
label="" | |
) | |
def create_status_markdown(initial_text: str = "Ready") -> gr.Markdown: | |
"""Creates a standardized status display.""" | |
return gr.Markdown(initial_text) | |
def create_primary_button(text: str, size: str = "lg") -> gr.Button: | |
"""Creates a standardized primary button.""" | |
return gr.Button(text, variant="primary", size=size, elem_classes="learnflow-button-large learnflow-button-rounded") | |
def create_secondary_button(text: str, size: str = "lg", elem_classes: Optional[str] = None) -> gr.Button: | |
"""Creates a standardized secondary button.""" | |
classes = "learnflow-button-large learnflow-button-rounded" | |
if elem_classes: | |
classes += f" {elem_classes}" | |
return gr.Button(text, variant="secondary", size=size, elem_classes=classes) | |
def create_quiz_components(): | |
"""Creates standardized quiz UI components.""" | |
mcq_section = gr.Column(visible=False, elem_classes="quiz-section") | |
with mcq_section: | |
mcq_question = gr.Markdown("### Multiple Choice Questions") | |
mcq_choices = gr.Radio(choices=[], label="Select your answer") | |
mcq_submit = gr.Button("Submit MCQ Answer", elem_classes="learnflow-button-large learnflow-button-rounded") | |
mcq_feedback = gr.Markdown("", elem_classes="correct-feedback") | |
mcq_next = gr.Button("Next Question", visible=False, elem_classes="learnflow-button-large learnflow-button-rounded") | |
open_ended_section = gr.Column(visible=False, elem_classes="quiz-section") | |
with open_ended_section: | |
open_question = gr.Markdown("### Open-Ended Questions") | |
open_answer = gr.Textbox(label="Your answer", lines=4, placeholder="Type your answer here...") | |
open_submit = gr.Button("Submit Open Answer", elem_classes="learnflow-button-large learnflow-button-rounded") | |
open_feedback = gr.Markdown("", elem_classes="correct-feedback") | |
open_next = gr.Button("Next Open-Ended Question", visible=False, elem_classes="learnflow-button-large learnflow-button-rounded") | |
tf_section = gr.Column(visible=False, elem_classes="quiz-section") | |
with tf_section: | |
tf_question = gr.Markdown("### True/False Questions") | |
tf_choices = gr.Radio(choices=["True", "False"], label="Your Answer") | |
tf_submit = gr.Button("Submit True/False Answer", elem_classes="learnflow-button-large learnflow-button-rounded") | |
tf_feedback = gr.Markdown("", elem_classes="correct-feedback") | |
tf_next = gr.Button("Next True/False Question", visible=False, elem_classes="learnflow-button-large learnflow-button-rounded") | |
fitb_section = gr.Column(visible=False, elem_classes="quiz-section") | |
with fitb_section: | |
fitb_question = gr.Markdown("### Fill in the Blank Questions") | |
fitb_answer = gr.Textbox(label="Your Answer", placeholder="Type your answer here...") | |
fitb_submit = gr.Button("Submit Fill in the Blank Answer", elem_classes="learnflow-button-large learnflow-button-rounded") | |
fitb_feedback = gr.Markdown("", elem_classes="correct-feedback") | |
fitb_next = gr.Button("Next Fill in the Blank Question", visible=False, elem_classes="learnflow-button-large learnflow-button-rounded") | |
return { | |
"mcq_section": mcq_section, | |
"mcq_question": mcq_question, | |
"mcq_choices": mcq_choices, | |
"mcq_submit": mcq_submit, | |
"mcq_feedback": mcq_feedback, | |
"mcq_next": mcq_next, | |
"open_ended_section": open_ended_section, | |
"open_question": open_question, | |
"open_answer": open_answer, | |
"open_submit": open_submit, | |
"open_feedback": open_feedback, | |
"open_next": open_next, | |
"tf_section": tf_section, | |
"tf_question": tf_question, | |
"tf_choices": tf_choices, | |
"tf_submit": tf_submit, | |
"tf_feedback": tf_feedback, | |
"tf_next": tf_next, | |
"fitb_section": fitb_section, | |
"fitb_question": fitb_question, | |
"fitb_answer": fitb_answer, | |
"fitb_submit": fitb_submit, | |
"fitb_feedback": fitb_feedback, | |
"fitb_next": fitb_next | |
} | |
def create_progress_components(): | |
"""Creates standardized progress display components.""" | |
return { | |
"overall_stats": gr.Markdown("No session data available."), | |
"progress_bar": gr.HTML(""), | |
"unit_details": gr.Dataframe( | |
headers=["Unit", "Status", "Quiz Score", "Completion"], | |
datatype=["str", "str", "str", "str"], | |
interactive=False | |
) | |
} | |
def create_session_management_components(): | |
"""Creates standardized session management components.""" | |
return { | |
"session_name_input": gr.Textbox(placeholder="Enter session name to save or load...", label="Session Name"), | |
"save_session_btn": gr.Button("πΎ Save Current Session", elem_classes="learnflow-button-large learnflow-button-rounded"), | |
"load_session_btn": gr.Button("π Load Session", elem_classes="learnflow-button-large learnflow-button-rounded"), | |
"saved_sessions_dropdown": gr.Dropdown(choices=["Choose from saved sessions..."], value="Choose from saved sessions...", label="Previous Sessions", interactive=True), | |
"session_status": gr.Markdown("") | |
} | |
def create_export_components(): | |
"""Creates standardized export components.""" | |
return { | |
"export_markdown_btn": gr.Button("π Export Markdown", elem_classes="learnflow-button-large learnflow-button-rounded"), | |
"export_html_btn": gr.Button("π Export HTML", elem_classes="learnflow-button-large learnflow-button-rounded"), | |
"export_pdf_btn": gr.Button("π Export PDF", elem_classes="learnflow-button-large learnflow-button-rounded"), | |
"export_file": gr.File(label="Download Exported File", visible=False), | |
"export_status": gr.Markdown("") | |
} | |
def create_difficulty_radio() -> gr.Radio: | |
"""Creates a radio group for difficulty level.""" | |
return gr.Radio( | |
choices=["Easy", "Medium", "Hard"], | |
value="Medium", | |
label="Difficulty Level", | |
interactive=True, | |
container=False, | |
elem_classes="difficulty-radio-group" | |
) | |
def create_question_number_slider(min_val: int = 3, max_val: int = 30, default_val: int = 8) -> gr.Slider: | |
"""Creates a slider for number of questions.""" | |
return gr.Slider( | |
minimum=min_val, | |
maximum=max_val, | |
value=default_val, | |
step=1, | |
label="Questions Count", | |
interactive=True | |
) | |
def create_question_types_checkboxgroup() -> gr.CheckboxGroup: | |
"""Creates a checkbox group for question types.""" | |
return gr.CheckboxGroup( | |
choices=["Multiple Choice", "Open-Ended", "True/False", "Fill in the Blank"], | |
value=["Multiple Choice", "Open-Ended", "True/False"], | |
label="Question Types", | |
interactive=True, | |
elem_classes="question-types-checkbox-group" | |
) | |
def create_ai_provider_dropdown(providers: List[str], default_value: str = "mistral") -> gr.Dropdown: | |
"""Creates a dropdown for AI provider.""" | |
return gr.Dropdown( | |
choices=providers, | |
value=default_value, | |
label="AI Provider", | |
interactive=True | |
) | |
def create_stats_card(title: str, value: str, description: str, icon: str, color: str) -> gr.Markdown: | |
"""Creates a standardized statistics card.""" | |
return gr.Markdown(f""" | |
<div style="background: rgba(51, 65, 85, 0.6); padding: 20px; border-radius: 12px; text-align: center;"> | |
<h3 style="color: {color}; margin-top: 0; font-size: 1.5em;">{icon} {title}</h3> | |
<p style="color: white; font-size: 2.5em; font-weight: 700; margin: 5px 0;">{value}</p> | |
<p style="color: #94a3b8; margin-bottom: 0;">{description}</p> | |
</div> | |
""") | |
def create_overall_progress_html(progress_percentage: int = 53) -> gr.HTML: | |
"""Creates the HTML for the overall learning progress bar.""" | |
return gr.HTML(f""" | |
<div style="background: rgba(51, 65, 85, 0.6); padding: 20px; border-radius: 12px; margin: 10px 0;"> | |
<h3 style="color: #10b981; margin-top: 0;">Total Course Progress: {progress_percentage}%</h3> | |
<div style="background: rgba(30, 41, 59, 0.8); border-radius: 8px; height: 20px; overflow: hidden;"> | |
<div style="background: linear-gradient(135deg, #10b981, #059669); height: 100%; width: {progress_percentage}%; transition: width 0.5s ease;"></div> | |
</div> | |
<p style="color: #94a3b8; margin-bottom: 0;">Keep going! You're making great progress.</p> | |
</div> | |
""") | |