- 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>
204 lines
6.6 KiB
Python
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"],
|
|
}
|