Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/whitiue/logiMathApp/llms.txt

Use this file to discover all available pages before exploring further.

The LogiMath frontend is a Python desktop application built with Flet, a framework that renders Flutter widgets from Python code. The entry point is src/FrontEnd/mainApp.py, which defines the LogiMathApp class. It opens a 400×750 px window, manages the current user in memory, and exposes a navigation dictionary that each view uses to trigger transitions without coupling views to one another.

The LogiMathApp class

LogiMathApp owns the authenticated user state (current_user, current_user_id) and builds a navigate dictionary that maps route names to callables. Each callable clears the page and renders the appropriate view.
mainApp.py
class LogiMathApp:

    def __init__(self):
        self.current_user: Optional[dict] = None
        self.current_user_id: Optional[int] = None

    def run(self):
        ft.app(target=self.main)

    def set_user(self, user, user_id):
        self.current_user = user
        self.current_user_id = user_id

    def main(self, page: ft.Page):

        page.title = "LogiMath"

        page.window_width = 400
        page.window_height = 750

        def go_to_login():
            page.clean()
            page.add(login_view(page, self.navigate, self.set_user))
            page.update()

        def go_to_register():
            page.clean()
            page.add(register_view(page, self.navigate))
            page.update()

        def go_to_home():
            page.clean()
            page.add(home_view(page, self.navigate, self.current_user))
            page.update()

        self.navigate = {
            "login": go_to_login,
            "register": go_to_register,
            "home": go_to_home,
        }

        go_to_login()
The navigation dictionary pattern keeps each view decoupled: a view receives the dictionary and calls navigate["home"]() to transition without importing sibling views directly.

Views

The application has three views, each defined as a plain function that returns an ft.Column.

login_view

Collects a username and password. On submit, calls set_user to store the user in the app state, then navigates to home. Login is currently simulated — no backend call is made.

register_view

Collects name, email, and password. Calls create_user from api_services.py and displays the result status. On success, the user can return to login.

home_view

Calls get_quizzes on mount and renders each quiz as an ElevatedButton in a scrollable ListView. Displays a count of found quizzes and provides a logout button.

login_view

login_view.py
def login_view(page, navigate, set_user):

    username_input = ft.TextField(label="Usuario", width=300)
    password_input = ft.TextField(label="Contraseña", password=True, width=300)
    status_text = ft.Text("", size=12, color="red")

    def handle_login(e):
        username = username_input.value.strip()
        password = password_input.value.strip()

        if not username or not password:
            status_text.value = "Completa todos los campos"
            page.update()
            return

        status_text.value = "Iniciando sesión..."
        page.update()

        # Login simulado
        set_user({"name": username}, 1)
        navigate["home"]()

    return ft.Column(
        controls=[
            ft.Text("LogiMath", size=32, weight="bold"),
            ft.Divider(height=20),
            username_input,
            password_input,
            status_text,
            ft.ElevatedButton("Iniciar Sesión", width=300, on_click=handle_login),
            ft.TextButton(
                "¿No tienes cuenta? Regístrate",
                on_click=lambda e: navigate["register"](),
            ),
        ],
        horizontal_alignment="center",
        alignment="center",
        spacing=15,
    )

register_view

register_view.py
def register_view(page, navigate):

    name_input = ft.TextField(label="Nombre", width=300)
    email_input = ft.TextField(label="Email", width=300)
    password_input = ft.TextField(label="Contraseña", password=True, width=300)
    status_text = ft.Text("", size=12, color="red")

    def handle_register(e):
        name = name_input.value.strip()
        email = email_input.value.strip()
        password = password_input.value.strip()

        if not name or not email or not password:
            status_text.value = "Completa todos los campos"
            page.update()
            return

        try:
            response = create_user(name, email)
            if response.status_code == 200:
                status_text.value = "Registro exitoso"
            else:
                status_text.value = "Error en el registro"
        except Exception as ex:
            status_text.value = str(ex)

        page.update()
    ...

home_view

home_view.py
def home_view(page, navigate, current_user):

    quizzes_list = ft.ListView(spacing=10, auto_scroll=True, height=400)
    status_text = ft.Text("Cargando quizzes...")

    def load_quizzes():
        try:
            response = get_quizzes()
            if response.status_code == 200:
                quizzes = response.json()
                quizzes_list.controls.clear()
                for quiz in quizzes:
                    quizzes_list.controls.append(
                        ft.ElevatedButton(
                            f"{quiz['title']} ({quiz['subject']})",
                            width=300,
                        )
                    )
                status_text.value = f"{len(quizzes)} quizzes encontrados"
            else:
                status_text.value = "Error al cargar quizzes"
        except Exception as ex:
            status_text.value = str(ex)
        page.update()

    load_quizzes()
    ...

API service layer

src/FrontEnd/services/api_services.py centralises all HTTP calls. It uses the requests library and targets http://localhost:8000 by default.
api_services.py
import requests

API_BASE_URL = "http://localhost:8000"


def get_quizzes():
    return requests.get(f"{API_BASE_URL}/quizzes")


def create_user(name, email):
    return requests.post(
        f"{API_BASE_URL}/users",
        params={
            "name": name,
            "email": email,
        },
    )
API_BASE_URL is hardcoded to http://localhost:8000. When running the frontend against a containerised backend, update this value or expose it through an environment variable.

Android compilation

The repository includes a buildozer.spec file that configures the Buildozer toolchain to compile the Flet application into an Android APK. Run buildozer android debug from src/FrontEnd/ to produce the APK.

Build docs developers (and LLMs) love