import React, { useState, useRef, useEffect, useCallback } from 'react'; import ReactDOM from 'react-dom/client'; import { GoogleGenAI, Chat } from '@google/genai'; // --- TYPE DEFINITIONS --- interface Service { icon: React.ReactNode; title: string; description: string; } interface PortfolioItem { id: number; title: string; description: string; imageUrl: string; } interface Message { sender: 'user' | 'bot'; text: string; } interface NavLink { href: string; label: string; } // --- ICON COMPONENTS --- const iconProps = { className: "w-12 h-12", strokeWidth: 1.5 }; const BriefcaseIcon = () => ( ); const MegaphoneIcon = () => ( ); const BuildingOfficeIcon = () => ( ); const ComputerDesktopIcon = () => ( ); const ShoppingCartIcon = () => ( ); const TruckIcon = () => ( ); const VideoCameraIcon = () => ( ); const navIconProps = { className: "w-8 h-8", strokeWidth: 2 }; const Bars3Icon = () => ( ); const XMarkIcon = () => ( ); const sliderIconProps = { className: "w-8 h-8", strokeWidth: 2 }; const ChevronLeftIcon = () => ( ); const ChevronRightIcon = () => ( ); const chatIconProps = { className: "w-6 h-6", strokeWidth: 2 }; const ChatBubbleIcon = () => ( ); const CloseIcon = () => ( ); const PaperAirplaneIcon = () => ( ); const adminIconProps = { className: "w-6 h-6", strokeWidth: 1.5 }; const Cog6ToothIcon = () => ( ); const socialIconProps = { className: "w-6 h-6" }; const FacebookIcon = () => ( ); const InstagramIcon = () => ( ); // --- MOCK DATA --- const navLinksData: NavLink[] = [ { href: '#services', label: 'Servicios' }, { href: '#portfolio', label: 'Portafolio' }, { href: '#contact', label: 'Contacto' }, ]; const servicesData: Service[] = [ { icon: React.createElement(BriefcaseIcon), title: 'Incubadora', description: 'Transformamos tu idea en un negocio viable y escalable con nuestra metodología de incubación probada.' }, { icon: React.createElement(MegaphoneIcon), title: 'Marketing', description: 'Creamos estrategias de marketing digital y tradicional que conectan tu marca con la audiencia correcta.' }, { icon: React.createElement(BuildingOfficeIcon), title: 'Arquitectura', description: 'Diseño arquitectónico innovador y funcional para espacios comerciales y corporativos que inspiran.' }, { icon: React.createElement(ComputerDesktopIcon), title: 'Tecnología', description: 'Desarrollo de software a medida, aplicaciones web y móviles para potenciar la transformación digital.' }, { icon: React.createElement(ShoppingCartIcon), title: 'POS', description: 'Soluciones de Punto de Venta (POS) eficientes y seguras para optimizar tus operaciones de venta.' }, { icon: React.createElement(TruckIcon), title: 'Drive Thru', description: 'Implementación y optimización de sistemas Drive Thru para una experiencia de cliente rápida y fluida.' }, { icon: React.createElement(VideoCameraIcon), title: 'Audiovisual', description: 'Producción de contenido audiovisual de alta calidad, desde videos corporativos hasta campañas publicitarias.' }, ]; const portfolioData: PortfolioItem[] = [ { id: 1, title: 'Branding Corporativo para Fintech', description: 'Desarrollamos una identidad de marca completa para una startup financiera, logrando un posicionamiento sólido en el mercado.', imageUrl: 'https://picsum.photos/seed/tech1/1200/800' }, { id: 2, title: 'Diseño de Oficinas Modernas', description: 'Proyecto arquitectónico para un hub tecnológico, creando un espacio de trabajo colaborativo y vanguardista.', imageUrl: 'https://picsum.photos/seed/arch1/1200/800' }, { id: 3, title: 'Campaña de Marketing Digital 360°', description: 'Ejecutamos una campaña multicanal para una marca de consumo masivo, aumentando su alcance en un 200%.', imageUrl: 'https://picsum.photos/seed/market1/1200/800' }, { id: 4, title: 'App Móvil para E-commerce', description: 'Una aplicación móvil intuitiva y de alto rendimiento que impulsó las ventas online de un cliente retail en un 40%.', imageUrl: 'https://picsum.photos/seed/ecomm1/1200/800' }, ]; // --- UI COMPONENTS --- const Header: React.FC<{ navLinks: NavLink[] }> = ({ navLinks }) => { const [isOpen, setIsOpen] = useState(false); const handleScroll = (e: React.MouseEvent, href: string) => { e.preventDefault(); const targetId = href.replace(/.*#/, ""); const elem = document.getElementById(targetId); elem?.scrollIntoView({ behavior: 'smooth' }); setIsOpen(false); }; return (
handleScroll(e, '#home')} className="text-2xl font-bold text-white">ImagiDone.
{isOpen && (
)}
); }; const Hero: React.FC = () => { const handleScrollToContact = (e: React.MouseEvent) => { e.preventDefault(); document.getElementById('contact')?.scrollIntoView({ behavior: 'smooth' }); }; return (

Donde las Grandes Ideas
se Convierten en Realidades.

Somos ImagiDone, la agencia de servicios integrales que impulsa tu visión desde la concepción hasta la ejecución.

Hablemos de tu Proyecto
); }; const ServiceCard: React.FC<{ service: Service }> = ({ service }) => (
{service.icon}

{service.title}

{service.description}

); const Services: React.FC<{ services: Service[] }> = ({ services }) => (

Nuestros Servicios

Soluciones integrales para llevar tu negocio al siguiente nivel.

); const Portfolio: React.FC<{ portfolioItems: PortfolioItem[] }> = ({ portfolioItems }) => { const [currentIndex, setCurrentIndex] = useState(0); const prevSlide = () => { setCurrentIndex(prevIndex => prevIndex === 0 ? portfolioItems.length - 1 : prevIndex - 1); }; const nextSlide = useCallback(() => { setCurrentIndex(prevIndex => prevIndex === portfolioItems.length - 1 ? 0 : prevIndex + 1); }, [portfolioItems.length]); useEffect(() => { if (portfolioItems.length === 0) return; const slideInterval = setInterval(nextSlide, 5000); return () => clearInterval(slideInterval); }, [nextSlide, portfolioItems.length]); if (portfolioItems.length === 0) { return (

Nuestro Portafolio

Próximamente mostraremos nuestros casos de éxito.

); } const currentItem = portfolioItems[currentIndex]; return (

Nuestro Portafolio

Casos de éxito que demuestran nuestra pasión y experiencia.

{currentItem.title}

{currentItem.description}

{portfolioItems.map((_, index) => (
setCurrentIndex(index)} className={`w-3 h-3 rounded-full cursor-pointer transition-colors ${currentIndex === index ? 'bg-brand-red' : 'bg-gray-400'}`}>
))}
); }; const ContactForm: React.FC = () => { const [formData, setFormData] = useState({ name: '', email: '', message: '' }); const [isSubmitted, setIsSubmitted] = useState(false); const handleChange = (e: React.ChangeEvent) => { const { name, value } = e.target; setFormData(prevState => ({ ...prevState, [name]: value })); }; const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); console.log('Form submitted:', formData); setIsSubmitted(true); setTimeout(() => { setIsSubmitted(false); setFormData({ name: '', email: '', message: '' }); }, 3000); }; return (

Contáctanos

¿Listo para empezar? Cuéntanos sobre tu proyecto.

{isSubmitted && (

¡Gracias! Tu mensaje ha sido enviado con éxito.

)}
); }; const Footer: React.FC<{ onAdminClick: () => void; }> = ({ onAdminClick }) => (

© {new Date().getFullYear()} ImagiDone. Todos los derechos reservados.

); const Chatbot: React.FC = () => { const [isOpen, setIsOpen] = useState(false); const [messages, setMessages] = useState([]); const [input, setInput] = useState(''); const [isLoading, setIsLoading] = useState(false); const chatRef = useRef(null); const messagesEndRef = useRef(null); const scrollToBottom = () => { messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' }); }; useEffect(scrollToBottom, [messages]); const initializeChat = () => { const apiKey = 'TU_CLAVE_DE_API_AQUI'; // IMPORTANTE: Reemplaza con tu clave de API de Google Gemini. if (!apiKey || apiKey === 'TU_CLAVE_DE_API_AQUI') { setMessages([{ sender: 'bot', text: '¡Hola! Para usar el chat, el propietario del sitio debe configurar una clave de API válida.' }]); return; } const ai = new GoogleGenAI({ apiKey: apiKey }); const servicesInfo = servicesData.map(s => `- ${s.title}: ${s.description}`).join('\n'); const portfolioInfo = portfolioData.map(p => `- ${p.title}: ${p.description}`).join('\n'); const systemInstruction = `Eres un asistente virtual amigable y profesional para "ImagiDone", una agencia de servicios integrales. Tu objetivo es responder las preguntas de los usuarios basándote únicamente en la siguiente información. No inventes servicios, proyectos o detalles. Si no sabes la respuesta a una pregunta, di amablemente que no tienes esa información. Sé conciso y directo.\n\nInformación de Servicios de ImagiDone:\n${servicesInfo}\n\nInformación del Portafolio de ImagiDone:\n${portfolioInfo}\n\nResponde siempre en español.`; chatRef.current = ai.chats.create({ model: 'gemini-3-flash-preview', config: { systemInstruction } }); setMessages([{ sender: 'bot', text: '¡Hola! Soy el asistente de ImagiDone. ¿En qué puedo ayudarte hoy?' }]); }; useEffect(() => { if (isOpen && messages.length === 0) { initializeChat(); } }, [isOpen]); const handleSendMessage = async (e: React.FormEvent) => { e.preventDefault(); if (!input.trim() || isLoading) return; const userMessage: Message = { sender: 'user', text: input }; setMessages(prev => [...prev, userMessage]); setInput(''); setIsLoading(true); try { if (!chatRef.current) { throw new Error('Chat not initialized. API key might be missing.'); } const response = await chatRef.current.sendMessage({ message: input }); const botMessage: Message = { sender: 'bot', text: response.text }; setMessages(prev => [...prev, botMessage]); } catch (error) { console.error('Error sending message to Gemini:', error); const errorMessage: Message = { sender: 'bot', text: 'Lo siento, estoy teniendo problemas para conectarme. Por favor, verifica la configuración de la API o inténtalo de nuevo más tarde.' }; setMessages(prev => [...prev, errorMessage]); } finally { setIsLoading(false); } }; return ( <>

Asistente ImagiDone

{messages.map((msg, index) => (

{msg.text}

))} {isLoading && (
)}
setInput(e.target.value)} placeholder="Escribe tu pregunta..." className="flex-1 bg-brand-gray-light border border-gray-600 rounded-full py-2 px-4 text-white placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-brand-red" disabled={isLoading || messages.length === 0} />
); }; interface AdminProps { onLogout: () => void; navLinks: NavLink[]; setNavLinks: React.Dispatch>; services: Service[]; setServices: React.Dispatch>; portfolioItems: PortfolioItem[]; setPortfolioItems: React.Dispatch>; } const Admin: React.FC = ({ onLogout, navLinks, setNavLinks, services, setServices, portfolioItems, setPortfolioItems }) => { const [isLoggedIn, setIsLoggedIn] = useState(false); const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); const [error, setError] = useState(''); const [localNavLinks, setLocalNavLinks] = useState(navLinks); const [localServices, setLocalServices] = useState(services); const [localPortfolio, setLocalPortfolio] = useState(portfolioItems); const handleLogin = (e: React.FormEvent) => { e.preventDefault(); if (username === 'ima2018' && password === 'DunnCorp@6775') { setIsLoggedIn(true); setError(''); } else { setError('Usuario o contraseña incorrectos.'); } }; const handleSave = () => { setNavLinks(localNavLinks); setServices(localServices); setPortfolioItems(localPortfolio); alert('¡Contenido guardado exitosamente!'); onLogout(); }; const handleNavLinkChange = (index: number, field: keyof NavLink, value: string) => { const updated = [...localNavLinks]; updated[index] = { ...updated[index], [field]: value }; setLocalNavLinks(updated); }; const handleServiceChange = (index: number, field: keyof Service, value: string) => { const updated = [...localServices]; const serviceToUpdate = { ...updated[index] }; if (field === 'title' || field === 'description') { serviceToUpdate[field] = value; } updated[index] = serviceToUpdate; setLocalServices(updated); }; const handlePortfolioChange = (index: number, field: keyof PortfolioItem, value: string) => { const updated = [...localPortfolio]; const itemToUpdate = { ...updated[index] }; if (field === 'title' || field === 'description' || field === 'imageUrl') { itemToUpdate[field] = value; } updated[index] = itemToUpdate; setLocalPortfolio(updated); }; if (!isLoggedIn) { return (

Admin Login

setUsername(e.target.value)} className="w-full bg-gray-700 text-white p-3 rounded-md focus:outline-none focus:ring-2 focus:ring-brand-red" /> setPassword(e.target.value)} className="w-full bg-gray-700 text-white p-3 rounded-md focus:outline-none focus:ring-2 focus:ring-brand-red" /> {error &&

{error}

}
); } return (

Panel de Administración

Menú de Navegación

{localNavLinks.map((link, index) => (
handleNavLinkChange(index, 'label', e.target.value)} className="bg-gray-700 p-2 rounded-md" placeholder="Texto del botón"/> handleNavLinkChange(index, 'href', e.target.value)} className="bg-gray-700 p-2 rounded-md" placeholder="Enlace (ej. #services)"/>
))}

Servicios

{localServices.map((service, index) => (
{servicesData[index].icon}
handleServiceChange(index, 'title', e.target.value)} className="bg-gray-700 p-2 rounded-md w-full font-bold"/>