Spaces:
Running
from pathlib import Path
Browse files# Créer le dossier pour les fichiers du thème complet
theme_path = Path("/mnt/data/espace_codage_theme")
theme_path.mkdir(parents=True, exist_ok=True)
# 1. index.html
html_code = """<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Espace Codage</title>
<link rel="stylesheet" href="styles.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css"/>
</head>
<body>
<div class="container">
<!-- Colonne 1 : Navigation -->
<aside class="sidebar">
<div class="header">
<a href="#" class="logo">Espace Codage</a>
</div>
<nav class="menu">
<button>Nouvelle tâche</button>
<button>Rechercher</button>
<button>Bibliothèque</button>
</nav>
<div class="projects">
<h3>Projets</h3>
<ul id="projectList">
<!-- Projets ajoutés ici -->
</ul>
</div>
</aside>
<!-- Colonne 2 : Chat IA Rosalinda -->
<main class="chat">
<div class="chat-header">
<h2>Espace Codage – Rosalinda</h2>
<div class="activity-monitor">[ Activité IA en cours... ]</div>
</div>
<div class="chat-messages" id="chatMessages">
<!-- Messages Rosalinda ici -->
</div>
<div class="chat-input">
<button title="Ajouter un fichier"><i class="fas fa-plus"></i></button>
<button title="Connexion"><i class="fas fa-plug"></i></button>
<input type="text" placeholder="Écrire à Rosalinda..." />
<button title="Micro"><i class="fas fa-microphone"></i></button>
<button title="Envoyer"><i class="fas fa-paper-plane"></i></button>
</div>
</main>
<!-- Colonne 3 : Résultat & Code -->
<section class="output">
<div class="output-tabs">
<button><i class="fas fa-code"></i> Code</button>
<button><i class="fas fa-chart-pie"></i> Tableau de bord</button>
<button><i class="fas fa-database"></i> Base de données</button>
<button><i class="fas fa-folder"></i> Stockage</button>
<button><i class="fas fa-cog"></i> Paramètres</button>
</div>
<div class="code-output" id="codeOutput">
<pre><code>// Code généré s'affichera ici...</code></pre>
</div>
<div class="result-output">
<p>Résultat final ici (image, vidéo ou page)...</p>
</div>
</section>
</div>
<script src="script.js"></script>
</body>
</html>
"""
# 2. styles.css
css_code = """
* {
box-sizing: border-box;
margin: 0;
padding: 0;
font-family: Arial, sans-serif;
}
body, html {
height: 100%;
width: 100%;
}
.container {
display: flex;
height: 100vh;
}
/* Colonne 1 */
.sidebar {
width: 20%;
background: #f1f1f1;
border-right: 1px solid #ccc;
padding: 20px;
display: flex;
flex-direction: column;
}
.sidebar .logo {
font-weight: bold;
font-size: 18px;
text-decoration: none;
color: #222;
margin-bottom: 20px;
display: block;
}
.menu button {
display: block;
width: 100%;
margin-bottom: 10px;
padding: 10px;
background: #e0e0e0;
border: none;
cursor: pointer;
}
.projects h3 {
margin-top: 20px;
margin-bottom: 10px;
}
.projects ul {
list-style: none;
}
.projects li {
padding: 5px 0;
border-bottom: 1px solid #ccc;
}
/* Colonne 2 */
.chat {
width: 45%;
display: flex;
flex-direction: column;
padding: 20px;
}
.chat-header h2 {
font-size: 18px;
margin-bottom: 5px;
}
.activity-monitor {
font-size: 12px;
color: gray;
margin-bottom: 15px;
}
.chat-messages {
flex: 1;
background: #fafafa;
padding: 10px;
border: 1px solid #ddd;
overflow-y: auto;
}
.chat-input {
display: flex;
align-items: center;
gap: 8px;
margin-top: 10px;
}
.chat-input input {
flex: 1;
padding: 10px;
}
.chat-input button {
background: #ddd;
border: none;
padding: 10px;
cursor: pointer;
}
/* Colonne 3 */
.output {
width: 35%;
background: #fcfcfc;
border-left: 1px solid #ccc;
display: flex;
flex-direction: column;
padding: 20px;
}
.output-tabs {
display: flex;
gap: 10px;
margin-bottom: 10px;
}
.output-tabs button {
flex: 1;
padding: 8px;
font-size: 12px;
background: #e8e8e8;
border: none;
cursor: pointer;
display: flex;
align-items: center;
gap: 5px;
}
.code-output {
flex: 1;
background: #000;
color: #0f0;
padding: 10px;
font-family: monospace;
overflow-y: auto;
margin-bottom: 10px;
}
.result-output {
background: #fff;
border: 1px solid #ccc;
padding: 10px;
text-align: center;
}
"""
# 3. script.js
js_code = """console.log("Interface Espace Codage chargée.");
// Tu pourras ajouter ici les fonctions pour Rosalinda plus tard
"""
# Sauvegarder les fichiers
(theme_path / "index.html").write_text(html_code, encoding="utf-8")
(theme_path / "styles.css").write_text(css_code, encoding="utf-8")
(theme_path / "script.js").write_text(js_code, encoding="utf-8")
# Créer le ZIP pour téléchargement
import shutil
zip_file = "/mnt/data/espace_codage_theme.zip"
shutil.make_archive(str(theme_path), 'zip', str(theme_path))
zip_file
Résultat
'/mnt/data/espace_codage_theme.zip'
✅ Le thème complet Espace Codage que tu m’as décrit est prêt !
👉 Clique ici pour télécharger le projet complet
Le dossier contient :
index.html — structure HTML en 3 colonnes avec tous les éléments que tu as demandés
styles.css — design avec icônes et mise en page
script.js — fichier JavaScript prêt à être enrichi
Intégration de Font Awesome pour toutes les icônes personnalisées
Tu peux :
Extraire le .zip sur ton ordinateur
Ouvrir index.html dans ton navigateur pour voir le rendu
Modifier les fichiers à volonté
Si tu veux maintenant ajouter :
Des actions à Rosalinda (texte / image / vidéo)
Des appels API (OpenAI, Whisper, DALL·E, etc.)
L’enregistrement des projets dans une base de données
- README.md +7 -4
- index.html +141 -19
- script.js +183 -0
- styles.css +282 -0
|
@@ -1,10 +1,13 @@
|
|
| 1 |
---
|
| 2 |
title: Espace Codage Theme
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
sdk: static
|
| 7 |
pinned: false
|
|
|
|
|
|
|
| 8 |
---
|
| 9 |
|
| 10 |
-
|
|
|
|
|
|
| 1 |
---
|
| 2 |
title: Espace Codage Theme
|
| 3 |
+
colorFrom: blue
|
| 4 |
+
colorTo: red
|
| 5 |
+
emoji: 🐳
|
| 6 |
sdk: static
|
| 7 |
pinned: false
|
| 8 |
+
tags:
|
| 9 |
+
- deepsite-v3
|
| 10 |
---
|
| 11 |
|
| 12 |
+
# Welcome to your new DeepSite project!
|
| 13 |
+
This project was created with [DeepSite](https://huggingface.co/deepsite).
|
|
@@ -1,19 +1,141 @@
|
|
| 1 |
-
<!
|
| 2 |
-
<html>
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="fr" class="h-full">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8" />
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
| 6 |
+
<title>Espace Codage</title>
|
| 7 |
+
|
| 8 |
+
<!-- TailwindCSS (CDN) -->
|
| 9 |
+
<script src="https://cdn.tailwindcss.com"></script>
|
| 10 |
+
<script>
|
| 11 |
+
tailwind.config = {
|
| 12 |
+
theme: {
|
| 13 |
+
extend: {
|
| 14 |
+
colors: {
|
| 15 |
+
primary: {
|
| 16 |
+
500: 'var(--primary-500, #6366F1)',
|
| 17 |
+
},
|
| 18 |
+
secondary: {
|
| 19 |
+
500: 'var(--secondary-500, #22C55E)',
|
| 20 |
+
},
|
| 21 |
+
},
|
| 22 |
+
},
|
| 23 |
+
},
|
| 24 |
+
darkMode: 'class',
|
| 25 |
+
}
|
| 26 |
+
</script>
|
| 27 |
+
|
| 28 |
+
<!-- Font Awesome -->
|
| 29 |
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css"/>
|
| 30 |
+
|
| 31 |
+
<link rel="stylesheet" href="styles.css" />
|
| 32 |
+
</head>
|
| 33 |
+
<body class="h-full bg-slate-50 text-slate-900 dark:bg-slate-950 dark:text-slate-100 transition-colors">
|
| 34 |
+
|
| 35 |
+
<div class="container">
|
| 36 |
+
|
| 37 |
+
<!-- Colonne 1 : Navigation -->
|
| 38 |
+
<aside class="sidebar">
|
| 39 |
+
<div class="flex items-center justify-between mb-6">
|
| 40 |
+
<a href="#" class="logo">
|
| 41 |
+
<i class="fa-solid fa-code"></i>
|
| 42 |
+
<span>Espace Codage</span>
|
| 43 |
+
</a>
|
| 44 |
+
<button id="themeToggle" class="theme-toggle" title="Basculer le thème">
|
| 45 |
+
<i class="fa-solid fa-moon"></i>
|
| 46 |
+
</button>
|
| 47 |
+
</div>
|
| 48 |
+
<nav class="menu">
|
| 49 |
+
<button id="newTaskBtn" class="btn">
|
| 50 |
+
<i class="fa-solid fa-plus"></i>
|
| 51 |
+
Nouvelle tâche
|
| 52 |
+
</button>
|
| 53 |
+
<button id="searchBtn" class="btn">
|
| 54 |
+
<i class="fa-solid fa-magnifying-glass"></i>
|
| 55 |
+
Rechercher
|
| 56 |
+
</button>
|
| 57 |
+
<button id="libraryBtn" class="btn">
|
| 58 |
+
<i class="fa-solid fa-book"></i>
|
| 59 |
+
Bibliothèque
|
| 60 |
+
</button>
|
| 61 |
+
</nav>
|
| 62 |
+
<div class="projects">
|
| 63 |
+
<h3>Projets</h3>
|
| 64 |
+
<ul id="projectList" class="project-list">
|
| 65 |
+
<!-- Projets ajoutés ici -->
|
| 66 |
+
</ul>
|
| 67 |
+
</div>
|
| 68 |
+
</aside>
|
| 69 |
+
|
| 70 |
+
<!-- Colonne 2 : Chat IA Rosalinda -->
|
| 71 |
+
<main class="chat">
|
| 72 |
+
<div class="chat-header">
|
| 73 |
+
<h2>Espace Codage – Rosalinda</h2>
|
| 74 |
+
<div class="activity-monitor">
|
| 75 |
+
<span id="aiActivityDot" class="dot"></span>
|
| 76 |
+
<span id="aiActivityText">IA en veille</span>
|
| 77 |
+
</div>
|
| 78 |
+
</div>
|
| 79 |
+
<div class="chat-messages" id="chatMessages">
|
| 80 |
+
<div class="msg msg-ai">
|
| 81 |
+
<div class="avatar">
|
| 82 |
+
<i class="fa-solid fa-robot"></i>
|
| 83 |
+
</div>
|
| 84 |
+
<div class="bubble">
|
| 85 |
+
Bonjour ! Je suis Rosalinda, votre assistante IA. Comment puis-je vous aider aujourd’hui ?
|
| 86 |
+
</div>
|
| 87 |
+
</div>
|
| 88 |
+
</div>
|
| 89 |
+
<div class="chat-input">
|
| 90 |
+
<button id="attachBtn" title="Ajouter un fichier">
|
| 91 |
+
<i class="fas fa-plus"></i>
|
| 92 |
+
</button>
|
| 93 |
+
<button id="connectBtn" title="Connexion">
|
| 94 |
+
<i class="fas fa-plug"></i>
|
| 95 |
+
</button>
|
| 96 |
+
<input type="text" id="chatInput" placeholder="Écrire à Rosalinda..." />
|
| 97 |
+
<button id="micBtn" title="Micro">
|
| 98 |
+
<i class="fas fa-microphone"></i>
|
| 99 |
+
</button>
|
| 100 |
+
<button id="sendBtn" title="Envoyer">
|
| 101 |
+
<i class="fas fa-paper-plane"></i>
|
| 102 |
+
</button>
|
| 103 |
+
</div>
|
| 104 |
+
</main>
|
| 105 |
+
|
| 106 |
+
<!-- Colonne 3 : Résultat & Code -->
|
| 107 |
+
<section class="output">
|
| 108 |
+
<div class="output-tabs">
|
| 109 |
+
<button class="tab-btn active" data-tab="code">
|
| 110 |
+
<i class="fas fa-code"></i> Code
|
| 111 |
+
</button>
|
| 112 |
+
<button class="tab-btn" data-tab="dashboard">
|
| 113 |
+
<i class="fas fa-chart-pie"></i> Tableau de bord
|
| 114 |
+
</button>
|
| 115 |
+
<button class="tab-btn" data-tab="db">
|
| 116 |
+
<i class="fas fa-database"></i> Base de données
|
| 117 |
+
</button>
|
| 118 |
+
<button class="tab-btn" data-tab="storage">
|
| 119 |
+
<i class="fas fa-folder"></i> Stockage
|
| 120 |
+
</button>
|
| 121 |
+
<button class="tab-btn" data-tab="settings">
|
| 122 |
+
<i class="fas fa-cog"></i> Paramètres
|
| 123 |
+
</button>
|
| 124 |
+
</div>
|
| 125 |
+
|
| 126 |
+
<div class="code-output" id="codeOutput">
|
| 127 |
+
<pre><code>// Code généré s’affichera ici...
|
| 128 |
+
</code></pre>
|
| 129 |
+
</div>
|
| 130 |
+
|
| 131 |
+
<div class="result-output">
|
| 132 |
+
<p>Résultat final ici (image, vidéo ou page)...</p>
|
| 133 |
+
</div>
|
| 134 |
+
</section>
|
| 135 |
+
|
| 136 |
+
</div>
|
| 137 |
+
|
| 138 |
+
<script src="script.js"></script>
|
| 139 |
+
<script src="https://huggingface.co/deepsite/deepsite-badge.js"></script>
|
| 140 |
+
</body>
|
| 141 |
+
</html>
|
|
@@ -0,0 +1,183 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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)');
|
| 6 |
+
const storedTheme = localStorage.getItem('theme'); // 'dark' | 'light' | null
|
| 7 |
+
const setTheme = (mode) => {
|
| 8 |
+
const html = document.documentElement;
|
| 9 |
+
if (mode === 'dark') {
|
| 10 |
+
html.classList.add('dark');
|
| 11 |
+
localStorage.setItem('theme', 'dark');
|
| 12 |
+
themeToggle.innerHTML = '<i class="fa-solid fa-sun"></i>';
|
| 13 |
+
} else {
|
| 14 |
+
html.classList.remove('dark');
|
| 15 |
+
localStorage.setItem('theme', 'light');
|
| 16 |
+
themeToggle.innerHTML = '<i class="fa-solid fa-moon"></i>';
|
| 17 |
+
}
|
| 18 |
+
};
|
| 19 |
+
setTheme(storedTheme ? storedTheme : (prefersDark.matches ? 'dark' : 'light'));
|
| 20 |
+
themeToggle.addEventListener('click', () => {
|
| 21 |
+
const current = document.documentElement.classList.contains('dark') ? 'dark' : 'light';
|
| 22 |
+
setTheme(current === 'dark' ? 'light' : 'dark');
|
| 23 |
+
});
|
| 24 |
+
prefersDark.addEventListener('change', (e) => {
|
| 25 |
+
if (!localStorage.getItem('theme')) {
|
| 26 |
+
setTheme(e.matches ? 'dark' : 'light');
|
| 27 |
+
}
|
| 28 |
+
});
|
| 29 |
+
|
| 30 |
+
// ===== Éléments du DOM =====
|
| 31 |
+
const projectList = document.getElementById('projectList');
|
| 32 |
+
const chatMessages = document.getElementById('chatMessages');
|
| 33 |
+
const chatInput = document.getElementById('chatInput');
|
| 34 |
+
const sendBtn = document.getElementById('sendBtn');
|
| 35 |
+
const micBtn = document.getElementById('micBtn');
|
| 36 |
+
const connectBtn = document.getElementById('connectBtn');
|
| 37 |
+
const attachBtn = document.getElementById('attachBtn');
|
| 38 |
+
const codeOutput = document.getElementById('codeOutput').querySelector('code');
|
| 39 |
+
const aiActivityText = document.getElementById('aiActivityText');
|
| 40 |
+
const aiActivityDot = document.getElementById('aiActivityDot');
|
| 41 |
+
const tabButtons = document.querySelectorAll('.tab-btn');
|
| 42 |
+
|
| 43 |
+
// ===== Gestion des projets =====
|
| 44 |
+
let projects = JSON.parse(localStorage.getItem('projects') || '[]');
|
| 45 |
+
|
| 46 |
+
function saveProjects() {
|
| 47 |
+
localStorage.setItem('projects', JSON.stringify(projects));
|
| 48 |
+
}
|
| 49 |
+
function renderProjects() {
|
| 50 |
+
projectList.innerHTML = '';
|
| 51 |
+
if (projects.length === 0) {
|
| 52 |
+
const li = document.createElement('li');
|
| 53 |
+
li.className = 'text-slate-500';
|
| 54 |
+
li.textContent = 'Aucun projet. Cliquez sur "Nouvelle tâche" pour commencer.';
|
| 55 |
+
projectList.appendChild(li);
|
| 56 |
+
return;
|
| 57 |
+
}
|
| 58 |
+
projects.forEach((p, idx) => {
|
| 59 |
+
const li = document.createElement('li');
|
| 60 |
+
li.innerHTML = `
|
| 61 |
+
<span>${p}</span>
|
| 62 |
+
<span class="actions">
|
| 63 |
+
<button title="Renommer" data-action="rename" data-index="${idx}"><i class="fa-solid fa-pen"></i></button>
|
| 64 |
+
<button title="Supprimer" data-action="delete" data-index="${idx}"><i class="fa-solid fa-trash"></i></button>
|
| 65 |
+
</span>
|
| 66 |
+
`;
|
| 67 |
+
projectList.appendChild(li);
|
| 68 |
+
});
|
| 69 |
+
}
|
| 70 |
+
function addProject(name) {
|
| 71 |
+
if (!name) return;
|
| 72 |
+
projects.push(name);
|
| 73 |
+
saveProjects();
|
| 74 |
+
renderProjects();
|
| 75 |
+
}
|
| 76 |
+
function renameProject(index) {
|
| 77 |
+
const newName = prompt('Nouveau nom du projet:', projects[index]);
|
| 78 |
+
if (newName && newName.trim()) {
|
| 79 |
+
projects[index] = newName.trim();
|
| 80 |
+
saveProjects();
|
| 81 |
+
renderProjects();
|
| 82 |
+
}
|
| 83 |
+
}
|
| 84 |
+
function deleteProject(index) {
|
| 85 |
+
if (confirm('Supprimer ce projet ?')) {
|
| 86 |
+
projects.splice(index, 1);
|
| 87 |
+
saveProjects();
|
| 88 |
+
renderProjects();
|
| 89 |
+
}
|
| 90 |
+
}
|
| 91 |
+
projectList.addEventListener('click', (e) => {
|
| 92 |
+
const btn = e.target.closest('button[data-action]');
|
| 93 |
+
if (!btn) return;
|
| 94 |
+
const idx = Number(btn.dataset.index);
|
| 95 |
+
if (btn.dataset.action === 'rename') renameProject(idx);
|
| 96 |
+
if (btn.dataset.action === 'delete') deleteProject(idx);
|
| 97 |
+
});
|
| 98 |
+
document.getElementById('newTaskBtn').addEventListener('click', () => {
|
| 99 |
+
const name = prompt('Nom du nouveau projet:');
|
| 100 |
+
if (name) addProject(name.trim());
|
| 101 |
+
});
|
| 102 |
+
document.getElementById('searchBtn').addEventListener('click', () => {
|
| 103 |
+
alert('Fonction "Rechercher" à implémenter.');
|
| 104 |
+
});
|
| 105 |
+
document.getElementById('libraryBtn').addEventListener('click', () => {
|
| 106 |
+
alert('Fonction "Bibliothèque" à implémenter.');
|
| 107 |
+
});
|
| 108 |
+
renderProjects();
|
| 109 |
+
|
| 110 |
+
// ===== Chat (Rosalinda) =====
|
| 111 |
+
function setAIActivity(text, active = true) {
|
| 112 |
+
aiActivityText.textContent = text;
|
| 113 |
+
aiActivityDot.style.background = active ? 'rgb(34,197,94)' : 'rgb(100,116,139)'; // emerald vs slate
|
| 114 |
+
}
|
| 115 |
+
function addMessage(role, content) {
|
| 116 |
+
const msg = document.createElement('div');
|
| 117 |
+
msg.className = 'msg ' + (role === 'user' ? 'msg-user' : 'msg-ai');
|
| 118 |
+
if (role === 'user') {
|
| 119 |
+
msg.innerHTML = `
|
| 120 |
+
<div class="bubble">${escapeHTML(content)}</div>
|
| 121 |
+
<div class="avatar">
|
| 122 |
+
<i class="fa-solid fa-user"></i>
|
| 123 |
+
</div>
|
| 124 |
+
`;
|
| 125 |
+
} else {
|
| 126 |
+
msg.innerHTML = `
|
| 127 |
+
<div class="avatar">
|
| 128 |
+
<i class="fa-solid fa-robot"></i>
|
| 129 |
+
</div>
|
| 130 |
+
<div class="bubble">${content}</div>
|
| 131 |
+
`;
|
| 132 |
+
}
|
| 133 |
+
chatMessages.appendChild(msg);
|
| 134 |
+
chatMessages.scrollTop = chatMessages.scrollHeight;
|
| 135 |
+
}
|
| 136 |
+
function escapeHTML(str) {
|
| 137 |
+
return str.replace(/[&<>"']/g, (m) => ({
|
| 138 |
+
'&': '&', '<': '<', '>': '>', '"': '"', "'": '''
|
| 139 |
+
}[m]));
|
| 140 |
+
}
|
| 141 |
+
function sendMessage() {
|
| 142 |
+
const text = chatInput.value.trim();
|
| 143 |
+
if (!text) return;
|
| 144 |
+
addMessage('user', text);
|
| 145 |
+
chatInput.value = '';
|
| 146 |
+
// Simulation d'activité IA
|
| 147 |
+
setAIActivity('Rosalinda réfléchit...', true);
|
| 148 |
+
setTimeout(() => {
|
| 149 |
+
setAIActivity('IA en veille', false);
|
| 150 |
+
addMessage('ai', `J’ai bien reçu: "${text}". Comment souhaitez-vous continuer ?`);
|
| 151 |
+
codeOutput.textContent = `// Exemple de sortie pour: ${text}\nconsole.log("${text}");`;
|
| 152 |
+
}, 800);
|
| 153 |
+
}
|
| 154 |
+
sendBtn.addEventListener('click', sendMessage);
|
| 155 |
+
chatInput.addEventListener('keydown', (e) => {
|
| 156 |
+
if (e.key === 'Enter') sendMessage();
|
| 157 |
+
});
|
| 158 |
+
micBtn.addEventListener('click', () => {
|
| 159 |
+
alert('Fonction "Micro" à implémenter (Web Speech API, Whisper, etc.).');
|
| 160 |
+
});
|
| 161 |
+
connectBtn.addEventListener('click', () => {
|
| 162 |
+
alert('Fonction "Connexion" à implémenter (OAuth, clés API, etc.).');
|
| 163 |
+
});
|
| 164 |
+
attachBtn.addEventListener('click', () => {
|
| 165 |
+
alert('Fonction "Ajouter un fichier" à implémenter (FileReader, uploads, etc.).');
|
| 166 |
+
});
|
| 167 |
+
|
| 168 |
+
// ===== Onglets =====
|
| 169 |
+
tabButtons.forEach(btn => {
|
| 170 |
+
btn.addEventListener('click', () => {
|
| 171 |
+
tabButtons.forEach(b => b.classList.remove('active'));
|
| 172 |
+
btn.classList.add('active');
|
| 173 |
+
const tab = btn.dataset.tab;
|
| 174 |
+
const demo = {
|
| 175 |
+
code: '// Code généré s’affichera ici...',
|
| 176 |
+
dashboard: 'Tableau de bord (graphiques, KPIs)...',
|
| 177 |
+
db: 'Visualisation base de données (tables, requêtes)...',
|
| 178 |
+
storage: 'Gestion du stockage (fichiers, objets)...',
|
| 179 |
+
settings: 'Paramètres (thème, clés API, intégrations)...'
|
| 180 |
+
};
|
| 181 |
+
codeOutput.textContent = demo[tab] || '// ...';
|
| 182 |
+
});
|
| 183 |
+
});
|
|
@@ -0,0 +1,282 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* CSS Variables (avec valeurs de secours) */
|
| 2 |
+
:root {
|
| 3 |
+
--primary-500: var(--primary-500, #6366F1); /* Indigo */
|
| 4 |
+
--secondary-500: var(--secondary-500, #22C55E); /* Green */
|
| 5 |
+
}
|
| 6 |
+
|
| 7 |
+
/* Mise en page globale */
|
| 8 |
+
* { box-sizing: border-box; }
|
| 9 |
+
html, body { height: 100%; }
|
| 10 |
+
body { margin: 0; font-family: Inter, ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, "Apple Color Emoji", "Segoe UI Emoji"; }
|
| 11 |
+
|
| 12 |
+
/* Container principal en 3 colonnes */
|
| 13 |
+
.container {
|
| 14 |
+
display: flex;
|
| 15 |
+
height: 100vh;
|
| 16 |
+
}
|
| 17 |
+
|
| 18 |
+
/* Colonne 1 : Sidebar */
|
| 19 |
+
.sidebar {
|
| 20 |
+
width: 20%;
|
| 21 |
+
min-width: 240px;
|
| 22 |
+
background: rgb(248 250 252); /* slate-50 */
|
| 23 |
+
border-right: 1px solid rgb(226 232 240); /* slate-200 */
|
| 24 |
+
padding: 16px;
|
| 25 |
+
display: flex;
|
| 26 |
+
flex-direction: column;
|
| 27 |
+
gap: 16px;
|
| 28 |
+
}
|
| 29 |
+
.dark .sidebar {
|
| 30 |
+
background: rgb(15 23 42); /* slate-900 */
|
| 31 |
+
border-right-color: rgb(30 41 59); /* slate-800 */
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
.logo {
|
| 35 |
+
display: flex;
|
| 36 |
+
align-items: center;
|
| 37 |
+
gap: 8px;
|
| 38 |
+
font-weight: 700;
|
| 39 |
+
font-size: 18px;
|
| 40 |
+
color: rgb(15 23 42);
|
| 41 |
+
text-decoration: none;
|
| 42 |
+
}
|
| 43 |
+
.dark .logo { color: rgb(248 250 252); }
|
| 44 |
+
|
| 45 |
+
.menu { display: flex; flex-direction: column; gap: 8px; }
|
| 46 |
+
.btn {
|
| 47 |
+
width: 100%;
|
| 48 |
+
display: inline-flex;
|
| 49 |
+
align-items: center;
|
| 50 |
+
justify-content: flex-start;
|
| 51 |
+
gap: 8px;
|
| 52 |
+
padding: 10px 12px;
|
| 53 |
+
background: rgb(241 245 249); /* slate-100 */
|
| 54 |
+
color: rgb(15 23 42);
|
| 55 |
+
border: 1px solid rgb(226 232 240);
|
| 56 |
+
border-radius: 8px;
|
| 57 |
+
cursor: pointer;
|
| 58 |
+
}
|
| 59 |
+
.btn:hover { background: rgb(226 232 240); } /* slate-200 */
|
| 60 |
+
.dark .btn {
|
| 61 |
+
background: rgb(30 41 59); /* slate-800 */
|
| 62 |
+
color: rgb(226 232 240);
|
| 63 |
+
border-color: rgb(51 65 85); /* slate-700 */
|
| 64 |
+
}
|
| 65 |
+
.dark .btn:hover { background: rgb(51 65 85); }
|
| 66 |
+
|
| 67 |
+
.projects h3 {
|
| 68 |
+
font-size: 14px;
|
| 69 |
+
color: rgb(100 116 139); /* slate-500 */
|
| 70 |
+
margin-bottom: 8px;
|
| 71 |
+
text-transform: uppercase;
|
| 72 |
+
letter-spacing: 0.06em;
|
| 73 |
+
}
|
| 74 |
+
.dark .projects h3 { color: rgb(148 163 184); }
|
| 75 |
+
|
| 76 |
+
.project-list { list-style: none; display: flex; flex-direction: column; gap: 6px; padding: 0; margin: 0; }
|
| 77 |
+
.project-list li {
|
| 78 |
+
display: flex; align-items: center; justify-content: space-between;
|
| 79 |
+
padding: 8px 10px; border: 1px solid rgb(226 232 240); border-radius: 8px;
|
| 80 |
+
background: white;
|
| 81 |
+
}
|
| 82 |
+
.dark .project-list li { background: rgb(30 41 59); border-color: rgb(51 65 85); }
|
| 83 |
+
.project-list .actions { display: flex; gap: 6px; }
|
| 84 |
+
.project-list button {
|
| 85 |
+
padding: 4px 6px; border: 1px solid rgb(226 232 240); background: rgb(248 250 252); border-radius: 6px; cursor: pointer;
|
| 86 |
+
}
|
| 87 |
+
.dark .project-list button { background: rgb(15 23 42); border-color: rgb(51 65 85); }
|
| 88 |
+
|
| 89 |
+
/* Colonne 2 : Chat */
|
| 90 |
+
.chat {
|
| 91 |
+
width: 45%;
|
| 92 |
+
min-width: 320px;
|
| 93 |
+
display: flex;
|
| 94 |
+
flex-direction: column;
|
| 95 |
+
padding: 16px;
|
| 96 |
+
gap: 12px;
|
| 97 |
+
}
|
| 98 |
+
.chat-header h2 { font-size: 18px; margin: 0; }
|
| 99 |
+
.activity-monitor {
|
| 100 |
+
display: flex; align-items: center; gap: 8px;
|
| 101 |
+
font-size: 12px; color: rgb(100 116 139);
|
| 102 |
+
}
|
| 103 |
+
.dark .activity-monitor { color: rgb(148 163 184); }
|
| 104 |
+
.dot {
|
| 105 |
+
width: 8px; height: 8px; border-radius: 9999px;
|
| 106 |
+
background: rgb(34 197 94); /* emerald-500 */
|
| 107 |
+
display: inline-block;
|
| 108 |
+
}
|
| 109 |
+
|
| 110 |
+
.chat-messages {
|
| 111 |
+
flex: 1;
|
| 112 |
+
background: rgb(255 255 255);
|
| 113 |
+
border: 1px solid rgb(226 232 240);
|
| 114 |
+
border-radius: 12px;
|
| 115 |
+
padding: 12px;
|
| 116 |
+
overflow-y: auto;
|
| 117 |
+
}
|
| 118 |
+
.dark .chat-messages {
|
| 119 |
+
background: rgb(2 6 23); /* slate-950 */
|
| 120 |
+
border-color: rgb(30 41 59);
|
| 121 |
+
}
|
| 122 |
+
|
| 123 |
+
.msg {
|
| 124 |
+
display: flex; gap: 10px; margin-bottom: 12px;
|
| 125 |
+
}
|
| 126 |
+
.msg-ai .avatar {
|
| 127 |
+
width: 32px; height: 32px; border-radius: 9999px;
|
| 128 |
+
display: grid; place-items: center;
|
| 129 |
+
background: var(--primary-500);
|
| 130 |
+
color: white;
|
| 131 |
+
}
|
| 132 |
+
.msg-user { justify-content: flex-end; }
|
| 133 |
+
.msg-user .bubble {
|
| 134 |
+
background: var(--secondary-500);
|
| 135 |
+
color: white;
|
| 136 |
+
border-bottom-right-radius: 4px;
|
| 137 |
+
}
|
| 138 |
+
.msg-ai .bubble {
|
| 139 |
+
background: rgb(241 245 249); color: rgb(15 23 42);
|
| 140 |
+
border-bottom-left-radius: 4px;
|
| 141 |
+
}
|
| 142 |
+
.dark .msg-ai .bubble {
|
| 143 |
+
background: rgb(30 41 59); color: rgb(226 232 240);
|
| 144 |
+
}
|
| 145 |
+
.bubble {
|
| 146 |
+
max-width: 70%;
|
| 147 |
+
padding: 10px 12px;
|
| 148 |
+
border-radius: 12px;
|
| 149 |
+
box-shadow: 0 1px 0 rgba(0,0,0,.04);
|
| 150 |
+
}
|
| 151 |
+
|
| 152 |
+
.chat-input {
|
| 153 |
+
display: grid;
|
| 154 |
+
grid-template-columns: auto auto 1fr auto auto;
|
| 155 |
+
gap: 8px;
|
| 156 |
+
align-items: center;
|
| 157 |
+
}
|
| 158 |
+
.chat-input input {
|
| 159 |
+
padding: 10px 12px;
|
| 160 |
+
border-radius: 8px;
|
| 161 |
+
border: 1px solid rgb(226 232 240);
|
| 162 |
+
background: white;
|
| 163 |
+
outline: none;
|
| 164 |
+
}
|
| 165 |
+
.dark .chat-input input {
|
| 166 |
+
background: rgb(2 6 23);
|
| 167 |
+
border-color: rgb(30 41 59);
|
| 168 |
+
color: rgb(226 232 240);
|
| 169 |
+
}
|
| 170 |
+
.chat-input button {
|
| 171 |
+
padding: 10px 12px;
|
| 172 |
+
border-radius: 8px;
|
| 173 |
+
border: 1px solid rgb(226 232 240);
|
| 174 |
+
background: rgb(248 250 252);
|
| 175 |
+
cursor: pointer;
|
| 176 |
+
}
|
| 177 |
+
.dark .chat-input button {
|
| 178 |
+
background: rgb(15 23 42);
|
| 179 |
+
border-color: rgb(30 41 59);
|
| 180 |
+
}
|
| 181 |
+
.chat-input button:hover { background: rgb(241 245 249); }
|
| 182 |
+
.dark .chat-input button:hover { background: rgb(30 41 59); }
|
| 183 |
+
|
| 184 |
+
/* Colonne 3 : Output */
|
| 185 |
+
.output {
|
| 186 |
+
width: 35%;
|
| 187 |
+
min-width: 300px;
|
| 188 |
+
background: rgb(252 252 252);
|
| 189 |
+
border-left: 1px solid rgb(226 232 240);
|
| 190 |
+
display: flex;
|
| 191 |
+
flex-direction: column;
|
| 192 |
+
padding: 16px;
|
| 193 |
+
gap: 12px;
|
| 194 |
+
}
|
| 195 |
+
.dark .output {
|
| 196 |
+
background: rgb(12 16 24);
|
| 197 |
+
border-left-color: rgb(30 41 59);
|
| 198 |
+
}
|
| 199 |
+
|
| 200 |
+
.output-tabs {
|
| 201 |
+
display: grid;
|
| 202 |
+
grid-template-columns: repeat(5, 1fr);
|
| 203 |
+
gap: 8px;
|
| 204 |
+
}
|
| 205 |
+
.output-tabs .tab-btn {
|
| 206 |
+
padding: 8px;
|
| 207 |
+
font-size: 12px;
|
| 208 |
+
background: rgb(232 232 232);
|
| 209 |
+
border: none;
|
| 210 |
+
cursor: pointer;
|
| 211 |
+
border-radius: 8px;
|
| 212 |
+
display: inline-flex;
|
| 213 |
+
align-items: center;
|
| 214 |
+
justify-content: center;
|
| 215 |
+
gap: 6px;
|
| 216 |
+
}
|
| 217 |
+
.output-tabs .tab-btn.active {
|
| 218 |
+
background: var(--primary-500);
|
| 219 |
+
color: white;
|
| 220 |
+
}
|
| 221 |
+
|
| 222 |
+
.code-output {
|
| 223 |
+
flex: 1;
|
| 224 |
+
background: #000;
|
| 225 |
+
color: #0f0;
|
| 226 |
+
padding: 12px;
|
| 227 |
+
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
| 228 |
+
overflow-y: auto;
|
| 229 |
+
border-radius: 10px;
|
| 230 |
+
border: 1px solid rgb(30 41 59);
|
| 231 |
+
}
|
| 232 |
+
.code-output code { white-space: pre; display: block; }
|
| 233 |
+
|
| 234 |
+
.result-output {
|
| 235 |
+
background: #fff;
|
| 236 |
+
border: 1px solid rgb(226 232 240);
|
| 237 |
+
padding: 12px;
|
| 238 |
+
text-align: center;
|
| 239 |
+
border-radius: 10px;
|
| 240 |
+
}
|
| 241 |
+
.dark .result-output {
|
| 242 |
+
background: rgb(2 6 23);
|
| 243 |
+
border-color: rgb(30 41 59);
|
| 244 |
+
}
|
| 245 |
+
|
| 246 |
+
/* Thème (mode undefined = fallback par défaut déjà appliqué) */
|
| 247 |
+
.theme-toggle {
|
| 248 |
+
border: 1px solid rgb(226 232 240);
|
| 249 |
+
background: rgb(248 250 252);
|
| 250 |
+
color: rgb(15 23 42);
|
| 251 |
+
padding: 8px 10px;
|
| 252 |
+
border-radius: 8px;
|
| 253 |
+
cursor: pointer;
|
| 254 |
+
}
|
| 255 |
+
.dark .theme-toggle {
|
| 256 |
+
background: rgb(15 23 42);
|
| 257 |
+
border-color: rgb(30 41 59);
|
| 258 |
+
color: rgb(226 232 240);
|
| 259 |
+
}
|
| 260 |
+
|
| 261 |
+
/* Scrollbar (Webkit) */
|
| 262 |
+
.chat-messages::-webkit-scrollbar,
|
| 263 |
+
.code-output::-webkit-scrollbar {
|
| 264 |
+
width: 10px;
|
| 265 |
+
}
|
| 266 |
+
.chat-messages::-webkit-scrollbar-thumb,
|
| 267 |
+
.code-output::-webkit-scrollbar-thumb {
|
| 268 |
+
background: rgb(226 232 240);
|
| 269 |
+
border-radius: 8px;
|
| 270 |
+
}
|
| 271 |
+
.dark .chat-messages::-webkit-scrollbar-thumb,
|
| 272 |
+
.dark .code-output::-webkit-scrollbar-thumb {
|
| 273 |
+
background: rgb(51 65 85);
|
| 274 |
+
}
|
| 275 |
+
|
| 276 |
+
/* Responsive */
|
| 277 |
+
@media (max-width: 1100px) {
|
| 278 |
+
.container { flex-direction: column; }
|
| 279 |
+
.sidebar { width: 100%; border-right: none; border-bottom: 1px solid rgb(226 232 240); }
|
| 280 |
+
.chat { width: 100%; }
|
| 281 |
+
.output { width: 100%; }
|
| 282 |
+
}
|