# app/core/theme_presets.py """ Theme presets for vendor shops. Presets define default color schemes, fonts, and layouts that vendors can choose from. Each preset provides a complete theme configuration that can be customized further. """ from models.database.vendor_theme import VendorTheme THEME_PRESETS = { "default": { "colors": { "primary": "#6366f1", # Indigo "secondary": "#8b5cf6", # Purple "accent": "#ec4899", # Pink "background": "#ffffff", # White "text": "#1f2937", # Gray-800 "border": "#e5e7eb", # Gray-200 }, "fonts": {"heading": "Inter, sans-serif", "body": "Inter, sans-serif"}, "layout": {"style": "grid", "header": "fixed", "product_card": "modern"}, }, "modern": { "colors": { "primary": "#6366f1", # Indigo - Modern tech look "secondary": "#8b5cf6", # Purple "accent": "#ec4899", # Pink "background": "#ffffff", # White "text": "#1f2937", # Gray-800 "border": "#e5e7eb", # Gray-200 }, "fonts": {"heading": "Inter, sans-serif", "body": "Inter, sans-serif"}, "layout": {"style": "grid", "header": "fixed", "product_card": "modern"}, }, "classic": { "colors": { "primary": "#1e40af", # Dark blue - Traditional "secondary": "#7c3aed", # Purple "accent": "#dc2626", # Red "background": "#ffffff", # White "text": "#1f2937", # Gray-800 "border": "#d1d5db", # Gray-300 }, "fonts": {"heading": "Georgia, serif", "body": "Arial, sans-serif"}, "layout": {"style": "list", "header": "static", "product_card": "classic"}, }, "minimal": { "colors": { "primary": "#000000", # Black - Ultra minimal "secondary": "#404040", # Dark gray "accent": "#666666", # Medium gray "background": "#ffffff", # White "text": "#000000", # Black "border": "#e5e7eb", # Light gray }, "fonts": {"heading": "Helvetica, sans-serif", "body": "Helvetica, sans-serif"}, "layout": {"style": "grid", "header": "transparent", "product_card": "minimal"}, }, "vibrant": { "colors": { "primary": "#f59e0b", # Orange - Bold & energetic "secondary": "#ef4444", # Red "accent": "#8b5cf6", # Purple "background": "#ffffff", # White "text": "#1f2937", # Gray-800 "border": "#fbbf24", # Yellow }, "fonts": {"heading": "Poppins, sans-serif", "body": "Open Sans, sans-serif"}, "layout": {"style": "masonry", "header": "fixed", "product_card": "modern"}, }, "elegant": { "colors": { "primary": "#6b7280", # Gray - Sophisticated "secondary": "#374151", # Dark gray "accent": "#d97706", # Amber "background": "#ffffff", # White "text": "#1f2937", # Gray-800 "border": "#e5e7eb", # Gray-200 }, "fonts": {"heading": "Playfair Display, serif", "body": "Lato, sans-serif"}, "layout": {"style": "grid", "header": "fixed", "product_card": "classic"}, }, "nature": { "colors": { "primary": "#059669", # Green - Natural & eco "secondary": "#10b981", # Emerald "accent": "#f59e0b", # Amber "background": "#ffffff", # White "text": "#1f2937", # Gray-800 "border": "#d1fae5", # Light green }, "fonts": {"heading": "Montserrat, sans-serif", "body": "Open Sans, sans-serif"}, "layout": {"style": "grid", "header": "fixed", "product_card": "modern"}, }, } def get_preset(preset_name: str) -> dict: """ Get a theme preset by name. Args: preset_name: Name of the preset (e.g., 'modern', 'classic') Returns: dict: Theme configuration Raises: ValueError: If preset name is unknown """ if preset_name not in THEME_PRESETS: available = ", ".join(THEME_PRESETS.keys()) raise ValueError(f"Unknown preset: {preset_name}. Available: {available}") return THEME_PRESETS[preset_name] def apply_preset(theme: VendorTheme, preset_name: str) -> VendorTheme: """ Apply a preset to a vendor theme. Args: theme: VendorTheme instance to update preset_name: Name of the preset to apply Returns: VendorTheme: Updated theme instance Raises: ValueError: If preset name is unknown Example: theme = VendorTheme(vendor_id=1) apply_preset(theme, "modern") db.add(theme) db.commit() """ preset = get_preset(preset_name) # Set theme name theme.theme_name = preset_name # Apply colors (all of them!) theme.colors = preset["colors"] # Apply fonts theme.font_family_heading = preset["fonts"]["heading"] theme.font_family_body = preset["fonts"]["body"] # Apply layout settings theme.layout_style = preset["layout"]["style"] theme.header_style = preset["layout"]["header"] theme.product_card_style = preset["layout"]["product_card"] # Mark as active theme.is_active = True return theme def get_available_presets() -> list[str]: """ Get list of available preset names. Returns: list: Available preset names """ return list(THEME_PRESETS.keys()) def get_preset_preview(preset_name: str) -> dict: """ Get preview information for a preset (for UI display). Args: preset_name: Name of the preset Returns: dict: Preview info with colors, fonts, description """ preset = get_preset(preset_name) descriptions = { "default": "Clean and professional - perfect for getting started", "modern": "Contemporary tech-inspired design with vibrant colors", "classic": "Traditional and trustworthy with serif typography", "minimal": "Ultra-clean black and white aesthetic", "vibrant": "Bold and energetic with bright accent colors", "elegant": "Sophisticated gray tones with refined typography", "nature": "Fresh and eco-friendly green color palette", } return { "name": preset_name, "description": descriptions.get(preset_name, ""), "primary_color": preset["colors"]["primary"], "secondary_color": preset["colors"]["secondary"], "accent_color": preset["colors"]["accent"], "heading_font": preset["fonts"]["heading"], "body_font": preset["fonts"]["body"], "layout_style": preset["layout"]["style"], } def create_custom_preset( colors: dict, fonts: dict, layout: dict, name: str = "custom" ) -> dict: """ Create a custom preset from provided settings. Args: colors: Dict with primary, secondary, accent, background, text, border fonts: Dict with heading and body fonts layout: Dict with style, header, product_card name: Name for the custom preset Returns: dict: Custom preset configuration Example: custom = create_custom_preset( colors={"primary": "#ff0000", "secondary": "#00ff00", ...}, fonts={"heading": "Arial", "body": "Arial"}, layout={"style": "grid", "header": "fixed", "product_card": "modern"}, name="my_custom_theme" ) """ # Validate colors required_colors = ["primary", "secondary", "accent", "background", "text", "border"] for color_key in required_colors: if color_key not in colors: colors[color_key] = THEME_PRESETS["default"]["colors"][color_key] # Validate fonts if "heading" not in fonts: fonts["heading"] = "Inter, sans-serif" if "body" not in fonts: fonts["body"] = "Inter, sans-serif" # Validate layout if "style" not in layout: layout["style"] = "grid" if "header" not in layout: layout["header"] = "fixed" if "product_card" not in layout: layout["product_card"] = "modern" return {"colors": colors, "fonts": fonts, "layout": layout}