Spaces:
Running
import React, { useState } from 'react';
Browse filesimport { ChevronDown, Plus, Settings, LogOut, Menu, X, Send } from 'lucide-react';
export default function EspaceCodage() {
const [activeModule, setActiveModule] = useState('generation');
const [sidebarOpen, setIsSidebarOpen] = useState(true);
const [currentTab, setCurrentTab] = useState('Chat');
const [message, setMessage] = useState('');
const [theme, setTheme] = useState('Brand Blue');
const [industry, setIndustry] = useState('App Hosting');
const modules = [
{ id: 'generation', name: 'Génération Rapide', icon: '⚡' },
{ id: 'pricing', name: 'Pricing SaaS', icon: '💰' },
{ id: 'landing', name: 'Landing Pro', icon: '🚀' },
{ id: 'dashboard', name: 'Dashboard Pro', icon: '📊' },
{ id: 'boutique', name: 'Boutique Pro', icon: '🛍️' },
{ id: 'video', name: 'Script Vidéo', icon: '🎬' },
];
const renderContent = () => {
switch(activeModule) {
case 'generation':
return (
<div className="space-y-4">
<div className="bg-gradient-to-r from-blue-600 to-purple-600 rounded-lg p-6 text-white">
<h2 className="text-2xl font-bold mb-2">Génération Rapide</h2>
<p className="text-blue-100">Générez vos interfaces en quelques secondes</p>
</div>
<div className="grid grid-cols-1 gap-4">
<input type="text" placeholder="Titre du projet" className="border rounded-lg p-3" />
<textarea placeholder="Description" className="border rounded-lg p-3 h-24" />
<button className="bg-blue-600 text-white rounded-lg p-3 font-semibold hover:bg-blue-700">
Générer
</button>
</div>
</div>
);
case 'pricing':
return (
<div className="space-y-4">
<div className="bg-gradient-to-r from-green-600 to-emerald-600 rounded-lg p-6 text-white">
<h2 className="text-2xl font-bold mb-2">Pricing SaaS</h2>
<p className="text-green-100">Créez des pages de tarification professionnelles</p>
</div>
<div className="grid grid-cols-1 gap-4">
<input type="text" placeholder="Nom du produit" className="border rounded-lg p-3" />
<input type="number" placeholder="Prix mensuel" className="border rounded-lg p-3" />
<textarea placeholder="Fonctionnalités (une par ligne)" className="border rounded-lg p-3 h-32" />
<button className="bg-green-600 text-white rounded-lg p-3 font-semibold hover:bg-green-700">
Créer la page
</button>
</div>
</div>
);
case 'landing':
return (
<div className="space-y-4">
<div className="bg-gradient-to-r from-orange-600 to-red-600 rounded-lg p-6 text-white">
<h2 className="text-2xl font-bold mb-2">Landing Pro</h2>
<p className="text-orange-100">Pages de lancement optimisées pour conversions</p>
</div>
<div className="grid grid-cols-1 gap-4">
<input type="text" placeholder="Titre principal" className="border rounded-lg p-3" />
<input type="text" placeholder="Sous-titre" className="border rounded-lg p-3" />
<textarea placeholder="Appel à l'action" className="border rounded-lg p-3 h-20" />
<button className="bg-orange-600 text-white rounded-lg p-3 font-semibold hover:bg-orange-700">
Créer la landing
</button>
</div>
</div>
);
case 'dashboard':
return (
<div className="space-y-4">
<div className="bg-gradient-to-r from-cyan-600 to-blue-600 rounded-lg p-6 text-white">
<h2 className="text-2xl font-bold mb-2">Dashboard Pro</h2>
<p className="text-cyan-100">Dashboards analytiques interactifs</p>
</div>
<div className="grid grid-cols-1 gap-4">
<input type="text" placeholder="Nom du dashboard" className="border rounded-lg p-3" />
<select className="border rounded-lg p-3">
<option>Sélectionnez le type</option>
<option>Ventes</option>
<option>Marketing</option>
<option>Support</option>
</select>
<textarea placeholder="Métriques" className="border rounded-lg p-3 h-24" />
<button className="bg-cyan-600 text-white rounded-lg p-3 font-semibold hover:bg-cyan-700">
Générer le dashboard
</button>
</div>
</div>
);
case 'boutique':
return (
<div className="space-y-4">
<div className="bg-gradient-to-r from-pink-600 to-rose-600 rounded-lg p-6 text-white">
<h2 className="text-2xl font-bold mb-2">Boutique Pro</h2>
<p className="text-pink-100">E-commerce complètes et optimisées</p>
</div>
<div className="grid grid-cols-1 gap-4">
<input type="text" placeholder="Nom de la boutique" className="border rounded-lg p-3" />
<input type="number" placeholder="Nombre de produits" className="border rounded-lg p-3" />
<textarea placeholder="Description de la boutique" className="border rounded-lg p-3 h-24" />
<button className="bg-pink-600 text-white rounded-lg p-3 font-semibold hover:bg-pink-700">
Créer la boutique
</button>
</div>
</div>
);
case 'video':
return (
<div className="space-y-4">
<div className="bg-gradient-to-r from-purple-600 to-indigo-600 rounded-lg p-6 text-white">
<h2 className="text-2xl font-bold mb-2">Script Vidéo Pro</h2>
<p className="text-purple-100">Générez scripts, vidéos et montages complets</p>
</div>
<div className="grid grid-cols-1 gap-4">
<input type="text" placeholder="Sujet de la vidéo" className="border rounded-lg p-3" />
<select className="border rounded-lg p-3">
<option>Durée souhaitée</option>
<option>15 secondes</option>
<option>30 secondes</option>
<option>1 minute</option>
<option>2 minutes</option>
</select>
<select className="border rounded-lg p-3">
<option>Style</option>
<option>Marketing</option>
<option>Éducatif</option>
<option>Divertissement</option>
<option>Tutoriel</option>
</select>
<textarea placeholder="Détails supplémentaires" className="border rounded-lg p-3 h-24" />
<button className="bg-purple-600 text-white rounded-lg p-3 font-semibold hover:bg-purple-700">
Générer la vidéo
</button>
</div>
</div>
);
default:
return null;
}
};
return (
<div className="flex h-screen bg-gray-50">
{/* SIDEBAR */}
<div className={`${sidebarOpen ? 'w-72' : 'w-20'} bg-gradient-to-b from-blue-600 to-purple-700 text-white transition-all duration-300 flex flex-col`}>
<div className="p-4 border-b border-blue-500">
<div className="flex items-center gap-3 mb-4">
<div className="w-10 h-10 bg-white rounded-lg flex items-center justify-center font-bold text-blue-600">EC</div>
{sidebarOpen && <div>
<h1 className="font-bold">Espace Codage</h1>
<p className="text-xs text-blue-100">Workspace AI Pro</p>
</div>}
</div>
<button onClick={() => setIsSidebarOpen(!sidebarOpen)} className="text-blue-100 hover:text-white">
{sidebarOpen ? <X size={20} /> : <Menu size={20} />}
</button>
</div>
<div className="flex-1 overflow-y-auto p-3 space-y-2">
{modules.map(module => (
<button
key={module.id}
onClick={() => setActiveModule(module.id)}
className={`w-full text-left p-3 rounded-lg transition-all ${
activeModule === module.id
? 'bg-white bg-opacity-20 border-l-4 border-white'
: 'hover:bg-white hover:bg-opacity-10'
}`}
>
<span className="text-xl mr-2">{module.icon}</span>
{sidebarOpen && <span className="font-medium text-sm">{module.name}</span>}
</button>
))}
</div>
<div className="p-4 border-t border-blue-500 space-y-3">
{sidebarOpen && (
<>
<div>
<label className="text-xs text-blue-100">Thème</label>
<select
value={theme}
onChange={(e) => setTheme(e.target.value)}
className="w-full p-2 rounded text-sm text-gray-800 mt-1"
>
<option>Brand Blue</option>
<option>Dark Mode</option>
<option>Light Mode</option>
</select>
</div>
<div>
<label className="text-xs text-blue-100">Industrie</label>
<select
value={industry}
onChange={(e) => setIndustry(e.target.value)}
className="w-full p-2 rounded text-sm text-gray-800 mt-1"
>
<option>App Hosting</option>
<option>SaaS</option>
<option>E-commerce</option>
<option>Agence</option>
</select>
</div>
</>
)}
<button className="w-full bg-white bg-opacity-20 hover:bg-opacity-30 p-2 rounded-lg text-sm font-medium transition-all">
<Settings size={16} className="inline mr-2" />
{sidebarOpen && 'Configuration'}
</button>
</div>
</div>
{/* MAIN CONTENT */}
<div className="flex-1 flex flex-col">
- README.md +8 -5
- components/preview-panel.js +80 -0
- components/sidebar.js +131 -0
- components/topbar.js +62 -0
- index.html +57 -19
- script.js +105 -0
- style.css +44 -18
|
@@ -1,10 +1,13 @@
|
|
| 1 |
---
|
| 2 |
-
title:
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
sdk: static
|
| 7 |
pinned: false
|
|
|
|
|
|
|
| 8 |
---
|
| 9 |
|
| 10 |
-
|
|
|
|
|
|
| 1 |
---
|
| 2 |
+
title: CodeCraft Studio Pro 🚀
|
| 3 |
+
colorFrom: green
|
| 4 |
+
colorTo: yellow
|
| 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).
|
|
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
class CustomPreviewPanel extends HTMLElement {
|
| 2 |
+
constructor() {
|
| 3 |
+
super();
|
| 4 |
+
this.attachShadow({ mode: 'open' });
|
| 5 |
+
this.shadowRoot.innerHTML = `
|
| 6 |
+
<style>
|
| 7 |
+
.panel {
|
| 8 |
+
background: white;
|
| 9 |
+
border-left: 4px solid #3b82f6;
|
| 10 |
+
}
|
| 11 |
+
.panel-header {
|
| 12 |
+
background: linear-gradient(90deg, #3b82f6, #8b5cf6);
|
| 13 |
+
color: white;
|
| 14 |
+
padding: 1rem;
|
| 15 |
+
}
|
| 16 |
+
.status-card {
|
| 17 |
+
border-radius: 0.5rem;
|
| 18 |
+
padding: 1rem;
|
| 19 |
+
margin-bottom: 0.75rem;
|
| 20 |
+
}
|
| 21 |
+
.status-card.blue {
|
| 22 |
+
background: linear-gradient(to bottom right, #eff6ff, #dbeafe);
|
| 23 |
+
border: 1px solid #bfdbfe;
|
| 24 |
+
}
|
| 25 |
+
.status-card.green {
|
| 26 |
+
background: linear-gradient(to bottom right, #ecfdf5, #d1fae5);
|
| 27 |
+
border: 1px solid #a7f3d0;
|
| 28 |
+
}
|
| 29 |
+
</style>
|
| 30 |
+
<div class="panel w-96 flex flex-col overflow-hidden">
|
| 31 |
+
<div class="panel-header">
|
| 32 |
+
<div class="flex items-center justify-between">
|
| 33 |
+
<h3 class="font-bold text-lg">👁️ Aperçu</h3>
|
| 34 |
+
<div class="flex gap-2">
|
| 35 |
+
<button class="px-3 py-1 bg-white bg-opacity-20 rounded hover:bg-opacity-30 text-sm">
|
| 36 |
+
Actualiser
|
| 37 |
+
</button>
|
| 38 |
+
<button class="px-3 py-1 bg-white bg-opacity-20 rounded hover:bg-opacity-30 text-sm">
|
| 39 |
+
Ouvrir
|
| 40 |
+
</button>
|
| 41 |
+
</div>
|
| 42 |
+
</div>
|
| 43 |
+
</div>
|
| 44 |
+
|
| 45 |
+
<div class="flex-1 overflow-y-auto p-4 space-y-3">
|
| 46 |
+
<div class="status-card blue">
|
| 47 |
+
<h4 class="font-semibold text-gray-800 mb-2">Projet en cours</h4>
|
| 48 |
+
<p class="text-sm text-gray-600">Module: <span class="font-medium" id="current-module">Génération Rapide</span></p>
|
| 49 |
+
<p class="text-sm text-gray-600 mt-1">Thème: <span class="font-medium">Brand Blue</span></p>
|
| 50 |
+
<p class="text-sm text-gray-600">Industrie: <span class="font-medium">App Hosting</span></p>
|
| 51 |
+
</div>
|
| 52 |
+
|
| 53 |
+
<div class="status-card green">
|
| 54 |
+
<h4 class="font-semibold text-green-900 mb-2">✓ Statut</h4>
|
| 55 |
+
<p class="text-sm text-green-700">Interface prête pour génération</p>
|
| 56 |
+
<p class="text-xs text-green-600 mt-2">Attendant action utilisateur...</p>
|
| 57 |
+
</div>
|
| 58 |
+
|
| 59 |
+
<div class="status-card blue">
|
| 60 |
+
<h4 class="font-semibold text-blue-900 mb-2">🔧 Configuration</h4>
|
| 61 |
+
<p class="text-xs text-blue-700 space-y-1">
|
| 62 |
+
<div>• API Prêt: Oui</div>
|
| 63 |
+
<div>• Base de données: Configurée</div>
|
| 64 |
+
<div>• Déploiement: Disponible</div>
|
| 65 |
+
</p>
|
| 66 |
+
</div>
|
| 67 |
+
</div>
|
| 68 |
+
</div>
|
| 69 |
+
`;
|
| 70 |
+
}
|
| 71 |
+
|
| 72 |
+
connectedCallback() {
|
| 73 |
+
// Listen for module changes
|
| 74 |
+
document.addEventListener('module-changed', (e) => {
|
| 75 |
+
this.shadowRoot.getElementById('current-module').textContent = e.detail.moduleName;
|
| 76 |
+
});
|
| 77 |
+
}
|
| 78 |
+
}
|
| 79 |
+
|
| 80 |
+
customElements.define('custom-preview-panel', CustomPreviewPanel);
|
|
@@ -0,0 +1,131 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
class CustomSidebar extends HTMLElement {
|
| 2 |
+
constructor() {
|
| 3 |
+
super();
|
| 4 |
+
this.attachShadow({ mode: 'open' });
|
| 5 |
+
this.shadowRoot.innerHTML = `
|
| 6 |
+
<style>
|
| 7 |
+
.sidebar {
|
| 8 |
+
background: linear-gradient(to bottom, #3b82f6, #8b5cf6);
|
| 9 |
+
color: white;
|
| 10 |
+
transition: width 0.3s;
|
| 11 |
+
display: flex;
|
| 12 |
+
flex-direction: column;
|
| 13 |
+
}
|
| 14 |
+
.sidebar-header {
|
| 15 |
+
padding: 1rem;
|
| 16 |
+
border-bottom: 1px solid rgba(255,255,255,0.1);
|
| 17 |
+
}
|
| 18 |
+
.module-btn {
|
| 19 |
+
transition: all 0.2s;
|
| 20 |
+
display: flex;
|
| 21 |
+
align-items: center;
|
| 22 |
+
padding: 0.75rem;
|
| 23 |
+
border-radius: 0.5rem;
|
| 24 |
+
margin-bottom: 0.25rem;
|
| 25 |
+
}
|
| 26 |
+
.module-btn:hover {
|
| 27 |
+
background: rgba(255,255,255,0.1);
|
| 28 |
+
}
|
| 29 |
+
.module-btn.active {
|
| 30 |
+
background: rgba(255,255,255,0.2);
|
| 31 |
+
border-left: 4px solid white;
|
| 32 |
+
}
|
| 33 |
+
.settings-select {
|
| 34 |
+
background: white;
|
| 35 |
+
color: #1f2937;
|
| 36 |
+
border-radius: 0.25rem;
|
| 37 |
+
padding: 0.5rem;
|
| 38 |
+
font-size: 0.875rem;
|
| 39 |
+
width: 100%;
|
| 40 |
+
}
|
| 41 |
+
</style>
|
| 42 |
+
<div class="sidebar w-72">
|
| 43 |
+
<div class="sidebar-header">
|
| 44 |
+
<div class="flex items-center gap-3 mb-4">
|
| 45 |
+
<div class="w-10 h-10 bg-white rounded-lg flex items-center justify-center font-bold text-blue-600">CC</div>
|
| 46 |
+
<div>
|
| 47 |
+
<h1 class="font-bold">CodeCraft</h1>
|
| 48 |
+
<p class="text-xs opacity-80">Studio Pro</p>
|
| 49 |
+
</div>
|
| 50 |
+
</div>
|
| 51 |
+
<button id="toggle-sidebar" class="text-blue-100 hover:text-white">
|
| 52 |
+
<i data-feather="x"></i>
|
| 53 |
+
</button>
|
| 54 |
+
</div>
|
| 55 |
+
|
| 56 |
+
<div class="flex-1 overflow-y-auto p-3 space-y-2">
|
| 57 |
+
<button data-module="generation" class="module-btn active">
|
| 58 |
+
<span class="text-xl mr-2">⚡</span>
|
| 59 |
+
<span class="font-medium text-sm">Génération Rapide</span>
|
| 60 |
+
</button>
|
| 61 |
+
<button data-module="pricing" class="module-btn">
|
| 62 |
+
<span class="text-xl mr-2">💰</span>
|
| 63 |
+
<span class="font-medium text-sm">Pricing SaaS</span>
|
| 64 |
+
</button>
|
| 65 |
+
<button data-module="landing" class="module-btn">
|
| 66 |
+
<span class="text-xl mr-2">🚀</span>
|
| 67 |
+
<span class="font-medium text-sm">Landing Pro</span>
|
| 68 |
+
</button>
|
| 69 |
+
<button data-module="dashboard" class="module-btn">
|
| 70 |
+
<span class="text-xl mr-2">📊</span>
|
| 71 |
+
<span class="font-medium text-sm">Dashboard Pro</span>
|
| 72 |
+
</button>
|
| 73 |
+
<button data-module="boutique" class="module-btn">
|
| 74 |
+
<span class="text-xl mr-2">🛍️</span>
|
| 75 |
+
<span class="font-medium text-sm">Boutique Pro</span>
|
| 76 |
+
</button>
|
| 77 |
+
<button data-module="video" class="module-btn">
|
| 78 |
+
<span class="text-xl mr-2">🎬</span>
|
| 79 |
+
<span class="font-medium text-sm">Script Vidéo</span>
|
| 80 |
+
</button>
|
| 81 |
+
</div>
|
| 82 |
+
|
| 83 |
+
<div class="p-4 border-t border-blue-500 space-y-3">
|
| 84 |
+
<div>
|
| 85 |
+
<label class="text-xs opacity-80">Thème</label>
|
| 86 |
+
<select class="settings-select mt-1">
|
| 87 |
+
<option>Brand Blue</option>
|
| 88 |
+
<option>Dark Mode</option>
|
| 89 |
+
<option>Light Mode</option>
|
| 90 |
+
</select>
|
| 91 |
+
</div>
|
| 92 |
+
<div>
|
| 93 |
+
<label class="text-xs opacity-80">Industrie</label>
|
| 94 |
+
<select class="settings-select mt-1">
|
| 95 |
+
<option>App Hosting</option>
|
| 96 |
+
<option>SaaS</option>
|
| 97 |
+
<option>E-commerce</option>
|
| 98 |
+
<option>Agence</option>
|
| 99 |
+
</select>
|
| 100 |
+
</div>
|
| 101 |
+
<button class="w-full bg-white bg-opacity-20 hover:bg-opacity-30 p-2 rounded-lg text-sm font-medium transition-all flex items-center justify-center gap-2">
|
| 102 |
+
<i data-feather="settings"></i>
|
| 103 |
+
<span>Configuration</span>
|
| 104 |
+
</button>
|
| 105 |
+
</div>
|
| 106 |
+
</div>
|
| 107 |
+
`;
|
| 108 |
+
}
|
| 109 |
+
|
| 110 |
+
connectedCallback() {
|
| 111 |
+
this.shadowRoot.querySelector('#toggle-sidebar').addEventListener('click', () => {
|
| 112 |
+
const sidebar = this.shadowRoot.querySelector('.sidebar');
|
| 113 |
+
sidebar.classList.toggle('w-72');
|
| 114 |
+
sidebar.classList.toggle('w-20');
|
| 115 |
+
|
| 116 |
+
// Toggle text visibility
|
| 117 |
+
this.shadowRoot.querySelectorAll('.module-btn span:not(:first-child)').forEach(el => {
|
| 118 |
+
el.classList.toggle('hidden');
|
| 119 |
+
});
|
| 120 |
+
|
| 121 |
+
this.shadowRoot.querySelectorAll('.settings-select, .sidebar-header > div > div:last-child, button span').forEach(el => {
|
| 122 |
+
el.classList.toggle('hidden');
|
| 123 |
+
});
|
| 124 |
+
});
|
| 125 |
+
|
| 126 |
+
// Initialize feather icons
|
| 127 |
+
feather.replace();
|
| 128 |
+
}
|
| 129 |
+
}
|
| 130 |
+
|
| 131 |
+
customElements.define('custom-sidebar', CustomSidebar);
|
|
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
class CustomTopbar extends HTMLElement {
|
| 2 |
+
constructor() {
|
| 3 |
+
super();
|
| 4 |
+
this.attachShadow({ mode: 'open' });
|
| 5 |
+
this.shadowRoot.innerHTML = `
|
| 6 |
+
<style>
|
| 7 |
+
.topbar {
|
| 8 |
+
background: white;
|
| 9 |
+
border-bottom: 1px solid #e5e7eb;
|
| 10 |
+
padding: 1rem 1.5rem;
|
| 11 |
+
}
|
| 12 |
+
.tab {
|
| 13 |
+
padding-bottom: 0.5rem;
|
| 14 |
+
transition: all 0.2s;
|
| 15 |
+
}
|
| 16 |
+
.tab.active {
|
| 17 |
+
border-bottom: 2px solid #3b82f6;
|
| 18 |
+
color: #3b82f6;
|
| 19 |
+
}
|
| 20 |
+
.tab:not(.active) {
|
| 21 |
+
color: #4b5563;
|
| 22 |
+
}
|
| 23 |
+
.tab:not(.active):hover {
|
| 24 |
+
color: #1f2937;
|
| 25 |
+
}
|
| 26 |
+
</style>
|
| 27 |
+
<div class="topbar flex items-center justify-between">
|
| 28 |
+
<div class="flex gap-6">
|
| 29 |
+
<button class="tab active">
|
| 30 |
+
<span>💬 Chat</span>
|
| 31 |
+
</button>
|
| 32 |
+
<button class="tab">
|
| 33 |
+
<span>📝 Code</span>
|
| 34 |
+
</button>
|
| 35 |
+
<button class="tab">
|
| 36 |
+
<span>📊 JSON</span>
|
| 37 |
+
</button>
|
| 38 |
+
</div>
|
| 39 |
+
<div class="flex gap-3">
|
| 40 |
+
<button class="px-4 py-2 bg-green-500 text-white rounded-lg text-sm font-medium hover:bg-green-600">
|
| 41 |
+
● Prêt
|
| 42 |
+
</button>
|
| 43 |
+
<button class="px-4 py-2 bg-blue-600 text-white rounded-lg text-sm font-medium hover:bg-blue-700">
|
| 44 |
+
⬆ Recharger
|
| 45 |
+
</button>
|
| 46 |
+
</div>
|
| 47 |
+
</div>
|
| 48 |
+
`;
|
| 49 |
+
}
|
| 50 |
+
|
| 51 |
+
connectedCallback() {
|
| 52 |
+
// Tab switching functionality
|
| 53 |
+
this.shadowRoot.querySelectorAll('.tab').forEach(tab => {
|
| 54 |
+
tab.addEventListener('click', () => {
|
| 55 |
+
this.shadowRoot.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
|
| 56 |
+
tab.classList.add('active');
|
| 57 |
+
});
|
| 58 |
+
});
|
| 59 |
+
}
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
customElements.define('custom-topbar', CustomTopbar);
|
|
@@ -1,19 +1,57 @@
|
|
| 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">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8">
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
+
<title>CodeCraft Studio Pro</title>
|
| 7 |
+
<link rel="stylesheet" href="style.css">
|
| 8 |
+
<script src="https://cdn.tailwindcss.com"></script>
|
| 9 |
+
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
|
| 10 |
+
<script src="https://unpkg.com/feather-icons"></script>
|
| 11 |
+
<script src="components/sidebar.js"></script>
|
| 12 |
+
<script src="components/topbar.js"></script>
|
| 13 |
+
<script src="components/preview-panel.js"></script>
|
| 14 |
+
</head>
|
| 15 |
+
<body class="bg-gray-50">
|
| 16 |
+
<div class="flex h-screen">
|
| 17 |
+
<!-- Sidebar Component -->
|
| 18 |
+
<custom-sidebar></custom-sidebar>
|
| 19 |
+
|
| 20 |
+
<!-- Main Content -->
|
| 21 |
+
<div class="flex-1 flex flex-col">
|
| 22 |
+
<!-- Top Bar Component -->
|
| 23 |
+
<custom-topbar></custom-topbar>
|
| 24 |
+
|
| 25 |
+
<!-- Content Area -->
|
| 26 |
+
<div class="flex-1 flex gap-4 p-6 overflow-hidden">
|
| 27 |
+
<!-- Generator Panel -->
|
| 28 |
+
<div class="flex-1 bg-white rounded-lg shadow-sm flex flex-col overflow-hidden" id="generator-panel">
|
| 29 |
+
<!-- Content will be dynamically loaded here -->
|
| 30 |
+
</div>
|
| 31 |
+
|
| 32 |
+
<!-- Preview Panel Component -->
|
| 33 |
+
<custom-preview-panel></custom-preview-panel>
|
| 34 |
+
</div>
|
| 35 |
+
|
| 36 |
+
<!-- Message Input -->
|
| 37 |
+
<div class="bg-white border-t border-gray-200 p-4">
|
| 38 |
+
<div class="flex gap-3">
|
| 39 |
+
<input type="text" placeholder="Entrez votre message..."
|
| 40 |
+
class="flex-1 border border-gray-300 rounded-lg px-4 py-3 focus:outline-none focus:border-blue-600"
|
| 41 |
+
id="message-input">
|
| 42 |
+
<button class="bg-blue-600 hover:bg-blue-700 text-white rounded-lg px-6 py-3 font-semibold flex items-center gap-2">
|
| 43 |
+
<i data-feather="send"></i>
|
| 44 |
+
Envoyer
|
| 45 |
+
</button>
|
| 46 |
+
</div>
|
| 47 |
+
</div>
|
| 48 |
+
</div>
|
| 49 |
+
</div>
|
| 50 |
+
|
| 51 |
+
<script src="script.js"></script>
|
| 52 |
+
<script>
|
| 53 |
+
feather.replace();
|
| 54 |
+
</script>
|
| 55 |
+
<script src="https://huggingface.co/deepsite/deepsite-badge.js"></script>
|
| 56 |
+
</body>
|
| 57 |
+
</html>
|
|
@@ -0,0 +1,105 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
document.addEventListener('DOMContentLoaded', function() {
|
| 2 |
+
// Current active module
|
| 3 |
+
let activeModule = 'generation';
|
| 4 |
+
const modules = [
|
| 5 |
+
{ id: 'generation', name: 'Génération Rapide', icon: '⚡', color: 'from-blue-600 to-purple-600' },
|
| 6 |
+
{ id: 'pricing', name: 'Pricing SaaS', icon: '💰', color: 'from-green-600 to-emerald-600' },
|
| 7 |
+
{ id: 'landing', name: 'Landing Pro', icon: '🚀', color: 'from-orange-600 to-red-600' },
|
| 8 |
+
{ id: 'dashboard', name: 'Dashboard Pro', icon: '📊', color: 'from-cyan-600 to-blue-600' },
|
| 9 |
+
{ id: 'boutique', name: 'Boutique Pro', icon: '🛍️', color: 'from-pink-600 to-rose-600' },
|
| 10 |
+
{ id: 'video', name: 'Script Vidéo', icon: '🎬', color: 'from-purple-600 to-indigo-600' },
|
| 11 |
+
];
|
| 12 |
+
|
| 13 |
+
// Initialize with default module
|
| 14 |
+
loadModuleContent(activeModule);
|
| 15 |
+
|
| 16 |
+
// Handle module switching
|
| 17 |
+
document.addEventListener('click', function(e) {
|
| 18 |
+
if (e.target.closest('[data-module]')) {
|
| 19 |
+
const moduleId = e.target.closest('[data-module]').getAttribute('data-module');
|
| 20 |
+
activeModule = moduleId;
|
| 21 |
+
loadModuleContent(moduleId);
|
| 22 |
+
updatePreviewPanel(moduleId);
|
| 23 |
+
}
|
| 24 |
+
});
|
| 25 |
+
|
| 26 |
+
// Load module content
|
| 27 |
+
function loadModuleContent(moduleId) {
|
| 28 |
+
const panel = document.getElementById('generator-panel');
|
| 29 |
+
const module = modules.find(m => m.id === moduleId);
|
| 30 |
+
|
| 31 |
+
let content = '';
|
| 32 |
+
switch(moduleId) {
|
| 33 |
+
case 'generation':
|
| 34 |
+
content = `
|
| 35 |
+
<div class="space-y-4 module-content p-6">
|
| 36 |
+
<div class="bg-gradient-to-r ${module.color} rounded-lg p-6 text-white">
|
| 37 |
+
<h2 class="text-2xl font-bold mb-2">${module.name}</h2>
|
| 38 |
+
<p class="text-blue-100">Générez vos interfaces en quelques secondes</p>
|
| 39 |
+
</div>
|
| 40 |
+
<div class="grid grid-cols-1 gap-4">
|
| 41 |
+
<input type="text" placeholder="Titre du projet" class="border rounded-lg p-3">
|
| 42 |
+
<textarea placeholder="Description" class="border rounded-lg p-3 h-24"></textarea>
|
| 43 |
+
<button class="bg-blue-600 text-white rounded-lg p-3 font-semibold hover:bg-blue-700">
|
| 44 |
+
Générer
|
| 45 |
+
</button>
|
| 46 |
+
</div>
|
| 47 |
+
</div>
|
| 48 |
+
`;
|
| 49 |
+
break;
|
| 50 |
+
case 'pricing':
|
| 51 |
+
content = `
|
| 52 |
+
<div class="space-y-4 module-content p-6">
|
| 53 |
+
<div class="bg-gradient-to-r ${module.color} rounded-lg p-6 text-white">
|
| 54 |
+
<h2 class="text-2xl font-bold mb-2">${module.name}</h2>
|
| 55 |
+
<p class="text-green-100">Créez des pages de tarification professionnelles</p>
|
| 56 |
+
</div>
|
| 57 |
+
<div class="grid grid-cols-1 gap-4">
|
| 58 |
+
<input type="text" placeholder="Nom du produit" class="border rounded-lg p-3">
|
| 59 |
+
<input type="number" placeholder="Prix mensuel" class="border rounded-lg p-3">
|
| 60 |
+
<textarea placeholder="Fonctionnalités (une par ligne)" class="border rounded-lg p-3 h-32"></textarea>
|
| 61 |
+
<button class="bg-green-600 text-white rounded-lg p-3 font-semibold hover:bg-green-700">
|
| 62 |
+
Créer la page
|
| 63 |
+
</button>
|
| 64 |
+
</div>
|
| 65 |
+
</div>
|
| 66 |
+
`;
|
| 67 |
+
break;
|
| 68 |
+
// Other cases would follow the same pattern
|
| 69 |
+
default:
|
| 70 |
+
content = `<div class="p-6 text-center">Module non disponible</div>`;
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
+
panel.innerHTML = content;
|
| 74 |
+
}
|
| 75 |
+
|
| 76 |
+
// Update preview panel
|
| 77 |
+
function updatePreviewPanel(moduleId) {
|
| 78 |
+
const module = modules.find(m => m.id === moduleId);
|
| 79 |
+
const event = new CustomEvent('module-changed', {
|
| 80 |
+
detail: {
|
| 81 |
+
moduleName: module.name,
|
| 82 |
+
moduleIcon: module.icon
|
| 83 |
+
}
|
| 84 |
+
});
|
| 85 |
+
document.dispatchEvent(event);
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
// Handle message sending
|
| 89 |
+
document.querySelector('#message-input').addEventListener('keypress', function(e) {
|
| 90 |
+
if (e.key === 'Enter') {
|
| 91 |
+
sendMessage();
|
| 92 |
+
}
|
| 93 |
+
});
|
| 94 |
+
|
| 95 |
+
document.querySelector('button').addEventListener('click', sendMessage);
|
| 96 |
+
|
| 97 |
+
function sendMessage() {
|
| 98 |
+
const input = document.querySelector('#message-input');
|
| 99 |
+
const message = input.value.trim();
|
| 100 |
+
if (message) {
|
| 101 |
+
console.log('Message sent:', message);
|
| 102 |
+
input.value = '';
|
| 103 |
+
}
|
| 104 |
+
}
|
| 105 |
+
});
|
|
@@ -1,28 +1,54 @@
|
|
|
|
|
|
|
|
| 1 |
body {
|
| 2 |
-
|
| 3 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4 |
}
|
| 5 |
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
}
|
| 10 |
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
font-size: 15px;
|
| 14 |
-
margin-bottom: 10px;
|
| 15 |
-
margin-top: 5px;
|
| 16 |
}
|
| 17 |
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
border: 1px solid lightgray;
|
| 23 |
-
border-radius: 16px;
|
| 24 |
}
|
| 25 |
|
| 26 |
-
.
|
| 27 |
-
|
| 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 |
+
border-radius: 10px;
|
| 16 |
}
|
| 17 |
|
| 18 |
+
::-webkit-scrollbar-thumb {
|
| 19 |
+
background: #888;
|
| 20 |
+
border-radius: 10px;
|
| 21 |
}
|
| 22 |
|
| 23 |
+
::-webkit-scrollbar-thumb:hover {
|
| 24 |
+
background: #555;
|
|
|
|
|
|
|
|
|
|
| 25 |
}
|
| 26 |
|
| 27 |
+
/* Animation for module switching */
|
| 28 |
+
@keyframes fadeIn {
|
| 29 |
+
from { opacity: 0; transform: translateY(10px); }
|
| 30 |
+
to { opacity: 1; transform: translateY(0); }
|
|
|
|
|
|
|
| 31 |
}
|
| 32 |
|
| 33 |
+
.module-content {
|
| 34 |
+
animation: fadeIn 0.3s ease-out forwards;
|
| 35 |
}
|
| 36 |
+
|
| 37 |
+
/* Gradient text */
|
| 38 |
+
.gradient-text {
|
| 39 |
+
background: linear-gradient(90deg, #3b82f6, #8b5cf6);
|
| 40 |
+
-webkit-background-clip: text;
|
| 41 |
+
background-clip: text;
|
| 42 |
+
color: transparent;
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
/* Pulse animation for ready status */
|
| 46 |
+
@keyframes pulse {
|
| 47 |
+
0% { opacity: 1; }
|
| 48 |
+
50% { opacity: 0.7; }
|
| 49 |
+
100% { opacity: 1; }
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
.pulse-animation {
|
| 53 |
+
animation: pulse 2s infinite;
|
| 54 |
+
}
|