|
import gradio as gr |
|
import re |
|
from agent import HektoreAgent |
|
|
|
def rgba_to_hex(color: str) -> str: |
|
if color.startswith("#"): |
|
return color |
|
|
|
match = re.match(r"rgba?\(([\d.]+),\s*([\d.]+),\s*([\d.]+)", color) |
|
if not match: |
|
return "#000000" |
|
|
|
r, g, b = map(lambda x: int(float(x)), match.groups()) |
|
return "#{:02x}{:02x}{:02x}".format(r, g, b) |
|
|
|
|
|
SECTIONS = [ |
|
"Header with logo and top bar. No Hero block, just header menu with svg", |
|
"Hero section: with background gradient, headline, subtext, and CTA button. Must be at least 600px height.", |
|
"Trusted by / Our fake Clients logos section (use placeholder logos)", |
|
"Services section: at least 3 cards, each with icon, title, and description", |
|
"About / mission section with side image and text block", |
|
"Fake Testimonials carousel with names, quotes, and photos (placeholders OK)", |
|
"CTA section to contact or get a quote", |
|
"Newsletter sign-up form with email input", |
|
"Footer: multiple columns (nav, contact, social icons)" |
|
] |
|
|
|
def generate_full_site_streaming(brief, colorOne, colorTwo, language, company_name): |
|
agent = HektoreAgent() |
|
full_html = "" |
|
|
|
color1_hex = rgba_to_hex(colorOne) |
|
color2_hex = rgba_to_hex(colorTwo) |
|
|
|
for section in SECTIONS: |
|
section_html = agent(section, brief, color1_hex, color2_hex, language, company_name, full_html, additional_args={}) |
|
full_html += section_html + "\n" |
|
yield f""" |
|
<div id='loading-message' style='text-align:center; font-size:18px; margin-bottom: 20px;'>⏳ Website is building...</div> |
|
{wrap_iframe_preview(build_full_html(full_html))} |
|
""" |
|
|
|
|
|
|
|
def wrap_iframe_preview(content: str) -> str: |
|
escaped = content.replace('"', '"').replace("'", "'") |
|
return f""" |
|
<div style="border: 1px solid #ccc; border-radius: 8px; overflow: hidden; box-shadow: 0 0 10px rgba(0,0,0,0.1);"> |
|
<iframe |
|
sandbox="allow-scripts" |
|
width="100%" |
|
height="800px" |
|
style="border: none;" |
|
srcdoc="{escaped}" |
|
></iframe> |
|
</div> |
|
""" |
|
|
|
def build_full_html(content: str) -> str: |
|
return f"""<!DOCTYPE html> |
|
<html lang="en"> |
|
<head> |
|
<meta charset="UTF-8" /> |
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
|
<script src="https://cdn.tailwindcss.com"></script> |
|
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/cdn.min.js" defer></script> |
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.css" /> |
|
<script src="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.js"></script> |
|
<link |
|
rel="stylesheet" |
|
href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css" |
|
/> |
|
<script src="https://unpkg.com/micromodal/dist/micromodal.min.js"></script> |
|
<style> |
|
body {{ |
|
background-color: #f0f0f0; |
|
margin: 0; |
|
padding: 0rem; |
|
font-family: sans-serif; |
|
}} |
|
|
|
</style> |
|
</head> |
|
<body class="bg-gray-100 text-gray-900"> |
|
{content} |
|
</body> |
|
</html>""" |
|
|
|
def wrap_iframe_preview(html: str) -> str: |
|
escaped = html.replace('"', '"').replace("'", "'") |
|
return f""" |
|
<iframe |
|
sandbox="allow-scripts" |
|
width="100%" |
|
height="900px" |
|
style="border: none; border-radius: 8px; box-shadow: 0 0 10px rgba(0,0,0,0.1);" |
|
srcdoc="{escaped}" |
|
></iframe> |
|
""" |
|
|
|
|
|
with gr.Blocks() as demo: |
|
gr.Markdown("## 🧬 Full Website Generator from a Brief") |
|
company_name = gr.Textbox(label="Company or project name", value="Klovis", placeholder="Ex. : OpenAI") |
|
|
|
brief = gr.Textbox(label="Describe your project or company", lines=6, value="We are a cutting-edge AI consulting agency dedicated to helping businesses harness the full power of artificial intelligence. Our mission is to make AI accessible, strategic, and impactful for organizations across industries. We offer a comprehensive range of services including AI solution development, strategic consulting, team training, system integration, and innovation roadmapping. We work closely with enterprise clients in sectors such as finance, healthcare, e-commerce, logistics, and manufacturing to deliver tailored solutions that enhance efficiency, improve decision-making, and unlock new business opportunities.") |
|
with gr.Row(): |
|
color_primary = gr.ColorPicker(label="Primary color", value="#5836AC") |
|
color_secondary = gr.ColorPicker(label="Secondary color", value="#B21CC4") |
|
|
|
language = gr.Dropdown( |
|
label="Website language", |
|
choices=["French", "English", "Spanish", "German"], |
|
value="English" |
|
) |
|
|
|
generate_btn = gr.Button("⚡ Generate (can take few minutes)") |
|
html_output = gr.HTML(value=wrap_iframe_preview(""" |
|
<div id='loading-message' style='text-align:center; font-size:18px; margin-top: 40px;'>⏳ Website is building...</div> |
|
""")) |
|
|
|
generate_btn.click(fn=generate_full_site_streaming, inputs=[brief, color_primary, color_secondary, language, company_name], outputs=html_output) |
|
|
|
demo.launch() |
|
|