Files
orion/app/templates/platform/sections/_cta.html
Samir Boulahtit dca52d004e feat: implement section-based homepage management system
Add structured JSON sections to ContentPage for multi-language homepage editing:

Database:
- Add `sections` JSON column to content_pages table
- Migration z8i9j0k1l2m3 adds the column

Schema:
- New models/schema/homepage_sections.py with Pydantic schemas
- TranslatableText for language-keyed translations
- HeroSection, FeaturesSection, PricingSection, CTASection

Templates:
- New section partials in app/templates/platform/sections/
- Updated homepage-default.html to render sections dynamically
- Fallback to placeholder content when sections not configured

Service:
- update_homepage_sections() - validate and save all sections
- update_single_section() - update individual section
- get_default_sections() - empty structure for new homepages

API:
- GET /{page_id}/sections - get sections with platform languages
- PUT /{page_id}/sections - update all sections
- PUT /{page_id}/sections/{section_name} - update single section

Admin UI:
- Section editor appears when editing homepage (slug='home')
- Language tabs from platform.supported_languages
- Accordion sections for Hero, Features, Pricing, CTA
- Button/feature card repeaters with add/remove

Also fixes broken line 181 in z4e5f6a7b8c9 migration.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 14:31:23 +01:00

55 lines
2.4 KiB
HTML

{# app/templates/platform/sections/_cta.html #}
{# Call-to-action section partial with multi-language support #}
{#
Parameters:
- cta: CTASection object (or dict)
- lang: Current language code
- default_lang: Fallback language
#}
{% macro render_cta(cta, lang, default_lang) %}
{% if cta and cta.enabled %}
<section class="py-16 lg:py-24 {% if cta.background_type == 'gradient' %}bg-gradient-to-r from-indigo-600 to-purple-600{% else %}bg-indigo-600{% endif %}">
<div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
{# Title #}
{% set title = cta.title.translations.get(lang) or cta.title.translations.get(default_lang) or '' %}
{% if title %}
<h2 class="text-3xl md:text-4xl font-bold text-white mb-6">
{{ title }}
</h2>
{% endif %}
{# Subtitle #}
{% if cta.subtitle and cta.subtitle.translations %}
{% set subtitle = cta.subtitle.translations.get(lang) or cta.subtitle.translations.get(default_lang) %}
{% if subtitle %}
<p class="text-xl text-indigo-100 mb-10 max-w-2xl mx-auto">
{{ subtitle }}
</p>
{% endif %}
{% endif %}
{# Buttons #}
{% if cta.buttons %}
<div class="flex flex-col sm:flex-row gap-4 justify-center items-center">
{% for button in cta.buttons %}
{% set btn_text = button.text.translations.get(lang) or button.text.translations.get(default_lang) or '' %}
{% if btn_text and button.url %}
<a href="{{ button.url }}"
class="{% if button.style == 'primary' %}bg-white text-indigo-600 hover:bg-gray-100{% elif button.style == 'secondary' %}bg-indigo-500 text-white hover:bg-indigo-400{% else %}border-2 border-white text-white hover:bg-white/10{% endif %} px-10 py-4 rounded-xl font-bold transition inline-flex items-center space-x-2">
<span>{{ btn_text }}</span>
{% if button.style == 'primary' %}
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 7l5 5m0 0l-5 5m5-5H6"></path>
</svg>
{% endif %}
</a>
{% endif %}
{% endfor %}
</div>
{% endif %}
</div>
</section>
{% endif %}
{% endmacro %}