Spaces:
Running
Running
| <html lang="fr"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Grok Chat - Sandbox Creator</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| /* Custom scrollbar */ | |
| ::-webkit-scrollbar { | |
| width: 8px; | |
| } | |
| ::-webkit-scrollbar-track { | |
| background: #1e293b; | |
| } | |
| ::-webkit-scrollbar-thumb { | |
| background: #64748b; | |
| border-radius: 4px; | |
| } | |
| ::-webkit-scrollbar-thumb:hover { | |
| background: #94a3b8; | |
| } | |
| /* Pulse animation for sandbox indicator */ | |
| @keyframes pulse { | |
| 0%, 100% { | |
| opacity: 1; | |
| } | |
| 50% { | |
| opacity: 0.5; | |
| } | |
| } | |
| .animate-pulse { | |
| animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; | |
| } | |
| /* Gradient border for sandbox */ | |
| .gradient-border { | |
| position: relative; | |
| border-radius: 0.5rem; | |
| overflow: hidden; | |
| } | |
| .gradient-border::before { | |
| content: ""; | |
| position: absolute; | |
| top: -2px; | |
| left: -2px; | |
| right: -2px; | |
| bottom: -2px; | |
| background: linear-gradient(45deg, #14b8a6, #0ea5e9, #a855f7); | |
| z-index: -1; | |
| border-radius: 0.6rem; | |
| animation: rotate 4s linear infinite; | |
| } | |
| @keyframes rotate { | |
| 0% { | |
| filter: hue-rotate(0deg); | |
| } | |
| 100% { | |
| filter: hue-rotate(360deg); | |
| } | |
| } | |
| /* Smooth transitions */ | |
| .smooth-transition { | |
| transition: all 0.3s ease; | |
| } | |
| /* Code block styles */ | |
| .code-block { | |
| font-family: Monaco, Consolas, "Courier New", monospace; | |
| font-size: 0.85rem; | |
| line-height: 1.5; | |
| white-space: pre-wrap; | |
| word-break: break-word; | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-slate-900 text-slate-100 min-h-screen flex flex-col"> | |
| <!-- Header --> | |
| <header class="bg-slate-800 border-b border-slate-700 p-4 flex items-center justify-between"> | |
| <div class="flex items-center space-x-2"> | |
| <i class="fas fa-robot text-2xl text-emerald-500"></i> | |
| <h1 class="text-xl font-bold bg-gradient-to-r from-emerald-500 to-cyan-400 bg-clip-text text-transparent"> | |
| Grok AI Sandbox | |
| </h1> | |
| </div> | |
| <div class="flex items-center space-x-4"> | |
| <button id="sandboxBtn" class="flex items-center space-x-2 bg-slate-700 hover:bg-slate-600 px-3 py-1 rounded-md smooth-transition"> | |
| <i class="fas fa-box-open text-amber-400"></i> | |
| <span>Sandbox</span> | |
| <span class="h-2 w-2 rounded-full bg-emerald-400 animate-pulse"></span> | |
| </button> | |
| <div class="relative group"> | |
| <button id="userMenuBtn" class="w-8 h-8 rounded-full bg-slate-700 flex items-center justify-center hover:bg-slate-600 smooth-transition"> | |
| <i class="fas fa-user"></i> | |
| </button> | |
| <div id="userMenu" class="absolute right-0 mt-2 w-48 bg-slate-800 rounded-md shadow-lg py-1 z-20 hidden group-hover:block border border-slate-700"> | |
| <a href="#account" class="block px-4 py-2 text-sm hover:bg-slate-700 smooth-transition">Mon compte</a> | |
| <a href="#settings" class="block px-4 py-2 text-sm hover:bg-slate-700 smooth-transition">Paramètres</a> | |
| <a href="#logout" class="block px-4 py-2 text-sm hover:bg-slate-700 text-rose-400 smooth-transition">Déconnexion</a> | |
| </div> | |
| </div> | |
| </div> | |
| </header> | |
| <div class="flex flex-1 overflow-hidden"> | |
| <!-- Sidebar --> | |
| <aside class="w-64 bg-slate-800 border-r border-slate-700 p-4 flex flex-col"> | |
| <div class="mb-6"> | |
| <h2 class="text-sm font-semibold text-slate-400 mb-2 uppercase tracking-wider">Projets récents</h2> | |
| <ul class="space-y-1"> | |
| <li> | |
| <a href="#project/dashboard" class="flex items-center space-x-2 p-2 rounded-md hover:bg-slate-700 smooth-transition"> | |
| <i class="fas fa-project-diagram text-blue-400 text-sm"></i> | |
| <span class="text-sm">Dashboard Admin</span> | |
| </a> | |
| </li> | |
| <li> | |
| <a href="#project/ecommerce-api" class="flex items-center space-x-2 p-2 rounded-md hover:bg-slate-700 smooth-transition"> | |
| <i class="fas fa-project-diagram text-purple-400 text-sm"></i> | |
| <span class="text-sm">API E-commerce</span> | |
| </a> | |
| </li> | |
| <li> | |
| <a href="#project/twitter-bot" class="flex items-center space-x-2 p-2 rounded-md hover:bg-slate-700 smooth-transition"> | |
| <i class="fas fa-project-diagram text-emerald-400 text-sm"></i> | |
| <span class="text-sm">Bot Twitter</span> | |
| </a> | |
| </li> | |
| </ul> | |
| </div> | |
| <div> | |
| <h2 class="text-sm font-semibold text-slate-400 mb-2 uppercase tracking-wider">Créer nouveau</h2> | |
| <button id="newProjectBtn" class="w-full bg-emerald-600 hover:bg-emerald-500 text-white py-2 px-3 rounded-md text-sm flex items-center justify-center space-x-2 smooth-transition"> | |
| <i class="fas fa-plus"></i> | |
| <span>Nouveau projet</span> | |
| </button> | |
| <div class="mt-4 p-3 bg-slate-700 rounded-md"> | |
| <h3 class="text-xs font-semibold text-slate-300 mb-1">Modèles</h3> | |
| <p class="text-[0.7rem] text-slate-400 mb-2">Démarrez rapidement avec un modèle préconfiguré</p> | |
| <select id="templateSelect" class="w-full bg-slate-800 border border-slate-600 rounded-md px-2 py-1 text-sm focus:outline-none focus:ring-1 focus:ring-emerald-400 smooth-transition"> | |
| <option value="">Choisir un modèle...</option> | |
| <option value="react">Application React</option> | |
| <option value="node">API Node.js</option> | |
| <option value="static">Site Statique</option> | |
| <option value="discord">Bot Discord</option> | |
| <option value="dashboard">Dashboard</option> | |
| </select> | |
| </div> | |
| </div> | |
| <div class="mt-auto pt-4 border-t border-slate-700"> | |
| <div class="flex items-center justify-between text-sm text-slate-400"> | |
| <span>Crédits Sandbox</span> | |
| <span class="font-bold text-emerald-400">12/50</span> | |
| </div> | |
| <div class="w-full bg-slate-700 h-1.5 rounded-full mt-1"> | |
| <div class="bg-emerald-500 h-1.5 rounded-full smooth-transition" style="width: 24%"></div> | |
| </div> | |
| </div> | |
| </aside> | |
| <!-- Main Content --> | |
| <main class="flex-1 flex flex-col overflow-hidden"> | |
| <!-- Chat container --> | |
| <div class="flex-1 overflow-y-auto p-4 space-y-4" id="chatContainer"> | |
| <!-- Welcome message --> | |
| <div class="flex items-start space-x-2 max-w-3xl mx-auto"> | |
| <div class="w-8 h-8 rounded-full bg-emerald-500 flex items-center justify-center flex-shrink-0"> | |
| <i class="fas fa-robot text-white text-sm"></i> | |
| </div> | |
| <div class="bg-slate-800 p-4 rounded-lg rounded-tl-none shadow-md flex-1"> | |
| <h3 class="font-bold text-emerald-400 mb-1">Grok AI</h3> | |
| <p class="text-sm">Bonjour ! Je suis Grok AI, votre assistant pour créer des applications dans le sandbox. Je peux vous aider à générer du code, configurer des environnements et résoudre des problèmes. Comment puis-je vous aider aujourd'hui ?</p> | |
| <div class="mt-3 pt-3 border-t border-slate-700"> | |
| <p class="text-xs text-slate-400 mb-2">Exemples rapides :</p> | |
| <div class="flex flex-wrap gap-2"> | |
| <button class="quick-prompt text-xs bg-slate-700 hover:bg-slate-600 px-2 py-1 rounded smooth-transition">Créer une app React</button> | |
| <button class="quick-prompt text-xs bg-slate-700 hover:bg-slate-600 px-2 py-1 rounded smooth-transition">Générer une API REST</button> | |
| <button class="quick-prompt text-xs bg-slate-700 hover:bg-slate-600 px-2 py-1 rounded smooth-transition">Configurer une base de données</button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Input area --> | |
| <div class="border-t border-slate-700 p-4"> | |
| <div class="max-w-3xl mx-auto"> | |
| <div class="relative"> | |
| <textarea id="messageInput" rows="1" class="w-full bg-slate-800 border border-slate-700 rounded-lg px-4 py-3 pr-10 focus:outline-none focus:ring-1 focus:ring-emerald-400 resize-none smooth-transition" placeholder="Envoyez un message à Grok..." maxlength="2000"></textarea> | |
| <button id="sendBtn" class="absolute right-2 bottom-2 w-8 h-8 rounded-full bg-emerald-600 hover:bg-emerald-500 flex items-center justify-center smooth-transition"> | |
| <i class="fas fa-paper-plane text-sm"></i> | |
| </button> | |
| </div> | |
| <div class="mt-2 flex items-center justify-between text-xs text-slate-500"> | |
| <div class="flex items-center space-x-2"> | |
| <button id="generateWithAI" class="flex items-center space-x-1 hover:text-slate-300 smooth-transition"> | |
| <i class="fas fa-magic"></i> | |
| <span>Générer avec IA</span> | |
| </button> | |
| <button id="runInSandbox" class="flex items-center space-x-1 hover:text-slate-300 smooth-transition"> | |
| <i class="fas fa-terminal"></i> | |
| <span>Exécuter dans Sandbox</span> | |
| </button> | |
| </div> | |
| <span> | |
| <span id="charCount">0</span>/2000 | |
| </span> | |
| </div> | |
| </div> | |
| </div> | |
| </main> | |
| <!-- Sandbox Panel --> | |
| <div id="sandboxPanel" class="hidden w-80 bg-slate-800 border-l border-slate-700 p-4 flex flex-col"> | |
| <div class="flex items-center justify-between mb-4"> | |
| <h2 class="font-semibold text-lg flex items-center space-x-2"> | |
| <i class="fas fa-box-open text-amber-400"></i> | |
| <span>Sandbox</span> | |
| </h2> | |
| <button id="closeSandboxBtn" class="text-slate-400 hover:text-white smooth-transition"> | |
| <i class="fas fa-times"></i> | |
| </button> | |
| </div> | |
| <div class="gradient-border p-0.5 rounded-lg mb-4"> | |
| <div class="bg-slate-800 rounded-md p-3"> | |
| <div class="flex items-center space-x-2 mb-2"> | |
| <div class="w-2 h-2 rounded-full bg-emerald-4 animate-pulse"></div> | |
| <span class="text-xs font-semibold text-emerald-400">CONNECTÉ</span> | |
| </div> | |
| <p class="text-xs text-slate-300">Environnement Sandbox Node.js v18.12.1</p> | |
| </div> | |
| </div> | |
| <div class="mb-4"> | |
| <h3 class="text-sm font-semibold text-slate-400 mb-2">Fichiers du projet</h3> | |
| <div class="bg-slate-900 rounded-md p-2 text-sm font-mono"> | |
| <div class="flex items-center space-x-1 text-amber-300 py-1 pl-1 hover:bg-slate-700 rounded cursor-pointer smooth-transition"> | |
| <i class="fas fa-folder-open text-xs"></i> | |
| <span>/projet</span> | |
| </div> | |
| <div class="pl-5 space-y-1"> | |
| <div class="flex items-center space-x-1 text-blue-300 hover:bg-slate-700 px-1 py-0.5 rounded cursor-pointer smooth-transition"> | |
| <i class="fas fa-file text-xs"></i> | |
| <span>index.js</span> | |
| </div> | |
| <div class="flex items-center space-x-1 text-blue-300 hover:bg-slate-700 px-1 py-0.5 rounded cursor-pointer smooth-transition"> | |
| <i class="fas fa-file text-xs"></i> | |
| <span>package.json</span> | |
| </div> | |
| <div class="flex items-center space-x-1 text-blue-300 hover:bg-slate-700 px-1 py-0.5 rounded cursor-pointer smooth-transition"> | |
| <i class="fas fa-file text-xs"></i> | |
| <span>README.md</span> | |
| </div> | |
| <div class="flex items-center space-x-1 text-green-300 hover:bg-slate-700 px-1 py-0.5 rounded cursor-pointer smooth-transition"> | |
| <i class="fas fa-folder text-xs"></i> | |
| <span>public</span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="mb-4"> | |
| <h3 class="text-sm font-semibold text-slate-400 mb-2">Console</h3> | |
| <div class="bg-slate-900 rounded-md p-2 text-xs font-mono h-32 overflow-y-auto text-slate-300"> | |
| <div class="text-green-400 mb-0.5">> node index.js</div> | |
| <div class="mb-0.5">Serveur démarré sur le port 3000</div> | |
| <div class="text-yellow-400 mb-0.5">> [WARN] Variable non utilisée détectée</div> | |
| </div> | |
| </div> | |
| <div class="mt-auto"> | |
| <div class="grid grid-cols-2 gap-2 mb-3"> | |
| <button id="runSandboxBtn" class="bg-blue-600 hover:bg-blue-500 text-white py-1 px-2 rounded-md text-xs flex items-center justify-center space-x-1 smooth-transition"> | |
| <i class="fas fa-play"></i> | |
| <span>Exécuter</span> | |
| </button> | |
| <button id="restartSandboxBtn" class="bg-slate-700 hover:bg-slate-600 text-white py-1 px-2 rounded-md text-xs flex items-center justify-center space-x-1 smooth-transition"> | |
| <i class="fas fa-redo"></i> | |
| <span>Redémarrer</span> | |
| </button> | |
| </div> | |
| <button id="deployProjectBtn" class="w-full bg-emerald-600 hover:bg-emerald-500 text-white py-2 px-3 rounded-md text-sm flex items-center justify-center space-x-2 smooth-transition"> | |
| <i class="fas fa-cloud-upload-alt"></i> | |
| <span>Déployer le projet</span> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| // DOM Elements | |
| const sandboxBtn = document.getElementById('sandboxBtn'); | |
| const closeSandboxBtn = document.getElementById('closeSandboxBtn'); | |
| const sandboxPanel = document.getElementById('sandboxPanel'); | |
| const messageInput = document.getElementById('messageInput'); | |
| const sendBtn = document.getElementById('sendBtn'); | |
| const chatContainer = document.getElementById('chatContainer'); | |
| const charCount = document.getElementById('charCount'); | |
| const quickPrompts = document.querySelectorAll('.quick-prompt'); | |
| const newProjectBtn = document.getElementById('newProjectBtn'); | |
| const templateSelect = document.getElementById('templateSelect'); | |
| const generateWithAI = document.getElementById('generateWithAI'); | |
| const runInSandbox = document.getElementById('runInSandbox'); | |
| const runSandboxBtn = document.getElementById('runSandboxBtn'); | |
| const restartSandboxBtn = document.getElementById('restartSandboxBtn'); | |
| const deployProjectBtn = document.getElementById('deployProjectBtn'); | |
| const userMenuBtn = document.getElementById('userMenuBtn'); | |
| const userMenu = document.getElementById('userMenu'); | |
| // Current state | |
| let currentProject = null; | |
| let isSandboxRunning = false; | |
| // Initialize | |
| document.addEventListener('DOMContentLoaded', () => { | |
| // Check for hash route | |
| if (window.location.hash) { | |
| handleRouteChange(window.location.hash); | |
| } | |
| // Set up event listeners | |
| setupEventListeners(); | |
| }); | |
| // Set up all event listeners | |
| function setupEventListeners() { | |
| // Toggle sandbox panel | |
| sandboxBtn.addEventListener('click', toggleSandboxPanel); | |
| closeSandboxBtn.addEventListener('click', () => sandboxPanel.classList.add('hidden')); | |
| // Auto-resize textarea | |
| messageInput.addEventListener('input', handleTextareaInput); | |
| // Send message on enter (shift+enter for new line) | |
| messageInput.addEventListener('keydown', (e) => { | |
| if (e.key === 'Enter' && !e.shiftKey) { | |
| e.preventDefault(); | |
| sendMessage(); | |
| } | |
| }); | |
| sendBtn.addEventListener('click', sendMessage); | |
| // Quick prompt buttons | |
| quickPrompts.forEach(button => { | |
| button.addEventListener('click', () => { | |
| messageInput.value = button.textContent; | |
| messageInput.focus(); | |
| messageInput.dispatchEvent(new Event('input', { bubbles: true })); | |
| }); | |
| }); | |
| // New project button | |
| newProjectBtn.addEventListener('click', createNewProject); | |
| // Template selection | |
| templateSelect.addEventListener('change', (e) => { | |
| if (e.target.value) { | |
| createProjectFromTemplate(e.target.value); | |
| } | |
| }); | |
| // AI generation button | |
| generateWithAI.addEventListener('click', generateWithAIHandler); | |
| // Run in sandbox button | |
| runInSandbox.addEventListener('click', runInSandboxHandler); | |
| // Sandbox controls | |
| runSandboxBtn.addEventListener('click', runSandbox); | |
| restartSandboxBtn.addEventListener('click', restartSandbox); | |
| deployProjectBtn.addEventListener('click', deployProject); | |
| // User menu | |
| userMenuBtn.addEventListener('click', toggleUserMenu); | |
| // Handle route changes | |
| window.addEventListener('hashchange', () => { | |
| handleRouteChange(window.location.hash); | |
| }); | |
| } | |
| // Handle route changes | |
| function handleRouteChange(hash) { | |
| const route = hash.substring(1); | |
| if (route.startsWith('project/')) { | |
| const projectId = route.split('/')[1]; | |
| loadProject(projectId); | |
| } else if (route === 'account') { | |
| showAccountSettings(); | |
| } else if (route === 'settings') { | |
| showSettings(); | |
| } else if (route === 'logout') { | |
| logoutUser(); | |
| } | |
| } | |
| // Toggle sandbox panel | |
| function toggleSandboxPanel() { | |
| sandboxPanel.classList.toggle('hidden'); | |
| if (!sandboxPanel.classList.contains('hidden')) { | |
| // Focus on sandbox when opened | |
| setTimeout(() => { | |
| const firstInteractive = sandboxPanel.querySelector('button'); | |
| if (firstInteractive) firstInteractive.focus(); | |
| }, 100); | |
| } | |
| } | |
| // Handle textarea input | |
| function handleTextareaInput() { | |
| this.style.height = 'auto'; | |
| this.style.height = (this.scrollHeight) + 'px'; | |
| charCount.textContent = this.value.length; | |
| } | |
| // Send message function | |
| function sendMessage() { | |
| const message = messageInput.value.trim(); | |
| if (message === '') return; | |
| addMessageToChat(message, 'user'); | |
| messageInput.value = ''; | |
| messageInput.style.height = 'auto'; | |
| charCount.textContent = '0'; | |
| // Simulate AI response after a delay | |
| setTimeout(() => { | |
| const response = generateAIResponse(message); | |
| </html> |