# THEME PRESETS USAGE GUIDE ## What Changed in Your Presets ### ✅ What You Had Right - Good preset structure with colors, fonts, layout - Clean `apply_preset()` function - Good preset names (modern, classic, minimal, vibrant) ### 🔧 What We Added 1. **Missing color fields:** `background`, `text`, `border` 2. **Missing layout field:** `product_card` style 3. **"default" preset:** Your platform's default theme 4. **Extra presets:** "elegant" and "nature" themes 5. **Helper functions:** `get_preset()`, `get_available_presets()`, `get_preset_preview()` 6. **Custom preset builder:** `create_custom_preset()` --- ## Usage Examples ### 1. Apply Preset to New Store ```python from models.database.store_theme import StoreTheme from app.core.theme_presets import apply_preset from app.core.database import SessionLocal # Create theme for store db = SessionLocal() store_id = 1 # Create and apply preset theme = StoreTheme(store_id=store_id) apply_preset(theme, "modern") db.add(theme) db.commit() ``` ### 2. Change Store's Theme ```python from models.database.store_theme import StoreTheme from app.core.theme_presets import apply_preset # Get existing theme theme = db.query(StoreTheme).filter( StoreTheme.store_id == store_id ).first() if theme: # Update to new preset apply_preset(theme, "classic") else: # Create new theme theme = StoreTheme(store_id=store_id) apply_preset(theme, "classic") db.add(theme) db.commit() ``` ### 3. Get Available Presets (For UI Dropdown) ```python from app.core.theme_presets import get_available_presets, get_preset_preview # Get list of preset names presets = get_available_presets() # Returns: ['default', 'modern', 'classic', 'minimal', 'vibrant', 'elegant', 'nature'] # Get preview info for UI previews = [] for preset_name in presets: preview = get_preset_preview(preset_name) previews.append(preview) # Returns list of dicts with: # { # "name": "modern", # "description": "Contemporary tech-inspired design...", # "primary_color": "#6366f1", # "secondary_color": "#8b5cf6", # ... # } ``` ### 4. API Endpoint to Apply Preset ```python # In your API route from fastapi import APIRouter, Depends from app.core.theme_presets import apply_preset, get_available_presets @router.put("/theme/preset") def apply_theme_preset( preset_name: str, store: Store = Depends(require_store_context()), db: Session = Depends(get_db), ): """Apply a theme preset to store.""" # Validate preset name if preset_name not in get_available_presets(): raise HTTPException( status_code=400, detail=f"Invalid preset. Available: {get_available_presets()}" ) # Get or create store theme theme = db.query(StoreTheme).filter( StoreTheme.store_id == store.id ).first() if not theme: theme = StoreTheme(store_id=store.id) db.add(theme) # Apply preset apply_preset(theme, preset_name) db.commit() db.refresh(theme) return { "message": f"Theme preset '{preset_name}' applied successfully", "theme": theme.to_dict() } ``` ### 5. Get All Presets for Theme Selector ```python @router.get("/theme/presets") def get_theme_presets(): """Get all available theme presets with previews.""" from app.core.theme_presets import get_available_presets, get_preset_preview presets = [] for preset_name in get_available_presets(): preview = get_preset_preview(preset_name) presets.append(preview) return {"presets": presets} # Returns: # { # "presets": [ # { # "name": "default", # "description": "Clean and professional...", # "primary_color": "#6366f1", # "secondary_color": "#8b5cf6", # "accent_color": "#ec4899", # "heading_font": "Inter, sans-serif", # "body_font": "Inter, sans-serif", # "layout_style": "grid" # }, # ... # ] # } ``` ### 6. Create Custom Theme (Not from Preset) ```python from app.core.theme_presets import create_custom_preset # User provides custom colors custom_preset = create_custom_preset( colors={ "primary": "#ff0000", "secondary": "#00ff00", "accent": "#0000ff", "background": "#ffffff", "text": "#000000", "border": "#cccccc" }, fonts={ "heading": "Arial, sans-serif", "body": "Verdana, sans-serif" }, layout={ "style": "grid", "header": "fixed", "product_card": "modern" }, name="my_custom" ) # Apply to store theme theme = StoreTheme(store_id=store_id) theme.theme_name = "custom" theme.colors = custom_preset["colors"] theme.font_family_heading = custom_preset["fonts"]["heading"] theme.font_family_body = custom_preset["fonts"]["body"] theme.layout_style = custom_preset["layout"]["style"] theme.header_style = custom_preset["layout"]["header"] theme.product_card_style = custom_preset["layout"]["product_card"] theme.is_active = True db.add(theme) db.commit() ``` --- ## Available Presets | Preset | Description | Primary Color | Use Case | |--------|-------------|---------------|----------| | `default` | Clean & professional | Indigo (#6366f1) | General purpose | | `modern` | Tech-inspired | Indigo (#6366f1) | Tech products | | `classic` | Traditional | Dark Blue (#1e40af) | Established brands | | `minimal` | Ultra-clean B&W | Black (#000000) | Minimalist brands | | `vibrant` | Bold & energetic | Orange (#f59e0b) | Creative brands | | `elegant` | Sophisticated | Gray (#6b7280) | Luxury products | | `nature` | Eco-friendly | Green (#059669) | Organic/eco brands | --- ## Complete Preset Structure Each preset includes: ```python { "colors": { "primary": "#6366f1", # Main brand color "secondary": "#8b5cf6", # Supporting color "accent": "#ec4899", # Call-to-action color "background": "#ffffff", # Page background "text": "#1f2937", # Text color "border": "#e5e7eb" # Border/divider color }, "fonts": { "heading": "Inter, sans-serif", # Headings (h1-h6) "body": "Inter, sans-serif" # Body text }, "layout": { "style": "grid", # grid | list | masonry "header": "fixed", # fixed | static | transparent "product_card": "modern" # modern | classic | minimal } } ``` --- ## Integration with Admin Panel ### Theme Editor UI Flow 1. **Preset Selector** ```javascript // Fetch available presets fetch('/api/v1/store/theme/presets') .then(r => r.json()) .then(data => { // Display preset cards with previews data.presets.forEach(preset => { showPresetCard(preset.name, preset.primary_color, preset.description) }) }) ``` 2. **Apply Preset Button** ```javascript function applyPreset(presetName) { fetch('/api/v1/store/theme/preset', { method: 'PUT', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({preset_name: presetName}) }) .then(() => { alert('Theme updated!') location.reload() // Refresh to show new theme }) } ``` 3. **Custom Color Picker** (After applying preset) ```javascript // User can then customize colors function updateColors(colors) { fetch('/api/v1/store/theme/colors', { method: 'PUT', body: JSON.stringify({colors}) }) } ``` --- ## Testing Presets ```python # Test script from app.core.theme_presets import apply_preset, get_available_presets from models.database.store_theme import StoreTheme def test_all_presets(): """Test applying all presets""" presets = get_available_presets() for preset_name in presets: theme = StoreTheme(store_id=999) # Test store apply_preset(theme, preset_name) assert theme.theme_name == preset_name assert theme.colors is not None assert theme.font_family_heading is not None assert theme.is_active == True print(f"✅ {preset_name} preset OK") test_all_presets() ``` --- ## CSS Variables Generation Your middleware already handles this via `StoreTheme.to_dict()`, which includes: ```python "css_variables": { "--color-primary": "#6366f1", "--color-secondary": "#8b5cf6", "--color-accent": "#ec4899", "--color-background": "#ffffff", "--color-text": "#1f2937", "--color-border": "#e5e7eb", "--font-heading": "Inter, sans-serif", "--font-body": "Inter, sans-serif", } ``` Use in templates: ```html ``` --- ## Next Steps 1. ✅ Copy `theme_presets.py` to `app/core/theme_presets.py` 2. ✅ Create API endpoints for applying presets 3. ✅ Build theme selector UI in admin panel 4. ✅ Test all presets work correctly 5. ✅ Add custom color picker for fine-tuning Perfect! Your presets are now complete and production-ready! 🎨