Cristobal299 commited on
Commit
72d7bb2
·
1 Parent(s): 8da132a

Interfaz a pantalla completa y clonado exacto

Browse files
Files changed (2) hide show
  1. app.py +12 -19
  2. index.html +28 -39
app.py CHANGED
@@ -15,38 +15,32 @@ class GenerateRequest(BaseModel):
15
  @app.post("/api/generate")
16
  async def generate_site(data: GenerateRequest):
17
  try:
18
- # 1. Scrapeamos la web original para entender qué hacen
19
- r = requests.get(data.url, headers={'User-Agent': 'Mozilla/5.0'}, timeout=10)
20
  soup = BeautifulSoup(r.text, 'html.parser')
21
- texto_original = soup.get_text()[:3000] # Cogemos lo esencial
22
 
23
- # 2. La IA actúa como Diseñador Web Pro
24
  prompt = (
25
- f"Actúa como un Desarrollador Frontend experto en Tailwind CSS. \n"
26
- f"Debes crear una LANDING PAGE moderna y elegante basada en este negocio: {texto_original}. \n\n"
27
- f"REGLAS DEL DISEÑO:\n"
28
- f"1. Nombre del negocio: {data.nuevo_nombre}.\n"
29
- f"2. Color principal: {data.color_primario} (usa clases de Tailwind como 'bg-{data.color_primario}-600').\n"
30
- f"3. Estilo: Minimalista, con sombras (shadow-xl) y bordes redondeados (rounded-3xl).\n"
31
- f"4. Estructura: Hero con imagen, sección de Servicios, sección de 'Sobre nosotros' y un Formulario de contacto.\n"
32
- f"5. Fotos: Usa fotos de alta calidad de Unsplash (ej: https://images.unsplash.com/photo-XXXXX?auto=format&fit=crop&w=800).\n\n"
33
- f"IMPORTANTE: Devuelve SOLO el código HTML con Tailwind (usando el CDN de Tailwind). No des explicaciones."
34
  )
35
 
36
  payload = {
37
  "model": "llama-3.3-70b-versatile",
38
- "messages": [{"role": "system", "content": "Eres un generador de código HTML/Tailwind."},
39
- {"role": "user", "content": prompt}],
40
- "max_tokens": 4000
41
  }
42
 
43
  headers = {"Authorization": f"Bearer {GROQ_API_KEY}"}
44
  r_ia = requests.post("https://api.groq.com/openai/v1/chat/completions", json=payload, headers=headers)
45
  html_generado = r_ia.json()["choices"][0]["message"]["content"]
46
 
47
- # Limpiar posibles etiquetas de markdown que ponga la IA
48
  html_final = re.sub(r'```html|```', '', html_generado).strip()
49
-
50
  return {"status": "success", "html": html_final}
51
  except Exception as e:
52
  return JSONResponse({"status": "error", "detail": str(e)}, status_code=400)
@@ -54,4 +48,3 @@ async def generate_site(data: GenerateRequest):
54
  @app.get("/", response_class=HTMLResponse)
55
  async def index():
56
  with open("index.html", "r", encoding="utf-8") as f: return f.read()
57
-
 
15
  @app.post("/api/generate")
16
  async def generate_site(data: GenerateRequest):
17
  try:
18
+ r = requests.get(data.url, headers={'User-Agent': 'Mozilla/5.0'}, timeout=12)
 
19
  soup = BeautifulSoup(r.text, 'html.parser')
20
+ texto_original = soup.get_text()[:4000]
21
 
 
22
  prompt = (
23
+ f"Actúa como un clonador de webs experto en HTML y Tailwind CSS. \n"
24
+ f"Tu objetivo es crear una página que tenga la MISMA ESTRUCTURA Y SECCIONES que esta información original: {texto_original}. \n"
25
+ f"REGLAS ESTRICTAS:\n"
26
+ f"1. Sustituye el nombre del negocio original por: {data.nuevo_nombre}.\n"
27
+ f"2. Cambia todos los colores principales para usar la paleta: {data.color_primario} (ej: bg-{data.color_primario}-600, text-{data.color_primario}-500).\n"
28
+ f"3. Mantén los mismos servicios, textos y el mismo enfoque de ventas que la web original, no te inventes cosas nuevas.\n"
29
+ f"4. Diseño profesional, a pantalla completa.\n"
30
+ f"5. Devuelve SOLO el código HTML completo con Tailwind embebido, sin Markdown, sin explicaciones previas ni posteriores."
 
31
  )
32
 
33
  payload = {
34
  "model": "llama-3.3-70b-versatile",
35
+ "messages": [{"role": "system", "content": "Eres un experto en clonación y diseño web."},
36
+ {"role": "user", "content": prompt}]
 
37
  }
38
 
39
  headers = {"Authorization": f"Bearer {GROQ_API_KEY}"}
40
  r_ia = requests.post("https://api.groq.com/openai/v1/chat/completions", json=payload, headers=headers)
41
  html_generado = r_ia.json()["choices"][0]["message"]["content"]
42
 
 
43
  html_final = re.sub(r'```html|```', '', html_generado).strip()
 
44
  return {"status": "success", "html": html_final}
45
  except Exception as e:
46
  return JSONResponse({"status": "error", "detail": str(e)}, status_code=400)
 
48
  @app.get("/", response_class=HTMLResponse)
49
  async def index():
50
  with open("index.html", "r", encoding="utf-8") as f: return f.read()
 
index.html CHANGED
@@ -5,47 +5,32 @@
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
  <title>IA Web Re-Designer</title>
7
  <script src="https://cdn.tailwindcss.com"></script>
 
8
  </head>
9
- <body class="bg-slate-900 text-white min-h-screen p-4 md:p-10">
10
 
11
- <div class="max-w-6xl mx-auto">
12
- <div class="text-center mb-10">
13
- <h1 class="text-4xl font-bold mb-2">IA Web Re-Designer 🚀</h1>
14
- <p class="text-slate-400">Clona y mejora cualquier web en segundos</p>
15
- </div>
16
-
17
- <div class="grid md:grid-cols-3 gap-8">
18
- <div class="bg-slate-800 p-6 rounded-3xl border border-slate-700 h-fit">
19
- <div class="space-y-4">
20
- <div>
21
- <label class="block text-xs font-bold text-slate-500 uppercase mb-2">URL Original</label>
22
- <input type="text" id="url" placeholder="https://web-vieja.com" class="w-full p-3 rounded-xl bg-slate-900 border border-slate-600 outline-none focus:border-blue-500">
23
- </div>
24
- <div>
25
- <label class="block text-xs font-bold text-slate-500 uppercase mb-2">Nuevo Nombre</label>
26
- <input type="text" id="nombre" placeholder="Mi Nueva Clínica" class="w-full p-3 rounded-xl bg-slate-900 border border-slate-600 outline-none focus:border-blue-500">
27
- </div>
28
- <div>
29
- <label class="block text-xs font-bold text-slate-500 uppercase mb-2">Color (Tailwind: blue, red, emerald...)</label>
30
- <input type="text" id="color" placeholder="blue" class="w-full p-3 rounded-xl bg-slate-900 border border-slate-600 outline-none focus:border-blue-500">
31
- </div>
32
- <button onclick="generarWeb()" id="btn" class="w-full bg-blue-600 p-4 rounded-2xl font-bold hover:bg-blue-500 transition-all shadow-lg shadow-blue-900/20">
33
- REDISEÑAR AHORA
34
- </button>
35
- </div>
36
- </div>
37
-
38
- <div class="md:col-span-2">
39
- <div class="bg-white rounded-3xl overflow-hidden shadow-2xl h-[600px] border-4 border-slate-800">
40
- <iframe id="preview" class="w-full h-full" srcdoc="<div style='display:flex; height:100%; align-items:center; justify-content:center; font-family:sans-serif; color:#94a3b8'>La nueva web aparecerá aquí...</div>"></iframe>
41
- </div>
42
- </div>
43
  </div>
44
  </div>
45
 
 
 
46
  <script>
47
  async function generarWeb() {
48
  const btn = document.getElementById('btn');
 
49
  const preview = document.getElementById('preview');
50
 
51
  const data = {
@@ -54,9 +39,9 @@
54
  color_primario: document.getElementById('color').value
55
  };
56
 
57
- if(!data.url || !data.nuevo_nombre) return alert("Rellena los datos");
58
 
59
- btn.innerHTML = " Diseñando con IA...";
60
  btn.disabled = true;
61
 
62
  try {
@@ -68,14 +53,18 @@
68
  const result = await res.json();
69
 
70
  if(result.status === "success") {
 
 
 
71
  preview.srcdoc = result.html;
72
  } else {
73
- alert("Error en la generación");
 
 
74
  }
75
  } catch(e) {
76
- alert("Error de conexión");
77
- } finally {
78
- btn.innerHTML = "REDISEÑAR AHORA";
79
  btn.disabled = false;
80
  }
81
  }
 
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
  <title>IA Web Re-Designer</title>
7
  <script src="https://cdn.tailwindcss.com"></script>
8
+ <style> body { overflow: hidden; } </style>
9
  </head>
10
+ <body class="bg-slate-50">
11
 
12
+ <div id="setup-panel" class="absolute inset-0 flex items-center justify-center z-50 p-4">
13
+ <div class="bg-white p-8 md:p-12 rounded-[40px] shadow-2xl shadow-blue-100 w-full max-w-md text-center border border-slate-100">
14
+ <div class="w-16 h-16 bg-emerald-500 rounded-2xl mx-auto mb-6 flex items-center justify-center text-white text-3xl font-bold shadow-lg shadow-emerald-200">🎨</div>
15
+ <h1 class="text-3xl font-bold text-slate-900 mb-2">Web Re-Designer</h1>
16
+ <p class="text-slate-500 mb-8 font-medium">Clona y cambia de color cualquier web</p>
17
+
18
+ <input type="text" id="url" placeholder="URL original (Ej: https://...)" class="w-full p-4 rounded-2xl bg-slate-50 border border-slate-200 mb-4 outline-none focus:ring-2 focus:ring-emerald-500">
19
+ <input type="text" id="nombre" placeholder="Nuevo Nombre del Negocio" class="w-full p-4 rounded-2xl bg-slate-50 border border-slate-200 mb-4 outline-none focus:ring-2 focus:ring-emerald-500">
20
+ <input type="text" id="color" placeholder="Color (blue, red, emerald, purple...)" class="w-full p-4 rounded-2xl bg-slate-50 border border-slate-200 mb-6 outline-none focus:ring-2 focus:ring-emerald-500">
21
+
22
+ <button onclick="generarWeb()" id="btn" class="w-full bg-emerald-500 text-white py-4 rounded-2xl font-bold shadow-xl shadow-emerald-200 hover:bg-emerald-600 transition-all">
23
+ CLONAR Y REDISEÑAR
24
+ </button>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  </div>
26
  </div>
27
 
28
+ <iframe id="preview" class="w-full h-screen border-none hidden absolute top-0 left-0 z-10"></iframe>
29
+
30
  <script>
31
  async function generarWeb() {
32
  const btn = document.getElementById('btn');
33
+ const panel = document.getElementById('setup-panel');
34
  const preview = document.getElementById('preview');
35
 
36
  const data = {
 
39
  color_primario: document.getElementById('color').value
40
  };
41
 
42
+ if(!data.url || !data.nuevo_nombre) return alert("Faltan datos por rellenar");
43
 
44
+ btn.innerHTML = " Escaneando y programando...";
45
  btn.disabled = true;
46
 
47
  try {
 
53
  const result = await res.json();
54
 
55
  if(result.status === "success") {
56
+ // Ocultar panel y mostrar web a pantalla completa
57
+ panel.style.display = 'none';
58
+ preview.style.display = 'block';
59
  preview.srcdoc = result.html;
60
  } else {
61
+ alert("Error al clonar la web.");
62
+ btn.innerHTML = "CLONAR Y REDISEÑAR";
63
+ btn.disabled = false;
64
  }
65
  } catch(e) {
66
+ alert("Error de conexión con la IA.");
67
+ btn.innerHTML = "CLONAR Y REDISEÑAR";
 
68
  btn.disabled = false;
69
  }
70
  }