Spaces:
Running
on
Zero
Running
on
Zero
#!/usr/bin/env python | |
import gradio as gr | |
# CSS perso pour : | |
# 1) Le fond pastel | |
# 2) La barre de navigation | |
# 3) Les nuages + positionnement | |
custom_css = """ | |
/* Fond pastel sur toute la page */ | |
html, body { | |
margin: 0; padding: 0; | |
height: 100%; | |
background: linear-gradient(135deg, #FDE2E2, #E2ECFD) !important; | |
font-family: 'Arial', sans-serif; | |
} | |
/* Barre de navigation */ | |
.nav-bar { | |
display: flex; | |
align-items: center; | |
justify-content: space-between; | |
padding: 0.5rem 2rem; | |
background-color: #fbe8d3; /* Couleur très légère pour la barre */ | |
} | |
.nav-left, .nav-right { | |
display: flex; | |
align-items: center; | |
} | |
.nav-logo { | |
font-size: 1.5rem; | |
font-weight: bold; | |
margin-right: 2rem; | |
} | |
.nav-links a { | |
margin-right: 1.5rem; | |
text-decoration: none; | |
color: #8c5b3e; | |
font-weight: 500; | |
} | |
.nav-links a:hover { | |
text-decoration: underline; | |
} | |
/* Conteneur principal au centre (pour le robot + nuages) */ | |
.main-container { | |
position: relative; | |
width: 100%; | |
max-width: 600px; | |
height: 600px; | |
margin: 1rem auto; | |
text-align: center; | |
} | |
/* Style de l'icône robot */ | |
.robot-icon { | |
width: 80px; | |
margin: 1rem auto; | |
} | |
/* Texte sous le robot */ | |
.title-consent { | |
font-size: 1.2rem; | |
font-weight: bold; | |
margin-bottom: 0.3rem; | |
} | |
.subtitle-consent { | |
font-size: 0.9rem; | |
color: #333; | |
margin-bottom: 1.2rem; | |
} | |
/* Positionnement et style des nuages */ | |
.cloud { | |
position: absolute; | |
width: 130px; | |
padding: 0.5rem; | |
background: #fff; | |
border-radius: 50px; | |
box-shadow: 0 2px 4px rgba(0,0,0,0.2); | |
cursor: pointer; | |
transition: transform 0.2s; | |
text-align: center; | |
font-size: 0.9rem; | |
} | |
.cloud:hover { | |
transform: scale(1.05); | |
} | |
/* 5 nuages : positionnés autour du centre */ | |
.cloud1 { top: 5%; left: 40%; } | |
.cloud2 { top: 30%; left: 10%; } | |
.cloud3 { top: 30%; right: 10%; } | |
.cloud4 { bottom: 10%; left: 20%; } | |
.cloud5 { bottom: 10%; right: 20%; } | |
/* Pied de page ou zone pour le chat */ | |
.footer-chat { | |
margin-top: 2rem; | |
} | |
/* Couleur du texte dans la zone markdown */ | |
.markdown-prose { | |
color: #000 !important; | |
} | |
""" | |
# HTML pour la barre de navigation | |
nav_bar_html = """ | |
<div class="nav-bar"> | |
<div class="nav-left"> | |
<div class="nav-logo">LÉLI</div> | |
</div> | |
<div class="nav-right nav-links"> | |
<a href="#">Pourquoi ?</a> | |
<a href="#">Discute avec Léli</a> | |
<a href="#">Contacts utiles</a> | |
</div> | |
</div> | |
""" | |
# HTML pour la zone centrale (robot + nuages). | |
# onclick="cloudClicked('xxxx')" => appelle une fonction JS | |
main_html = """ | |
<div class="main-container"> | |
<!-- Robot icône --> | |
<img src="https://cdn-icons-png.flaticon.com/512/6188/6188530.png" class="robot-icon" alt="Robot" /> | |
<!-- Titre et sous-titre --> | |
<div class="title-consent">LE CONSENTEMENT</div> | |
<div class="subtitle-consent">Clique sur un nuage pour en découvrir le contenu</div> | |
<!-- Nuages --> | |
<div class="cloud cloud1" onclick="cloudClicked('Ce que c’est')">Ce que c'est</div> | |
<div class="cloud cloud2" onclick="cloudClicked('Ce que ce n’est pas')">Ce que ce n’est pas</div> | |
<div class="cloud cloud3" onclick="cloudClicked('Les risques si tu ne le respectes pas')">Les risques si tu ne le respectes pas</div> | |
<div class="cloud cloud4" onclick="cloudClicked('Mise en situation')">Mise en situation</div> | |
<div class="cloud cloud5" onclick="cloudClicked('Comment faire en pratique')">Comment faire en pratique</div> | |
</div> | |
<script> | |
function cloudClicked(message) { | |
// Sélectionner la zone de texte du chat (Placeholder: "Type a message...") | |
let textBox = document.querySelector('textarea[placeholder="Type a message..."]'); | |
if (textBox) { | |
textBox.value = message; | |
// Facultatif : automatiquement "envoyer" le message ? | |
// On peut simuler un Enter, etc. Mais souvent on laisse l'utilisateur cliquer "Send". | |
} | |
} | |
</script> | |
""" | |
def dummy_chatbot(user_input, history): | |
""" | |
Exemple de fonction simple pour répondre dans le chat. | |
- user_input: question de l’utilisateur | |
- history: historique [(user_msg, bot_msg), ...] | |
""" | |
history = history or [] | |
# Pour l’exemple : on se contente de renvoyer un message "Réponse". | |
# À remplacer par votre propre logique, ou un modèle HF. | |
bot_message = f"Voici un contenu sur : {user_input}" | |
history.append((user_input, bot_message)) | |
return history | |
with gr.Blocks(css=custom_css) as demo: | |
# La barre de navigation | |
gr.HTML(nav_bar_html) | |
# La zone "robot + nuages" | |
gr.HTML(main_html) | |
# Le chatbot en bas | |
with gr.Box(elem_id="footer-chat"): | |
chatbot = gr.Chatbot() | |
msg = gr.Textbox( | |
label="Pose ta question à Léli", | |
placeholder="Type a message...", | |
show_label=False | |
) | |
submit_btn = gr.Button("Send") | |
def respond(user_input, chat_history): | |
return dummy_chatbot(user_input, chat_history) | |
submit_btn.click( | |
fn=respond, | |
inputs=[msg, chatbot], | |
outputs=chatbot | |
) | |
# Optional: envoyer au "Enter" direct | |
msg.submit( | |
fn=respond, | |
inputs=[msg, chatbot], | |
outputs=chatbot | |
) | |
if __name__ == "__main__": | |
demo.launch() | |