Update app.py
Browse files
app.py
CHANGED
|
@@ -62,6 +62,15 @@ body {
|
|
| 62 |
align-items: center;
|
| 63 |
transition: background 0.2s ease;
|
| 64 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 65 |
.sidebar-item span {
|
| 66 |
color: #ccc;
|
| 67 |
}
|
|
@@ -132,16 +141,21 @@ def generate_sidebar(user_prompt):
|
|
| 132 |
sidebar_html = "<div class='sidebar'>"
|
| 133 |
sidebar_html += f"<div class='sidebar-header'>{SVG_FLUENT['hamburger']} App Title</div>"
|
| 134 |
|
|
|
|
| 135 |
defaults = [("home", "Home"), ("recent", "Recent"), ("pinned", "Pinned")]
|
| 136 |
for key, label in defaults:
|
| 137 |
sidebar_html += f"<div class='sidebar-item'>{SVG_FLUENT[key]}<span>{label}</span></div>"
|
| 138 |
|
| 139 |
sidebar_html += "<div class='sidebar-section'>My Work</div>"
|
| 140 |
|
|
|
|
| 141 |
prompt = (
|
| 142 |
-
"You are a Microsoft PowerApps UI designer. "
|
| 143 |
-
"
|
| 144 |
-
"
|
|
|
|
|
|
|
|
|
|
| 145 |
)
|
| 146 |
|
| 147 |
try:
|
|
@@ -152,15 +166,20 @@ def generate_sidebar(user_prompt):
|
|
| 152 |
Dashboard [ACTIVE] | <svg viewBox='0 0 24 24'><path d='M3 13h8V3H3v10z'/></svg>
|
| 153 |
Analytics | <svg viewBox='0 0 24 24'><path d='M12 2L1 21h22L12 2z'/></svg>"""
|
| 154 |
|
| 155 |
-
|
|
|
|
| 156 |
for line in text.splitlines():
|
| 157 |
-
if
|
| 158 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 159 |
if not line.startswith(" ") and ":" in line:
|
| 160 |
section = line.split(":")[0].strip()
|
| 161 |
sidebar_html += f"<div class='sidebar-section'>{section}</div>"
|
| 162 |
elif "|" in line:
|
| 163 |
-
match = re.match(r"
|
| 164 |
if match:
|
| 165 |
label_raw, svg = match.groups()
|
| 166 |
is_active = "[ACTIVE]" in label_raw
|
|
@@ -177,12 +196,13 @@ def generate_sidebar(user_prompt):
|
|
| 177 |
def generate_mockup(user_prompt):
|
| 178 |
system_prompt = (
|
| 179 |
"You are a PowerApps mockup generator. "
|
| 180 |
-
"Generate ONLY the inner HTML for the main screen content
|
|
|
|
| 181 |
)
|
| 182 |
response = model.generate_content(system_prompt + "\n" + user_prompt)
|
| 183 |
user_html = response.text.strip()
|
| 184 |
-
|
| 185 |
-
|
| 186 |
|
| 187 |
sidebar_html = generate_sidebar(user_prompt)
|
| 188 |
full_html = BASE_TEMPLATE.replace("{user_sidebar}", sidebar_html).replace("{user_content}", user_html)
|
|
@@ -196,7 +216,7 @@ def generate_mockup(user_prompt):
|
|
| 196 |
return img_path
|
| 197 |
|
| 198 |
# -----------------------
|
| 199 |
-
#
|
| 200 |
# -----------------------
|
| 201 |
def analyze_business_pdf(pdf_file):
|
| 202 |
text = ""
|
|
@@ -204,13 +224,11 @@ def analyze_business_pdf(pdf_file):
|
|
| 204 |
for page in pdf.pages:
|
| 205 |
text += page.extract_text() + "\n"
|
| 206 |
|
| 207 |
-
# Now convert business requirements into inferred UI requirements
|
| 208 |
inference_prompt = (
|
| 209 |
"You are an expert PowerApps UI architect. "
|
| 210 |
"Analyze the following business requirements and infer what PowerApps modules, screens, and components "
|
| 211 |
"the app would need. Describe the inferred UI requirements clearly, focusing on screen purpose, key components, "
|
| 212 |
-
"charts, forms, lists, and any relevant side menu items.\n\n"
|
| 213 |
-
"Business Requirements:\n"
|
| 214 |
)
|
| 215 |
|
| 216 |
response = model.generate_content(inference_prompt + text)
|
|
@@ -218,7 +236,7 @@ def analyze_business_pdf(pdf_file):
|
|
| 218 |
return inferred_ui
|
| 219 |
|
| 220 |
# -----------------------
|
| 221 |
-
#
|
| 222 |
# -----------------------
|
| 223 |
def generate_from_pdf(pdf_file):
|
| 224 |
inferred_ui_text = analyze_business_pdf(pdf_file)
|
|
|
|
| 62 |
align-items: center;
|
| 63 |
transition: background 0.2s ease;
|
| 64 |
}
|
| 65 |
+
.sidebar-item svg {
|
| 66 |
+
width: 16px;
|
| 67 |
+
height: 16px;
|
| 68 |
+
min-width: 16px;
|
| 69 |
+
min-height: 16px;
|
| 70 |
+
margin-right: 8px;
|
| 71 |
+
fill: #c5c5c5;
|
| 72 |
+
flex-shrink: 0;
|
| 73 |
+
}
|
| 74 |
.sidebar-item span {
|
| 75 |
color: #ccc;
|
| 76 |
}
|
|
|
|
| 141 |
sidebar_html = "<div class='sidebar'>"
|
| 142 |
sidebar_html += f"<div class='sidebar-header'>{SVG_FLUENT['hamburger']} App Title</div>"
|
| 143 |
|
| 144 |
+
# Default fixed icons
|
| 145 |
defaults = [("home", "Home"), ("recent", "Recent"), ("pinned", "Pinned")]
|
| 146 |
for key, label in defaults:
|
| 147 |
sidebar_html += f"<div class='sidebar-item'>{SVG_FLUENT[key]}<span>{label}</span></div>"
|
| 148 |
|
| 149 |
sidebar_html += "<div class='sidebar-section'>My Work</div>"
|
| 150 |
|
| 151 |
+
# Updated, cleaner sidebar generation prompt
|
| 152 |
prompt = (
|
| 153 |
+
"You are a Microsoft PowerApps UI designer. Based on the following business or user requirement, "
|
| 154 |
+
"generate ONLY the 'My Work' sidebar section (not the entire sidebar). "
|
| 155 |
+
"Each section must follow this format:\n"
|
| 156 |
+
"Section Name:\n Label [ACTIVE optional] | <svg viewBox='0 0 24 24'><path ... /></svg>\n"
|
| 157 |
+
"Include concise section names and realistic Fluent-style icons. "
|
| 158 |
+
"Do NOT add explanations, just the raw structure as shown above."
|
| 159 |
)
|
| 160 |
|
| 161 |
try:
|
|
|
|
| 166 |
Dashboard [ACTIVE] | <svg viewBox='0 0 24 24'><path d='M3 13h8V3H3v10z'/></svg>
|
| 167 |
Analytics | <svg viewBox='0 0 24 24'><path d='M12 2L1 21h22L12 2z'/></svg>"""
|
| 168 |
|
| 169 |
+
# Clean out unwanted explanations, only valid icon lines
|
| 170 |
+
cleaned_lines = []
|
| 171 |
for line in text.splitlines():
|
| 172 |
+
if "| <svg" in line:
|
| 173 |
+
cleaned_lines.append(line.strip())
|
| 174 |
+
elif ":" in line and not line.strip().startswith("```"):
|
| 175 |
+
cleaned_lines.append(line.strip())
|
| 176 |
+
|
| 177 |
+
for line in cleaned_lines:
|
| 178 |
if not line.startswith(" ") and ":" in line:
|
| 179 |
section = line.split(":")[0].strip()
|
| 180 |
sidebar_html += f"<div class='sidebar-section'>{section}</div>"
|
| 181 |
elif "|" in line:
|
| 182 |
+
match = re.match(r"(.+?)\s*\|\s*(<svg.*?</svg>)", line)
|
| 183 |
if match:
|
| 184 |
label_raw, svg = match.groups()
|
| 185 |
is_active = "[ACTIVE]" in label_raw
|
|
|
|
| 196 |
def generate_mockup(user_prompt):
|
| 197 |
system_prompt = (
|
| 198 |
"You are a PowerApps mockup generator. "
|
| 199 |
+
"Generate ONLY the inner HTML for the main screen content, without <html> or sidebar. "
|
| 200 |
+
"Keep layout and styling consistent with Microsoft PowerApps."
|
| 201 |
)
|
| 202 |
response = model.generate_content(system_prompt + "\n" + user_prompt)
|
| 203 |
user_html = response.text.strip()
|
| 204 |
+
# Remove any code fences like ```html
|
| 205 |
+
user_html = re.sub(r"```(?:html)?", "", user_html).strip()
|
| 206 |
|
| 207 |
sidebar_html = generate_sidebar(user_prompt)
|
| 208 |
full_html = BASE_TEMPLATE.replace("{user_sidebar}", sidebar_html).replace("{user_content}", user_html)
|
|
|
|
| 216 |
return img_path
|
| 217 |
|
| 218 |
# -----------------------
|
| 219 |
+
# Convert PDF → Inferred UI Requirements
|
| 220 |
# -----------------------
|
| 221 |
def analyze_business_pdf(pdf_file):
|
| 222 |
text = ""
|
|
|
|
| 224 |
for page in pdf.pages:
|
| 225 |
text += page.extract_text() + "\n"
|
| 226 |
|
|
|
|
| 227 |
inference_prompt = (
|
| 228 |
"You are an expert PowerApps UI architect. "
|
| 229 |
"Analyze the following business requirements and infer what PowerApps modules, screens, and components "
|
| 230 |
"the app would need. Describe the inferred UI requirements clearly, focusing on screen purpose, key components, "
|
| 231 |
+
"charts, forms, lists, and any relevant side menu items.\n\nBusiness Requirements:\n"
|
|
|
|
| 232 |
)
|
| 233 |
|
| 234 |
response = model.generate_content(inference_prompt + text)
|
|
|
|
| 236 |
return inferred_ui
|
| 237 |
|
| 238 |
# -----------------------
|
| 239 |
+
# Full Pipeline: PDF → Mockup
|
| 240 |
# -----------------------
|
| 241 |
def generate_from_pdf(pdf_file):
|
| 242 |
inferred_ui_text = analyze_business_pdf(pdf_file)
|