// 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 (
Bonjour, {props.name} !
Vous avez cliqué {count} fois
);
}`,
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 = `
`;
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
Chargement...
;\n \n return (\n
\n
Tableau de bord de {userData.name}
\n
\n \n \n \n
\n
\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
\n
Vous avez cliqué {count} fois
\n \n
\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 = `
`;
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 = '';
} else {
html.classList.remove('light');
html.classList.add('dark');
currentTheme = 'dark';
themeToggle.innerHTML = '';
}
});
// 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);
});