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> | |
| """) | |