File size: 15,912 Bytes
b4676a0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86918ad
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b4676a0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
// Theme: default dark (fallback for undefined)
let currentTheme = 'dark';
let currentTab = 'code';
let messageCount = 0;

// Elements
const typingIndicator = document.getElementById('typingIndicator');
const iaOutput = document.getElementById('iaOutput');
const codeInput = document.getElementById('codeInput');
const sidebar = document.getElementById('sidebar');

// Tab switching
document.querySelectorAll('.input-tab').forEach(tab => {
  tab.addEventListener('click', () => changeTab(tab.dataset.tab));
});

function changeTab(tabName) {
  currentTab = tabName;
  document.querySelectorAll('.input-tab').forEach(tab => {
    tab.classList.toggle('active', tab.dataset.tab === tabName);
  });

  const placeholders = {
    code: 'Écrivez votre code ou instruction ici... Exemple: Crée une fonction Python qui calcule la factorielle d\'un nombre',
    image: 'Décrivez l\'image que vous souhaitez générer... Exemple: Un logo futuriste pour une application de codage',
    video: 'Décrivez la vidéo que vous souhaitez générer... Exemple: Un tutoriel de 1 minute sur les fonctions en JavaScript',
    text: 'Écrivez votre demande textuelle... Exemple: Explique-moi le pattern Builder en programmation',
  };
  codeInput.placeholder = placeholders[tabName] || placeholders.code;
}

// Use snippet
document.querySelectorAll('.snippet-card').forEach(card => {
  card.addEventListener('click', () => useSnippet(card.dataset.snippet));
});

function useSnippet(type) {
  const snippets = {
    react: `// Composant React fonctionnel
function Welcome(props) {
  const [count, setCount] = useState(0);
  
  return (
    <div className="welcome-container">
      <h1>Bonjour, {props.name} !</h1>
      <p>Vous avez cliqué {count} fois</p>
      <button onClick={() => setCount(count + 1)}>
        Cliquez ici
      </button>
    </div>
  );
}`,
    python: `# Fonction Python avec typage et docstring
def fibonacci_sequence(n: int) -> list:
    """
    Génère une séquence de Fibonacci jusqu'à n termes.
    
    Args:
        n (int): Nombre de termes à générer
        
    Returns:
        list: Séquence de Fibonacci
    """
    if n <= 0:
        return []
    elif n == 1:
        return [0]
    
    sequence = [0, 1]
    for i in range(2, n):
        sequence.append(sequence[i-1] + sequence[i-2])
    
    return sequence

# Exemple d'utilisation
if __name__ == "__main__":
    print(fibonacci_sequence(10))`,
    factorial: `def factorielle(n):
    """
    Calcule la factorielle d'un nombre entier non négatif.

    Args:
        n (int): Le nombre dont on veut calculer la factorielle.

    Returns:
        int: La factorielle de n.
        str: Un message d'erreur si n est négatif.
    """
    if n < 0:
        return "La factorielle n'est pas définie pour les nombres négatifs."
    elif n == 0:
        return 1
    else:
        res = 1
        for i in range(1, n + 1):
            res *= i
        return res

# Exemple d'utilisation :
print(f"La factorielle de 5 est : {factorielle(5)}")  # Output: 120
print(f"La factorielle de 0 est : {factorielle(0)}")  # Output: 1
print(f"La factorielle de -3 est : {factorielle(-3)}") # Output: La factorielle n'est pas définie pour les nombres négatifs."`,
    stack: `class Pile:
    """
    Implémentation d'une structure de données de type Pile (LIFO).
    """
    def __init__(self):
        """Initialise une nouvelle pile vide."""
        self.elements = []

    def est_vide(self):
        """Vérifie si la pile est vide."""
        return len(self.elements) == 0

    def empiler(self, element):
        """Ajoute un élément au sommet de la pile."""
        self.elements.append(element)
        print(f"'{element}' a été empilé.")

    def depiler(self):
        """
        Retire et retourne l'élément au sommet de la pile.
        Lève une erreur si la pile est vide.
        """
        if self.est_vide():
            raise IndexError("Impossible de dépiler d'une pile vide.")
        element = self.elements.pop()
        print(f"'{element}' a été dépilé.")
        return element

    def sommet(self):
        """
        Retourne l'élément au sommet de la pile sans le retirer.
        Lève une erreur si la pile est vide.
        """
        if self.est_vide():
            raise IndexError("La pile est vide, pas de sommet.")
        return self.elements[-1]

    def taille(self):
        """Retourne le nombre d'éléments dans la pile."""
        return len(self.elements)

# Exemple d'utilisation :
ma_pile = Pile()
print(f"La pile est vide : {ma_pile.est_vide()}")

ma_pile.empiler(10)
ma_pile.empiler(20)
ma_pile.empiler(30)

print(f"Taille de la pile : {ma_pile.taille()}")
print(f"Sommet de la pile : {ma_pile.sommet()}")

ma_pile.depiler()
print(f"Taille de la pile après dépilage : {ma_pile.taille()}")
print(f"Sommet de la pile après dépilage : {ma_pile.sommet()}")

ma_pile.depiler()
ma_pile.depiler()
print(f"La pile est vide : {ma_pile.est_vide()}")

try:
    ma_pile.depiler()
except IndexError as e:
    print(e)`
};
  codeInput.value = snippets[type] || '';
  codeInput.focus();
  addMessage(`J'utilise le snippet ${type}`, 'user');
}

// Add message to chat
function addMessage(content, sender) {
  messageCount++;
  const messageDiv = document.createElement('div');
  messageDiv.className = `message ${sender} animate-appear`;

  const now = new Date();
  const timeString = now.toLocaleTimeString('fr-FR', { hour: '2-digit', minute: '2-digit' });

  messageDiv.innerHTML = `
    <div class="message-header">
      <i class="fas fa-${sender === 'user' ? 'user' : 'robot'}"></i>
      <strong>${sender === 'user' ? 'Vous' : 'IA Rosalinda'}</strong>
      <span class="text-slate-400 text-xs">${timeString}</span>
    </div>
    <div class="message-content">${content}</div>
  `;

  iaOutput.appendChild(messageDiv);
  iaOutput.scrollTop = iaOutput.scrollHeight;

  return messageDiv;
}

// Simulate IA response
function simulateIAResponse(userInput) {
  typingIndicator.style.display = 'flex';

  const responses = {
    code: [
      `J'ai analysé votre code. Voici une version améliorée :\n\n\`\`\`python\ndef factorial(n):\n    """Calcule la factorielle de n de manière récursive"""\n    if n <= 1:\n        return 1\n    return n * factorial(n-1)\n\n# Version itérative (plus efficace)\ndef factorial_iterative(n):\n    result = 1\n    for i in range(2, n+1):\n        result *= i\n    return result\n\nprint(factorial(5))  # 120\n\`\`\`\n\nJ'ai également généré une visualisation de l'algorithme.`,
      `Voici le code demandé :\n\n\`\`\`javascript\n// Générateur de mots de passe sécurisés\nfunction generatePassword(length = 12) {\n  const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*";\n  let password = "";\n  \n  for (let i = 0; i < length; i++) {\n    const randomIndex = Math.floor(Math.random() * chars.length);\n    password += chars[randomIndex];\n  }\n  \n  return password;\n}\n\n// Utilisation\nconsole.log("Mot de passe généré:", generatePassword());\n\`\`\``,
      `Je vois que vous essayez de créer un composant React. Voici une structure recommandée :\n\n\`\`\`jsx\nimport React, { useState, useEffect } from 'react';\n\nexport default function UserDashboard({ userId }) {\n  const [userData, setUserData] = useState(null);\n  const [loading, setLoading] = useState(true);\n  \n  useEffect(() => {\n    // Récupérer les données utilisateur\n    fetchUserData(userId).then(data => {\n      setUserData(data);\n      setLoading(false);\n    });\n  }, [userId]);\n  \n  if (loading) return <div>Chargement...</div>;\n  \n  return (\n    <div className="dashboard">\n      <h1>Tableau de bord de {userData.name}</h1>\n      <div className="stats">\n        <StatCard title="Projets" value={userData.projectCount} />\n        <StatCard title="Tâches" value={userData.taskCount} />\n        <StatCard title="Contributions" value={userData.contributions} />\n      </div>\n    </div>\n  );\n}\n\`\`\``
    ],
    image: [
      `J'ai généré une image basée sur votre description. Voici ce que j'ai créé :\n\n**Image générée :** Logo futuriste "Espace Codage"\n\n*Caractéristiques :*\n- Forme géométrique abstraite combinant un cube et un cerveau\n- Dégradé de bleu électrique à violet\n- Éléments de code en filigrane\n- Typographie moderne et lisible\n\nL'image a été sauvegardée dans votre dossier "Générations".`,
      `Voici l'image que j'ai créée pour vous :\n\n**"Interface de développement futuriste"**\n\nCette image représente un environnement de codage avancé avec :\n- Plusieurs écrans affichant du code en temps réel\n- Un schéma 3D d'architecture logicielle\n- Des éléments holographiques interactifs\n- Palette de couleurs : bleu nocturne, cyan et magenta\n\nL'image est au format PNG 1920x1080 et peut être utilisée comme fond d'écran.`
    ],
    video: [
      `J'ai généré une vidéo explicative de 1 minute basée sur votre code. Voici le résultat :\n\n**Vidéo : "Comprendre les fonctions JavaScript en 60 secondes"**\n\n*Contenu de la vidéo :*\n- Introduction aux fonctions (0:00-0:15)\n- Syntaxe de base (0:15-0:30)\n- Paramètres et valeurs de retour (0:30-0:45)\n- Exemple pratique (0:45-1:00)\n\nLa vidéo inclut des animations de code, des explications audio et des visuels clairs. Elle est disponible au téléchargement.`,
      `Votre vidéo tutorielle a été générée avec succès !\n\n**"Créer une API REST avec Node.js - Tutoriel"**\n\nDurée : 3 minutes 45 secondes\nFormat : MP4 1080p\n\n*Sections :*\n1. Configuration du projet (0:00-0:45)\n2. Création du serveur Express (0:45-1:30)\n3. Définition des routes API (1:30-2:15)\n4. Connexion à la base de données (2:15-3:00)\n5. Test et déploiement (3:00-3:45)\n\nLa vidéo est prête à être visionnée et partagée.`
    ],
    text: [
      `Le pattern Builder est un pattern de conception qui permet de construire des objets complexes étape par étape. Il sépare la construction d'un objet complexe de sa représentation, de sorte que le même processus de construction puisse créer différentes représentations.\n\n**Avantages :**\n- Contrôle fin sur le processus de construction\n- Réutilisable pour différents produits\n- Code plus lisible pour les objets complexes\n- Respect du principe de responsabilité unique\n\n**Exemple en Python :**\n\n\`\`\`python\nfrom abc import ABC, abstractmethod\n\nclass ConstructeurMaison(ABC):\n    @abstractmethod\n    def construire_fondation(self): pass\n    @abstractmethod\n    def construire_murs(self): pass\n    @abstractmethod\n    def construire_toit(self): pass\n\nclass ConstructeurMaisonModerne(ConstructeurMaison):\n    def __init__(self):\n        self.maison = Maison()\n    \n    def construire_fondation(self):\n        self.maison.ajouter_partie("Fondation en béton armé")\n    \n    def construire_murs(self):\n        self.maison.ajouter_partie("Murs en verre et acier")\n    \n    def construire_toit(self):\n        self.maison.ajouter_partie("Toit végétalisé")\n\`\`\``,
      `Voici une explication détaillée sur les hooks React :\n\nLes hooks sont des fonctions qui permettent d'utiliser l'état et d'autres fonctionnalités de React dans les composants fonctionnels. Ils ont été introduits dans React 16.8.\n\n**Hooks principaux :**\n1. \`useState\` - Gérer l'état local\n2. \`useEffect\` - Effets de bord (remplace lifecycle methods)\n3. \`useContext\` - Accéder au contexte React\n4. \`useReducer\` - Gestion d'état complexe\n5. \`useCallback\` - Mémoriser des fonctions\n6. \`useMemo\` - Mémoriser des valeurs calculées\n\n**Règles des hooks :**\n- N'appelez les hooks qu'au niveau racine des fonctions\n- N'appelez les hooks que depuis des fonctions React\n\n**Exemple :**\n\n\`\`\`jsx\nimport React, { useState, useEffect } from 'react';\n\nfunction Compteur() {\n  const [count, setCount] = useState(0);\n  \n  useEffect(() => {\n    document.title = \`Vous avez cliqué \${count} fois\`;\n  }, [count]); // Se ré-exécute quand count change\n  \n  return (\n    <div>\n      <p>Vous avez cliqué {count} fois</p>\n      <button onClick={() => setCount(count + 1)}>\n        Cliquez ici\n      </button>\n    </div>\n  );\n}\n\`\`\``
    ]
  };

  const tabResponses = responses[currentTab] || responses.code;
  const randomResponse = tabResponses[Math.floor(Math.random() * tabResponses.length)];

  setTimeout(() => {
    typingIndicator.style.display = 'none';
    const msg = addMessage(randomResponse, 'ia');

    if (currentTab === 'code') {
      const actionDiv = document.createElement('div');
      actionDiv.className = 'flex gap-2 mt-3';
      actionDiv.innerHTML = `
        <button class="secondary-btn text-sm px-3 py-2" onclick="executeCode()">
          <i class="fas fa-play mr-1"></i> Exécuter le code
        </button>
        <button class="secondary-btn text-sm px-3 py-2" onclick="saveCode()">
          <i class="fas fa-save mr-1"></i> Sauvegarder
        </button>
      `;
      msg.querySelector('.message-content').appendChild(actionDiv);
    }
  }, 2000 + Math.random() * 2000);
}

// Send input to IA
function sendToIA() {
  const userInput = codeInput.value.trim();
  if (!userInput) {
    alert('Veuillez entrer du texte avant d\'envoyer à l\'IA.');
    return;
  }
  addMessage(userInput, 'user');
  codeInput.value = '';
  simulateIAResponse(userInput);
}

// Clear input
function clearInput() {
  codeInput.value = '';
}

// Execute code (simulation)
function executeCode() {
  addMessage(`Exécution du code en cours...\n\n**Résultat :**\n\`\`\`\n>>> Calcul de la factorielle de 5\n120\n\n>>> Génération de mot de passe\n"X7g!9kLp@2qW"\n\`\`\`\n\nLe code a été exécuté avec succès !`, 'ia');
}

// Save code (simulation)
function saveCode() {
  addMessage(`Code sauvegardé dans votre dossier "Projets/Espace Codage/scripts/".\n\n**Fichier :** script_${Date.now()}.py\n**Taille :** 1.2 KB\n\nVous pouvez y accéder depuis le menu "Projets".`, 'ia');
}

// Theme toggle
const themeToggle = document.getElementById('themeToggle');
themeToggle.addEventListener('click', () => {
  const html = document.documentElement;
  if (html.classList.contains('dark')) {
    html.classList.remove('dark');
    html.classList.add('light');
    currentTheme = 'light';
    themeToggle.innerHTML = '<i class="fas fa-sun"></i>';
  } else {
    html.classList.remove('light');
    html.classList.add('dark');
    currentTheme = 'dark';
    themeToggle.innerHTML = '<i class="fas fa-moon"></i>';
  }
});

// Buttons
document.getElementById('sendBtn').addEventListener('click', sendToIA);
document.getElementById('clearBtn').addEventListener('click', clearInput);
document.getElementById('newChatBtn').addEventListener('click', () => {
  iaOutput.innerHTML = '';
  addMessage('Nouvelle conversation démarrée. Comment puis-je vous aider ?', 'ia');
});
document.getElementById('settingsBtn').addEventListener('click', () => {
  addMessage('Les paramètres IA ne sont pas encore disponibles. Bientôt disponible !', 'ia');
});
document.getElementById('helpBtn').addEventListener('click', () => {
  addMessage('Besoin d\'aide ? Essayez de décrire votre tâche :\n- Génération de code (onglet Code)\n- Création d\'image (onglet Image)\n- Génération de vidéo (onglet Vidéo)\n- Explications théoriques (onglet Texte)', 'ia');
});

// Keyboard shortcut Ctrl+Enter
codeInput.addEventListener('keydown', (e) => {
  if (e.ctrlKey && e.key === 'Enter') {
    sendToIA();
  }
});

// Initial welcome message
document.addEventListener('DOMContentLoaded', () => {
  setTimeout(() => {
    addMessage("Je suis prête à travailler avec vous ! N'hésitez pas à me demander de générer du code, des images ou des vidéos explicatives. Je peux également analyser votre code existant et suggérer des améliorations.", 'ia');
  }, 1500);
});