Nous sommes là pour vous aider. Remplissez le formulaire et nous vous répondrons sous 24h.
📧
hello@votresite.com
📞
+33 1 23 45 67 89
📍
Paris, France
Envoyer un message
`,
},
},
];
/* ── AI response engine ── */
function generateAIResponse(msg, files) {
const lower = msg.toLowerCase();
const hasFiles = Object.keys(files).length > 0;
// Detect intent
const wantsLanding = /landing|hero|accueil|home|presentaci/i.test(msg);
const wantsNav = /nav|menu|header|barre|navigation/i.test(msg);
const wantsColor = /couleur|color|bleu|blue|rouge|red|vert|green|violet|purple|rose|pink/i.test(msg);
const wantsButton = /bouton|button|btn|cta/i.test(msg);
const wantsFooter = /footer|pied de page|bas de page/i.test(msg);
const wantsAnimate = /anim|transition|effet|effect/i.test(msg);
const wantsPortfolio = /portfolio|cv|curriculum|skills?/i.test(msg);
const wantsContact = /contact|formulaire|form/i.test(msg);
const wantsDark = /dark|sombre|nuit|night/i.test(msg);
const wantsStyle = /style|css|design/i.test(msg);
if (!hasFiles) {
// No files yet — generate a starter
if (wantsPortfolio) {
return {
text: gm(
'¡Perfecto! He creado un portfolio profesional para ti. Tienes una navegación elegante, una sección hero impactante y una grilla de proyectos. ¡Personalízalo con tus datos! 🎨',
'Parfait ! J\'ai créé un portfolio professionnel pour vous. Il inclut une navigation élégante, une section hero percutante et une grille de projets. Personnalisez-le avec vos informations ! 🎨',
'Perfect! I created a professional portfolio for you. It includes elegant navigation, an impactful hero section, and a projects grid. Customize it with your info! 🎨'
),
files: { 'index.html': LIB_TEMPLATES[1].files['index.html'] },
};
}
if (wantsContact) {
return {
text: gm(
'¡Listo! He creado un formulario de contacto moderno con layout en dos columnas. La izquierda muestra la información de contacto y la derecha el formulario. 📬',
'Voilà ! J\'ai créé un formulaire de contact moderne en deux colonnes. La gauche affiche les infos de contact et la droite le formulaire. 📬',
'Done! I created a modern two-column contact form. The left shows contact info and the right has the form. 📬'
),
files: { 'index.html': LIB_TEMPLATES[5].files['index.html'] },
};
}
// Default: landing page
return {
text: gm(
'¡He creado tu página de inicio! Tiene un hero con gradiente, sección de características con tarjetas y un footer. Puedes pedirme que modifique los colores, el texto, añada secciones o cualquier otra cosa. 🚀',
'J\'ai créé votre page d\'accueil ! Elle comprend un hero avec dégradé, une section features avec des cartes et un footer. Vous pouvez me demander de modifier les couleurs, le texte, ajouter des sections, etc. 🚀',
'I created your homepage! It includes a gradient hero, a features section with cards, and a footer. Ask me to change colors, text, add sections, or anything else. 🚀'
),
files: { 'index.html': LIB_TEMPLATES[0].files['index.html'] },
};
}
// Files exist — modify them
if (wantsDark) {
return {
text: gm(
'He actualizado el diseño a modo oscuro. Los fondos son ahora de color #0f172a y los textos en tonos claros. ¡Se ve muy profesional! 🌙',
'J\'ai mis à jour le design en mode sombre. Les fonds sont maintenant en #0f172a avec des textes clairs. Très professionnel ! 🌙',
'I updated the design to dark mode. Backgrounds are now #0f172a with light text. Looks very professional! 🌙'
),
files: null,
hint: 'dark',
};
}
if (wantsColor) {
return {
text: gm(
'He actualizado la paleta de colores. Los nuevos tonos dan un aspecto más moderno y vibrante a tu proyecto. 🎨',
'J\'ai mis à jour la palette de couleurs. Les nouvelles teintes donnent un aspect plus moderne et vibrant à votre projet. 🎨',
'I updated the color palette. The new tones give a more modern and vibrant look to your project. 🎨'
),
files: null,
};
}
if (wantsNav) {
return {
text: gm(
'He añadido una barra de navegación responsiva con logo, links y un botón CTA. Se vuelve sticky al hacer scroll. 🗂️',
'J\'ai ajouté une barre de navigation responsive avec logo, liens et un bouton CTA. Elle devient sticky au scroll. 🗂️',
'I added a responsive navigation bar with logo, links, and a CTA button. It becomes sticky on scroll. 🗂️'
),
files: null,
};
}
if (wantsFooter) {
return {
text: gm(
'He añadido un footer completo con links, redes sociales y copyright. Se adapta perfectamente al diseño existente. 🔻',
'J\'ai ajouté un footer complet avec des liens, réseaux sociaux et copyright. Il s\'adapte parfaitement au design existant. 🔻',
'I added a complete footer with links, social networks, and copyright. It fits perfectly with the existing design. 🔻'
),
files: null,
};
}
if (wantsAnimate) {
return {
text: gm(
'He añadido animaciones suaves de entrada (fade + slide). Las tarjetas aparecen con un efecto elegante al cargar la página. ✨',
'J\'ai ajouté des animations d\'entrée douces (fade + slide). Les cartes apparaissent avec un effet élégant au chargement. ✨',
'I added smooth entrance animations (fade + slide). Cards appear with an elegant effect on page load. ✨'
),
files: null,
};
}
// Generic response
return {
text: gm(
'He aplicado los cambios que pediste. La estructura sigue siendo sólida y el diseño se mantiene coherente. ¿Qué más quieres ajustar? ✅',
'J\'ai appliqué les modifications demandées. La structure reste solide et le design cohérent. Que souhaitez-vous ajuster d\'autre ? ✅',
'I applied the changes you requested. The structure remains solid and the design coherent. What else would you like to adjust? ✅'
),
files: null,
};
}
/* ── File type → icon ── */
function fileIcon(name) {
if (name.endsWith('.html')) return '📄';
if (name.endsWith('.css')) return '🎨';
if (name.endsWith('.js')) return '⚡';
if (name.endsWith('.jsx')) return '⚛️';
if (name.endsWith('.json')) return '📋';
if (name.endsWith('.md')) return '📝';
if (name.endsWith('.png') || name.endsWith('.jpg') || name.endsWith('.svg')) return '🖼️';
return '📄';
}
/* ── Library Modal ── */
function LibraryModal({ onClose, onSelect }) {
const [selected, setSelected] = useWS(null);
return (
e.stopPropagation()}>
{gm('Importar plantilla', 'Importer un modèle', 'Import a template')}
{gm('Elige una plantilla de inicio para tu workspace.','Choisissez un modèle de départ pour votre workspace.','Choose a starter template for your workspace.')}
{gm(
'Pide a la IA lo que quieres crear. El contexto incluye todos los archivos analizados.',
'Demandez à l\'IA ce que vous voulez créer. Le contexte inclut tous les fichiers analysés.',
'Ask the AI what you want to create. Context includes all analyzed files.'
)}