Files
orion/app/modules/cms/services/theme_presets.py
Samir Boulahtit 481deaa67d refactor: fix all 177 architecture validator warnings
- Replace 153 broad `except Exception` with specific types (SQLAlchemyError,
  TemplateError, OSError, SMTPException, ClientError, etc.) across 37 services
- Break catalog↔inventory circular dependency (IMPORT-004)
- Create 19 skeleton test files for MOD-024 coverage
- Exclude aggregator services from MOD-024 (false positives)
- Update test mocks to match narrowed exception types

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 11:59:44 +01:00

204 lines
6.6 KiB
Python

# app/core/theme_presets.py
"""
Theme presets for store shops.
Presets define default color schemes, fonts, and layouts that stores can choose from.
Each preset provides a complete theme configuration that can be customized further.
"""
from app.modules.cms.models import StoreTheme
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: StoreTheme, preset_name: str) -> StoreTheme:
"""
Apply a preset to a store theme.
Args:
theme: StoreTheme instance to update
preset_name: Name of the preset to apply
Returns:
StoreTheme: Updated theme instance
Raises:
ValueError: If preset name is unknown
Example:
theme = StoreTheme(store_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"],
}