Doctorrick commited on
Commit
56b2b0b
·
verified ·
1 Parent(s): 0e533c4

Update app.py from anycoder

Browse files
Files changed (1) hide show
  1. app.py +300 -472
app.py CHANGED
@@ -2,332 +2,261 @@ import gradio as gr
2
  import json
3
  import base64
4
  from datetime import datetime
 
 
 
5
 
6
  def generate_theme_preview(primary_color, secondary_color, accent_color, background_color,
7
  header_style, animation_type, layout_type, enable_woocommerce,
8
  gallery_columns, show_videos, contact_form_fields):
9
- """Generate a live preview of the WordPress theme with all customizations"""
10
 
11
- # Generate CSS based on selections
12
- css_preview = f"""
 
 
 
 
 
 
 
13
  <style>
 
 
14
  :root {{
15
- --primary-color: {primary_color};
16
- --secondary-color: {secondary_color};
17
- --accent-color: {accent_color};
18
- --background-color: {background_color};
19
- --header-style: {header_style};
20
  }}
21
 
22
- body {{
23
- font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
24
- background: {background_color};
25
- margin: 0;
26
- padding: 0;
27
- animation: {animation_type} 0.5s ease-in-out;
 
 
28
  }}
29
 
 
30
  .theme-header {{
31
- background: linear-gradient(135deg, {primary_color}, {secondary_color});
32
- color: white;
33
  padding: 2rem;
34
- text-align: center;
35
- box-shadow: 0 4px 20px rgba(0,0,0,0.1);
36
  position: relative;
37
  overflow: hidden;
 
38
  }}
39
 
40
- .theme-header::before {{
41
- content: '';
42
- position: absolute;
43
- top: -50%;
44
- left: -50%;
45
- width: 200%;
46
- height: 200%;
47
- background: radial-gradient(circle, rgba(255,255,255,0.1) 0%, transparent 70%);
48
- animation: shimmer 3s infinite linear;
49
  }}
50
 
51
- .theme-nav {{
52
- background: {secondary_color};
53
- padding: 1rem;
 
54
  display: flex;
55
- justify-content: center;
56
- gap: 2rem;
57
- flex-wrap: wrap;
58
  }}
59
 
60
- .theme-nav a {{
61
- color: white;
 
 
 
 
 
 
 
62
  text-decoration: none;
63
- font-weight: 600;
64
- transition: all 0.3s ease;
65
- padding: 0.5rem 1rem;
66
- border-radius: 8px;
 
 
 
 
 
 
67
  }}
68
 
69
- .theme-nav a:hover {{
70
- background: {accent_color};
71
- transform: translateY(-2px);
72
- box-shadow: 0 4px 12px rgba(0,0,0,0.15);
 
 
73
  }}
74
 
75
- .theme-content {{
76
- max-width: 1200px;
77
- margin: 2rem auto;
78
- padding: 0 1rem;
79
  display: grid;
80
- grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
81
  gap: 2rem;
 
82
  }}
83
 
84
  .product-card {{
85
  background: white;
86
  border-radius: 16px;
87
- overflow: hidden;
88
- box-shadow: 0 4px 20px rgba(0,0,0,0.08);
89
- transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
90
- animation: fadeInUp 0.6s ease-out;
91
  }}
92
 
93
  .product-card:hover {{
94
- transform: translateY(-8px) scale(1.02);
95
- box-shadow: 0 12px 40px rgba(0,0,0,0.15);
 
96
  }}
97
 
98
- .product-card img {{
99
  width: 100%;
100
- height: 200px;
 
 
 
101
  object-fit: cover;
102
- transition: transform 0.5s ease;
103
  }}
104
 
105
- .product-card:hover img {{
106
- transform: scale(1.05);
107
- }}
108
-
109
- .product-info {{
110
- padding: 1.5rem;
111
- }}
112
-
113
- .product-title {{
114
- font-size: 1.25rem;
115
- font-weight: 700;
116
- color: {primary_color};
117
- margin-bottom: 0.5rem;
118
- }}
119
-
120
- .product-price {{
121
- font-size: 1.5rem;
122
  font-weight: 800;
123
- color: {accent_color};
124
- }}
125
-
126
- .theme-footer {{
127
- background: {primary_color};
128
- color: white;
129
- padding: 3rem 2rem;
130
- margin-top: 4rem;
131
- text-align: center;
132
- }}
133
-
134
- .contact-form {{
135
- background: white;
136
- padding: 2rem;
137
- border-radius: 16px;
138
- box-shadow: 0 4px 20px rgba(0,0,0,0.08);
139
- max-width: 600px;
140
- margin: 2rem auto;
141
- }}
142
-
143
- .form-field {{
144
- margin-bottom: 1.5rem;
145
- }}
146
-
147
- .form-field label {{
148
- display: block;
149
- font-weight: 600;
150
- color: {primary_color};
151
- margin-bottom: 0.5rem;
152
- }}
153
-
154
- .form-field input,
155
- .form-field textarea {{
156
- width: 100%;
157
- padding: 0.75rem;
158
- border: 2px solid #e0e0e0;
159
- border-radius: 8px;
160
- font-size: 1rem;
161
- transition: border-color 0.3s ease;
162
- }}
163
-
164
- .form-field input:focus,
165
- .form-field textarea:focus {{
166
- outline: none;
167
- border-color: {accent_color};
168
  }}
169
 
170
- .btn-primary {{
171
- background: linear-gradient(135deg, {accent_color}, {secondary_color});
172
  color: white;
173
- padding: 0.75rem 2rem;
174
  border: none;
175
- border-radius: 12px;
176
- font-size: 1rem;
177
- font-weight: 600;
178
  cursor: pointer;
179
- transition: all 0.3s ease;
180
- box-shadow: 0 4px 15px rgba(0,0,0,0.2);
181
- }}
182
-
183
- .btn-primary:hover {{
184
- transform: translateY(-2px);
185
- box-shadow: 0 6px 20px rgba(0,0,0,0.25);
186
- }}
187
-
188
- .woocommerce-badge {{
189
- display: {'inline-block' if enable_woocommerce else 'none'};
190
- background: #7b68ee;
191
- color: white;
192
- padding: 0.25rem 0.75rem;
193
- border-radius: 20px;
194
- font-size: 0.75rem;
195
  font-weight: 600;
196
- margin-left: 0.5rem;
197
- }}
198
-
199
- @keyframes shimmer {{
200
- 0% {{ transform: rotate(0deg); }}
201
- 100% {{ transform: rotate(360deg); }}
202
- }}
203
-
204
- @keyframes fadeInUp {{
205
- from {{ opacity: 0; transform: translateY(30px); }}
206
- to {{ opacity: 1; transform: translateY(0); }}
207
- }}
208
-
209
- @keyframes slideInLeft {{
210
- from {{ opacity: 0; transform: translateX(-30px); }}
211
- to {{ opacity: 1; transform: translateX(0); }}
212
- }}
213
-
214
- @keyframes bounceIn {{
215
- 0% {{ opacity: 0; transform: scale(0.3); }}
216
- 50% {{ opacity: 1; transform: scale(1.05); }}
217
- 70% {{ transform: scale(0.9); }}
218
- 100% {{ transform: scale(1); }}
219
  }}
220
 
221
- .gallery-grid {{
 
 
 
222
  display: grid;
223
  grid-template-columns: repeat({gallery_columns}, 1fr);
224
- gap: 1rem;
225
- margin: 2rem 0;
226
  }}
227
-
228
- .video-embed {{
229
- width: 100%;
230
- height: 300px;
231
- border-radius: 12px;
232
  overflow: hidden;
233
- box-shadow: 0 4px 20px rgba(0,0,0,0.1);
234
- display: {'block' if show_videos else 'none'};
235
  }}
236
 
237
- .layout-{layout_type} {{
238
- font-family: {'"Roboto", sans-serif' if layout_type == 'modern' else '"Inter", sans-serif'};
239
- line-height: {1.6 if layout_type == 'clean' else 1.5};
 
 
 
 
 
 
 
 
 
 
 
 
240
  }}
 
 
 
 
 
 
241
  </style>
 
242
 
243
- <div class="layout-{layout_type}">
244
- <header class="theme-header">
245
- <h1>🎨 Tema WordPress 3D Print Store
246
- <span class="woocommerce-badge">WooCommerce</span>
247
- </h1>
248
- <p>Tema moderno, animado y super editable</p>
 
 
 
 
 
 
 
 
249
  </header>
250
 
251
- <nav class="theme-nav">
252
- <a href="#">Inicio</a>
253
- <a href="#">Productos</a>
254
- <a href="#">Galería</a>
255
- <a href="#">Videos</a>
256
- <a href="#">Contacto</a>
257
- </nav>
258
 
259
- <div class="theme-content">
260
- <div class="product-card">
261
- <img src="https://via.placeholder.com/400x300/{primary_color[1:]}/ffffff?text=Impresi%C3%B3n+3D" alt="Producto 3D">
262
- <div class="product-info">
263
- <h3 class="product-title">Figura Custom 3D</h3>
264
- <p>Impresión de alta calidad en PLA</p>
265
- <div class="product-price">$29.99</div>
266
- </div>
267
  </div>
268
-
269
- <div class="product-card">
270
- <img src="https://via.placeholder.com/400x300/{secondary_color[1:]}/ffffff?text=Prototipo" alt="Prototipo">
271
- <div class="product-info">
272
- <h3 class="product-title">Prototipo Rápido</h3>
273
- <p>Ideal para pruebas de concepto</p>
274
- <div class="product-price">$49.99</div>
275
- </div>
276
  </div>
277
-
278
- <div class="product-card">
279
- <img src="https://via.placeholder.com/400x300/{accent_color[1:]}/ffffff?text=Pieza+Functional" alt="Pieza">
280
- <div class="product-info">
281
- <h3 class="product-title">Pieza Functional</h3>
282
- <p>Resistente y duradera</p>
283
- <div class="product-price">$39.99</div>
284
- </div>
285
  </div>
286
  </div>
287
 
288
- <div class="gallery-grid">
289
- <img src="https://via.placeholder.com/300/{primary_color[1:]}/ffffff?text=Gal1" alt="Gallery">
290
- <img src="https://via.placeholder.com/300/{secondary_color[1:]}/ffffff?text=Gal2" alt="Gallery">
291
- <img src="https://via.placeholder.com/300/{accent_color[1:]}/ffffff?text=Gal3" alt="Gallery">
292
- <img src="https://via.placeholder.com/300/{primary_color[1:]}/ffffff?text=Gal4" alt="Gallery">
293
- </div>
294
 
295
- <div class="video-embed">
296
- <iframe width="100%" height="100%"
297
- src="https://www.youtube.com/embed/dQw4w9WgXcQ"
298
- frameborder="0" allowfullscreen>
299
- </iframe>
300
- </div>
301
 
302
- <div class="contact-form">
303
- <h2 style="color: {primary_color}; text-align: center; margin-bottom: 1.5rem;">Formulario de Contacto</h2>
304
- <div class="form-field">
305
- <label>Nombre:</label>
306
- <input type="text" placeholder="Tu nombre">
307
- </div>
308
- <div class="form-field">
309
- <label>Email:</label>
310
- <input type="email" placeholder="tu@email.com">
311
- </div>
312
- <div class="form-field">
313
- <label>Mensaje:</label>
314
- <textarea rows="4" placeholder="Tu mensaje..."></textarea>
315
- </div>
316
- <button class="btn-primary" style="width: 100%;">Enviar Mensaje</button>
317
  </div>
318
 
319
- <footer class="theme-footer">
320
- <h3>🚀 Tema WordPress 3D Print Pro</h3>
321
- <p>© 2024 - Diseñado para impresión 3D y WooCommerce</p>
322
- <p>Colores vibrantes | Animaciones modernas | Super editable</p>
323
  </footer>
324
  </div>
325
  """
326
 
327
- # Generate configuration JSON
328
- config = {
329
- "theme_name": "3D Print Store Pro",
330
- "created_at": datetime.now().isoformat(),
331
  "colors": {
332
  "primary": primary_color,
333
  "secondary": secondary_color,
@@ -335,104 +264,51 @@ def generate_theme_preview(primary_color, secondary_color, accent_color, backgro
335
  "background": background_color
336
  },
337
  "layout": {
338
- "header_style": header_style,
339
- "animation_type": animation_type,
340
- "layout_type": layout_type,
341
- "gallery_columns": gallery_columns
342
  },
343
- "features": {
344
  "woocommerce": enable_woocommerce,
345
- "video_section": show_videos,
346
- "contact_form": len(contact_form_fields) > 0
347
- },
348
- "form_fields": contact_form_fields
349
  }
350
 
351
- return css_preview, json.dumps(config, indent=2)
352
 
353
- def export_theme(config_json):
354
- """Export theme configuration as downloadable file"""
355
- try:
356
- config = json.loads(config_json)
357
- filename = f"wp_theme_{config['theme_name'].replace(' ', '_').lower()}.json"
358
- return filename, json.dumps(config, indent=2)
359
- except:
360
- return "theme_config.json", '{"error": "Invalid configuration"}'
 
 
361
 
362
- def generate_woocommerce_code():
363
- """Generate WooCommerce compatibility code snippet"""
364
- code = '''
365
- // WooCommerce Compatibility Functions
366
- add_action('after_setup_theme', 'wp3d_print_woocommerce_support');
367
- function wp3d_print_woocommerce_support() {
368
- add_theme_support('woocommerce');
369
- add_theme_support('wc-product-gallery-zoom');
370
- add_theme_support('wc-product-gallery-lightbox');
371
- add_theme_support('wc-product-gallery-slider');
372
- }
373
-
374
- // Custom Product Loop
375
- function wp3d_print_product_loop() {
376
- $args = array(
377
- 'post_type' => 'product',
378
- 'posts_per_page' => 12,
379
- 'orderby' => 'date',
380
- 'order' => 'DESC'
381
- );
382
-
383
- $products = new WP_Query($args);
384
-
385
- if($products->have_posts()):
386
- echo '<div class="product-grid">';
387
- while($products->have_posts()): $products->the_post();
388
- global $product;
389
- ?>
390
- <div class="product-card">
391
- <div class="product-image">
392
- <?php echo woocommerce_get_product_thumbnail(); ?>
393
- </div>
394
- <div class="product-info">
395
- <h3 class="product-title"><?php the_title(); ?></h3>
396
- <p class="product-price"><?php echo $product->get_price_html(); ?></p>
397
- <a href="<?php the_permalink(); ?>" class="btn-primary">Ver Producto</a>
398
- </div>
399
- </div>
400
- <?php
401
- endwhile;
402
- echo '</div>';
403
- endif;
404
- wp_reset_postdata();
405
- }
406
- '''
407
- return code.strip()
408
 
409
- def generate_contact_form_html(fields):
410
- """Generate contact form HTML based on selected fields"""
411
- if not fields:
412
- return "<!-- No contact form fields selected -->"
413
-
414
- html = '<div class="contact-form-wrapper">\n <form id="wp3d-contact-form">\n'
415
-
416
- field_types = {
417
- "name": '<input type="text" name="name" placeholder="Tu nombre" required>',
418
- "email": '<input type="email" name="email" placeholder="tu@email.com" required>',
419
- "phone": '<input type="tel" name="phone" placeholder="+34 123 456 789">',
420
- "message": '<textarea name="message" rows="5" placeholder="Tu mensaje..." required></textarea>',
421
- "subject": '<input type="text" name="subject" placeholder="Asunto">'
422
- }
423
-
424
- for field in fields:
425
- if field in field_types:
426
- html += f' <div class="form-group">\n <label>{field.capitalize()}</label>\n {field_types[field]}\n </div>\n'
427
-
428
- html += ' <button type="submit" class="btn-submit">Enviar Mensaje</button>\n </form>\n</div>'
429
- return html
430
 
431
- # Main Gradio 6 Application
432
  with gr.Blocks() as demo:
433
  gr.Markdown(
434
  """
435
- # 🎨 WordPress 3D Print Store Theme Customizer
436
  <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" style="text-decoration: none;">
437
  <span style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 8px 16px;
438
  border-radius: 20px; font-weight: 600; font-size: 0.9em; box-shadow: 0 4px 15px rgba(0,0,0,0.2);">
@@ -440,164 +316,116 @@ with gr.Blocks() as demo:
440
  </span>
441
  </a>
442
 
443
- **Crea temas WordPress modernos, animados y super editables para tiendas de impresión 3D**
444
  """
445
  )
446
 
447
- with gr.Tabs():
448
- with gr.TabItem("🎨 Personalización de Colores"):
449
- gr.Markdown("### Paleta de Colores - Header, Body y Footer")
450
- with gr.Row():
451
- primary_color = gr.ColorPicker(value="#FF6B6B", label="Color Primario (Header)")
452
- secondary_color = gr.ColorPicker(value="#4ECDC4", label="Color Secundario (Body)")
453
- accent_color = gr.ColorPicker(value="#FFE66D", label="Color Acento (Botones)")
454
- background_color = gr.ColorPicker(value="#F7FFF7", label="Color de Fondo")
455
-
456
- with gr.TabItem("📐 Diseño y Animaciones"):
457
- gr.Markdown("### Configuración de Diseño")
458
- with gr.Row():
459
- header_style = gr.Dropdown(
460
- ["gradient", "solid", "glassmorphism", "animated"],
461
- value="gradient",
462
- label="Estilo del Header"
463
- )
464
- animation_type = gr.Radio(
465
- ["fadeInUp", "slideInLeft", "bounceIn", "none"],
466
- value="fadeInUp",
467
- label="Tipo de Animación"
468
- )
469
- layout_type = gr.Radio(
470
- ["modern", "clean", "minimal"],
471
- value="modern",
472
- label="Tipo de Layout"
473
- )
474
-
475
- with gr.Row():
476
- gallery_columns = gr.Slider(2, 6, value=4, step=1, label="Columnas de Galería")
477
- show_videos = gr.Checkbox(value=True, label="Mostrar Sección de Videos")
478
-
479
- with gr.TabItem("🛒 WooCommerce"):
480
- gr.Markdown("### Configuración de WooCommerce")
481
- enable_woocommerce = gr.Checkbox(value=True, label="Habilitar WooCommerce")
482
-
483
- with gr.Accordion("Código PHP para WooCommerce", open=False):
484
- woocommerce_code = gr.Code(
485
- value=generate_woocommerce_code(),
486
- language="php",
487
- label="functions.php Snippet",
488
- lines=15
489
- )
490
-
491
- with gr.TabItem("📧 Formulario de Contacto"):
492
- gr.Markdown("### Campos del Formulario de Contacto")
493
- contact_form_fields = gr.CheckboxGroup(
494
- ["name", "email", "phone", "message", "subject"],
495
- value=["name", "email", "message"],
496
- label="Campos a incluir",
497
- info="Selecciona los campos para tu formulario"
498
- )
499
-
500
- with gr.Accordion("Vista Previa HTML del Formulario", open=False):
501
- form_preview = gr.HTML()
502
-
503
- def update_form_preview(fields):
504
- return generate_contact_form_html(fields)
505
-
506
- contact_form_fields.change(
507
- update_form_preview,
508
- inputs=contact_form_fields,
509
- outputs=form_preview
510
- )
511
-
512
- with gr.TabItem("📱 Vista Previa en Vivo"):
513
- gr.Markdown("### Vista Previa Interactiva del Tema")
514
- preview_btn = gr.Button("🔄 Actualizar Vista Previa", variant="primary")
515
-
516
- # Live Preview Section
517
- gr.Markdown("### 🎯 Vista Previa del Tema")
518
  with gr.Row():
519
- with gr.Column(scale=2):
520
- theme_preview = gr.HTML(label="Vista Previa")
521
  with gr.Column(scale=1):
522
- config_output = gr.JSON(label="Configuración del Tema")
523
-
524
- # Export Section
525
- with gr.Row():
526
- export_btn = gr.Button("💾 Exportar Configuración", variant="huggingface")
527
- export_file = gr.File(label="Descargar Configuración")
528
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
529
  # Event Listeners
530
- def update_preview(pri, sec, acc, bg, header, anim, layout, woo, cols, vids, fields):
531
- preview, config = generate_theme_preview(
532
- pri, sec, acc, bg, header, anim, layout, woo, cols, vids, fields
533
- )
534
- return preview, config
535
 
536
- # Update preview on button click
537
- preview_btn.click(
538
- update_preview,
539
- inputs=[
540
- primary_color, secondary_color, accent_color, background_color,
541
- header_style, animation_type, layout_type, enable_woocommerce,
542
- gallery_columns, show_videos, contact_form_fields
543
- ],
544
- outputs=[theme_preview, config_output],
545
- api_visibility="public"
546
  )
547
 
548
- # Auto-update on color changes
549
- color_inputs = [
550
- primary_color, secondary_color, accent_color, background_color,
551
- header_style, animation_type, layout_type, enable_woocommerce,
552
- gallery_columns, show_videos, contact_form_fields
553
- ]
554
-
555
- for input_comp in color_inputs:
556
- input_comp.change(
557
- update_preview,
558
- inputs=color_inputs,
559
- outputs=[theme_preview, config_output],
560
  api_visibility="private"
561
  )
562
-
563
- # Export functionality
564
- def export_config(config_json):
565
- filename, content = export_theme(config_json)
566
- return gr.File(value=(filename, content), visible=True)
567
-
568
- export_btn.click(
569
- export_config,
570
- inputs=config_output,
571
- outputs=export_file,
572
  api_visibility="public"
573
  )
574
 
575
- # Initialize preview on load
576
- demo.load(
577
- update_preview,
578
- inputs=color_inputs,
579
- outputs=[theme_preview, config_output],
580
- api_visibility="private"
581
  )
582
 
583
- # Gradio 6 - Launch with theme and footer links
584
  demo.launch(
585
  theme=gr.themes.Soft(
586
- primary_hue="blue",
587
- secondary_hue="indigo",
588
  neutral_hue="slate",
589
- text_size="lg",
590
- spacing_size="lg",
591
- radius_size="md"
592
  ).set(
593
  button_primary_background_fill="*primary_600",
594
  button_primary_background_fill_hover="*primary_700",
595
- block_title_text_weight="600"
596
  ),
597
  footer_links=[
598
  {"label": "Built with anycoder", "url": "https://huggingface.co/spaces/akhaliq/anycoder"},
599
- {"label": "WordPress Docs", "url": "https://wordpress.org/documentation/"},
600
- {"label": "WooCommerce", "url": "https://woocommerce.com/"}
601
- ],
602
- show_error=True
603
- )
 
2
  import json
3
  import base64
4
  from datetime import datetime
5
+ import os
6
+
7
+ # --- Utility Functions ---
8
 
9
  def generate_theme_preview(primary_color, secondary_color, accent_color, background_color,
10
  header_style, animation_type, layout_type, enable_woocommerce,
11
  gallery_columns, show_videos, contact_form_fields):
12
+ """Generate a live HTML/CSS preview of the WordPress theme"""
13
 
14
+ # Determine font based on layout
15
+ font_family = "'Inter', sans-serif"
16
+ if layout_type == "modern":
17
+ font_family = "'Outfit', sans-serif" # Modern geometric font for 3D printing
18
+ elif layout_type == "clean":
19
+ font_family = "'Roboto', sans-serif"
20
+
21
+ # CSS Generation
22
+ css = f"""
23
  <style>
24
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600;800&family=Outfit:wght@300;500;700&family=Roboto:wght@400;500&display=swap');
25
+
26
  :root {{
27
+ --primary: {primary_color};
28
+ --secondary: {secondary_color};
29
+ --accent: {accent_color};
30
+ --bg: {background_color};
 
31
  }}
32
 
33
+ .wp-theme-preview {{
34
+ font-family: {font_family};
35
+ background-color: var(--bg);
36
+ color: #333;
37
+ overflow: hidden;
38
+ border-radius: 12px;
39
+ box-shadow: 0 10px 30px rgba(0,0,0,0.1);
40
+ position: relative;
41
  }}
42
 
43
+ /* Header Styles */
44
  .theme-header {{
 
 
45
  padding: 2rem;
46
+ color: white;
 
47
  position: relative;
48
  overflow: hidden;
49
+ transition: all 0.3s ease;
50
  }}
51
 
52
+ .header-gradient {{ background: linear-gradient(135deg, var(--primary), var(--secondary)); }}
53
+ .header-solid {{ background: var(--primary); }}
54
+ .header-glass {{
55
+ background: rgba(255, 255, 255, 0.1);
56
+ backdrop-filter: blur(10px);
57
+ border-bottom: 1px solid rgba(255,255,255,0.2);
58
+ color: var(--primary);
 
 
59
  }}
60
 
61
+ .logo {{
62
+ font-size: 1.8rem;
63
+ font-weight: 800;
64
+ letter-spacing: -0.5px;
65
  display: flex;
66
+ align-items: center;
67
+ gap: 10px;
 
68
  }}
69
 
70
+ .nav-menu {{
71
+ display: flex;
72
+ gap: 20px;
73
+ margin-top: 1rem;
74
+ font-weight: 500;
75
+ }}
76
+
77
+ .nav-menu a {{
78
+ color: inherit;
79
  text-decoration: none;
80
+ opacity: 0.9;
81
+ transition: 0.2s;
82
+ }}
83
+ .nav-menu a:hover {{ opacity: 1; transform: translateY(-2px); }}
84
+
85
+ /* Hero Section */
86
+ .hero {{
87
+ padding: 4rem 2rem;
88
+ text-align: center;
89
+ animation: {animation_type} 0.8s ease-out;
90
  }}
91
 
92
+ .hero h2 {{
93
+ font-size: 2.5rem;
94
+ margin-bottom: 1rem;
95
+ background: -webkit-linear-gradient(45deg, var(--primary), var(--accent));
96
+ -webkit-background-clip: text;
97
+ -webkit-text-fill-color: transparent;
98
  }}
99
 
100
+ /* Product Grid */
101
+ .products-grid {{
 
 
102
  display: grid;
103
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
104
  gap: 2rem;
105
+ padding: 2rem;
106
  }}
107
 
108
  .product-card {{
109
  background: white;
110
  border-radius: 16px;
111
+ padding: 1rem;
112
+ box-shadow: 0 4px 15px rgba(0,0,0,0.05);
113
+ transition: transform 0.3s ease, box-shadow 0.3s ease;
114
+ animation: {animation_type} 0.6s ease-out backwards;
115
  }}
116
 
117
  .product-card:hover {{
118
+ transform: translateY(-10px);
119
+ box-shadow: 0 15px 30px rgba(0,0,0,0.1);
120
+ border: 2px solid var(--accent);
121
  }}
122
 
123
+ .product-img {{
124
  width: 100%;
125
+ height: 150px;
126
+ background: #f0f0f0;
127
+ border-radius: 8px;
128
+ margin-bottom: 1rem;
129
  object-fit: cover;
 
130
  }}
131
 
132
+ .price-tag {{
133
+ color: var(--accent);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
134
  font-weight: 800;
135
+ font-size: 1.2rem;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
136
  }}
137
 
138
+ .btn {{
139
+ background: var(--primary);
140
  color: white;
 
141
  border: none;
142
+ padding: 8px 16px;
143
+ border-radius: 6px;
 
144
  cursor: pointer;
145
+ width: 100%;
146
+ margin-top: 10px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
  font-weight: 600;
148
+ transition: 0.2s;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
149
  }}
150
 
151
+ .btn:hover {{ background: var(--accent); }}
152
+
153
+ /* Gallery */
154
+ .gallery {{
155
  display: grid;
156
  grid-template-columns: repeat({gallery_columns}, 1fr);
157
+ gap: 10px;
158
+ padding: 2rem;
159
  }}
160
+ .gallery-item {{
161
+ aspect-ratio: 1;
162
+ background: #ddd;
163
+ border-radius: 8px;
 
164
  overflow: hidden;
 
 
165
  }}
166
 
167
+ /* Contact Form */
168
+ .contact-section {{
169
+ background: white;
170
+ margin: 2rem;
171
+ padding: 2rem;
172
+ border-radius: 16px;
173
+ border-left: 5px solid var(--accent);
174
+ }}
175
+
176
+ .form-input {{
177
+ width: 100%;
178
+ padding: 10px;
179
+ margin-bottom: 10px;
180
+ border: 1px solid #eee;
181
+ border-radius: 6px;
182
  }}
183
+
184
+ /* Animations */
185
+ @keyframes fadeInUp {{ from {{ opacity: 0; transform: translateY(20px); }} to {{ opacity: 1; transform: translateY(0); }} }}
186
+ @keyframes slideInLeft {{ from {{ opacity: 0; transform: translateX(-50px); }} to {{ opacity: 1; transform: translateX(0); }} }}
187
+ @keyframes bounceIn {{ 0% {{ transform: scale(0.3); opacity: 0; }} 50% {{ transform: scale(1.05); }} 70% {{ transform: scale(0.9); }} 100% {{ transform: scale(1); opacity: 1; }} }}
188
+ @keyframes pulse {{ 0% {{ transform: scale(1); }} 50% {{ transform: scale(1.02); }} 100% {{ transform: scale(1); }} }}
189
  </style>
190
+ """
191
 
192
+ # HTML Structure
193
+ html = f"""
194
+ <div class="wp-theme-preview">
195
+ <header class="theme-header header-{header_style}">
196
+ <div class="logo">
197
+ <span style="font-size: 1.5em">🧊</span> 3D PRINT <span style="color: {accent_color}">PRO</span>
198
+ </div>
199
+ <nav class="nav-menu">
200
+ <a href="#">Tienda</a>
201
+ <a href="#">Filamentos</a>
202
+ <a href="#">Servicios 3D</a>
203
+ <a href="#">Contacto</a>
204
+ {'<a href="#" style="background:rgba(255,255,255,0.2); padding:2px 10px; border-radius:20px;">🛒 2</a>' if enable_woocommerce else ''}
205
+ </nav>
206
  </header>
207
 
208
+ <div class="hero">
209
+ <h2>Impresión 3D de Alta Precisión</h2>
210
+ <p style="margin-bottom: 2rem; color: #666;">Diseños personalizados, prototipos rápidos y arte en PLA/Resina.</p>
211
+ <button class="btn" style="width: auto; padding: 12px 30px; border-radius: 30px; background: {accent_color}">
212
+ Ver Catálogo
213
+ </button>
214
+ </div>
215
 
216
+ <div class="products-grid">
217
+ <div class="product-card" style="animation-delay: 0.1s">
218
+ <img src="https://placehold.co/400x300/333/FFF?text=Estatua+PLA" class="product-img" alt="Product">
219
+ <h3>Figura Coleccionable</h3>
220
+ <div class="price-tag">$45.00</div>
221
+ <button class="btn">Añadir al Carrito</button>
 
 
222
  </div>
223
+ <div class="product-card" style="animation-delay: 0.2s">
224
+ <img src="https://placehold.co/400x300/666/FFF?text=Pieza+Mecánica" class="product-img" alt="Product">
225
+ <h3>Engranaje Nylon</h3>
226
+ <div class="price-tag">$12.50</div>
227
+ <button class="btn">Añadir al Carrito</button>
 
 
 
228
  </div>
229
+ <div class="product-card" style="animation-delay: 0.3s">
230
+ <img src="https://placehold.co/400x300/444/FFF?text=Jarrón+Voronoi" class="product-img" alt="Product">
231
+ <h3>Jarrón Voronoi</h3>
232
+ <div class="price-tag">$28.99</div>
233
+ <button class="btn">Añadir al Carrito</button>
 
 
 
234
  </div>
235
  </div>
236
 
237
+ {'<div class="gallery">' + ''.join([f'<div class="gallery-item"><img src="https://placehold.co/200/eee/ccc?text=Print+{i+1}" style="width:100%;height:100%;object-fit:cover;"></div>' for i in range(gallery_columns)]) + '</div>' if gallery_columns > 0 else ''}
 
 
 
 
 
238
 
239
+ {f'<div style="padding: 2rem;"><h3 style="text-align:center; margin-bottom:1rem;">Proceso de Impresión</h3><div style="background:#000; height:200px; border-radius:12px; display:flex; align-items:center; justify-content:center; color:white;">▶ Video Embed Placeholder</div></div>' if show_videos else ''}
 
 
 
 
 
240
 
241
+ <div class="contact-section">
242
+ <h3 style="color: {primary_color}">Solicita tu Presupuesto</h3>
243
+ {'<input type="text" placeholder="Nombre" class="form-input">' if "name" in contact_form_fields else ''}
244
+ {'<input type="email" placeholder="Email" class="form-input">' if "email" in contact_form_fields else ''}
245
+ {'<input type="text" placeholder="Teléfono" class="form-input">' if "phone" in contact_form_fields else ''}
246
+ {'<textarea placeholder="Describe tu proyecto 3D..." class="form-input" rows="3"></textarea>' if "message" in contact_form_fields else ''}
247
+ <button class="btn">Enviar Solicitud</button>
 
 
 
 
 
 
 
 
248
  </div>
249
 
250
+ <footer style="background: #222; color: white; padding: 2rem; text-align: center; margin-top: 2rem;">
251
+ <p>© 2024 3D Print Store. Theme generated by Anycoder.</p>
 
 
252
  </footer>
253
  </div>
254
  """
255
 
256
+ # Configuration Object
257
+ config_data = {
258
+ "theme_name": "3D Print Store Theme",
259
+ "version": "1.0.0",
260
  "colors": {
261
  "primary": primary_color,
262
  "secondary": secondary_color,
 
264
  "background": background_color
265
  },
266
  "layout": {
267
+ "header": header_style,
268
+ "animation": animation_type,
269
+ "font": layout_type
 
270
  },
271
+ "modules": {
272
  "woocommerce": enable_woocommerce,
273
+ "gallery_cols": gallery_columns,
274
+ "video_enabled": show_videos,
275
+ "contact_fields": contact_form_fields
276
+ }
277
  }
278
 
279
+ return css + html, config_data
280
 
281
+ def generate_woo_php():
282
+ return """<?php
283
+ // Add to your theme's functions.php
284
+ function theme_add_woocommerce_support() {
285
+ add_theme_support('woocommerce');
286
+ add_theme_support('wc-product-gallery-zoom');
287
+ add_theme_support('wc-product-gallery-lightbox');
288
+ add_theme_support('wc-product-gallery-slider');
289
+ }
290
+ add_action('after_setup_theme', 'theme_add_woocommerce_support');
291
 
292
+ // Custom 3D Print Badge
293
+ add_action('woocommerce_before_shop_loop_item_title', 'add_3d_badge', 10);
294
+ function add_3d_badge() {
295
+ echo '<span class="badge-3d">3D PRINTED</span>';
296
+ }
297
+ ?>"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
298
 
299
+ def export_theme_config(config_data):
300
+ # For Gradio 6, we can write to a temp file and return the path
301
+ filename = "theme_config.json"
302
+ with open(filename, "w") as f:
303
+ json.dump(config_data, f, indent=4)
304
+ return filename
305
+
306
+ # --- Gradio Application ---
 
 
 
 
 
 
 
 
 
 
 
 
 
307
 
 
308
  with gr.Blocks() as demo:
309
  gr.Markdown(
310
  """
311
+ # 🎨 WordPress Theme Builder: 3D Print Store Edition
312
  <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" style="text-decoration: none;">
313
  <span style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 8px 16px;
314
  border-radius: 20px; font-weight: 600; font-size: 0.9em; box-shadow: 0 4px 15px rgba(0,0,0,0.2);">
 
316
  </span>
317
  </a>
318
 
319
+ Diseña un tema **vibrante, moderno y optimizado** para vender productos impresos en 3D.
320
  """
321
  )
322
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
323
  with gr.Row():
 
 
324
  with gr.Column(scale=1):
325
+ with gr.Tabs():
326
+ with gr.TabItem("🎨 Colores & Estilo"):
327
+ gr.Markdown("### Paleta de Colores 'Llamativa'")
328
+ primary_col = gr.ColorPicker(label="Primario (Marca)", value="#6366f1")
329
+ secondary_col = gr.ColorPicker(label="Secundario (Gradientes)", value="#ec4899")
330
+ accent_col = gr.ColorPicker(label="Acento (Botones/Precios)", value="#f43f5e")
331
+ bg_col = gr.ColorPicker(label="Fondo (Cuerpo)", value="#f8fafc")
332
+
333
+ gr.Markdown("### Estructura Visual")
334
+ header_style = gr.Dropdown(
335
+ choices=["gradient", "solid", "glass"],
336
+ value="gradient",
337
+ label="Estilo del Header"
338
+ )
339
+ layout_type = gr.Radio(
340
+ choices=["modern", "clean"],
341
+ value="modern",
342
+ label="Tipografía y Layout"
343
+ )
344
+
345
+ with gr.TabItem("⚡ Animaciones & Módulos"):
346
+ animation_type = gr.Dropdown(
347
+ choices=["fadeInUp", "slideInLeft", "bounceIn", "pulse"],
348
+ value="fadeInUp",
349
+ label="Animación de Entrada"
350
+ )
351
+ enable_woo = gr.Checkbox(label="Activar WooCommerce", value=True)
352
+ show_videos = gr.Checkbox(label="Sección de Video (Proceso de Impresión)", value=True)
353
+ gallery_cols = gr.Slider(minimum=2, maximum=6, step=1, value=4, label="Columnas Galería")
354
+
355
+ with gr.TabItem("📧 Contacto"):
356
+ contact_fields = gr.CheckboxGroup(
357
+ choices=["name", "email", "phone", "message"],
358
+ value=["name", "email", "message"],
359
+ label="Campos del Formulario"
360
+ )
361
+
362
+ with gr.Accordion("💻 Código PHP (WooCommerce)", open=False):
363
+ gr.Code(value=generate_woo_php(), language="php", interactive=False)
364
+
365
+ btn_generate = gr.Button("🔄 Actualizar Diseño", variant="primary")
366
+ btn_export = gr.Button("💾 Exportar Configuración JSON")
367
+ file_output = gr.File(label="Descargar Tema Config")
368
+
369
+ with gr.Column(scale=2):
370
+ gr.Markdown("### 👁️ Vista Previa en Vivo (HTML/CSS)")
371
+ preview_html = gr.HTML(label="Theme Preview")
372
+ json_output = gr.JSON(label="JSON Data", visible=False)
373
+
374
  # Event Listeners
375
+ inputs = [
376
+ primary_col, secondary_col, accent_col, bg_col,
377
+ header_style, animation_type, layout_type, enable_woo,
378
+ gallery_cols, show_videos, contact_fields
379
+ ]
380
 
381
+ # Initial Load
382
+ demo.load(
383
+ fn=generate_theme_preview,
384
+ inputs=inputs,
385
+ outputs=[preview_html, json_output],
386
+ api_visibility="private"
 
 
 
 
387
  )
388
 
389
+ # Update on Change
390
+ for inp in inputs:
391
+ inp.change(
392
+ fn=generate_theme_preview,
393
+ inputs=inputs,
394
+ outputs=[preview_html, json_output],
 
 
 
 
 
 
395
  api_visibility="private"
396
  )
397
+
398
+ # Button Click
399
+ btn_generate.click(
400
+ fn=generate_theme_preview,
401
+ inputs=inputs,
402
+ outputs=[preview_html, json_output],
 
 
 
 
403
  api_visibility="public"
404
  )
405
 
406
+ # Export
407
+ btn_export.click(
408
+ fn=export_theme_config,
409
+ inputs=[json_output],
410
+ outputs=[file_output],
411
+ api_visibility="public"
412
  )
413
 
414
+ # Launch App
415
  demo.launch(
416
  theme=gr.themes.Soft(
417
+ primary_hue="indigo",
418
+ secondary_hue="pink",
419
  neutral_hue="slate",
420
+ font=gr.themes.GoogleFont("Inter")
 
 
421
  ).set(
422
  button_primary_background_fill="*primary_600",
423
  button_primary_background_fill_hover="*primary_700",
424
+ block_shadow="*shadow_drop_lg"
425
  ),
426
  footer_links=[
427
  {"label": "Built with anycoder", "url": "https://huggingface.co/spaces/akhaliq/anycoder"},
428
+ {"label": "WordPress.org", "url": "https://wordpress.org"},
429
+ {"label": "WooCommerce", "url": "https://woocommerce.com"}
430
+ ]
431
+ )