Spaces:
Running
import zipfile
Browse filesimport os
# Créer un dossier pour le backend corrigé
output_dir = "/mnt/data/espace_codage_corrected_backend"
os.makedirs(output_dir, exist_ok=True)
# Exemple de fichier index.html modifié (chat input visible et mise en page corrigée)
index_html_content = """
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Espace Codage – Rosalinda</title>
<style>
body {
display: flex;
height: 100vh;
margin: 0;
font-family: Arial, sans-serif;
}
.colonne1, .colonne2, .colonne3 {
height: 100%;
overflow-y: auto;
padding: 10px;
}
.colonne1 {
width: 20%;
background-color: #f0f0f0;
}
.colonne2 {
width: 40%;
background-color: #fff;
border-left: 1px solid #ccc;
border-right: 1px solid #ccc;
}
.colonne3 {
width: 40%;
background-color: #000;
color: #0f0;
}
.chat-input {
display: flex;
margin-top: 10px;
}
.chat-input input[type="text"] {
flex: 1;
padding: 10px;
color: #000;
background-color: #fff;
border: 1px solid #ccc;
}
.chat-input button {
padding: 10px;
}
</style>
</head>
<body>
<div class="colonne1">
<h2>Espace Codage</h2>
<button>Nouvelle tâche</button><br>
<button>Rechercher</button><br>
<button>Bibliothèque</button>
</div>
<div class="colonne2">
<h2>Rosalinda</h2>
<div id="chat-area">
<p>Bonjour ! Je suis Rosalinda, votre assistante IA.</p>
</div>
<div class="chat-input">
<input type="text" id="userInput" placeholder="Écrire à Rosalinda..." />
<button onclick="sendMessage()">Envoyer</button>
</div>
</div>
<div class="colonne3">
<h3>// Résultat pour: bonjour</h3>
<pre id="output">console.log("bonjour");</pre>
</div>
<script>
async function sendMessage() {
const input = document.getElementById("userInput").value;
document.getElementById("chat-area").innerHTML += "<p><strong>Vous :</strong> " + input + "</p>";
const response = await fetch("https://api.openai.com/v1/completions", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_API_KEY_HERE"
},
body: JSON.stringify({
model: "text-davinci-003",
prompt: input,
max_tokens: 100
})
});
const data = await response.json();
const output = data.choices?.[0]?.text || "Erreur de réponse.";
document.getElementById("chat-area").innerHTML += "<p><strong>Rosalinda :</strong> " + output + "</p>";
document.getElementById("output").innerText = output;
}
</script>
</body>
</html>
"""
# Écrire le fichier dans le dossier
html_file_path = os.path.join(output_dir, "index.html")
with open(html_file_path, "w", encoding="utf-8") as f:
f.write(index_html_content)
# Créer un fichier ZIP à partir du dossier
zip_path = "/mnt/data/espace_codage_rosalinda_final.zip"
with zipfile.ZipFile(zip_path, 'w') as zipf:
zipf.write(html_file_path, arcname="index.html")
zip_path
- components/sidebar.js +86 -0
- index.html +1 -1
- script.js +73 -0
- style.css +4 -3
- styles.css +1 -3
|
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
class CustomSidebar extends HTMLElement {
|
| 2 |
+
connectedCallback() {
|
| 3 |
+
this.attachShadow({ mode: 'open' });
|
| 4 |
+
this.shadowRoot.innerHTML = `
|
| 5 |
+
<style>
|
| 6 |
+
:host {
|
| 7 |
+
display: block;
|
| 8 |
+
width: 100%;
|
| 9 |
+
padding: 16px;
|
| 10 |
+
}
|
| 11 |
+
.logo {
|
| 12 |
+
display: flex;
|
| 13 |
+
align-items: center;
|
| 14 |
+
gap: 8px;
|
| 15 |
+
font-weight: 700;
|
| 16 |
+
font-size: 18px;
|
| 17 |
+
color: var(--text-color, rgb(15 23 42));
|
| 18 |
+
text-decoration: none;
|
| 19 |
+
}
|
| 20 |
+
.menu {
|
| 21 |
+
display: flex;
|
| 22 |
+
flex-direction: column;
|
| 23 |
+
gap: 8px;
|
| 24 |
+
margin: 16px 0;
|
| 25 |
+
}
|
| 26 |
+
.btn {
|
| 27 |
+
width: 100%;
|
| 28 |
+
display: inline-flex;
|
| 29 |
+
align-items: center;
|
| 30 |
+
justify-content: flex-start;
|
| 31 |
+
gap: 8px;
|
| 32 |
+
padding: 10px 12px;
|
| 33 |
+
background: var(--btn-bg, rgb(241 245 249));
|
| 34 |
+
color: var(--btn-text, rgb(15 23 42));
|
| 35 |
+
border: 1px solid var(--btn-border, rgb(226 232 240));
|
| 36 |
+
border-radius: 8px;
|
| 37 |
+
cursor: pointer;
|
| 38 |
+
transition: all 0.2s ease;
|
| 39 |
+
}
|
| 40 |
+
.btn:hover {
|
| 41 |
+
background: var(--btn-hover, rgb(226 232 240));
|
| 42 |
+
}
|
| 43 |
+
.projects h3 {
|
| 44 |
+
font-size: 14px;
|
| 45 |
+
color: var(--subtext-color, rgb(100 116 139));
|
| 46 |
+
margin-bottom: 8px;
|
| 47 |
+
text-transform: uppercase;
|
| 48 |
+
letter-spacing: 0.06em;
|
| 49 |
+
}
|
| 50 |
+
.project-list {
|
| 51 |
+
list-style: none;
|
| 52 |
+
padding: 0;
|
| 53 |
+
margin: 0;
|
| 54 |
+
display: flex;
|
| 55 |
+
flex-direction: column;
|
| 56 |
+
gap: 6px;
|
| 57 |
+
}
|
| 58 |
+
</style>
|
| 59 |
+
<div class="sidebar-content">
|
| 60 |
+
<div class="logo">
|
| 61 |
+
<i class="fa-solid fa-code"></i>
|
| 62 |
+
<span>Espace Codage</span>
|
| 63 |
+
</div>
|
| 64 |
+
<nav class="menu">
|
| 65 |
+
<button id="newTaskBtn" class="btn">
|
| 66 |
+
<i class="fa-solid fa-plus"></i>
|
| 67 |
+
Nouvelle tâche
|
| 68 |
+
</button>
|
| 69 |
+
<button id="searchBtn" class="btn">
|
| 70 |
+
<i class="fa-solid fa-magnifying-glass"></i>
|
| 71 |
+
Rechercher
|
| 72 |
+
</button>
|
| 73 |
+
<button id="libraryBtn" class="btn">
|
| 74 |
+
<i class="fa-solid fa-book"></i>
|
| 75 |
+
Bibliothèque
|
| 76 |
+
</button>
|
| 77 |
+
</nav>
|
| 78 |
+
<div class="projects">
|
| 79 |
+
<h3>Projets</h3>
|
| 80 |
+
<ul id="projectList" class="project-list"></ul>
|
| 81 |
+
</div>
|
| 82 |
+
</div>
|
| 83 |
+
`;
|
| 84 |
+
}
|
| 85 |
+
}
|
| 86 |
+
customElements.define('custom-sidebar', CustomSidebar);
|
|
@@ -32,9 +32,9 @@
|
|
| 32 |
</head>
|
| 33 |
<body class="h-full bg-slate-50 text-slate-900 dark:bg-slate-950 dark:text-slate-100 transition-colors">
|
| 34 |
<div class="container">
|
| 35 |
-
|
| 36 |
<!-- Colonne 1 : Menu -->
|
| 37 |
<aside class="sidebar">
|
|
|
|
| 38 |
<div class="flex items-center justify-between mb-6">
|
| 39 |
<a href="#" class="logo">
|
| 40 |
<i class="fa-solid fa-code"></i>
|
|
|
|
| 32 |
</head>
|
| 33 |
<body class="h-full bg-slate-50 text-slate-900 dark:bg-slate-950 dark:text-slate-100 transition-colors">
|
| 34 |
<div class="container">
|
|
|
|
| 35 |
<!-- Colonne 1 : Menu -->
|
| 36 |
<aside class="sidebar">
|
| 37 |
+
<custom-sidebar></custom-sidebar>
|
| 38 |
<div class="flex items-center justify-between mb-6">
|
| 39 |
<a href="#" class="logo">
|
| 40 |
<i class="fa-solid fa-code"></i>
|
|
@@ -1,5 +1,78 @@
|
|
|
|
|
| 1 |
console.log("Interface Espace Codage chargée.");
|
| 2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3 |
// ===== Thème (light/dark) =====
|
| 4 |
const themeToggle = document.getElementById('themeToggle');
|
| 5 |
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)');
|
|
|
|
| 1 |
+
|
| 2 |
console.log("Interface Espace Codage chargée.");
|
| 3 |
|
| 4 |
+
// Create sidebar component
|
| 5 |
+
class CustomSidebar extends HTMLElement {
|
| 6 |
+
connectedCallback() {
|
| 7 |
+
this.attachShadow({ mode: 'open' });
|
| 8 |
+
this.shadowRoot.innerHTML = `
|
| 9 |
+
<style>
|
| 10 |
+
:host {
|
| 11 |
+
display: block;
|
| 12 |
+
width: 100%;
|
| 13 |
+
}
|
| 14 |
+
.logo {
|
| 15 |
+
display: flex;
|
| 16 |
+
align-items: center;
|
| 17 |
+
gap: 8px;
|
| 18 |
+
font-weight: 700;
|
| 19 |
+
font-size: 18px;
|
| 20 |
+
color: rgb(15 23 42);
|
| 21 |
+
text-decoration: none;
|
| 22 |
+
}
|
| 23 |
+
.menu {
|
| 24 |
+
display: flex;
|
| 25 |
+
flex-direction: column;
|
| 26 |
+
gap: 8px;
|
| 27 |
+
margin-top: 16px;
|
| 28 |
+
}
|
| 29 |
+
.btn {
|
| 30 |
+
width: 100%;
|
| 31 |
+
display: inline-flex;
|
| 32 |
+
align-items: center;
|
| 33 |
+
justify-content: flex-start;
|
| 34 |
+
gap: 8px;
|
| 35 |
+
padding: 10px 12px;
|
| 36 |
+
background: rgb(241 245 249);
|
| 37 |
+
color: rgb(15 23 42);
|
| 38 |
+
border: 1px solid rgb(226 232 240);
|
| 39 |
+
border-radius: 8px;
|
| 40 |
+
cursor: pointer;
|
| 41 |
+
}
|
| 42 |
+
.btn:hover {
|
| 43 |
+
background: rgb(226 232 240);
|
| 44 |
+
}
|
| 45 |
+
</style>
|
| 46 |
+
<div class="sidebar-content">
|
| 47 |
+
<div class="flex items-center justify-between mb-6">
|
| 48 |
+
<a href="#" class="logo">
|
| 49 |
+
<i class="fa-solid fa-code"></i>
|
| 50 |
+
<span>Espace Codage</span>
|
| 51 |
+
</a>
|
| 52 |
+
</div>
|
| 53 |
+
<nav class="menu">
|
| 54 |
+
<button id="newTaskBtn" class="btn">
|
| 55 |
+
<i class="fa-solid fa-plus"></i>
|
| 56 |
+
Nouvelle tâche
|
| 57 |
+
</button>
|
| 58 |
+
<button id="searchBtn" class="btn">
|
| 59 |
+
<i class="fa-solid fa-magnifying-glass"></i>
|
| 60 |
+
Rechercher
|
| 61 |
+
</button>
|
| 62 |
+
<button id="libraryBtn" class="btn">
|
| 63 |
+
<i class="fa-solid fa-book"></i>
|
| 64 |
+
Bibliothèque
|
| 65 |
+
</button>
|
| 66 |
+
</nav>
|
| 67 |
+
<div class="projects">
|
| 68 |
+
<h3>Projets</h3>
|
| 69 |
+
<ul id="projectList" class="project-list"></ul>
|
| 70 |
+
</div>
|
| 71 |
+
</div>
|
| 72 |
+
`;
|
| 73 |
+
}
|
| 74 |
+
}
|
| 75 |
+
customElements.define('custom-sidebar', CustomSidebar);
|
| 76 |
// ===== Thème (light/dark) =====
|
| 77 |
const themeToggle = document.getElementById('themeToggle');
|
| 78 |
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)');
|
|
@@ -1,8 +1,9 @@
|
|
|
|
|
| 1 |
body {
|
| 2 |
-
|
| 3 |
-
|
|
|
|
| 4 |
}
|
| 5 |
-
|
| 6 |
h1 {
|
| 7 |
font-size: 16px;
|
| 8 |
margin-top: 0;
|
|
|
|
| 1 |
+
|
| 2 |
body {
|
| 3 |
+
padding: 0;
|
| 4 |
+
margin: 0;
|
| 5 |
+
font-family: -apple-system, BlinkMacSystemFont, "Inter", sans-serif;
|
| 6 |
}
|
|
|
|
| 7 |
h1 {
|
| 8 |
font-size: 16px;
|
| 9 |
margin-top: 0;
|
|
@@ -24,11 +24,9 @@ body { margin: 0; font-family: Inter, ui-sans-serif, system-ui, -apple-system, S
|
|
| 24 |
.sidebar {
|
| 25 |
width: 100%;
|
| 26 |
background: rgb(248 250 252); /* slate-50 */
|
| 27 |
-
border-right: 1px solid rgb(226 232 240); /* slate-200 */
|
| 28 |
-
padding: 16px;
|
| 29 |
display: flex;
|
| 30 |
flex-direction: column;
|
| 31 |
-
gap: 16px;
|
| 32 |
}
|
| 33 |
.dark .sidebar {
|
| 34 |
background: rgb(15 23 42); /* slate-900 */
|
|
|
|
| 24 |
.sidebar {
|
| 25 |
width: 100%;
|
| 26 |
background: rgb(248 250 252); /* slate-50 */
|
| 27 |
+
border-right: 1px solid rgb(226 232 240); /* slate-200 */
|
|
|
|
| 28 |
display: flex;
|
| 29 |
flex-direction: column;
|
|
|
|
| 30 |
}
|
| 31 |
.dark .sidebar {
|
| 32 |
background: rgb(15 23 42); /* slate-900 */
|