namaai commited on
Commit
2102175
·
verified ·
1 Parent(s): 252e93d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +252 -0
app.py CHANGED
@@ -0,0 +1,252 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import streamlit as st
3
+ from groq import Groq
4
+ import re
5
+
6
+
7
+ os.environ["GROQ_API_KEY"] = os.getenv("GROQ_API_KEY")
8
+ client = Groq(api_key=os.environ["GROQ_API_KEY"])
9
+
10
+ # Define available models
11
+ MODELS = [
12
+ "llama-3.2-90b-text-preview",
13
+ "llama-3.2-11b-text-preview",
14
+ "llama-3.2-3b-preview",
15
+ "llama-3.2-1b-preview",
16
+ "llama-3.1-70b-versatile",
17
+ "mixtral-8x7b-32768",
18
+ "gemma-7b-it",
19
+ ]
20
+
21
+ # Configure Streamlit page
22
+ st.set_page_config(page_title="Frontend Component Generator", layout="wide")
23
+ st.title("Frontend Component Generator")
24
+
25
+ # Sidebar for settings
26
+ with st.sidebar:
27
+ st.header("Settings")
28
+ llm_type = st.selectbox("Select Model", MODELS)
29
+ theme = st.selectbox(
30
+ " Theme",
31
+ [
32
+ "Modern",
33
+ "Vintage",
34
+ "Minimalist",
35
+ "Futuristic",
36
+ "Retro",
37
+ "Glassmorphism",
38
+ "Neumorphism",
39
+ "Material Design",
40
+ "Flat Design",
41
+ "Cyberpunk",
42
+ ],
43
+ )
44
+ st.markdown("---")
45
+ st.markdown("""
46
+ ### How to use:
47
+ 1. Enter a description of the component you want.
48
+ 2. Click 'Generate Component'.
49
+ 3. Preview the component.
50
+ 4. Click 'Convert to TSX' to generate a React component.
51
+ 5. Download the TSX version.
52
+ 6. Click 'Regenerate' for new versions.
53
+ """)
54
+
55
+ def sanitize_code(code: str) -> str:
56
+ """
57
+ Removes Markdown code fences and any leading/trailing whitespace from the code.
58
+ """
59
+ # Remove opening code fence (``` or ```javascript or ```html)
60
+ code = re.sub(r'^```(?:\w+)?\n?', '', code)
61
+ # Remove closing code fence (```)
62
+ code = re.sub(r'\n?```$', '', code)
63
+ # Strip leading and trailing whitespace
64
+ return code.strip()
65
+
66
+ def generate_html_js(prompt: str, theme: str):
67
+ """
68
+ Generates HTML, TailwindCSS, and JavaScript code using the GROQ API.
69
+ """
70
+ system_prompt = f"""You are an expert frontend developer.
71
+ Create a complete, functional component based on the user's description.
72
+
73
+ Requirements:
74
+ 1. Use pure HTML, TailwindCSS, and JavaScript without relying on any frameworks.
75
+ 2. Utilize the {theme} theme from TailwindCSS.
76
+ 3. Ensure the component is responsive.
77
+ 4. Include form validations if necessary.
78
+ 5. Add comments to explain the code where appropriate.
79
+
80
+ **Provide only the raw HTML, TailwindCSS classes, and JavaScript code without any markdown, explanations, or additional text.**"""
81
+
82
+ full_prompt = f"Create a component for: {prompt}"
83
+
84
+ try:
85
+ completion = client.chat.completions.create(
86
+ messages=[
87
+ {"role": "system", "content": system_prompt},
88
+ {"role": "user", "content": full_prompt}
89
+ ],
90
+ model=llm_type,
91
+ temperature=0.4
92
+ )
93
+
94
+ content = completion.choices[0].message.content.strip()
95
+ sanitized_content = sanitize_code(content)
96
+ return sanitized_content
97
+
98
+ except Exception as e:
99
+ st.error(f"Error generating component: {e}")
100
+ return None
101
+
102
+ def generate_tsx(html_code: str, js_code: str, theme: str):
103
+ """
104
+ Converts HTML, TailwindCSS, and JavaScript code into a React TSX component using the GROQ API.
105
+ """
106
+ system_prompt = f"""You are an expert React/TypeScript developer.
107
+ Convert the following HTML, TailwindCSS, and JavaScript code into a React TypeScript (TSX) component.
108
+
109
+ Requirements:
110
+ 1. Use functional components with React Hooks.
111
+ 2. Incorporate TailwindCSS for styling.
112
+ 3. Ensure all functionalities from the original JavaScript are preserved.
113
+ 4. Add appropriate TypeScript types and interfaces.
114
+ 5. Include necessary imports (e.g., React).
115
+ 6. Ensure the component is named appropriately and exported as default.
116
+
117
+ **Provide only the raw TSX component code without any markdown, explanations, or additional text.**"""
118
+
119
+ # Combine HTML and JS code into a single prompt
120
+ full_prompt = f"Convert the following code to a React TSX component:\n\nHTML:\n{html_code}\n\nJavaScript:\n{js_code}"
121
+
122
+ try:
123
+ completion = client.chat.completions.create(
124
+ messages=[
125
+ {"role": "system", "content": system_prompt},
126
+ {"role": "user", "content": full_prompt}
127
+ ],
128
+ model=llm_type,
129
+ temperature=0.4
130
+ )
131
+
132
+ tsx_content = completion.choices[0].message.content.strip()
133
+ tsx_content = sanitize_code(tsx_content)
134
+ return tsx_content
135
+
136
+ except Exception as e:
137
+ st.error(f"Error converting to TSX: {e}")
138
+ return None
139
+
140
+ def create_html_preview(html_code: str, js_code: str) -> str:
141
+ """
142
+ Embeds the generated HTML, TailwindCSS, and JavaScript into an HTML template for rendering.
143
+ """
144
+ return f"""
145
+ <!DOCTYPE html>
146
+ <html>
147
+ <head>
148
+ <meta charset="UTF-8">
149
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
150
+ <script src="https://cdn.tailwindcss.com"></script>
151
+ <style>
152
+ body {{ background-color: #f3f4f6; }}
153
+ #root {{ padding: 20px; }}
154
+ </style>
155
+ </head>
156
+ <body>
157
+ <div id="root">
158
+ {html_code}
159
+ </div>
160
+ <script>
161
+ {js_code}
162
+ </script>
163
+ </body>
164
+ </html>
165
+ """
166
+
167
+ # Main interface
168
+ user_input = st.text_area(
169
+ "Describe the component you want (e.g., 'a login page with email and password fields, remember me checkbox, and a submit button')",
170
+ height=150
171
+ )
172
+
173
+ # Initialize session state
174
+ if 'html_code' not in st.session_state:
175
+ st.session_state.html_code = None
176
+ if 'js_code' not in st.session_state:
177
+ st.session_state.js_code = None
178
+ if 'tsx_code' not in st.session_state:
179
+ st.session_state.tsx_code = None
180
+
181
+ if user_input:
182
+ generate_button = st.button("Generate Component")
183
+
184
+ if generate_button or not st.session_state.html_code:
185
+ with st.spinner("Generating component..."):
186
+ # Generate HTML and JS code
187
+ component_code = generate_html_js(user_input, theme)
188
+ if component_code:
189
+ # Assume that the LLM returns HTML and JS separated by script tags
190
+ # We'll need to parse them
191
+ # For simplicity, let's assume the JS is within <script> tags
192
+ html_part = re.findall(r'([\s\S]*?)<script>', component_code)
193
+ js_part = re.findall(r'<script>([\s\S]*)<\/script>', component_code)
194
+
195
+ html_code = html_part[0].strip() if html_part else ""
196
+ js_code = js_part[0].strip() if js_part else ""
197
+
198
+ st.session_state.html_code = html_code
199
+ st.session_state.js_code = js_code
200
+
201
+ st.success("Component generated successfully!")
202
+
203
+ if st.session_state.html_code and st.session_state.js_code:
204
+ # Create tabs for different views
205
+ tab1, tab2 = st.tabs(["Code", "Preview"])
206
+
207
+ with tab1:
208
+ st.subheader("Generated HTML")
209
+ st.code(st.session_state.html_code, language="html")
210
+
211
+ st.subheader("Generated JavaScript")
212
+ st.code(st.session_state.js_code, language="javascript")
213
+
214
+ with tab2:
215
+ st.subheader("Live Preview")
216
+ preview_html = create_html_preview(st.session_state.html_code, st.session_state.js_code)
217
+ st.components.v1.html(preview_html, height=600, scrolling=True)
218
+
219
+ # Button to convert to TSX
220
+ convert_button = st.button("Convert to TSX")
221
+
222
+ if convert_button and not st.session_state.tsx_code:
223
+ with st.spinner("Converting to TSX..."):
224
+ tsx_code = generate_tsx(st.session_state.html_code, st.session_state.js_code, theme)
225
+ if tsx_code:
226
+ st.session_state.tsx_code = tsx_code
227
+ st.success("Conversion to TSX successful!")
228
+
229
+ if st.session_state.tsx_code:
230
+ # Create tabs for TSX code and download
231
+ tsx_tab1, tsx_tab2 = st.tabs(["TSX Code", "Download"])
232
+
233
+ with tsx_tab1:
234
+ st.subheader("Generated TSX Component")
235
+ st.code(st.session_state.tsx_code, language="typescript")
236
+
237
+ with tsx_tab2:
238
+ st.subheader("Download TSX Component")
239
+ st.download_button(
240
+ label="Download TSX Component",
241
+ data=st.session_state.tsx_code,
242
+ file_name="Component.tsx",
243
+ mime="text/typescript"
244
+ )
245
+
246
+ # Regenerate button
247
+ if st.button("Regenerate"):
248
+ # Reset session state
249
+ st.session_state.html_code = None
250
+ st.session_state.js_code = None
251
+ st.session_state.tsx_code = None
252
+ st.rerun()