Spaces:
Sleeping
Sleeping
| from langchain_core.messages import AIMessage | |
| from utils.inference import call_model | |
| import re | |
| def run(state): | |
| architecture = state["architecture"] | |
| user_prompt = state["messages"][0].content | |
| prompt = f""" | |
| You are a senior front-end engineer. Based on the user prompt and architecture, generate a beautiful, fully responsive HTML page with embedded CSS. | |
| User Prompt: | |
| "{user_prompt}" | |
| UI Design Plan: | |
| {architecture} | |
| 🎨 Design Requirements: | |
| - Full HTML page starting with <!DOCTYPE html> | |
| - Use semantic HTML5 tags: <nav>, <section>, <footer>, etc. | |
| - Fixed top `.navbar` with horizontally centered links (not floating), styled with padding, hover states, and active class | |
| - Hero section: | |
| - Full viewport height | |
| - Unsplash image background based on the theme (car, travel, food, etc.) | |
| - A dark overlay using `rgba(0,0,0,0.6)` | |
| - Centered text and a button styled as `.btn` | |
| - Content: | |
| - Use `.container` with `max-width: 1200px; margin: auto;` | |
| - 3 content sections styled with `.section` class, using alternating background colors (#fff, #f9f9f9) | |
| - Each section must have a heading, paragraph, and one `.btn` | |
| - Footer: | |
| - Centered, with solid dark background and padding | |
| - Color Palette: | |
| - Use a visually appealing modern palette (not default black/gray) | |
| - Accent color for buttons and nav hover states | |
| - Typography: | |
| - Use system font stack or Google Fonts if needed | |
| - Responsiveness: | |
| - Use Flexbox or Grid | |
| - Add media queries for < 768px screens | |
| - Stack nav items and center hero text on mobile | |
| 🚫 DO NOT: | |
| - Return markdown or explanations | |
| - Include duplicate HTML tags | |
| - Forget to close any HTML tag | |
| Return only the final clean HTML code. | |
| """ | |
| output = call_model(prompt) | |
| # Clean markdown or triple backticks if any | |
| cleaned = re.sub(r"```(?:html|css)?", "", output).strip() | |
| # Extract valid HTML content | |
| matches = re.findall(r"<!DOCTYPE html>.*?</html>", cleaned, flags=re.DOTALL | re.IGNORECASE) | |
| if matches: | |
| final_html = matches[0] | |
| elif cleaned.lower().startswith("<!doctype"): | |
| final_html = cleaned | |
| else: | |
| # Wrap fallback | |
| final_html = f"""<!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <title>Generated UI</title> | |
| <style> | |
| body {{ | |
| font-family: Arial, sans-serif; | |
| background-color: #f4f4f4; | |
| padding: 2rem; | |
| }} | |
| </style> | |
| </head> | |
| <body> | |
| {cleaned} | |
| </body> | |
| </html>""" | |
| return { | |
| "messages": state["messages"] + [AIMessage(content=final_html)], | |
| "html_output": final_html | |
| } | |