Abmacode12 commited on
Commit
3376581
·
verified ·
1 Parent(s): 734c941

import React, { useState } from 'react';

Browse files

import { Plus, Search, Library, Share2, Menu, X, Code2, Settings, LogOut, Home, FolderOpen, MessageSquare, Send, ChevronRight, Star, Clock, Zap, Copy, Download, Eye } from 'lucide-react';

export default function EspaceCodage() {
const [sidebarOpen, setSidebarOpen] = useState(true);
const [currentView, setCurrentView] = useState('home');
const [userInput, setUserInput] = useState('');
const [chatActive, setChatActive] = useState(false);
const [messages, setMessages] = useState([]);
const [generatedCode, setGeneratedCode] = useState(null);
const [selectedProject, setSelectedProject] = useState(null);
const [projects, setProjects] = useState([
{ id: 1, name: 'Portfolio Pro', status: 'active', timestamp: '2 jours', code: '' },
{ id: 2, name: 'E-shop Mode', status: 'active', timestamp: '5 jours', code: '' },
{ id: 3, name: 'App SaaS', status: 'archived', timestamp: '10 jours', code: '' }
]);

// Rosalinda - IA intelligente pour générer du code
const rosalinda = async (userText) => {
try {
// Appel à l'API Claude pour générer du code complet
const response = await fetch("https://api.anthropic.com/v1/messages", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "claude-sonnet-4-20250514",
max_tokens: 2000,
system: `Tu es Rosalinda, une IA senior full-stack spécialisée dans la génération de code complet et professionnel.

Tu dois :
1. Comprendre exactement ce que l'utilisateur demande
2. Générer du code HTML/CSS/JavaScript complet et fonctionnel
3. Générer du code React moderne si demandé
4. Expliquer ton code clairement en français

Format de réponse :
- D'abord une explication courte
- Ensuite le code complet dans un bloc \`\`\`language
- Toujours du code prêt à l'emploi, sans placeholders

Sois créatif, professionnel et produis du vrai code !`,
messages: [
{ role: "user", content: userText }
],
})
});

const data = await response.json();
return data.content[0]?.text || "Erreur de génération";
} catch (error) {
return `Je vais générer du code pour: ${userText}. Voici une solution professionnelle !`;
}
};

const handleUserMessage = async (text) => {
if (!text.trim()) return;

// Ajouter le message de l'utilisateur
const newMessages = [...messages, {
id: Date.now(),
user: 'Vous',
type: 'user',
text: text,
time: new Date().toLocaleTimeString('fr-FR', { hour: '2-digit', minute: '2-digit' })
}];
setMessages(newMessages);

// Rosalinda génère une réponse intelligente
let rosalindaResponse = '';

// Appel à Rosalinda pour générer du code ou répondre
if (text.toLowerCase().includes('site') ||
text.toLowerCase().includes('code') ||
text.toLowerCase().includes('html') ||
text.toLowerCase().includes('app') ||
text.toLowerCase().includes('portfolio') ||
text.toLowerCase().includes('e-shop') ||
text.toLowerCase().includes('landing')) {

rosalindaResponse = await rosalinda(text);

// Extraire le code généré si présent
const codeMatch = rosalindaResponse.match(/```(?:html|jsx?|css|javascript)?\n([\s\S]*?)```/);
if (codeMatch) {
setGeneratedCode({
language: text.includes('react') ? 'jsx' : 'html',
code: codeMatch[1],
description: text
});
}
} else {
// Réponse standard si pas de demande de code
rosalindaResponse = await rosalinda(`Réponds brièvement (2-3 phrases max) en français à: ${text}`);
}

// Ajouter la réponse de Rosalinda
setTimeout(() => {
setMessages(prev => [...prev, {
id: Date.now() + 1,
user: 'Rosalinda',
type: 'assistant',
text: rosalindaResponse,
time: new Date().toLocaleTimeString('fr-FR', { hour: '2-digit', minute: '2-digit' })
}]);
}, 500);

setUserInput('');
};

const copyCode = (code) => {
navigator.clipboard.writeText(code);
alert('Code copié ! ✓');
};

const downloadCode = (code, filename = 'code.html') => {
const element = document.createElement('a');
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(code));
element.setAttribute('download', filename);
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
};

const saveProjectCode = () => {
if (generatedCode && selectedProject) {
const updatedProjects = projects.map(p =>
p.id === selectedProject
? { ...p, code: generatedCode.code }
: p
);
setProjects(updatedProjects);
alert('Projet sauvegardé ! ✓');
}
};

return (
<div className="flex h-screen bg-gray-50">
{/* Sidebar */}
<div className={`${sidebarOpen ? 'w-72' : 'w-20'} bg-white border-r border-gray-200 transition-all duration-300 flex flex-col`}>
{/* Logo */}
<div className="p-6 flex items-center justify-between border-b border-gray-200">
{sidebarOpen && (
<div className="flex items-center space-x-3">
<div className="w-10 h-10 bg-gradient-to-br from-blue-500 to-purple-600 rounded-lg flex items-center justify-center text-white font-bold text-lg">
EC
</div>
<div>
<h1 className="font-bold text-gray-900">Espace Codage</h1>
<p className="text-xs text-gray-500">Workspace Rosalinda</p>
</div>
</div>
)}
<button
onClick={() => setSidebarOpen(!sidebarOpen)}
className="p-2 hover:bg-gray-100 rounded-lg transition"
>
{sidebarOpen ? <X size={20} /> : <Menu size={20} />}
</button>
</div>

{/* New Task */}
{sidebarOpen && (
<div className="p-4 border-b border-gray-200">
<button className="w-full flex items-center justify-center space-x-2 bg-gray-900 text-white py-3 rounded-lg hover:bg-gray-800 transition font-semibold">
<Plus size={20} />
<span>Nouvelle tâche</span>
</button>
</div>
)}

{/* Search */}
{sidebarOpen && (
<div className="p-4 border-b border-gray-200">
<div className="relative">
<Search size={18} className="absolute left-3 top-3 text-gray-400" />
<input
type="text"
placeholder="Rechercher..."
className="w-full pl-10 pr-4 py-2 bg-gray-50 border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm"
/>
</div>
</div>
)}

{/* Navigation */}
<nav className="flex-1 p-4 space-y-2">
{[
{ id: 'home', icon: Home, label: 'Accueil' },
{ id: 'chat', icon: MessageSquare, label: 'Chat Rosalinda' },
{ id: 'projects', icon: FolderOpen, label: 'Mes Projets' },
{ id: 'code', icon: Code2, label: 'Code Généré' },
{ id: 'library', icon: Library, label: 'Bibliothèque' }
].map(item => (
<button
key={item.id}
onClick={() => {
setCurrentView(item.id);
if (item.id === 'chat') setChatActive(true);
}}
className={`w-full flex items-center space-x-3 p-3 rounded-lg transition ${
currentView === item.id
? 'bg-blue-100 text-blue-900'
: 'text-gray-600 hover:bg-gray-50'
}`}
>
<item.icon size={20} />
{sidebarOpen && <span>{item.label}</span>}
</button>
))}
</nav>

{/* Projects */}
{sidebarOpen && (
<div className="p-4 border-t border-gray-200">
<h3 className="font-semibold text-gray-900 mb-3 text-sm">Vos Projets</h3>
<div className="space-y-2">
{projects.map(project => (
<button
key={project.id}
onClick={() => setSelectedProject(project.id)}
className={`w-full text-left p-3 rounded-lg transition text-sm ${
selectedProject === project.id
? 'bg-green-100 border-l-4 border-green-500'
: 'hover:bg-gray-50'
}`}
>
<div className="flex items-center space-x-2">
<div className={`w-2 h-2 rounded-full ${project.status === 'active' ? 'bg-green-500' : 'bg-gray-300'}`}></div>
<span className="font-medium">{project.name}</span>
</div>
<p className="text-xs text-gray-500 mt-1">{project.timestamp}</p>
</button>
))}
</div>
</div>
)}

{/* Footer */}
{sidebarOpen && (
<div className="p-4 border-t border-gray-200 space-y-2">
<button className="w-full flex items-center space-x-3 p-3 text-gray-600 hover:bg-gray-50 rounded-lg transition text-sm">
<Settings size={18} />
<span>Paramètres</span>
</button>
<button className="w-full flex items-center space-x-3 p-3 text-gray-600 hover:bg-gray-50 rounded-lg transition text-sm">
<LogOut size={18} />
<span>Déconnexion</span>
</button>
</div>
)}
</div>

{/* Main Content */}
<div className="flex-1 flex flex-col">
{/* Header */}
<div className="bg-white border-b border-gray-200 p-6 sticky top-0 z-10">
<div className="flex justify-between items-center">
<div>
<h2 className="text-2xl font-bold text-gray-900">
{currentView === 'home' && '🚀 Bienvenue dans Espace C

Files changed (7) hide show
  1. README.md +8 -5
  2. components/chat.js +160 -0
  3. components/navbar.js +117 -0
  4. components/sidebar.js +335 -0
  5. index.html +122 -19
  6. script.js +50 -0
  7. style.css +42 -18
README.md CHANGED
@@ -1,10 +1,13 @@
1
  ---
2
- title: Rosalinda Code Wizard
3
- emoji: 🌖
4
- colorFrom: red
5
- colorTo: purple
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
1
  ---
2
+ title: Rosalinda Code Wizard 🧙‍♀️
3
+ colorFrom: purple
4
+ colorTo: gray
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).
components/chat.js ADDED
@@ -0,0 +1,160 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class CustomChat extends HTMLElement {
2
+ connectedCallback() {
3
+ this.attachShadow({ mode: 'open' });
4
+ this.shadowRoot.innerHTML = `
5
+ <style>
6
+ :host {
7
+ display: flex;
8
+ flex-direction: column;
9
+ height: 100%;
10
+ }
11
+
12
+ .chat-container {
13
+ flex: 1;
14
+ background: white;
15
+ border: 1px solid #e5e7eb;
16
+ border-radius: 0.75rem;
17
+ margin-bottom: 1.5rem;
18
+ overflow-y: auto;
19
+ padding: 1.5rem;
20
+ display: flex;
21
+ flex-direction: column;
22
+ gap: 1rem;
23
+ }
24
+
25
+ .empty-state {
26
+ display: flex;
27
+ align-items: center;
28
+ justify-content: center;
29
+ height: 100%;
30
+ text-align: center;
31
+ }
32
+
33
+ .empty-icon {
34
+ width: 5rem;
35
+ height: 5rem;
36
+ background: linear-gradient(135deg, #3b82f6, #8b5cf6);
37
+ border-radius: 50%;
38
+ display: flex;
39
+ align-items: center;
40
+ justify-content: center;
41
+ color: white;
42
+ font-size: 2.5rem;
43
+ margin: 0 auto 1rem;
44
+ }
45
+
46
+ .empty-title {
47
+ font-size: 1.125rem;
48
+ font-weight: 700;
49
+ color: #111827;
50
+ margin-bottom: 0.5rem;
51
+ }
52
+
53
+ .empty-description {
54
+ color: #6b7280;
55
+ margin-bottom: 0.25rem;
56
+ }
57
+
58
+ .empty-hint {
59
+ color: #9ca3af;
60
+ font-size: 0.875rem;
61
+ }
62
+
63
+ .message-user {
64
+ display: flex;
65
+ justify-content: flex-end;
66
+ }
67
+
68
+ .message-ai {
69
+ display: flex;
70
+ justify-content: flex-start;
71
+ }
72
+
73
+ .message-bubble {
74
+ max-width: 42rem;
75
+ padding: 1rem;
76
+ border-radius: 1rem;
77
+ font-size: 0.875rem;
78
+ line-height: 1.5;
79
+ white-space: pre-wrap;
80
+ }
81
+
82
+ .user-bubble {
83
+ background: #3b82f6;
84
+ color: white;
85
+ border-bottom-right-radius: 0;
86
+ }
87
+
88
+ .ai-bubble {
89
+ background: #f3f4f6;
90
+ color: #111827;
91
+ border-bottom-left-radius: 0;
92
+ }
93
+
94
+ .message-time {
95
+ font-size: 0.75rem;
96
+ margin-top: 0.5rem;
97
+ }
98
+
99
+ .user-time {
100
+ color: #bfdbfe;
101
+ }
102
+
103
+ .ai-time {
104
+ color: #9ca3af;
105
+ }
106
+
107
+ .input-container {
108
+ display: flex;
109
+ align-items: center;
110
+ gap: 0.5rem;
111
+ background: white;
112
+ border: 1px solid #e5e7eb;
113
+ border-radius: 0.75rem;
114
+ padding: 1rem;
115
+ }
116
+
117
+ .chat-input {
118
+ flex: 1;
119
+ border: none;
120
+ outline: none;
121
+ font-size: 0.875rem;
122
+ }
123
+
124
+ .send-btn {
125
+ padding: 0.75rem;
126
+ background: #3b82f6;
127
+ color: white;
128
+ border-radius: 0.5rem;
129
+ transition: all 0.2s;
130
+ }
131
+
132
+ .send-btn:hover {
133
+ background: #2563eb;
134
+ }
135
+ </style>
136
+
137
+ <div class="chat-container" id="chat-messages">
138
+ <div class="empty-state">
139
+ <div>
140
+ <div class="empty-icon">🤖</div>
141
+ <h3 class="empty-title">Rosalinda</h3>
142
+ <p class="empty-description">Votre IA générateur de code 100% propriétaire</p>
143
+ <p class="empty-hint">Demandez n'importe quoi pour générer du code !</p>
144
+ </div>
145
+ </div>
146
+ </div>
147
+
148
+ <div class="input-container">
149
+ <input type="text" class="chat-input" id="chat-input" placeholder="Décrivez votre projet, Rosalinda génère le code...">
150
+ <button class="send-btn" onclick="sendMessage()">
151
+ <i data-feather="send"></i>
152
+ </button>
153
+ </div>
154
+ `;
155
+
156
+ feather.replace();
157
+ }
158
+ }
159
+
160
+ customElements.define('custom-chat', CustomChat);
components/navbar.js ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class CustomNavbar extends HTMLElement {
2
+ connectedCallback() {
3
+ this.attachShadow({ mode: 'open' });
4
+ this.shadowRoot.innerHTML = `
5
+ <style>
6
+ :host {
7
+ display: block;
8
+ background: white;
9
+ border-bottom: 1px solid #e5e7eb;
10
+ padding: 1.5rem;
11
+ position: sticky;
12
+ top: 0;
13
+ z-index: 10;
14
+ }
15
+
16
+ .container {
17
+ display: flex;
18
+ justify-content: space-between;
19
+ align-items: center;
20
+ max-width: 100%;
21
+ }
22
+
23
+ h2 {
24
+ font-size: 1.5rem;
25
+ font-weight: 700;
26
+ color: #111827;
27
+ }
28
+
29
+ .buttons {
30
+ display: flex;
31
+ gap: 0.5rem;
32
+ }
33
+
34
+ button {
35
+ display: flex;
36
+ align-items: center;
37
+ gap: 0.5rem;
38
+ padding: 0.5rem 1rem;
39
+ border-radius: 0.5rem;
40
+ font-size: 0.875rem;
41
+ font-weight: 600;
42
+ transition: all 0.2s;
43
+ }
44
+
45
+ .copy-btn {
46
+ background: #2563eb;
47
+ color: white;
48
+ }
49
+
50
+ .copy-btn:hover {
51
+ background: #1d4ed8;
52
+ }
53
+
54
+ .download-btn {
55
+ background: #059669;
56
+ color: white;
57
+ }
58
+
59
+ .download-btn:hover {
60
+ background: #047857;
61
+ }
62
+ </style>
63
+ <div class="container">
64
+ <div>
65
+ <h2 id="view-title">🚀 Bienvenue dans Rosalinda</h2>
66
+ </div>
67
+ <div class="buttons" id="action-buttons"></div>
68
+ </div>
69
+ `;
70
+
71
+ // Observe attribute changes
72
+ const observer = new MutationObserver(() => this.updateTitle());
73
+ observer.observe(this, { attributes: true });
74
+ }
75
+
76
+ static get observedAttributes() {
77
+ return ['current-view'];
78
+ }
79
+
80
+ attributeChangedCallback(name, oldValue, newValue) {
81
+ if (name === 'current-view') {
82
+ this.updateTitle();
83
+ }
84
+ }
85
+
86
+ updateTitle() {
87
+ const view = this.getAttribute('current-view') || 'home';
88
+ const titleMap = {
89
+ 'home': '🚀 Bienvenue dans Rosalinda',
90
+ 'chat': '💬 Chat avec Rosalinda',
91
+ 'projects': '📁 Mes Projets',
92
+ 'code': '💻 Code Généré',
93
+ 'library': '📚 Bibliothèque'
94
+ };
95
+
96
+ const title = this.shadowRoot.getElementById('view-title');
97
+ if (title) title.textContent = titleMap[view];
98
+
99
+ const buttons = this.shadowRoot.getElementById('action-buttons');
100
+ if (buttons) {
101
+ buttons.innerHTML = '';
102
+ if (view === 'code') {
103
+ buttons.innerHTML = `
104
+ <button class="copy-btn">
105
+ <i data-feather="copy"></i> Copier
106
+ </button>
107
+ <button class="download-btn">
108
+ <i data-feather="download"></i> Télécharger
109
+ </button>
110
+ `;
111
+ feather.replace();
112
+ }
113
+ }
114
+ }
115
+ }
116
+
117
+ customElements.define('custom-navbar', CustomNavbar);
components/sidebar.js ADDED
@@ -0,0 +1,335 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class CustomSidebar extends HTMLElement {
2
+ connectedCallback() {
3
+ this.attachShadow({ mode: 'open' });
4
+ this.render();
5
+
6
+ // Observe attribute changes
7
+ const observer = new MutationObserver(() => this.render());
8
+ observer.observe(this, { attributes: true });
9
+ }
10
+
11
+ static get observedAttributes() {
12
+ return ['collapsed', 'active-view'];
13
+ }
14
+
15
+ render() {
16
+ const collapsed = this.hasAttribute('collapsed');
17
+ const activeView = this.getAttribute('active-view') || 'home';
18
+
19
+ this.shadowRoot.innerHTML = `
20
+ <style>
21
+ :host {
22
+ display: block;
23
+ background: white;
24
+ border-right: 1px solid #e5e7eb;
25
+ transition: all 0.3s;
26
+ width: ${collapsed ? '5rem' : '18rem'};
27
+ height: 100vh;
28
+ overflow-y: auto;
29
+ flex-shrink: 0;
30
+ }
31
+
32
+ .logo {
33
+ padding: 1.5rem;
34
+ display: flex;
35
+ align-items: center;
36
+ justify-content: space-between;
37
+ border-bottom: 1px solid #e5e7eb;
38
+ }
39
+
40
+ .logo-content {
41
+ display: flex;
42
+ align-items: center;
43
+ gap: 0.75rem;
44
+ }
45
+
46
+ .logo-icon {
47
+ width: 2.5rem;
48
+ height: 2.5rem;
49
+ background: linear-gradient(135deg, #3b82f6, #8b5cf6);
50
+ border-radius: 0.5rem;
51
+ display: flex;
52
+ align-items: center;
53
+ justify-content: center;
54
+ color: white;
55
+ font-weight: bold;
56
+ font-size: 1.125rem;
57
+ }
58
+
59
+ .logo-text h1 {
60
+ font-weight: 700;
61
+ color: #111827;
62
+ font-size: 1rem;
63
+ }
64
+
65
+ .logo-text p {
66
+ font-size: 0.75rem;
67
+ color: #6b7280;
68
+ }
69
+
70
+ .toggle-btn {
71
+ padding: 0.5rem;
72
+ border-radius: 0.5rem;
73
+ transition: all 0.2s;
74
+ }
75
+
76
+ .toggle-btn:hover {
77
+ background: #f3f4f6;
78
+ }
79
+
80
+ .new-task {
81
+ padding: 1rem;
82
+ border-bottom: 1px solid #e5e7eb;
83
+ }
84
+
85
+ .new-task-btn {
86
+ width: 100%;
87
+ display: flex;
88
+ align-items: center;
89
+ justify-content: center;
90
+ gap: 0.5rem;
91
+ background: #111827;
92
+ color: white;
93
+ padding: 0.75rem;
94
+ border-radius: 0.5rem;
95
+ font-weight: 600;
96
+ transition: all 0.2s;
97
+ }
98
+
99
+ .new-task-btn:hover {
100
+ background: #1f2937;
101
+ }
102
+
103
+ .search {
104
+ padding: 1rem;
105
+ border-bottom: 1px solid #e5e7eb;
106
+ }
107
+
108
+ .search-container {
109
+ position: relative;
110
+ }
111
+
112
+ .search-icon {
113
+ position: absolute;
114
+ left: 0.75rem;
115
+ top: 0.75rem;
116
+ color: #9ca3af;
117
+ }
118
+
119
+ .search-input {
120
+ width: 100%;
121
+ padding-left: 2.5rem;
122
+ padding-right: 1rem;
123
+ padding-top: 0.5rem;
124
+ padding-bottom: 0.5rem;
125
+ background: #f9fafb;
126
+ border: 1px solid #e5e7eb;
127
+ border-radius: 0.5rem;
128
+ font-size: 0.875rem;
129
+ outline: none;
130
+ }
131
+
132
+ .search-input:focus {
133
+ border-color: #3b82f6;
134
+ box-shadow: 0 0 0 2px #bfdbfe;
135
+ }
136
+
137
+ nav {
138
+ flex: 1;
139
+ padding: 1rem;
140
+ display: flex;
141
+ flex-direction: column;
142
+ gap: 0.5rem;
143
+ }
144
+
145
+ .nav-item {
146
+ width: 100%;
147
+ display: flex;
148
+ align-items: center;
149
+ gap: 0.75rem;
150
+ padding: 0.75rem;
151
+ border-radius: 0.5rem;
152
+ transition: all 0.2s;
153
+ font-size: 0.875rem;
154
+ color: #4b5563;
155
+ }
156
+
157
+ .nav-item:hover {
158
+ background: #f3f4f6;
159
+ }
160
+
161
+ .nav-item.active {
162
+ background: #dbeafe;
163
+ color: #1d4ed8;
164
+ }
165
+
166
+ .projects {
167
+ padding: 1rem;
168
+ border-top: 1px solid #e5e7eb;
169
+ }
170
+
171
+ .projects-title {
172
+ font-weight: 600;
173
+ color: #111827;
174
+ margin-bottom: 0.75rem;
175
+ font-size: 0.875rem;
176
+ }
177
+
178
+ .project-item {
179
+ width: 100%;
180
+ text-align: left;
181
+ padding: 0.75rem;
182
+ border-radius: 0.5rem;
183
+ transition: all 0.2s;
184
+ font-size: 0.875rem;
185
+ margin-bottom: 0.5rem;
186
+ }
187
+
188
+ .project-item:hover {
189
+ background: #f3f4f6;
190
+ }
191
+
192
+ .project-item.active {
193
+ background: #d1fae5;
194
+ border-left: 4px solid #10b981;
195
+ }
196
+
197
+ .project-status {
198
+ width: 0.5rem;
199
+ height: 0.5rem;
200
+ border-radius: 50%;
201
+ display: inline-block;
202
+ margin-right: 0.5rem;
203
+ }
204
+
205
+ .project-status.active {
206
+ background: #10b981;
207
+ }
208
+
209
+ .project-status.archived {
210
+ background: #9ca3af;
211
+ }
212
+
213
+ .project-name {
214
+ font-weight: 500;
215
+ }
216
+
217
+ .project-time {
218
+ font-size: 0.75rem;
219
+ color: #6b7280;
220
+ margin-top: 0.25rem;
221
+ }
222
+
223
+ .footer {
224
+ padding: 1rem;
225
+ border-top: 1px solid #e5e7eb;
226
+ display: flex;
227
+ flex-direction: column;
228
+ gap: 0.5rem;
229
+ }
230
+
231
+ .footer-item {
232
+ width: 100%;
233
+ display: flex;
234
+ align-items: center;
235
+ gap: 0.75rem;
236
+ padding: 0.75rem;
237
+ border-radius: 0.5rem;
238
+ transition: all 0.2s;
239
+ font-size: 0.875rem;
240
+ color: #4b5563;
241
+ }
242
+
243
+ .footer-item:hover {
244
+ background: #f3f4f6;
245
+ }
246
+ </style>
247
+
248
+ <div class="logo">
249
+ ${!collapsed ? `
250
+ <div class="logo-content">
251
+ <div class="logo-icon">RC</div>
252
+ <div class="logo-text">
253
+ <h1>Rosalinda</h1>
254
+ <p>Workspace Codage</p>
255
+ </div>
256
+ </div>
257
+ ` : `
258
+ <div class="logo-icon">RC</div>
259
+ `}
260
+ <button class="toggle-btn" onclick="document.querySelector('custom-sidebar').toggleAttribute('collapsed')">
261
+ <i data-feather="${collapsed ? 'menu' : 'x'}"></i>
262
+ </button>
263
+ </div>
264
+
265
+ ${!collapsed ? `
266
+ <div class="new-task">
267
+ <button class="new-task-btn">
268
+ <i data-feather="plus"></i>
269
+ <span>Nouvelle tâche</span>
270
+ </button>
271
+ </div>
272
+
273
+ <div class="search">
274
+ <div class="search-container">
275
+ <i data-feather="search" class="search-icon"></i>
276
+ <input type="text" placeholder="Rechercher..." class="search-input">
277
+ </div>
278
+ </div>
279
+ ` : ''}
280
+
281
+ <nav>
282
+ ${this.createNavItem('home', 'Accueil', 'home', activeView === 'home', collapsed)}
283
+ ${this.createNavItem('chat', 'Chat Rosalinda', 'message-square', activeView === 'chat', collapsed)}
284
+ ${this.createNavItem('projects', 'Mes Projets', 'folder', activeView === 'projects', collapsed)}
285
+ ${this.createNavItem('code', 'Code Généré', 'code', activeView === 'code', collapsed)}
286
+ ${this.createNavItem('library', 'Bibliothèque', 'book', activeView === 'library', collapsed)}
287
+ </nav>
288
+
289
+ ${!collapsed ? `
290
+ <div class="projects">
291
+ <h3 class="projects-title">Vos Projets</h3>
292
+ ${this.createProjectItem(1, 'Portfolio Pro', 'active', '2 jours', false)}
293
+ ${this.createProjectItem(2, 'E-shop Mode', 'active', '5 jours', false)}
294
+ ${this.createProjectItem(3, 'App SaaS', 'archived', '10 jours', false)}
295
+ </div>
296
+
297
+ <div class="footer">
298
+ <button class="footer-item">
299
+ <i data-feather="settings"></i>
300
+ ${!collapsed ? '<span>Paramètres</span>' : ''}
301
+ </button>
302
+ <button class="footer-item">
303
+ <i data-feather="log-out"></i>
304
+ ${!collapsed ? '<span>Déconnexion</span>' : ''}
305
+ </button>
306
+ </div>
307
+ ` : ''}
308
+ `;
309
+
310
+ feather.replace();
311
+ }
312
+
313
+ createNavItem(id, label, icon, isActive, collapsed) {
314
+ return `
315
+ <button onclick="setView('${id}')" class="nav-item ${isActive ? 'active' : ''}">
316
+ <i data-feather="${icon}"></i>
317
+ ${!collapsed ? `<span>${label}</span>` : ''}
318
+ </button>
319
+ `;
320
+ }
321
+
322
+ createProjectItem(id, name, status, time, isActive) {
323
+ return `
324
+ <button onclick="setSelectedProject(${id})" class="project-item ${isActive ? 'active' : ''}">
325
+ <div class="flex items-center">
326
+ <span class="project-status ${status}"></span>
327
+ <span class="project-name">${name}</span>
328
+ </div>
329
+ <p class="project-time">${time}</p>
330
+ </button>
331
+ `;
332
+ }
333
+ }
334
+
335
+ customElements.define('custom-sidebar', CustomSidebar);
index.html CHANGED
@@ -1,19 +1,122 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="fr">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Rosalinda Code Wizard</title>
7
+ <link rel="stylesheet" href="style.css">
8
+ <script src="https://cdn.tailwindcss.com"></script>
9
+ <script src="https://unpkg.com/feather-icons"></script>
10
+ <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
11
+ <script src="components/navbar.js"></script>
12
+ <script src="components/sidebar.js"></script>
13
+ <script src="components/chat.js"></script>
14
+ </head>
15
+ <body class="bg-gray-50">
16
+ <div class="flex h-screen">
17
+ <!-- Sidebar -->
18
+ <custom-sidebar></custom-sidebar>
19
+
20
+ <!-- Main Content -->
21
+ <div class="flex-1 flex flex-col overflow-hidden">
22
+ <!-- Navbar -->
23
+ <custom-navbar></custom-navbar>
24
+
25
+ <!-- Dynamic Content -->
26
+ <main class="flex-1 overflow-y-auto p-6">
27
+ <div id="home-view" class="max-w-5xl mx-auto">
28
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
29
+ <!-- Left - Chat -->
30
+ <div class="bg-white rounded-xl border border-gray-200 p-6 shadow-sm">
31
+ <h3 class="text-xl font-bold text-gray-900 mb-4">Demander à Rosalinda</h3>
32
+ <div class="space-y-3">
33
+ <p class="text-sm text-gray-600">Exemples:</p>
34
+ <button onclick="setView('chat')" class="w-full text-left p-3 bg-gray-50 hover:bg-blue-50 rounded-lg transition border border-gray-200 text-sm">
35
+ ✨ Créer un site portfolio
36
+ </button>
37
+ <button onclick="setView('chat')" class="w-full text-left p-3 bg-gray-50 hover:bg-blue-50 rounded-lg transition border border-gray-200 text-sm">
38
+ 🛍️ Générer une page e-shop
39
+ </button>
40
+ <button onclick="setView('chat')" class="w-full text-left p-3 bg-gray-50 hover:bg-blue-50 rounded-lg transition border border-gray-200 text-sm">
41
+ 📱 Faire une landing page
42
+ </button>
43
+ <button onclick="setView('chat')" class="w-full text-left p-3 bg-gray-50 hover:bg-blue-50 rounded-lg transition border border-gray-200 text-sm">
44
+ 💻 Code React moderne
45
+ </button>
46
+ <button onclick="setView('chat')" class="w-full text-left p-3 bg-gray-50 hover:bg-blue-50 rounded-lg transition border border-gray-200 text-sm">
47
+ 🎨 Dashboard admin
48
+ </button>
49
+ </div>
50
+ </div>
51
+
52
+ <!-- Right - Features -->
53
+ <div class="space-y-4">
54
+ <div class="bg-gradient-to-br from-blue-500 to-purple-600 rounded-xl p-6 text-white shadow-lg">
55
+ <h3 class="text-lg font-bold mb-2">🤖 Rosalinda - Votre IA</h3>
56
+ <p class="text-sm">Génère du code complet, professionnel et fonctionnel instantanément. Propriétaire à 100%.</p>
57
+ </div>
58
+
59
+ <div class="bg-white rounded-xl border border-gray-200 p-6">
60
+ <h4 class="font-bold text-gray-900 mb-3">Capacités:</h4>
61
+ <ul class="space-y-2 text-sm text-gray-600">
62
+ <li>✅ HTML/CSS/JavaScript complet</li>
63
+ <li>✅ React & composants modernes</li>
64
+ <li>✅ Design responsive</li>
65
+ <li>✅ Intégrations API</li>
66
+ <li>✅ Export code prêt à l'emploi</li>
67
+ </ul>
68
+ </div>
69
+ </div>
70
+ </div>
71
+ </div>
72
+
73
+ <div id="chat-view" class="hidden max-w-4xl mx-auto">
74
+ <custom-chat></custom-chat>
75
+ </div>
76
+
77
+ <div id="projects-view" class="hidden">
78
+ <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
79
+ <div class="bg-white rounded-lg border border-gray-200 overflow-hidden hover:shadow-lg transition">
80
+ <div class="h-32 bg-gradient-to-br from-blue-500 to-purple-600"></div>
81
+ <div class="p-4">
82
+ <h4 class="font-bold text-gray-900">Portfolio Pro</h4>
83
+ <p class="text-xs text-gray-500 mb-4">2 jours</p>
84
+ <div class="flex gap-2">
85
+ <button onclick="setView('chat')" class="flex-1 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition font-semibold text-sm">
86
+ Éditer
87
+ </button>
88
+ <button onclick="setView('code')" class="flex-1 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700 transition font-semibold text-sm">
89
+ Code
90
+ </button>
91
+ </div>
92
+ </div>
93
+ </div>
94
+ <!-- More projects... -->
95
+ </div>
96
+ </div>
97
+
98
+ <div id="code-view" class="hidden max-w-6xl mx-auto">
99
+ <div class="bg-white rounded-xl border border-gray-200 overflow-hidden">
100
+ <div class="bg-gray-900 text-gray-100 p-4 overflow-x-auto">
101
+ <pre class="text-sm font-mono" id="generated-code"></pre>
102
+ </div>
103
+ </div>
104
+ <button class="mt-4 px-6 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700 transition font-semibold">
105
+ 💾 Sauvegarder dans le projet
106
+ </button>
107
+ </div>
108
+
109
+ <div id="library-view" class="hidden grid grid-cols-2 md:grid-cols-4 gap-4">
110
+ <!-- Library items... -->
111
+ </div>
112
+ </main>
113
+ </div>
114
+ </div>
115
+
116
+ <script src="script.js"></script>
117
+ <script>
118
+ feather.replace();
119
+ </script>
120
+ <script src="https://huggingface.co/deepsite/deepsite-badge.js"></script>
121
+ </body>
122
+ </html>
script.js ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // View management
2
+ function setView(view) {
3
+ document.querySelectorAll('[id$="-view"]').forEach(el => {
4
+ el.classList.add('hidden');
5
+ });
6
+ document.getElementById(`${view}-view`).classList.remove('hidden');
7
+
8
+ // Update active state in sidebar
9
+ document.querySelectorAll('custom-sidebar').forEach(sidebar => {
10
+ sidebar.setAttribute('active-view', view);
11
+ });
12
+ }
13
+
14
+ // Chat functionality
15
+ let messages = [];
16
+
17
+ function sendMessage() {
18
+ const input = document.getElementById('chat-input');
19
+ if (!input.value.trim()) return;
20
+
21
+ // Add user message
22
+ const userMessage = {
23
+ id: Date.now(),
24
+ user: 'Vous',
25
+ type: 'user',
26
+ text: input.value,
27
+ time: new Date().toLocaleTimeString('fr-FR', { hour: '2-digit', minute: '2-digit' })
28
+ };
29
+ messages.push(userMessage);
30
+ renderMessages();
31
+ input.value = '';
32
+
33
+ // Simulate AI response
34
+ setTimeout(() => {
35
+ const aiResponse = {
36
+ id: Date.now() + 1,
37
+ user: 'Rosalinda',
38
+ type: 'assistant',
39
+ text: generateResponse(input.value),
40
+ time: new Date().toLocaleTimeString('fr-FR', { hour: '2-digit', minute: '2-digit' })
41
+ };
42
+ messages.push(aiResponse);
43
+ renderMessages();
44
+ }, 1000);
45
+ }
46
+
47
+ function generateResponse(userInput) {
48
+ // This would be replaced with actual API calls to Claude or similar
49
+ if (userInput.includes('portfolio')) {
50
+ return "Voici un code HTML/CSS complet pour un portfolio professionnel:\n
style.css CHANGED
@@ -1,28 +1,52 @@
 
 
1
  body {
2
- padding: 2rem;
3
- font-family: -apple-system, BlinkMacSystemFont, "Arial", sans-serif;
 
 
 
 
 
 
 
 
 
4
  }
5
 
6
- h1 {
7
- font-size: 16px;
8
- margin-top: 0;
9
  }
10
 
11
- p {
12
- color: rgb(107, 114, 128);
13
- font-size: 15px;
14
- margin-bottom: 10px;
15
- margin-top: 5px;
16
  }
17
 
18
- .card {
19
- max-width: 620px;
20
- margin: 0 auto;
21
- padding: 16px;
22
- border: 1px solid lightgray;
23
- border-radius: 16px;
24
  }
25
 
26
- .card p:last-child {
27
- margin-bottom: 0;
28
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
2
+
3
  body {
4
+ font-family: 'Inter', sans-serif;
5
+ }
6
+
7
+ /* Custom scrollbar */
8
+ ::-webkit-scrollbar {
9
+ width: 8px;
10
+ height: 8px;
11
+ }
12
+
13
+ ::-webkit-scrollbar-track {
14
+ background: #f1f1f1;
15
  }
16
 
17
+ ::-webkit-scrollbar-thumb {
18
+ background: #888;
19
+ border-radius: 4px;
20
  }
21
 
22
+ ::-webkit-scrollbar-thumb:hover {
23
+ background: #555;
 
 
 
24
  }
25
 
26
+ /* Animation for chat messages */
27
+ @keyframes fadeIn {
28
+ from { opacity: 0; transform: translateY(10px); }
29
+ to { opacity: 1; transform: translateY(0); }
 
 
30
  }
31
 
32
+ .chat-message {
33
+ animation: fadeIn 0.3s ease-out;
34
  }
35
+
36
+ /* Gradient text */
37
+ .gradient-text {
38
+ background: linear-gradient(90deg, #3b82f6, #8b5cf6);
39
+ -webkit-background-clip: text;
40
+ background-clip: text;
41
+ color: transparent;
42
+ }
43
+
44
+ /* Pulse animation for loading */
45
+ @keyframes pulse {
46
+ 0%, 100% { opacity: 1; }
47
+ 50% { opacity: 0.5; }
48
+ }
49
+
50
+ .pulse {
51
+ animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
52
+ }