Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -4,13 +4,59 @@ from crewai import Agent, Task, Crew, Process, LLM
|
|
| 4 |
from crewai_tools import FileWriterTool
|
| 5 |
from dotenv import load_dotenv
|
| 6 |
import traceback
|
|
|
|
|
|
|
|
|
|
| 7 |
|
| 8 |
load_dotenv()
|
| 9 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
# --- 1. SET UP THE GEMINI LLM ---
|
| 11 |
try:
|
| 12 |
llm = LLM(
|
| 13 |
-
model="gemini/gemini-2.
|
| 14 |
temperature=0.6,
|
| 15 |
api_key=os.environ.get("GOOGLE_API_KEY")
|
| 16 |
)
|
|
@@ -44,7 +90,8 @@ designer = Agent(
|
|
| 44 |
"- Mobile-first responsive breakpoints\n"
|
| 45 |
"- Accessibility (contrast ratios, focus states, ARIA)\n"
|
| 46 |
"- Performance (optimized assets, loading strategies)\n"
|
| 47 |
-
"- Brand consistency and design tokens"
|
|
|
|
| 48 |
),
|
| 49 |
verbose=True,
|
| 50 |
llm=llm,
|
|
@@ -68,7 +115,8 @@ copywriter = Agent(
|
|
| 68 |
"- Active voice and direct language\n"
|
| 69 |
"- Scannable content with proper heading hierarchy\n"
|
| 70 |
"- Benefits-focused rather than features-focused\n"
|
| 71 |
-
"- Appropriate reading level for target audience"
|
|
|
|
| 72 |
),
|
| 73 |
verbose=True,
|
| 74 |
llm=llm,
|
|
@@ -89,6 +137,11 @@ developer = Agent(
|
|
| 89 |
"- AOS (Animate On Scroll) for scroll-triggered animations\n"
|
| 90 |
"- CSS animations and transitions (cubic-bezier, keyframes)\n"
|
| 91 |
"- Intersection Observer API for performance\n\n"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 92 |
"**UI Components:**\n"
|
| 93 |
"- Hero sections with parallax/gradient backgrounds\n"
|
| 94 |
"- Cards with hover effects and shadows\n"
|
|
@@ -112,7 +165,8 @@ developer = Agent(
|
|
| 112 |
"- Smooth scrolling behavior\n"
|
| 113 |
"- Hover states and micro-interactions\n"
|
| 114 |
"- Mobile hamburger menu when needed\n"
|
| 115 |
-
"- Consistent spacing using design tokens"
|
|
|
|
| 116 |
),
|
| 117 |
verbose=True,
|
| 118 |
llm=llm,
|
|
@@ -124,42 +178,53 @@ developer = Agent(
|
|
| 124 |
design_task = Task(
|
| 125 |
description=(
|
| 126 |
"Analyze the user's prompt: '{prompt}' and create a comprehensive Design System Brief.\n\n"
|
|
|
|
| 127 |
"**Required Deliverables:**\n\n"
|
| 128 |
-
"1. **
|
|
|
|
|
|
|
|
|
|
|
|
|
| 129 |
" - Primary color (brand identity, CTAs)\n"
|
| 130 |
" - Secondary color (accents, highlights)\n"
|
| 131 |
" - Background colors (light/dark mode if applicable)\n"
|
| 132 |
" - Text colors (headings, body, muted)\n"
|
| 133 |
" - Semantic colors (success, warning, error)\n"
|
| 134 |
" - Provide exact hex codes and ensure WCAG AA contrast ratios\n\n"
|
| 135 |
-
"
|
| 136 |
" - Primary font (headings) from Google Fonts with fallbacks\n"
|
| 137 |
" - Secondary font (body text) from Google Fonts with fallbacks\n"
|
| 138 |
" - Font size scale (h1: Xpx, h2: Xpx, body: Xpx, small: Xpx)\n"
|
| 139 |
" - Line heights and letter spacing recommendations\n"
|
| 140 |
" - Font weights to use (300, 400, 600, 700)\n\n"
|
| 141 |
-
"
|
| 142 |
" - Base spacing unit (4px or 8px)\n"
|
| 143 |
" - Section padding/margins (mobile and desktop)\n"
|
| 144 |
" - Container max-width\n"
|
| 145 |
" - Grid system (columns, gaps)\n\n"
|
| 146 |
-
"
|
| 147 |
" - Button styles (primary, secondary, ghost)\n"
|
| 148 |
" - Card designs with shadows/borders\n"
|
| 149 |
" - Navigation style (sticky header, transparent, solid)\n"
|
| 150 |
" - Form input styles\n"
|
| 151 |
" - Image treatment (rounded corners, shadows, overlays)\n\n"
|
| 152 |
-
"
|
| 153 |
" - Scroll animations (fade, slide, zoom)\n"
|
| 154 |
" - Hover effects (buttons, cards, links)\n"
|
| 155 |
" - Transition timings (fast: 150ms, normal: 300ms, slow: 500ms)\n"
|
| 156 |
" - Easing functions to use\n\n"
|
| 157 |
-
"
|
| 158 |
-
" -
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 159 |
" - Hero section (with specific layout description)\n"
|
| 160 |
" - 3-5 main content sections with purposes\n"
|
| 161 |
-
" - Footer with sitemap\n
|
| 162 |
-
"
|
|
|
|
| 163 |
" - Overall aesthetic (minimalist, bold, playful, corporate, etc.)\n"
|
| 164 |
" - Imagery style (photos, illustrations, abstract)\n"
|
| 165 |
" - Border radius approach (sharp, slightly rounded, very rounded)\n"
|
|
@@ -167,7 +232,9 @@ design_task = Task(
|
|
| 167 |
" - Any specific design trends to incorporate"
|
| 168 |
),
|
| 169 |
expected_output=(
|
| 170 |
-
"A detailed, structured Design System Brief in markdown format with all
|
|
|
|
|
|
|
| 171 |
"Include specific values, measurements, and clear implementation guidelines. "
|
| 172 |
"The brief should be detailed enough for a developer to implement without additional questions."
|
| 173 |
),
|
|
@@ -177,36 +244,45 @@ design_task = Task(
|
|
| 177 |
copywriting_task = Task(
|
| 178 |
description=(
|
| 179 |
"Using the Design Brief, write comprehensive, professional website copy.\n\n"
|
|
|
|
| 180 |
"**Content Requirements:**\n\n"
|
| 181 |
-
"1. **
|
|
|
|
|
|
|
|
|
|
|
|
|
| 182 |
" - Main headline (6-10 words, powerful, benefit-focused)\n"
|
| 183 |
" - Subheadline (15-25 words, supporting the headline)\n"
|
| 184 |
" - Primary CTA text (2-4 words, action-oriented)\n"
|
| 185 |
" - Secondary CTA text if needed\n\n"
|
| 186 |
-
"
|
| 187 |
" - Section headline\n"
|
| 188 |
" - 2-3 paragraphs explaining who/what/why (100-150 words)\n"
|
| 189 |
" - Key value propositions (3-4 bullet points)\n\n"
|
| 190 |
-
"
|
| 191 |
" - Section headline\n"
|
| 192 |
" - 3-6 feature/service cards, each with:\n"
|
| 193 |
" * Title (3-5 words)\n"
|
| 194 |
" * Description (30-50 words)\n"
|
| 195 |
" * Icon suggestion (describe the icon)\n\n"
|
| 196 |
-
"
|
| 197 |
" - Section headline\n"
|
| 198 |
" - 2-3 testimonials with:\n"
|
| 199 |
" * Quote (20-40 words)\n"
|
| 200 |
" * Name and title/company\n\n"
|
| 201 |
-
"
|
| 202 |
" - Headline (compelling, urgent)\n"
|
| 203 |
" - Supporting text (20-40 words)\n"
|
| 204 |
" - CTA button text\n\n"
|
| 205 |
-
"
|
| 206 |
" - Brief tagline or description\n"
|
| 207 |
-
" - Navigation links\n"
|
| 208 |
-
" - Copyright text\n"
|
| 209 |
" - Social media platform suggestions\n\n"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 210 |
"**Writing Guidelines:**\n"
|
| 211 |
"- Match the vibe/tone from the design brief perfectly\n"
|
| 212 |
"- Use active voice and power words\n"
|
|
@@ -217,9 +293,11 @@ copywriting_task = Task(
|
|
| 217 |
"- Write at appropriate reading level for target audience"
|
| 218 |
),
|
| 219 |
expected_output=(
|
| 220 |
-
"A complete Content Map in markdown format with all
|
|
|
|
| 221 |
"Content should be polished, professional, and ready to copy-paste into HTML. "
|
| 222 |
-
"Include clear labels for each content piece and its placement on the page."
|
|
|
|
| 223 |
),
|
| 224 |
agent=copywriter,
|
| 225 |
context=[design_task]
|
|
@@ -227,15 +305,21 @@ copywriting_task = Task(
|
|
| 227 |
|
| 228 |
development_task = Task(
|
| 229 |
description=(
|
| 230 |
-
"Build a complete, production-ready
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 231 |
"**MANDATORY TECHNICAL REQUIREMENTS:**\n\n"
|
| 232 |
-
"1. **HTML Structure:**\n"
|
| 233 |
" ```html\n"
|
| 234 |
" <!DOCTYPE html>\n"
|
| 235 |
" <html lang=\"en\">\n"
|
| 236 |
" <head>\n"
|
| 237 |
" - Meta charset UTF-8\n"
|
| 238 |
" - Viewport meta tag\n"
|
|
|
|
| 239 |
" - SEO meta tags (title, description, keywords)\n"
|
| 240 |
" - Open Graph tags for social sharing\n"
|
| 241 |
" - Favicon (data URI or emoji)\n"
|
|
@@ -247,7 +331,12 @@ development_task = Task(
|
|
| 247 |
" - Custom CSS in <style> tags\n"
|
| 248 |
" </head>\n"
|
| 249 |
" ```\n\n"
|
| 250 |
-
"2. **
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 251 |
" - Use Tailwind utility classes for layout, spacing, and responsive design\n"
|
| 252 |
" - Define custom CSS variables for colors from design brief:\n"
|
| 253 |
" ```css\n"
|
|
@@ -264,7 +353,12 @@ development_task = Task(
|
|
| 264 |
" * Custom button hover effects\n"
|
| 265 |
" * Gradient backgrounds if specified\n"
|
| 266 |
" * Any design-specific styles not achievable with Tailwind\n\n"
|
| 267 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 268 |
" - Initialize AOS in script: `AOS.init({duration: 800, once: true});`\n"
|
| 269 |
" - Add AOS attributes to elements:\n"
|
| 270 |
" * `data-aos=\"fade-up\"` for hero elements\n"
|
|
@@ -276,14 +370,14 @@ development_task = Task(
|
|
| 276 |
" * Cards: lift effect (translateY + shadow)\n"
|
| 277 |
" * Links: color/underline transitions\n"
|
| 278 |
" - Use staggered animations with `data-aos-delay`\n\n"
|
| 279 |
-
"
|
| 280 |
" - Base styles for mobile (320px+)\n"
|
| 281 |
" - Tablet breakpoint (768px): `md:` prefix\n"
|
| 282 |
" - Desktop breakpoint (1024px): `lg:` prefix\n"
|
| 283 |
" - Large desktop (1280px): `xl:` prefix\n"
|
| 284 |
" - Test all sections at each breakpoint\n"
|
| 285 |
" - Mobile navigation (hamburger menu with smooth toggle)\n\n"
|
| 286 |
-
"
|
| 287 |
" - `<header>` with `<nav>` (sticky or fixed)\n"
|
| 288 |
" - `<main>` containing:\n"
|
| 289 |
" * `<section>` for hero with unique background\n"
|
|
@@ -292,53 +386,51 @@ development_task = Task(
|
|
| 292 |
" * `<section>` for testimonials/social proof (if applicable)\n"
|
| 293 |
" * `<section>` for final CTA\n"
|
| 294 |
" - `<footer>` with navigation and credits\n\n"
|
| 295 |
-
"
|
| 296 |
-
" -
|
| 297 |
-
" -
|
| 298 |
-
" -
|
| 299 |
-
" -
|
| 300 |
-
"
|
| 301 |
-
"7. **Accessibility Requirements:**\n"
|
| 302 |
" - Semantic HTML5 elements\n"
|
| 303 |
" - ARIA labels where needed\n"
|
| 304 |
" - Keyboard navigable (focus visible)\n"
|
| 305 |
" - Alt text for all images\n"
|
| 306 |
" - Sufficient color contrast (test against WCAG)\n"
|
| 307 |
" - Skip to content link\n\n"
|
| 308 |
-
"
|
| 309 |
-
" - Defer non-critical scripts\n"
|
| 310 |
-
" - Use font-display: swap for Google Fonts\n"
|
| 311 |
-
" - Minimize custom CSS/JS\n"
|
| 312 |
-
" - Use CSS transforms for animations (GPU accelerated)\n\n"
|
| 313 |
-
"9. **Code Quality:**\n"
|
| 314 |
" - Proper indentation (2 spaces)\n"
|
| 315 |
" - Comments for major sections\n"
|
| 316 |
" - Clean, readable code\n"
|
| 317 |
" - No console errors\n\n"
|
| 318 |
-
"**CRITICAL:** Save
|
| 319 |
-
"
|
| 320 |
-
"**Design Brief Reference:** Use exact colors, fonts, and
|
| 321 |
"**Content Reference:** Use exact copy from the Content Map.\n\n"
|
| 322 |
"Think step-by-step:\n"
|
| 323 |
-
"1.
|
| 324 |
-
"2.
|
| 325 |
-
"3.
|
| 326 |
-
"4.
|
| 327 |
-
"5.
|
| 328 |
-
"6.
|
| 329 |
-
"7.
|
| 330 |
-
"8.
|
| 331 |
-
"9.
|
| 332 |
-
"10.
|
| 333 |
-
"11.
|
|
|
|
|
|
|
| 334 |
),
|
| 335 |
expected_output=(
|
| 336 |
-
"
|
| 337 |
"- Renders perfectly in all modern browsers\n"
|
| 338 |
"- Is fully responsive (mobile to 4K)\n"
|
| 339 |
"- Includes smooth animations and transitions\n"
|
| 340 |
"- Uses Tailwind CSS and AOS library\n"
|
| 341 |
"- Implements the exact design and content from previous tasks\n"
|
|
|
|
|
|
|
| 342 |
"- Has no errors or missing dependencies\n"
|
| 343 |
"- Is production-ready and deployable"
|
| 344 |
),
|
|
@@ -355,63 +447,133 @@ vibe_crew = Crew(
|
|
| 355 |
verbose=True
|
| 356 |
)
|
| 357 |
|
| 358 |
-
# --- 6.
|
| 359 |
-
def
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 360 |
try:
|
| 361 |
if llm is None:
|
| 362 |
return (
|
| 363 |
"❌ **Error:** Gemini LLM not initialized. Please check your GOOGLE_API_KEY in environment variables.",
|
| 364 |
None,
|
| 365 |
gr.update(visible=False),
|
| 366 |
-
gr.update(visible=False)
|
|
|
|
|
|
|
| 367 |
)
|
| 368 |
|
| 369 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 370 |
return (
|
| 371 |
-
"❌ **Error:** Please
|
| 372 |
None,
|
| 373 |
gr.update(visible=False),
|
| 374 |
-
gr.update(visible=False)
|
|
|
|
|
|
|
| 375 |
)
|
| 376 |
|
| 377 |
# Clean up previous output
|
| 378 |
-
|
| 379 |
-
|
|
|
|
| 380 |
|
| 381 |
# Run the crew
|
| 382 |
-
inputs = {'prompt':
|
| 383 |
result = vibe_crew.kickoff(inputs=inputs)
|
| 384 |
|
| 385 |
-
#
|
| 386 |
-
|
| 387 |
-
|
| 388 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 389 |
|
| 390 |
-
|
| 391 |
-
|
| 392 |
-
|
| 393 |
-
|
| 394 |
-
success_message = "✅ **Success!** Your website has been generated with Tailwind CSS and AOS animations. Ready to download!"
|
| 395 |
-
|
| 396 |
return (
|
| 397 |
success_message,
|
| 398 |
preview_html,
|
| 399 |
-
gr.update(value=
|
| 400 |
-
gr.update(visible=True)
|
| 401 |
-
|
| 402 |
-
|
| 403 |
-
return (
|
| 404 |
-
"⚠️ **Warning:** File created but is empty. Please try again.",
|
| 405 |
-
None,
|
| 406 |
-
gr.update(visible=False),
|
| 407 |
-
gr.update(visible=False)
|
| 408 |
)
|
| 409 |
else:
|
|
|
|
| 410 |
return (
|
| 411 |
-
|
| 412 |
-
|
|
|
|
| 413 |
gr.update(visible=False),
|
| 414 |
-
gr.update(visible=
|
|
|
|
| 415 |
)
|
| 416 |
|
| 417 |
except Exception as e:
|
|
@@ -422,48 +584,96 @@ def run_crew(prompt):
|
|
| 422 |
error_message,
|
| 423 |
None,
|
| 424 |
gr.update(visible=False),
|
| 425 |
-
gr.update(visible=False)
|
|
|
|
|
|
|
| 426 |
)
|
| 427 |
|
| 428 |
-
# ---
|
| 429 |
with gr.Blocks(theme=gr.themes.Soft(), css="""
|
| 430 |
.container { max-width: 1400px; margin: auto; }
|
| 431 |
-
.status-box {
|
| 432 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 433 |
""") as iface:
|
| 434 |
|
| 435 |
gr.Markdown(
|
| 436 |
"""
|
| 437 |
# 🎨 Vibe Coder AI - Professional Edition
|
| 438 |
### Create stunning websites with Tailwind CSS & AOS Animations
|
| 439 |
-
|
| 440 |
|
| 441 |
-
**🚀
|
| 442 |
"""
|
| 443 |
)
|
| 444 |
|
| 445 |
-
|
| 446 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 447 |
lines=4,
|
| 448 |
placeholder="Example: A website for my new coffee shop in Brooklyn. The vibe should be cozy, rustic, and artisanal with warm colors and smooth animations.",
|
| 449 |
-
label="✍️ Describe Your Website
|
|
|
|
| 450 |
elem_classes="container"
|
| 451 |
)
|
| 452 |
|
| 453 |
-
|
| 454 |
-
|
|
|
|
|
|
|
|
|
|
| 455 |
|
| 456 |
with gr.Row():
|
| 457 |
-
gr.
|
| 458 |
-
|
| 459 |
-
|
| 460 |
-
|
| 461 |
-
|
| 462 |
-
["A fitness coach website. Vibe: energetic, motivating, and bold with dynamic animations and vibrant colors."],
|
| 463 |
-
["A luxury real estate agency. Vibe: sophisticated, elegant, minimal with subtle animations and gold accents."]
|
| 464 |
-
],
|
| 465 |
-
inputs=prompt_input,
|
| 466 |
-
label="💡 Try these examples"
|
| 467 |
)
|
| 468 |
|
| 469 |
with gr.Row():
|
|
@@ -481,11 +691,17 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
|
|
| 481 |
|
| 482 |
with gr.Row():
|
| 483 |
with gr.Column(scale=1):
|
| 484 |
-
|
| 485 |
label="📥 Download Website (HTML)",
|
| 486 |
visible=False,
|
| 487 |
elem_classes="download-section"
|
| 488 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 489 |
with gr.Column(scale=1):
|
| 490 |
view_code_btn = gr.Button(
|
| 491 |
"👁️ View Source Code",
|
|
@@ -502,29 +718,76 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
|
|
| 502 |
elem_classes="container"
|
| 503 |
)
|
| 504 |
|
| 505 |
-
|
| 506 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 507 |
|
| 508 |
-
def generate_website(
|
| 509 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 510 |
return (
|
| 511 |
status,
|
| 512 |
preview,
|
| 513 |
-
|
| 514 |
-
|
|
|
|
|
|
|
| 515 |
)
|
| 516 |
|
| 517 |
generate_btn.click(
|
| 518 |
fn=generate_website,
|
| 519 |
-
inputs=[
|
| 520 |
-
outputs=[
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 521 |
)
|
| 522 |
|
| 523 |
view_code_btn.click(
|
| 524 |
-
fn=lambda: (
|
|
|
|
|
|
|
|
|
|
| 525 |
inputs=None,
|
| 526 |
outputs=[code_row, code_output]
|
| 527 |
)
|
| 528 |
|
| 529 |
if __name__ == "__main__":
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 530 |
iface.launch(share=False)
|
|
|
|
| 4 |
from crewai_tools import FileWriterTool
|
| 5 |
from dotenv import load_dotenv
|
| 6 |
import traceback
|
| 7 |
+
import shutil
|
| 8 |
+
import glob
|
| 9 |
+
import json
|
| 10 |
|
| 11 |
load_dotenv()
|
| 12 |
|
| 13 |
+
# --- SYSTEM CONSTANTS ---
|
| 14 |
+
PROMPTS_FOR_AI = [
|
| 15 |
+
"🚀 SaaS Landing Page - Modern software startup with pricing, features, and demo CTA",
|
| 16 |
+
"💼 Professional Portfolio - Multi-page developer/designer portfolio with projects gallery",
|
| 17 |
+
"🎮 Interactive Quiz App - Educational quiz with multiple categories and score tracking",
|
| 18 |
+
"🛍️ E-commerce Product Page - Product showcase with cart, reviews, and checkout flow",
|
| 19 |
+
"📚 Online Course Platform - Multi-page learning platform with courses, instructors, and enrollment",
|
| 20 |
+
"🍔 Restaurant Website - Menu, reservations, locations, and online ordering system",
|
| 21 |
+
"🏋️ Fitness Tracker App - Dashboard with workouts, progress charts, and meal planning",
|
| 22 |
+
"📰 News Magazine - Multi-category blog with articles, authors, and comments",
|
| 23 |
+
"🎨 Digital Art Gallery - Virtual exhibition with artist profiles and artwork collections",
|
| 24 |
+
"🏠 Real Estate Platform - Property listings with search, filters, and virtual tours",
|
| 25 |
+
"📅 Event Management - Conference website with schedule, speakers, and registration",
|
| 26 |
+
"🎵 Music Streaming UI - Player interface with playlists, albums, and artist pages",
|
| 27 |
+
"💳 Banking Dashboard - Account overview, transactions, and financial analytics",
|
| 28 |
+
"🎓 University Website - Multi-page campus site with departments, admissions, and student portal",
|
| 29 |
+
"🚗 Car Rental Service - Vehicle catalog with booking system and pricing calculator"
|
| 30 |
+
]
|
| 31 |
+
|
| 32 |
+
PROMPT_FOR_IMAGE_GENERATION = """
|
| 33 |
+
When creating image placeholders or suggesting imagery:
|
| 34 |
+
1. Use professional stock photo services URLs (via placeholder services like unsplash.com/photos/...)
|
| 35 |
+
2. Suggest specific image dimensions (e.g., hero: 1920x1080, thumbnails: 400x300)
|
| 36 |
+
3. Include descriptive alt text for accessibility
|
| 37 |
+
4. Recommend image styles that match the brand (lifestyle, abstract, product shots)
|
| 38 |
+
5. Use CSS gradients or patterns as fallbacks
|
| 39 |
+
6. Ensure images are optimized for web (WebP format suggestion)
|
| 40 |
+
7. Consider lazy loading for performance
|
| 41 |
+
Example placeholder: https://source.unsplash.com/1920x1080/?[keyword]
|
| 42 |
+
"""
|
| 43 |
+
|
| 44 |
+
PROMPT_FOR_PROJECT_NAME = """
|
| 45 |
+
Generate a creative, memorable project name that:
|
| 46 |
+
1. Starts with a relevant emoji that represents the project
|
| 47 |
+
2. Is 2-3 words maximum
|
| 48 |
+
3. Is catchy and brandable
|
| 49 |
+
4. Reflects the project's purpose or vibe
|
| 50 |
+
5. Could work as a domain name
|
| 51 |
+
6. Avoids generic terms
|
| 52 |
+
Examples: "🚀 LaunchPad Pro", "🎨 PixelCraft Studio", "💫 Stellar Pages"
|
| 53 |
+
Format: Always return as "[emoji] [ProjectName]"
|
| 54 |
+
"""
|
| 55 |
+
|
| 56 |
# --- 1. SET UP THE GEMINI LLM ---
|
| 57 |
try:
|
| 58 |
llm = LLM(
|
| 59 |
+
model="gemini/gemini-2.0-flash-exp",
|
| 60 |
temperature=0.6,
|
| 61 |
api_key=os.environ.get("GOOGLE_API_KEY")
|
| 62 |
)
|
|
|
|
| 90 |
"- Mobile-first responsive breakpoints\n"
|
| 91 |
"- Accessibility (contrast ratios, focus states, ARIA)\n"
|
| 92 |
"- Performance (optimized assets, loading strategies)\n"
|
| 93 |
+
"- Brand consistency and design tokens\n\n"
|
| 94 |
+
f"IMAGE GENERATION GUIDELINES:\n{PROMPT_FOR_IMAGE_GENERATION}"
|
| 95 |
),
|
| 96 |
verbose=True,
|
| 97 |
llm=llm,
|
|
|
|
| 115 |
"- Active voice and direct language\n"
|
| 116 |
"- Scannable content with proper heading hierarchy\n"
|
| 117 |
"- Benefits-focused rather than features-focused\n"
|
| 118 |
+
"- Appropriate reading level for target audience\n\n"
|
| 119 |
+
f"PROJECT NAMING GUIDELINES:\n{PROMPT_FOR_PROJECT_NAME}"
|
| 120 |
),
|
| 121 |
verbose=True,
|
| 122 |
llm=llm,
|
|
|
|
| 137 |
"- AOS (Animate On Scroll) for scroll-triggered animations\n"
|
| 138 |
"- CSS animations and transitions (cubic-bezier, keyframes)\n"
|
| 139 |
"- Intersection Observer API for performance\n\n"
|
| 140 |
+
"**Multi-Page Support:**\n"
|
| 141 |
+
"- Create separate HTML files for multi-page projects\n"
|
| 142 |
+
"- Implement consistent navigation across pages\n"
|
| 143 |
+
"- Use relative links between pages\n"
|
| 144 |
+
"- Maintain design consistency across all pages\n\n"
|
| 145 |
"**UI Components:**\n"
|
| 146 |
"- Hero sections with parallax/gradient backgrounds\n"
|
| 147 |
"- Cards with hover effects and shadows\n"
|
|
|
|
| 165 |
"- Smooth scrolling behavior\n"
|
| 166 |
"- Hover states and micro-interactions\n"
|
| 167 |
"- Mobile hamburger menu when needed\n"
|
| 168 |
+
"- Consistent spacing using design tokens\n\n"
|
| 169 |
+
f"IMAGE IMPLEMENTATION:\n{PROMPT_FOR_IMAGE_GENERATION}"
|
| 170 |
),
|
| 171 |
verbose=True,
|
| 172 |
llm=llm,
|
|
|
|
| 178 |
design_task = Task(
|
| 179 |
description=(
|
| 180 |
"Analyze the user's prompt: '{prompt}' and create a comprehensive Design System Brief.\n\n"
|
| 181 |
+
"**PROJECT NAME:** Generate a creative project name following the naming guidelines.\n\n"
|
| 182 |
"**Required Deliverables:**\n\n"
|
| 183 |
+
"1. **Project Overview:**\n"
|
| 184 |
+
" - Creative project name with emoji\n"
|
| 185 |
+
" - Project type (single-page or multi-page)\n"
|
| 186 |
+
" - If multi-page, list all pages needed (e.g., index.html, about.html, contact.html)\n\n"
|
| 187 |
+
"2. **Color Palette (5-7 colors with specific usage):**\n"
|
| 188 |
" - Primary color (brand identity, CTAs)\n"
|
| 189 |
" - Secondary color (accents, highlights)\n"
|
| 190 |
" - Background colors (light/dark mode if applicable)\n"
|
| 191 |
" - Text colors (headings, body, muted)\n"
|
| 192 |
" - Semantic colors (success, warning, error)\n"
|
| 193 |
" - Provide exact hex codes and ensure WCAG AA contrast ratios\n\n"
|
| 194 |
+
"3. **Typography System:**\n"
|
| 195 |
" - Primary font (headings) from Google Fonts with fallbacks\n"
|
| 196 |
" - Secondary font (body text) from Google Fonts with fallbacks\n"
|
| 197 |
" - Font size scale (h1: Xpx, h2: Xpx, body: Xpx, small: Xpx)\n"
|
| 198 |
" - Line heights and letter spacing recommendations\n"
|
| 199 |
" - Font weights to use (300, 400, 600, 700)\n\n"
|
| 200 |
+
"4. **Spacing & Layout System:**\n"
|
| 201 |
" - Base spacing unit (4px or 8px)\n"
|
| 202 |
" - Section padding/margins (mobile and desktop)\n"
|
| 203 |
" - Container max-width\n"
|
| 204 |
" - Grid system (columns, gaps)\n\n"
|
| 205 |
+
"5. **UI Components & Patterns:**\n"
|
| 206 |
" - Button styles (primary, secondary, ghost)\n"
|
| 207 |
" - Card designs with shadows/borders\n"
|
| 208 |
" - Navigation style (sticky header, transparent, solid)\n"
|
| 209 |
" - Form input styles\n"
|
| 210 |
" - Image treatment (rounded corners, shadows, overlays)\n\n"
|
| 211 |
+
"6. **Animation & Interaction Guidelines:**\n"
|
| 212 |
" - Scroll animations (fade, slide, zoom)\n"
|
| 213 |
" - Hover effects (buttons, cards, links)\n"
|
| 214 |
" - Transition timings (fast: 150ms, normal: 300ms, slow: 500ms)\n"
|
| 215 |
" - Easing functions to use\n\n"
|
| 216 |
+
"7. **Image & Media Strategy:**\n"
|
| 217 |
+
" - Follow the image generation guidelines\n"
|
| 218 |
+
" - Specify placeholder images for each section\n"
|
| 219 |
+
" - Include dimensions and alt text requirements\n"
|
| 220 |
+
" - Suggest specific Unsplash keywords for each image\n\n"
|
| 221 |
+
"8. **Page Structure:**\n"
|
| 222 |
+
" - Header/Navigation (consistent across pages if multi-page)\n"
|
| 223 |
" - Hero section (with specific layout description)\n"
|
| 224 |
" - 3-5 main content sections with purposes\n"
|
| 225 |
+
" - Footer with sitemap\n"
|
| 226 |
+
" - Additional pages structure if multi-page project\n\n"
|
| 227 |
+
"9. **Design Style & Aesthetic:**\n"
|
| 228 |
" - Overall aesthetic (minimalist, bold, playful, corporate, etc.)\n"
|
| 229 |
" - Imagery style (photos, illustrations, abstract)\n"
|
| 230 |
" - Border radius approach (sharp, slightly rounded, very rounded)\n"
|
|
|
|
| 232 |
" - Any specific design trends to incorporate"
|
| 233 |
),
|
| 234 |
expected_output=(
|
| 235 |
+
"A detailed, structured Design System Brief in markdown format with all 9 sections completed. "
|
| 236 |
+
"Include the creative project name with emoji at the top. "
|
| 237 |
+
"Clearly specify if this is a single-page or multi-page project. "
|
| 238 |
"Include specific values, measurements, and clear implementation guidelines. "
|
| 239 |
"The brief should be detailed enough for a developer to implement without additional questions."
|
| 240 |
),
|
|
|
|
| 244 |
copywriting_task = Task(
|
| 245 |
description=(
|
| 246 |
"Using the Design Brief, write comprehensive, professional website copy.\n\n"
|
| 247 |
+
"**IMPORTANT:** Use the project name from the Design Brief throughout the content.\n\n"
|
| 248 |
"**Content Requirements:**\n\n"
|
| 249 |
+
"1. **Project Identity:**\n"
|
| 250 |
+
" - Use the creative project name with emoji from the Design Brief\n"
|
| 251 |
+
" - Create a tagline that complements the project name\n"
|
| 252 |
+
" - Establish brand voice based on the project type\n\n"
|
| 253 |
+
"2. **Hero Section:**\n"
|
| 254 |
" - Main headline (6-10 words, powerful, benefit-focused)\n"
|
| 255 |
" - Subheadline (15-25 words, supporting the headline)\n"
|
| 256 |
" - Primary CTA text (2-4 words, action-oriented)\n"
|
| 257 |
" - Secondary CTA text if needed\n\n"
|
| 258 |
+
"3. **About/Value Proposition Section:**\n"
|
| 259 |
" - Section headline\n"
|
| 260 |
" - 2-3 paragraphs explaining who/what/why (100-150 words)\n"
|
| 261 |
" - Key value propositions (3-4 bullet points)\n\n"
|
| 262 |
+
"4. **Features/Services Section:**\n"
|
| 263 |
" - Section headline\n"
|
| 264 |
" - 3-6 feature/service cards, each with:\n"
|
| 265 |
" * Title (3-5 words)\n"
|
| 266 |
" * Description (30-50 words)\n"
|
| 267 |
" * Icon suggestion (describe the icon)\n\n"
|
| 268 |
+
"5. **Social Proof/Testimonials (if applicable):**\n"
|
| 269 |
" - Section headline\n"
|
| 270 |
" - 2-3 testimonials with:\n"
|
| 271 |
" * Quote (20-40 words)\n"
|
| 272 |
" * Name and title/company\n\n"
|
| 273 |
+
"6. **Call-to-Action Section:**\n"
|
| 274 |
" - Headline (compelling, urgent)\n"
|
| 275 |
" - Supporting text (20-40 words)\n"
|
| 276 |
" - CTA button text\n\n"
|
| 277 |
+
"7. **Footer Content:**\n"
|
| 278 |
" - Brief tagline or description\n"
|
| 279 |
+
" - Navigation links (for all pages if multi-page)\n"
|
| 280 |
+
" - Copyright text with project name\n"
|
| 281 |
" - Social media platform suggestions\n\n"
|
| 282 |
+
"8. **Additional Pages Content (if multi-page):**\n"
|
| 283 |
+
" - Content for each additional page specified in the Design Brief\n"
|
| 284 |
+
" - Maintain consistent voice and tone\n"
|
| 285 |
+
" - Include page-specific CTAs and navigation\n\n"
|
| 286 |
"**Writing Guidelines:**\n"
|
| 287 |
"- Match the vibe/tone from the design brief perfectly\n"
|
| 288 |
"- Use active voice and power words\n"
|
|
|
|
| 293 |
"- Write at appropriate reading level for target audience"
|
| 294 |
),
|
| 295 |
expected_output=(
|
| 296 |
+
"A complete Content Map in markdown format with all sections filled out. "
|
| 297 |
+
"The project name with emoji should be prominently featured. "
|
| 298 |
"Content should be polished, professional, and ready to copy-paste into HTML. "
|
| 299 |
+
"Include clear labels for each content piece and its placement on the page. "
|
| 300 |
+
"If multi-page, provide content for all pages specified in the Design Brief."
|
| 301 |
),
|
| 302 |
agent=copywriter,
|
| 303 |
context=[design_task]
|
|
|
|
| 305 |
|
| 306 |
development_task = Task(
|
| 307 |
description=(
|
| 308 |
+
"Build a complete, production-ready website using modern web technologies.\n\n"
|
| 309 |
+
"**CRITICAL INSTRUCTIONS:**\n"
|
| 310 |
+
"1. Check the Design Brief for project type (single-page vs multi-page)\n"
|
| 311 |
+
"2. If SINGLE-PAGE: Save as 'outputs/index.html'\n"
|
| 312 |
+
"3. If MULTI-PAGE: Save each page separately (e.g., 'outputs/index.html', 'outputs/about.html', etc.)\n"
|
| 313 |
+
"4. Use the project name from the Design Brief in all page titles and metadata\n\n"
|
| 314 |
"**MANDATORY TECHNICAL REQUIREMENTS:**\n\n"
|
| 315 |
+
"1. **HTML Structure (for each page):**\n"
|
| 316 |
" ```html\n"
|
| 317 |
" <!DOCTYPE html>\n"
|
| 318 |
" <html lang=\"en\">\n"
|
| 319 |
" <head>\n"
|
| 320 |
" - Meta charset UTF-8\n"
|
| 321 |
" - Viewport meta tag\n"
|
| 322 |
+
" - Title with project name\n"
|
| 323 |
" - SEO meta tags (title, description, keywords)\n"
|
| 324 |
" - Open Graph tags for social sharing\n"
|
| 325 |
" - Favicon (data URI or emoji)\n"
|
|
|
|
| 331 |
" - Custom CSS in <style> tags\n"
|
| 332 |
" </head>\n"
|
| 333 |
" ```\n\n"
|
| 334 |
+
"2. **Multi-Page Navigation (if applicable):**\n"
|
| 335 |
+
" - Consistent navigation bar across all pages\n"
|
| 336 |
+
" - Use relative links (e.g., href=\"about.html\")\n"
|
| 337 |
+
" - Active page highlighting in navigation\n"
|
| 338 |
+
" - Mobile-responsive hamburger menu\n\n"
|
| 339 |
+
"3. **CSS Implementation:**\n"
|
| 340 |
" - Use Tailwind utility classes for layout, spacing, and responsive design\n"
|
| 341 |
" - Define custom CSS variables for colors from design brief:\n"
|
| 342 |
" ```css\n"
|
|
|
|
| 353 |
" * Custom button hover effects\n"
|
| 354 |
" * Gradient backgrounds if specified\n"
|
| 355 |
" * Any design-specific styles not achievable with Tailwind\n\n"
|
| 356 |
+
"4. **Image Implementation:**\n"
|
| 357 |
+
" - Use Unsplash placeholder images as specified in Design Brief\n"
|
| 358 |
+
" - Format: https://source.unsplash.com/[width]x[height]/?[keyword]\n"
|
| 359 |
+
" - Include proper alt text for all images\n"
|
| 360 |
+
" - Add loading=\"lazy\" for performance\n\n"
|
| 361 |
+
"5. **Animation Implementation:**\n"
|
| 362 |
" - Initialize AOS in script: `AOS.init({duration: 800, once: true});`\n"
|
| 363 |
" - Add AOS attributes to elements:\n"
|
| 364 |
" * `data-aos=\"fade-up\"` for hero elements\n"
|
|
|
|
| 370 |
" * Cards: lift effect (translateY + shadow)\n"
|
| 371 |
" * Links: color/underline transitions\n"
|
| 372 |
" - Use staggered animations with `data-aos-delay`\n\n"
|
| 373 |
+
"6. **Responsive Design (Mobile-First):**\n"
|
| 374 |
" - Base styles for mobile (320px+)\n"
|
| 375 |
" - Tablet breakpoint (768px): `md:` prefix\n"
|
| 376 |
" - Desktop breakpoint (1024px): `lg:` prefix\n"
|
| 377 |
" - Large desktop (1280px): `xl:` prefix\n"
|
| 378 |
" - Test all sections at each breakpoint\n"
|
| 379 |
" - Mobile navigation (hamburger menu with smooth toggle)\n\n"
|
| 380 |
+
"7. **Required Sections (use semantic HTML):**\n"
|
| 381 |
" - `<header>` with `<nav>` (sticky or fixed)\n"
|
| 382 |
" - `<main>` containing:\n"
|
| 383 |
" * `<section>` for hero with unique background\n"
|
|
|
|
| 386 |
" * `<section>` for testimonials/social proof (if applicable)\n"
|
| 387 |
" * `<section>` for final CTA\n"
|
| 388 |
" - `<footer>` with navigation and credits\n\n"
|
| 389 |
+
"8. **File Saving Instructions:**\n"
|
| 390 |
+
" - Single-page: Save to 'outputs/index.html'\n"
|
| 391 |
+
" - Multi-page: Save each page with descriptive names\n"
|
| 392 |
+
" - Ensure all internal links work correctly\n"
|
| 393 |
+
" - Test navigation between pages\n\n"
|
| 394 |
+
"9. **Accessibility Requirements:**\n"
|
|
|
|
| 395 |
" - Semantic HTML5 elements\n"
|
| 396 |
" - ARIA labels where needed\n"
|
| 397 |
" - Keyboard navigable (focus visible)\n"
|
| 398 |
" - Alt text for all images\n"
|
| 399 |
" - Sufficient color contrast (test against WCAG)\n"
|
| 400 |
" - Skip to content link\n\n"
|
| 401 |
+
"10. **Code Quality:**\n"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 402 |
" - Proper indentation (2 spaces)\n"
|
| 403 |
" - Comments for major sections\n"
|
| 404 |
" - Clean, readable code\n"
|
| 405 |
" - No console errors\n\n"
|
| 406 |
+
"**CRITICAL:** Save all HTML files to 'outputs/' directory using FileWriterTool.\n"
|
| 407 |
+
"Files must be immediately viewable in a browser without any modifications.\n\n"
|
| 408 |
+
"**Design Brief Reference:** Use exact colors, fonts, spacing, and project name from the Design Brief.\n"
|
| 409 |
"**Content Reference:** Use exact copy from the Content Map.\n\n"
|
| 410 |
"Think step-by-step:\n"
|
| 411 |
+
"1. Identify if single-page or multi-page from Design Brief\n"
|
| 412 |
+
"2. Set up HTML boilerplate with all CDN links\n"
|
| 413 |
+
"3. Define CSS variables for the color palette\n"
|
| 414 |
+
"4. Build header/navigation (with multi-page links if applicable)\n"
|
| 415 |
+
"5. Create hero section with animations\n"
|
| 416 |
+
"6. Build each content section with appropriate Tailwind classes\n"
|
| 417 |
+
"7. Add AOS animations to key elements\n"
|
| 418 |
+
"8. Implement hover effects and transitions\n"
|
| 419 |
+
"9. Build responsive footer\n"
|
| 420 |
+
"10. Add mobile menu functionality\n"
|
| 421 |
+
"11. For multi-page: Repeat for each additional page\n"
|
| 422 |
+
"12. Test responsive breakpoints\n"
|
| 423 |
+
"13. Save all files to outputs/ directory"
|
| 424 |
),
|
| 425 |
expected_output=(
|
| 426 |
+
"Complete, self-contained HTML file(s) saved to 'outputs/' directory that:\n"
|
| 427 |
"- Renders perfectly in all modern browsers\n"
|
| 428 |
"- Is fully responsive (mobile to 4K)\n"
|
| 429 |
"- Includes smooth animations and transitions\n"
|
| 430 |
"- Uses Tailwind CSS and AOS library\n"
|
| 431 |
"- Implements the exact design and content from previous tasks\n"
|
| 432 |
+
"- Uses the project name consistently\n"
|
| 433 |
+
"- Has working navigation for multi-page projects\n"
|
| 434 |
"- Has no errors or missing dependencies\n"
|
| 435 |
"- Is production-ready and deployable"
|
| 436 |
),
|
|
|
|
| 447 |
verbose=True
|
| 448 |
)
|
| 449 |
|
| 450 |
+
# --- 6. HELPER FUNCTIONS ---
|
| 451 |
+
def clean_outputs_directory():
|
| 452 |
+
"""Clean the outputs directory before generating new files."""
|
| 453 |
+
if os.path.exists("outputs"):
|
| 454 |
+
for file in glob.glob("outputs/*"):
|
| 455 |
+
try:
|
| 456 |
+
os.remove(file)
|
| 457 |
+
except Exception as e:
|
| 458 |
+
print(f"Error removing {file}: {e}")
|
| 459 |
+
|
| 460 |
+
def create_zip_archive():
|
| 461 |
+
"""Create a ZIP archive of all files in the outputs directory."""
|
| 462 |
+
try:
|
| 463 |
+
# Get all HTML files in outputs directory
|
| 464 |
+
html_files = glob.glob("outputs/*.html")
|
| 465 |
+
|
| 466 |
+
if len(html_files) > 1:
|
| 467 |
+
# Create ZIP file
|
| 468 |
+
shutil.make_archive("outputs/project", 'zip', "outputs")
|
| 469 |
+
return "outputs/project.zip"
|
| 470 |
+
return None
|
| 471 |
+
except Exception as e:
|
| 472 |
+
print(f"Error creating ZIP: {e}")
|
| 473 |
+
return None
|
| 474 |
+
|
| 475 |
+
def extract_project_name(result_text):
|
| 476 |
+
"""Extract project name from the crew result."""
|
| 477 |
+
try:
|
| 478 |
+
# Look for emoji + project name pattern
|
| 479 |
+
import re
|
| 480 |
+
pattern = r'([🚀🎨💫🌟✨🎯🔥💎🌈🎭🎪🎸🎬🎮🎯💼🏆🌸🦄🍕🍔🛍️📚🏠🏋️📰🎵💳🎓🚗][^\n]*(?:Pro|Studio|Hub|Lab|Plus|App|Site|Portal|Platform|Space|Zone|World|Center|Market|Shop|Store|Pages?))'
|
| 481 |
+
match = re.search(pattern, str(result_text))
|
| 482 |
+
if match:
|
| 483 |
+
return match.group(1).strip()
|
| 484 |
+
return "✨ Awesome Project"
|
| 485 |
+
except:
|
| 486 |
+
return "✨ Awesome Project"
|
| 487 |
+
|
| 488 |
+
# --- 7. CREATE THE GRADIO WEB INTERFACE ---
|
| 489 |
+
def run_crew(prompt, use_template):
|
| 490 |
try:
|
| 491 |
if llm is None:
|
| 492 |
return (
|
| 493 |
"❌ **Error:** Gemini LLM not initialized. Please check your GOOGLE_API_KEY in environment variables.",
|
| 494 |
None,
|
| 495 |
gr.update(visible=False),
|
| 496 |
+
gr.update(visible=False),
|
| 497 |
+
gr.update(visible=False),
|
| 498 |
+
""
|
| 499 |
)
|
| 500 |
|
| 501 |
+
# Determine the actual prompt to use
|
| 502 |
+
if use_template and prompt in PROMPTS_FOR_AI:
|
| 503 |
+
final_prompt = prompt
|
| 504 |
+
elif not use_template and prompt and prompt.strip() != "":
|
| 505 |
+
final_prompt = prompt
|
| 506 |
+
else:
|
| 507 |
return (
|
| 508 |
+
"❌ **Error:** Please select a template or enter a custom prompt.",
|
| 509 |
None,
|
| 510 |
gr.update(visible=False),
|
| 511 |
+
gr.update(visible=False),
|
| 512 |
+
gr.update(visible=False),
|
| 513 |
+
""
|
| 514 |
)
|
| 515 |
|
| 516 |
# Clean up previous output
|
| 517 |
+
clean_outputs_directory()
|
| 518 |
+
|
| 519 |
+
print(f"\n🚀 Starting generation with prompt: {final_prompt[:100]}...")
|
| 520 |
|
| 521 |
# Run the crew
|
| 522 |
+
inputs = {'prompt': final_prompt}
|
| 523 |
result = vibe_crew.kickoff(inputs=inputs)
|
| 524 |
|
| 525 |
+
# Extract project name
|
| 526 |
+
project_name = extract_project_name(result)
|
| 527 |
+
print(f"\n✅ Project Name: {project_name}")
|
| 528 |
+
|
| 529 |
+
# Check generated files
|
| 530 |
+
html_files = glob.glob("outputs/*.html")
|
| 531 |
+
|
| 532 |
+
if not html_files:
|
| 533 |
+
return (
|
| 534 |
+
"❌ **Error:** No HTML files were generated. Please try again.",
|
| 535 |
+
None,
|
| 536 |
+
gr.update(visible=False),
|
| 537 |
+
gr.update(visible=False),
|
| 538 |
+
gr.update(visible=False),
|
| 539 |
+
""
|
| 540 |
+
)
|
| 541 |
+
|
| 542 |
+
# Determine if single or multi-page
|
| 543 |
+
is_multipage = len(html_files) > 1
|
| 544 |
+
|
| 545 |
+
# Create preview (show index.html or first file)
|
| 546 |
+
preview_file = "outputs/index.html" if os.path.exists("outputs/index.html") else html_files[0]
|
| 547 |
+
with open(preview_file, "r", encoding="utf-8") as file:
|
| 548 |
+
html_content = file.read()
|
| 549 |
+
|
| 550 |
+
preview_html = f'<iframe srcdoc="{html_content.replace(chr(34), """)}" width="100%" height="800px" style="border: 2px solid #e0e0e0; border-radius: 8px;"></iframe>'
|
| 551 |
+
|
| 552 |
+
# Prepare success message
|
| 553 |
+
if is_multipage:
|
| 554 |
+
file_list = ", ".join([os.path.basename(f) for f in html_files])
|
| 555 |
+
success_message = f"✅ **Project Generated: {project_name}**\n\nMulti-page website created with {len(html_files)} pages: {file_list}"
|
| 556 |
|
| 557 |
+
# Create ZIP archive
|
| 558 |
+
zip_path = create_zip_archive()
|
| 559 |
+
if zip_path:
|
|
|
|
|
|
|
|
|
|
| 560 |
return (
|
| 561 |
success_message,
|
| 562 |
preview_html,
|
| 563 |
+
gr.update(value=preview_file, visible=True),
|
| 564 |
+
gr.update(value=zip_path, visible=True, label=f"📦 Download {project_name} (ZIP)"),
|
| 565 |
+
gr.update(visible=True),
|
| 566 |
+
project_name
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 567 |
)
|
| 568 |
else:
|
| 569 |
+
success_message = f"✅ **Project Generated: {project_name}**\n\nSingle-page website ready to download!"
|
| 570 |
return (
|
| 571 |
+
success_message,
|
| 572 |
+
preview_html,
|
| 573 |
+
gr.update(value=preview_file, visible=True, label=f"📥 Download {project_name} (HTML)"),
|
| 574 |
gr.update(visible=False),
|
| 575 |
+
gr.update(visible=True),
|
| 576 |
+
project_name
|
| 577 |
)
|
| 578 |
|
| 579 |
except Exception as e:
|
|
|
|
| 584 |
error_message,
|
| 585 |
None,
|
| 586 |
gr.update(visible=False),
|
| 587 |
+
gr.update(visible=False),
|
| 588 |
+
gr.update(visible=False),
|
| 589 |
+
""
|
| 590 |
)
|
| 591 |
|
| 592 |
+
# --- 8. CREATE THE GRADIO INTERFACE ---
|
| 593 |
with gr.Blocks(theme=gr.themes.Soft(), css="""
|
| 594 |
.container { max-width: 1400px; margin: auto; }
|
| 595 |
+
.status-box {
|
| 596 |
+
padding: 20px;
|
| 597 |
+
border-radius: 12px;
|
| 598 |
+
margin: 20px 0;
|
| 599 |
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
| 600 |
+
color: white;
|
| 601 |
+
font-weight: 500;
|
| 602 |
+
}
|
| 603 |
+
.download-section {
|
| 604 |
+
text-align: center;
|
| 605 |
+
padding: 20px;
|
| 606 |
+
background: #f7fafc;
|
| 607 |
+
border-radius: 12px;
|
| 608 |
+
margin: 10px;
|
| 609 |
+
}
|
| 610 |
+
.template-selector {
|
| 611 |
+
border: 2px solid #e2e8f0;
|
| 612 |
+
border-radius: 12px;
|
| 613 |
+
padding: 15px;
|
| 614 |
+
background: #f8fafc;
|
| 615 |
+
}
|
| 616 |
+
.project-name-display {
|
| 617 |
+
font-size: 1.5rem;
|
| 618 |
+
font-weight: bold;
|
| 619 |
+
text-align: center;
|
| 620 |
+
padding: 15px;
|
| 621 |
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
| 622 |
+
-webkit-background-clip: text;
|
| 623 |
+
-webkit-text-fill-color: transparent;
|
| 624 |
+
margin: 20px 0;
|
| 625 |
+
}
|
| 626 |
""") as iface:
|
| 627 |
|
| 628 |
gr.Markdown(
|
| 629 |
"""
|
| 630 |
# 🎨 Vibe Coder AI - Professional Edition
|
| 631 |
### Create stunning websites with Tailwind CSS & AOS Animations
|
| 632 |
+
Generate complete, production-ready websites with our AI team. Support for both single-page and multi-page projects!
|
| 633 |
|
| 634 |
+
**🚀 Features:** Tailwind CSS • AOS Animations • Google Fonts • Semantic HTML5 • Multi-page Support • Auto ZIP Export
|
| 635 |
"""
|
| 636 |
)
|
| 637 |
|
| 638 |
+
# Template Selection Section
|
| 639 |
+
with gr.Group(elem_classes="template-selector"):
|
| 640 |
+
gr.Markdown("### 📋 Choose Your Project Type")
|
| 641 |
+
|
| 642 |
+
use_template = gr.Radio(
|
| 643 |
+
choices=["Use Template", "Custom Prompt"],
|
| 644 |
+
value="Use Template",
|
| 645 |
+
label="Selection Mode",
|
| 646 |
+
interactive=True
|
| 647 |
+
)
|
| 648 |
+
|
| 649 |
+
template_dropdown = gr.Dropdown(
|
| 650 |
+
choices=PROMPTS_FOR_AI,
|
| 651 |
+
value=PROMPTS_FOR_AI[0],
|
| 652 |
+
label="🎯 Select a Template",
|
| 653 |
+
interactive=True,
|
| 654 |
+
visible=True
|
| 655 |
+
)
|
| 656 |
+
|
| 657 |
+
custom_prompt = gr.Textbox(
|
| 658 |
lines=4,
|
| 659 |
placeholder="Example: A website for my new coffee shop in Brooklyn. The vibe should be cozy, rustic, and artisanal with warm colors and smooth animations.",
|
| 660 |
+
label="✍️ Or Describe Your Custom Website",
|
| 661 |
+
visible=False,
|
| 662 |
elem_classes="container"
|
| 663 |
)
|
| 664 |
|
| 665 |
+
# Hidden project name display
|
| 666 |
+
project_name_display = gr.Markdown(
|
| 667 |
+
visible=False,
|
| 668 |
+
elem_classes="project-name-display"
|
| 669 |
+
)
|
| 670 |
|
| 671 |
with gr.Row():
|
| 672 |
+
generate_btn = gr.Button(
|
| 673 |
+
"🚀 Generate Professional Website",
|
| 674 |
+
variant="primary",
|
| 675 |
+
size="lg",
|
| 676 |
+
scale=1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 677 |
)
|
| 678 |
|
| 679 |
with gr.Row():
|
|
|
|
| 691 |
|
| 692 |
with gr.Row():
|
| 693 |
with gr.Column(scale=1):
|
| 694 |
+
download_single = gr.File(
|
| 695 |
label="📥 Download Website (HTML)",
|
| 696 |
visible=False,
|
| 697 |
elem_classes="download-section"
|
| 698 |
)
|
| 699 |
+
with gr.Column(scale=1):
|
| 700 |
+
download_zip = gr.File(
|
| 701 |
+
label="📦 Download Project (ZIP)",
|
| 702 |
+
visible=False,
|
| 703 |
+
elem_classes="download-section"
|
| 704 |
+
)
|
| 705 |
with gr.Column(scale=1):
|
| 706 |
view_code_btn = gr.Button(
|
| 707 |
"👁️ View Source Code",
|
|
|
|
| 718 |
elem_classes="container"
|
| 719 |
)
|
| 720 |
|
| 721 |
+
# Event handlers
|
| 722 |
+
def toggle_input_mode(mode):
|
| 723 |
+
if mode == "Use Template":
|
| 724 |
+
return gr.update(visible=True), gr.update(visible=False)
|
| 725 |
+
else:
|
| 726 |
+
return gr.update(visible=False), gr.update(visible=True)
|
| 727 |
+
|
| 728 |
+
use_template.change(
|
| 729 |
+
fn=toggle_input_mode,
|
| 730 |
+
inputs=[use_template],
|
| 731 |
+
outputs=[template_dropdown, custom_prompt]
|
| 732 |
+
)
|
| 733 |
|
| 734 |
+
def generate_website(use_template_val, template_val, custom_val):
|
| 735 |
+
# Determine which prompt to use
|
| 736 |
+
if use_template_val == "Use Template":
|
| 737 |
+
prompt = template_val
|
| 738 |
+
is_template = True
|
| 739 |
+
else:
|
| 740 |
+
prompt = custom_val
|
| 741 |
+
is_template = False
|
| 742 |
+
|
| 743 |
+
status, preview, download_s, download_z, view_btn, project_name = run_crew(prompt, is_template)
|
| 744 |
+
|
| 745 |
+
# Update project name display
|
| 746 |
+
if project_name:
|
| 747 |
+
project_display = gr.update(
|
| 748 |
+
value=f"### {project_name}",
|
| 749 |
+
visible=True
|
| 750 |
+
)
|
| 751 |
+
else:
|
| 752 |
+
project_display = gr.update(visible=False)
|
| 753 |
+
|
| 754 |
return (
|
| 755 |
status,
|
| 756 |
preview,
|
| 757 |
+
download_s,
|
| 758 |
+
download_z,
|
| 759 |
+
view_btn,
|
| 760 |
+
project_display
|
| 761 |
)
|
| 762 |
|
| 763 |
generate_btn.click(
|
| 764 |
fn=generate_website,
|
| 765 |
+
inputs=[use_template, template_dropdown, custom_prompt],
|
| 766 |
+
outputs=[
|
| 767 |
+
status_output,
|
| 768 |
+
preview_output,
|
| 769 |
+
download_single,
|
| 770 |
+
download_zip,
|
| 771 |
+
view_code_btn,
|
| 772 |
+
project_name_display
|
| 773 |
+
]
|
| 774 |
)
|
| 775 |
|
| 776 |
view_code_btn.click(
|
| 777 |
+
fn=lambda: (
|
| 778 |
+
gr.update(visible=True),
|
| 779 |
+
open("outputs/index.html", "r", encoding="utf-8").read() if os.path.exists("outputs/index.html") else open(glob.glob("outputs/*.html")[0], "r", encoding="utf-8").read() if glob.glob("outputs/*.html") else ""
|
| 780 |
+
),
|
| 781 |
inputs=None,
|
| 782 |
outputs=[code_row, code_output]
|
| 783 |
)
|
| 784 |
|
| 785 |
if __name__ == "__main__":
|
| 786 |
+
print("\n" + "="*50)
|
| 787 |
+
print("🎨 Vibe Coder AI - Professional Edition")
|
| 788 |
+
print("="*50)
|
| 789 |
+
print("\n✅ System initialized successfully!")
|
| 790 |
+
print(f"📋 {len(PROMPTS_FOR_AI)} templates loaded")
|
| 791 |
+
print("🚀 Launching Gradio interface...\n")
|
| 792 |
+
|
| 793 |
iface.launch(share=False)
|