Code/components/sidebar.py
2025-05-13 16:31:53 +02:00

160 lines
6.0 KiB
Python

import streamlit as st
from components.connexion import connexion, bouton_deconnexion
import streamlit.components.v1 as components
from utils.translations import _
def afficher_menu():
with st.sidebar:
st.markdown(f"""
<nav role="navigation" aria-label="{str(_('sidebar.menu', 'Menu principal'))}">
<div role="region" aria-label="{str(_('sidebar.navigation', 'Navigation principale'))}" class="onglets-accessibles">
""", unsafe_allow_html=True)
# Définir la variable instructions_text une seule fois en haut de la fonction
instructions_text = str(_("navigation.instructions", "Instructions"))
if "onglet" not in st.session_state:
st.session_state.onglet = instructions_text
onglet_choisi = None
onglets = [
str(_("navigation.instructions", "Instructions")),
str(_("navigation.personnalisation", "Personnalisation")),
str(_("navigation.analyse", "Analyse")),
str(_("navigation.visualisations", "Visualisations")),
str(_("navigation.fiches", "Fiches"))
]
for nom in onglets:
if st.session_state.onglet == nom:
st.markdown(f'<div class="bouton-fictif">{nom}</div>', unsafe_allow_html=True)
else:
if st.button(str(nom)):
onglet_choisi = nom
st.markdown("""
<hr />
</div>
</nav>""", unsafe_allow_html=True)
# === GESTION DU THÈME ===
#
# Le changement de thème induit un st.rerun qui vide les formula
# Pour éviter de perdre les informations dans les formulaires,
# le changement de thème n'est proposé que si l'utilisateur est sur l'onglet "Instructions"
#
if st.session_state.onglet == instructions_text:
if "theme_mode" not in st.session_state:
st.session_state.theme_mode = str(_("sidebar.theme_light", "Clair"))
theme_title = str(_("sidebar.theme", "Thème"))
st.markdown(f"""
<section role="region" aria-label="region-theme">
<div role="region" aria-labelledby="Theme">
<p id="Theme" class="decorative-heading">{theme_title}</p>
""", unsafe_allow_html=True)
theme_options = [
str(_("sidebar.theme_light", "Clair")),
str(_("sidebar.theme_dark", "Sombre"))
]
theme = st.radio(
str(_("sidebar.theme", "Thème")),
theme_options,
index=theme_options.index(st.session_state.theme_mode),
horizontal=True,
label_visibility="hidden"
)
st.markdown("""
<hr />
</div>
</nav>""", unsafe_allow_html=True)
else :
theme_title = str(_("sidebar.theme", "Thème"))
st.markdown(f"""
<section role="region" aria-label="region-theme">
<div role="region" aria-labelledby="Theme">
<p id="Theme" class="decorative-heading">{theme_title}</p>
""", unsafe_allow_html=True)
st.info(str(_("sidebar.theme_instructions_only", "Le changement de thème ne peut se faire que depuis l'onglet Instructions.")))
st.markdown("""
<hr />
</div>
</nav>""", unsafe_allow_html=True)
theme = st.session_state.theme_mode
connexion()
if st.session_state.get("logged_in", False):
bouton_deconnexion()
# === RERUN SI BESOIN ===
if (onglet_choisi and onglet_choisi != st.session_state.onglet) or (theme != st.session_state.theme_mode):
if onglet_choisi: # Ne met à jour que si on a cliqué
st.session_state.onglet = onglet_choisi
st.session_state.theme_mode = theme
st.rerun()
def afficher_impact(total_bytes):
impact_label = str(_("sidebar.impact", "Impact environnemental"))
loading_text = str(_("sidebar.loading", "Chargement en cours…"))
with st.sidebar:
components.html(f"""
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Impact Environnemental</title>
<style>
body,
html {{
font-family:
-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial,
sans-serif;
}}
/* Div réseau pour impact CO₂ */
#network-usage {{
display: block;
font-size: small;
margin-top: 1rem;
text-align: center;
}}
.decorative-heading {{
font-size: 1.25rem;
font-weight: bold;
margin-bottom: 0.5rem;
color: #145a1a;
text-align: center;
}}
span {{
text-align: center;
}}
</style>
</head>
<body>
<hr />
<div role="region" aria-label="{impact_label}" class="impact-environnement">
<p class="decorative-heading">{impact_label}</p>
<p><span id="network-usage">{loading_text}</span></p>
</div>
<script>
document.addEventListener("DOMContentLoaded", async function() {{
try {{
const module = await import("/assets/impact_co2.js");
module.calculerImpactCO2({total_bytes});
}} catch (error) {{
console.error("Erreur module impact_co2.js", error);
}}
}});
</script>
</body>
</html>
""")