import dash_bootstrap_components as dbc from dash import dcc, html from pathlib import Path from dotenv import load_dotenv load_dotenv() BUCKET_NAME = "moore-collection" # --- Helper pour récupérer les chapitres --- def get_chapter_paths(base_folder): base = Path(base_folder) return [d for d in base.iterdir() if d.is_dir()] chapters = get_chapter_paths("assets") chapter_options = [{"label": d.name, "value": str(d)} for d in chapters] # --- Fonctions de création des différentes cards --- def header_card(): """Carte d'en-tête avec le titre de l'application.""" return dbc.Row( dbc.Col( html.H1( "Outil de transcription audio", className="text-center my-4 text-primary", ), width=12, ) ) def user_info_card(): """Carte pour la saisie des informations utilisateur.""" return dbc.Row( dbc.Col( [ dbc.Input( id="user-info", placeholder="Entrez votre email, pseudonyme ou nom pour qu'on vous crédite", type="text", className="mb-3", ), dbc.Button( "Continuer", id="pseudo-continue-button", color="primary", className="w-100", ), ], width=12, ) ) def chapter_card(): """Carte pour la sélection d'un chapitre.""" return dbc.Row( id="chapter-section", style={"display": "none"}, children=[ dbc.Col( dbc.Card( [ dbc.CardHeader("Sélectionnez un chapitre"), dbc.CardBody( [ dcc.Dropdown( id="chapter-dropdown", options=chapter_options, placeholder="Choisissez un chapitre", ), dbc.Button( "Continuer", id="chapter-continue-button", color="primary", className="w-100 mt-2", ), ] ), ] ), width=12, ) ], ) def page_card(): """Carte pour la sélection d'une page.""" return dbc.Row( id="page-section", style={"display": "none"}, children=[ dbc.Col( dbc.Card( [ dbc.CardHeader("Sélectionnez une page"), dbc.CardBody( [ dcc.Dropdown( id="page-dropdown", placeholder="Choisissez une page", ), dbc.Button( "Démarrer la transcription", id="start-button", color="primary", className="w-100 mt-2", ), ] ), ] ), width=12, ) ], ) def transcription_card(): """Carte regroupant la lecture audio, les suggestions et les actions de transcription.""" audio_card = dbc.Card( [ dbc.CardHeader("Lecture audio"), dbc.CardBody( dcc.Loading( html.Audio( id="audio-player", controls=True, autoPlay=False, className="w-100", ) ) ), ], className="mb-4 shadow", ) suggestion_card = dbc.Card( [ dbc.CardHeader("Suggestions de transcriptions"), dbc.CardBody( dcc.Checklist( id="suggestion-checklist", options=[], # Initialement vide, sera mis à jour via callback value=[], style={"columns": "3", "column-gap": "1rem"}, ) ), ], className="mb-4 shadow", ) hidden_message = html.Div( id="hidden-message", style={"display": "none"}, children=[ html.P( "Traitement de la page actuelle terminé, vous devez changer de page pour continuer. N'oubliez pas de sauvegarder.", style={"color": "red"}, ) ], ) action_buttons = dbc.Col( [ dbc.Button( "Soumettre", id="submit-button", n_clicks=0, color="secondary", className="w-100", style={"marginTop": "20px"}, ), dbc.Button( "Sauvegarder résultats", id="save-results-button", n_clicks=0, color="success", className="w-100", style={"marginTop": "20px"}, ), ], width=12, ) confirmation_message = dbc.Col( html.Div( id="confirmation-message", className="text-success text-center mt-3", ), width=12, ) # La carte de transcription regroupe plusieurs composants et dcc.Store pour l'état return dbc.Row( id="transcription-section", style={"display": "none"}, children=[ dbc.Col(audio_card, width=12), dbc.Col(suggestion_card, width=12), dbc.Col(hidden_message, width=12), action_buttons, confirmation_message, # Stores pour l'état de l'application dcc.Store(id="transcription-store", data=[], storage_type='session'), dcc.Store(id="audio-store", data=[], storage_type='session'), dcc.Store(id="values-store", data=[], storage_type='session'), ], ) def create_layout(): """Compose le layout principal à partir des différentes cards.""" return dbc.Container( [ header_card(), user_info_card(), chapter_card(), page_card(), transcription_card(), ], fluid=True, className="p-4", ) # Initialisation du layout layout = create_layout() from .callbacks import *