From 83a6831b2ee0d42c03f02aabcbfe53b2308c13b4 Mon Sep 17 00:00:00 2001 From: Samir Boulahtit Date: Fri, 28 Nov 2025 07:17:30 +0100 Subject: [PATCH] feat: add platform homepage and content management system with improved UI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implemented a comprehensive CMS for managing platform homepage and content pages: - Platform homepage manager with template selection (default, minimal, modern) - Content pages CRUD with platform defaults and vendor overrides - Sidebar navigation for Content Management section - Dedicated API endpoints for creating, updating, deleting pages - Template support for customizable homepage layouts - Header/footer navigation integration for content pages - Comprehensive documentation for platform homepage setup - Migration script for creating initial platform pages UI improvements: - Fixed action buttons styling in content pages table to match design system - Added proper hover states, rounded corners, and better contrast - Increased button size and padding for better usability šŸ¤– Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- app/api/v1/admin/content_pages.py | 4 + app/routes/admin_pages.py | 87 +++ app/services/content_page_service.py | 7 + app/templates/admin/content-page-edit.html | 301 ++++++++ app/templates/admin/content-pages.html | 200 +++++ app/templates/admin/partials/sidebar.html | 62 ++ app/templates/admin/platform-homepage.html | 248 ++++++ app/templates/platform/base.html | 299 ++++++++ app/templates/platform/content-page.html | 246 ++++++ app/templates/platform/homepage-default.html | 228 ++++++ app/templates/platform/homepage-minimal.html | 100 +++ app/templates/platform/homepage-modern.html | 258 +++++++ docs/features/platform-homepage.md | 710 ++++++++++++++++++ .../platform-homepage-quick-start.md | 316 ++++++++ main.py | 132 ++++ mkdocs.yml | 2 + scripts/create_platform_pages.py | 491 ++++++++++++ static/admin/js/content-page-edit.js | 171 +++++ static/admin/js/content-pages.js | 161 ++++ static/admin/js/platform-homepage.js | 154 ++++ 20 files changed, 4177 insertions(+) create mode 100644 app/templates/admin/content-page-edit.html create mode 100644 app/templates/admin/content-pages.html create mode 100644 app/templates/admin/platform-homepage.html create mode 100644 app/templates/platform/base.html create mode 100644 app/templates/platform/content-page.html create mode 100644 app/templates/platform/homepage-default.html create mode 100644 app/templates/platform/homepage-minimal.html create mode 100644 app/templates/platform/homepage-modern.html create mode 100644 docs/features/platform-homepage.md create mode 100644 docs/getting-started/platform-homepage-quick-start.md create mode 100755 scripts/create_platform_pages.py create mode 100644 static/admin/js/content-page-edit.js create mode 100644 static/admin/js/content-pages.js create mode 100644 static/admin/js/platform-homepage.js diff --git a/app/api/v1/admin/content_pages.py b/app/api/v1/admin/content_pages.py index 2881973e..28d6c1b8 100644 --- a/app/api/v1/admin/content_pages.py +++ b/app/api/v1/admin/content_pages.py @@ -32,6 +32,7 @@ class ContentPageCreate(BaseModel): title: str = Field(..., max_length=200, description="Page title") content: str = Field(..., description="HTML or Markdown content") content_format: str = Field(default="html", description="Content format: html or markdown") + template: str = Field(default="default", max_length=50, description="Template name (default, minimal, modern)") meta_description: Optional[str] = Field(None, max_length=300, description="SEO meta description") meta_keywords: Optional[str] = Field(None, max_length=300, description="SEO keywords") is_published: bool = Field(default=False, description="Publish immediately") @@ -46,6 +47,7 @@ class ContentPageUpdate(BaseModel): title: Optional[str] = Field(None, max_length=200) content: Optional[str] = None content_format: Optional[str] = None + template: Optional[str] = Field(None, max_length=50) meta_description: Optional[str] = Field(None, max_length=300) meta_keywords: Optional[str] = Field(None, max_length=300) is_published: Optional[bool] = None @@ -120,6 +122,7 @@ def create_platform_page( content=page_data.content, vendor_id=None, # Platform default content_format=page_data.content_format, + template=page_data.template, meta_description=page_data.meta_description, meta_keywords=page_data.meta_keywords, is_published=page_data.is_published, @@ -202,6 +205,7 @@ def update_page( title=page_data.title, content=page_data.content, content_format=page_data.content_format, + template=page_data.template, meta_description=page_data.meta_description, meta_keywords=page_data.meta_keywords, is_published=page_data.is_published, diff --git a/app/routes/admin_pages.py b/app/routes/admin_pages.py index 0a0034b7..50544baf 100644 --- a/app/routes/admin_pages.py +++ b/app/routes/admin_pages.py @@ -21,6 +21,10 @@ Routes: - GET /users → User management page (auth required) - GET /imports → Import history page (auth required) - GET /settings → Settings page (auth required) +- GET /platform-homepage → Platform homepage manager (auth required) +- GET /content-pages → Content pages list (auth required) +- GET /content-pages/create → Create content page (auth required) +- GET /content-pages/{page_id}/edit → Edit content page (auth required) """ from fastapi import APIRouter, Request, Depends, Path @@ -306,6 +310,89 @@ async def admin_settings_page( ) +# ============================================================================ +# CONTENT MANAGEMENT SYSTEM (CMS) ROUTES +# ============================================================================ + +@router.get("/platform-homepage", response_class=HTMLResponse, include_in_schema=False) +async def admin_platform_homepage_manager( + request: Request, + current_user: User = Depends(get_current_admin_from_cookie_or_header), + db: Session = Depends(get_db) +): + """ + Render platform homepage manager. + Allows editing the main platform homepage with template selection. + """ + return templates.TemplateResponse( + "admin/platform-homepage.html", + { + "request": request, + "user": current_user, + } + ) + + +@router.get("/content-pages", response_class=HTMLResponse, include_in_schema=False) +async def admin_content_pages_list( + request: Request, + current_user: User = Depends(get_current_admin_from_cookie_or_header), + db: Session = Depends(get_db) +): + """ + Render content pages list. + Shows all platform defaults and vendor overrides with filtering. + """ + return templates.TemplateResponse( + "admin/content-pages.html", + { + "request": request, + "user": current_user, + } + ) + + +@router.get("/content-pages/create", response_class=HTMLResponse, include_in_schema=False) +async def admin_content_page_create( + request: Request, + current_user: User = Depends(get_current_admin_from_cookie_or_header), + db: Session = Depends(get_db) +): + """ + Render create content page form. + Allows creating new platform defaults or vendor-specific pages. + """ + return templates.TemplateResponse( + "admin/content-page-edit.html", + { + "request": request, + "user": current_user, + "page_id": None, # Indicates this is a create operation + } + ) + + +@router.get("/content-pages/{page_id}/edit", response_class=HTMLResponse, include_in_schema=False) +async def admin_content_page_edit( + request: Request, + page_id: int = Path(..., description="Content page ID"), + current_user: User = Depends(get_current_admin_from_cookie_or_header), + db: Session = Depends(get_db) +): + """ + Render edit content page form. + Allows editing existing platform or vendor content pages. + """ + return templates.TemplateResponse( + "admin/content-page-edit.html", + { + "request": request, + "user": current_user, + "page_id": page_id, + } + ) + + # ============================================================================ # DEVELOPER TOOLS - COMPONENTS & TESTING # ============================================================================ diff --git a/app/services/content_page_service.py b/app/services/content_page_service.py index 94aa7f1b..beb15fe4 100644 --- a/app/services/content_page_service.py +++ b/app/services/content_page_service.py @@ -176,6 +176,7 @@ class ContentPageService: content: str, vendor_id: Optional[int] = None, content_format: str = "html", + template: str = "default", meta_description: Optional[str] = None, meta_keywords: Optional[str] = None, is_published: bool = False, @@ -194,6 +195,7 @@ class ContentPageService: content: HTML or Markdown content vendor_id: Vendor ID (None for platform default) content_format: "html" or "markdown" + template: Template name for homepage/landing pages (default, minimal, modern, etc.) meta_description: SEO description meta_keywords: SEO keywords is_published: Publish immediately @@ -211,6 +213,7 @@ class ContentPageService: title=title, content=content, content_format=content_format, + template=template, meta_description=meta_description, meta_keywords=meta_keywords, is_published=is_published, @@ -236,6 +239,7 @@ class ContentPageService: title: Optional[str] = None, content: Optional[str] = None, content_format: Optional[str] = None, + template: Optional[str] = None, meta_description: Optional[str] = None, meta_keywords: Optional[str] = None, is_published: Optional[bool] = None, @@ -253,6 +257,7 @@ class ContentPageService: title: New title content: New content content_format: New format + template: New template name meta_description: New SEO description meta_keywords: New SEO keywords is_published: New publish status @@ -277,6 +282,8 @@ class ContentPageService: page.content = content if content_format is not None: page.content_format = content_format + if template is not None: + page.template = template if meta_description is not None: page.meta_description = meta_description if meta_keywords is not None: diff --git a/app/templates/admin/content-page-edit.html b/app/templates/admin/content-page-edit.html new file mode 100644 index 00000000..c8ee8e1b --- /dev/null +++ b/app/templates/admin/content-page-edit.html @@ -0,0 +1,301 @@ +{# app/templates/admin/content-page-edit.html #} +{% extends "admin/base.html" %} + +{% block title %}{% if page_id %}Edit{% else %}Create{% endif %} Content Page{% endblock %} + +{% block alpine_data %}contentPageEditor({{ page_id if page_id else 'null' }}){% endblock %} + +{% block content %} + +
+
+

+ +

+

+ Create a new platform default or vendor-specific page + Modify an existing content page +

+
+
+ + + Back to List + + +
+
+ + +
+ +

Loading page...

+
+ + +
+ +
+

Error

+

+
+
+ + +
+ +
+

+
+
+ + +
+
+ +
+

+ Basic Information +

+ +
+ +
+ + +
+ + +
+ + +

+ URL-safe identifier (lowercase, numbers, hyphens, underscores only) +

+
+ + +
+ + +

+ Platform defaults are shown to all vendors +

+
+
+
+ + +
+

+ Page Content +

+ + +
+ +
+ + +
+
+ + +
+ + +

+ Enter HTML content. Basic HTML tags are supported. + Enter Markdown content. Will be converted to HTML. +

+
+
+ + +
+

+ SEO & Metadata +

+ +
+ +
+ + +

+ /300 characters (150-160 recommended) +

+
+ + +
+ + +
+
+
+ + +
+

+ Navigation & Display +

+ +
+ +
+ + +

Lower = first

+
+ + +
+ +
+ + +
+ +
+
+
+ + +
+
+
+ +

+ Make this page visible to the public +

+
+ +
+ + Cancel + + +
+
+
+
+
+{% endblock %} + +{% block extra_scripts %} + +{% endblock %} diff --git a/app/templates/admin/content-pages.html b/app/templates/admin/content-pages.html new file mode 100644 index 00000000..9ab62559 --- /dev/null +++ b/app/templates/admin/content-pages.html @@ -0,0 +1,200 @@ +{# app/templates/admin/content-pages.html #} +{% extends "admin/base.html" %} + +{% block title %}Content Pages{% endblock %} + +{% block alpine_data %}contentPagesManager(){% endblock %} + +{% block content %} + +
+
+

+ Content Pages +

+

+ Manage platform defaults and vendor-specific content pages +

+
+ + + Create Page + +
+ + +
+ +

Loading pages...

+
+ + +
+ +
+

Error loading pages

+

+
+
+ + +
+
+ +
+ + + +
+ + +
+ + + + +
+
+
+ + +
+
+ + + + + + + + + + + + + + + +
PageSlugTypeStatusNavigationUpdatedActions
+
+
+ + +
+ +

No pages found

+

+ No pages match your search: "" +

+

+ No vendor-specific pages have been created yet. +

+ + + Create First Page + +
+{% endblock %} + +{% block extra_scripts %} + +{% endblock %} diff --git a/app/templates/admin/partials/sidebar.html b/app/templates/admin/partials/sidebar.html index 5fd1ab17..fc01dfed 100644 --- a/app/templates/admin/partials/sidebar.html +++ b/app/templates/admin/partials/sidebar.html @@ -54,6 +54,37 @@ + +
+
+
+

+ Content Management +

+ +

@@ -188,6 +219,37 @@ + +
+
+
+

+ Content Management +

+ +

diff --git a/app/templates/admin/platform-homepage.html b/app/templates/admin/platform-homepage.html new file mode 100644 index 00000000..84ed0c1a --- /dev/null +++ b/app/templates/admin/platform-homepage.html @@ -0,0 +1,248 @@ +{# app/templates/admin/platform-homepage.html #} +{% extends "admin/base.html" %} + +{% block title %}Platform Homepage Manager{% endblock %} + +{% block alpine_data %}platformHomepageManager(){% endblock %} + +{% block content %} + +
+
+

+ Platform Homepage +

+

+ Manage your platform's main landing page at localhost:8000 +

+
+
+ + + Preview + + +
+
+ + +
+ +

Loading homepage...

+
+ + +
+ +
+

Error loading homepage

+

+
+
+ + +
+ +
+

+
+
+ + +
+
+ +
+

+ Template Selection +

+

+ Choose the visual style for your homepage. Each template offers a different layout and design. +

+ +
+ + + + + + + + +
+
+ + +
+

+ Page Content +

+ + +
+ + +

+ Main heading displayed on the homepage +

+
+ + +
+ + +

+ HTML content shown below the title. Basic HTML tags are supported. +

+
+
+ + +
+

+ SEO Settings +

+ + +
+ + +

+ /300 characters +

+
+ + +
+ + +

+ Comma-separated keywords (optional) +

+
+
+ + +
+
+
+ +

+ Make this homepage visible to the public +

+
+ + +
+
+
+
+{% endblock %} + +{% block extra_scripts %} + +{% endblock %} diff --git a/app/templates/platform/base.html b/app/templates/platform/base.html new file mode 100644 index 00000000..ea4cb0eb --- /dev/null +++ b/app/templates/platform/base.html @@ -0,0 +1,299 @@ +{# app/templates/platform/base.html #} +{# Base template for platform public pages (homepage, about, faq, etc.) #} + + + + + + + {# Dynamic page title #} + {% block title %}Multi-Vendor Marketplace Platform{% endblock %} + + {# SEO Meta Tags #} + + + + {# Favicon #} + + + {# Platform color scheme #} + + + {# Fonts: Local fallback + Google Fonts #} + + + + {# Tailwind CSS with local fallback #} + + + {# Platform-specific styles #} + + + {% block extra_head %}{% endblock %} + + + + + {# Header / Navigation #} +
+ +
+ + {# Main Content #} +
+ {% block content %}{% endblock %} +
+ + {# Footer #} +
+
+
+ + {# Brand Column #} +
+
+
+ M +
+ + Marketplace + +
+

+ Connecting vendors with customers worldwide. Build your online store today. +

+
+ + {# Quick Links #} +
+

Quick Links

+
    + {% if footer_pages %} + {% for page in footer_pages %} +
  • + + {{ page.title }} + +
  • + {% endfor %} + {% endif %} +
+
+ + {# Platform Links #} +
+

Platform

+ +
+ + {# Contact Info #} +
+

Contact

+
    +
  • support@marketplace.com
  • +
  • +1 (555) 123-4567
  • +
  • 123 Business St, Suite 100
  • +
  • San Francisco, CA 94102
  • +
+
+
+ + {# Bottom Bar #} +
+
+

+ Ā© 2024 Marketplace Platform. All rights reserved. +

+ +
+
+
+
+ + {# Scripts #} + + + + + + + {% block extra_scripts %}{% endblock %} + + diff --git a/app/templates/platform/content-page.html b/app/templates/platform/content-page.html new file mode 100644 index 00000000..15f2a56d --- /dev/null +++ b/app/templates/platform/content-page.html @@ -0,0 +1,246 @@ +{# app/templates/platform/content-page.html #} +{# Generic template for platform content pages (About, FAQ, Terms, Contact, etc.) #} +{% extends "platform/base.html" %} + +{% block title %}{{ page.title }} - Marketplace{% endblock %} + +{% block meta_description %} + {% if page.meta_description %} + {{ page.meta_description }} + {% else %} + {{ page.title }} - Multi-Vendor Marketplace Platform + {% endif %} +{% endblock %} + +{% block meta_keywords %} + {% if page.meta_keywords %} + {{ page.meta_keywords }} + {% else %} + {{ page.title }}, marketplace, platform + {% endif %} +{% endblock %} + +{% block content %} +
+ + {# Breadcrumbs #} + + + {# Page Header #} +
+

+ {{ page.title }} +

+ + {# Published date (if available) #} + {% if page.published_at %} +
+ + + + Published {{ page.published_at.strftime('%B %d, %Y') }} +
+ {% endif %} +
+ + {# Page Content #} +
+
+ {% if page.content_format == 'markdown' %} + {# Future enhancement: Render with markdown library #} +
+ {{ page.content | safe }} +
+ {% else %} + {# HTML content (default) #} + {{ page.content | safe }} + {% endif %} +
+
+ + {# Last updated timestamp #} + {% if page.updated_at %} +
+

+ Last updated: {{ page.updated_at.strftime('%B %d, %Y') }} +

+
+ {% endif %} + + {# Call-to-action section (for specific pages) #} + {% if page.slug in ['about', 'contact'] %} +
+

+ {% if page.slug == 'about' %} + Ready to Get Started? + {% elif page.slug == 'contact' %} + Have Questions? + {% endif %} +

+

+ {% if page.slug == 'about' %} + Join thousands of vendors already selling on our platform + {% elif page.slug == 'contact' %} + Our team is here to help you succeed + {% endif %} +

+ + {% if page.slug == 'about' %} + Contact Sales + {% elif page.slug == 'contact' %} + Send Us a Message + {% endif %} + +
+ {% endif %} + +
+ +{# Additional styling for prose content #} + +{% endblock %} diff --git a/app/templates/platform/homepage-default.html b/app/templates/platform/homepage-default.html new file mode 100644 index 00000000..a3ad1675 --- /dev/null +++ b/app/templates/platform/homepage-default.html @@ -0,0 +1,228 @@ +{# app/templates/platform/homepage-default.html #} +{# Default platform homepage template #} +{% extends "platform/base.html" %} + +{% block title %} + {% if page %}{{ page.title }}{% else %}Home{% endif %} - Multi-Vendor Marketplace +{% endblock %} + +{% block meta_description %} + {% if page and page.meta_description %} + {{ page.meta_description }} + {% else %} + Leading multi-vendor marketplace platform. Connect with thousands of vendors and discover millions of products. + {% endif %} +{% endblock %} + +{% block content %} + + + +
+
+
+ {% if page %} + {# CMS-driven content #} +

+ {{ page.title }} +

+
+ {{ page.content | safe }} +
+ {% else %} + {# Default fallback content #} +

+ Welcome to Our Marketplace +

+

+ Connect vendors with customers worldwide. Build your online store and reach millions of shoppers. +

+ {% endif %} + + +
+
+
+ + + + +
+
+
+

+ Why Choose Our Platform? +

+

+ Everything you need to launch and grow your online business +

+
+ +
+ +
+
+ + + +
+

+ Lightning Fast +

+

+ Optimized for speed and performance. Your store loads in milliseconds. +

+
+ + +
+
+ + + +
+

+ Secure & Reliable +

+

+ Enterprise-grade security with 99.9% uptime guarantee. +

+
+ + +
+
+ + + +
+

+ Fully Customizable +

+

+ Brand your store with custom themes, colors, and layouts. +

+
+
+
+
+ + + + +
+
+
+

+ Featured Vendors +

+

+ Discover amazing shops from around the world +

+
+ +
+ +
+
+
+

+ Sample Vendor 1 +

+

+ Premium products and exceptional service +

+ + Visit Store + + + + +
+
+ + +
+
+
+

+ Sample Vendor 2 +

+

+ Quality craftsmanship meets modern design +

+ + Visit Store + + + + +
+
+ + +
+
+
+

+ Sample Vendor 3 +

+

+ Eco-friendly products for sustainable living +

+ + Visit Store + + + + +
+
+
+ + +
+
+ + + + +
+
+

+ Ready to Get Started? +

+

+ Join thousands of vendors already selling on our platform +

+ +
+
+{% endblock %} diff --git a/app/templates/platform/homepage-minimal.html b/app/templates/platform/homepage-minimal.html new file mode 100644 index 00000000..a675319e --- /dev/null +++ b/app/templates/platform/homepage-minimal.html @@ -0,0 +1,100 @@ +{# app/templates/platform/homepage-minimal.html #} +{# Minimal/clean platform homepage template #} +{% extends "platform/base.html" %} + +{% block title %} + {% if page %}{{ page.title }}{% else %}Home{% endif %} - Marketplace +{% endblock %} + +{% block content %} + + + +
+
+ {% if page %} +

+ {{ page.title }} +

+
+ {{ page.content | safe }} +
+ {% else %} +

+ Multi-Vendor
Marketplace +

+

+ The simplest way to launch your online store and connect with customers worldwide. +

+ {% endif %} + + + Get Started + +
+
+ + + + +
+
+
+
+
⚔
+

+ Fast +

+

+ Lightning-fast performance optimized for conversions +

+
+ +
+
šŸ”’
+

+ Secure +

+

+ Enterprise-grade security for your peace of mind +

+
+ +
+
šŸŽØ
+

+ Custom +

+

+ Fully customizable to match your brand identity +

+
+
+
+
+ + + + +
+
+

+ Ready to launch? +

+

+ Join our marketplace today +

+ +
+
+{% endblock %} diff --git a/app/templates/platform/homepage-modern.html b/app/templates/platform/homepage-modern.html new file mode 100644 index 00000000..564abe86 --- /dev/null +++ b/app/templates/platform/homepage-modern.html @@ -0,0 +1,258 @@ +{# app/templates/platform/homepage-modern.html #} +{# Modern/trendy platform homepage template with animations #} +{% extends "platform/base.html" %} + +{% block title %} + {% if page %}{{ page.title }}{% else %}Home{% endif %} - Marketplace +{% endblock %} + +{% block extra_head %} + +{% endblock %} + +{% block content %} + + + +
+ {# Decorative elements #} +
+
+
+
+ +
+
+ {# Left column - Content #} +
+ {% if page %} +

+ {{ page.title }} +

+
+ {{ page.content | safe }} +
+ {% else %} +
+ ✨ The Future of E-Commerce +
+

+ Build Your
+ + Dream Store + +

+

+ Launch a stunning online marketplace in minutes. No coding required. Scale effortlessly. +

+ {% endif %} + + + + {# Stats #} +
+
+
10K+
+
Active Vendors
+
+
+
50M+
+
Products Sold
+
+
+
99.9%
+
Uptime
+
+
+
+ + {# Right column - Visual element #} + +
+
+
+ + + + +
+
+
+
+ ✨ Features +
+

+ Everything You Need +

+

+ Powerful features to help you succeed in the digital marketplace +

+
+ +
+ {# Feature cards with hover effects #} +
+
+ + + +
+

+ Blazing Fast +

+

+ Optimized for performance with sub-second page loads and instant search results. +

+
+ +
+
+ + + +
+

+ Bank-Level Security +

+

+ Enterprise-grade encryption and security measures to protect your business. +

+
+ +
+
+ + + +
+

+ Fully Customizable +

+

+ Brand your store with custom themes, colors, fonts, and layouts. +

+
+ +
+
+ + + +
+

+ Analytics & Insights +

+

+ Powerful analytics to track sales, customer behavior, and growth metrics. +

+
+ +
+
+ + + +
+

+ Mobile-First Design +

+

+ Beautiful, responsive design that works perfectly on all devices. +

+
+ +
+
+ + + +
+

+ 24/7 Support +

+

+ Round-the-clock customer support to help you succeed at every step. +

+
+
+
+
+ + + + +
+
+ +
+

+ Start Your Journey Today +

+

+ Join thousands of successful vendors on our platform +

+ + + +

+ No credit card required Ā· Free 14-day trial Ā· Cancel anytime +

+
+
+{% endblock %} diff --git a/docs/features/platform-homepage.md b/docs/features/platform-homepage.md new file mode 100644 index 00000000..2dbb4c19 --- /dev/null +++ b/docs/features/platform-homepage.md @@ -0,0 +1,710 @@ +# Platform Homepage & Content Pages + +## Overview + +The Platform Homepage feature provides a customizable, CMS-driven public homepage and content pages for your multi-vendor marketplace platform at the root domain (e.g., `localhost:8000` or `platform.com`). + +**Key Features:** +- āœ… CMS-driven customizable homepage with multiple templates +- āœ… Multiple content pages (About, FAQ, Contact, Terms, Privacy) +- āœ… Dynamic header and footer navigation +- āœ… Responsive design with dark mode support +- āœ… SEO-optimized with meta tags +- āœ… Template selection system (default, minimal, modern) + +--- + +## Architecture + +### URL Structure + +| URL | Purpose | CMS Slug | Template | +|-----|---------|----------|----------| +| `/` | Platform Homepage | `platform_homepage` | Customizable (default/minimal/modern) | +| `/about` | About Us | `about` | `platform/content-page.html` | +| `/faq` | FAQ | `faq` | `platform/content-page.html` | +| `/contact` | Contact Us | `contact` | `platform/content-page.html` | +| `/terms` | Terms of Service | `terms` | `platform/content-page.html` | +| `/privacy` | Privacy Policy | `privacy` | `platform/content-page.html` | + +### Database Model + +All platform pages are stored in the `content_pages` table with `vendor_id = NULL`: + +```sql +-- Platform homepage +INSERT INTO content_pages (vendor_id, slug, title, template, ...) +VALUES (NULL, 'platform_homepage', 'Welcome', 'modern', ...); + +-- Content pages +INSERT INTO content_pages (vendor_id, slug, title, ...) +VALUES (NULL, 'about', 'About Us', ...); +``` + +### Navigation System + +Pages are configured to appear in header/footer navigation using flags: + +| Field | Purpose | Example | +|-------|---------|---------| +| `show_in_header` | Display in top navigation | About, FAQ, Contact | +| `show_in_footer` | Display in footer links | All pages | +| `display_order` | Sort order in menus | 1, 2, 3, ... | + +--- + +## File Structure + +``` +app/ +ā”œā”€ā”€ templates/platform/ +│ ā”œā”€ā”€ base.html # Base layout with nav/footer +│ ā”œā”€ā”€ homepage-default.html # Default homepage template +│ ā”œā”€ā”€ homepage-minimal.html # Minimal/clean template +│ ā”œā”€ā”€ homepage-modern.html # Modern template with animations +│ └── content-page.html # Generic content page template +ā”œā”€ā”€ services/ +│ └── content_page_service.py # CMS business logic +└── main.py # Platform routes (lines 284-404) + +scripts/ +└── create_platform_pages.py # Seeder script + +docs/features/ +└── platform-homepage.md # This file +``` + +--- + +## Templates + +### 1. Homepage Templates + +Three homepage templates are available: + +#### **Default Template** (`platform/homepage-default.html`) +- **Style:** Professional, feature-rich +- **Sections:** Hero, Features, Featured Vendors, CTA +- **Best for:** Comprehensive platform showcase + +#### **Minimal Template** (`platform/homepage-minimal.html`) +- **Style:** Clean, minimalist +- **Sections:** Simple hero, minimal features, simple CTA +- **Best for:** Focus on simplicity + +#### **Modern Template** (`platform/homepage-modern.html`) +- **Style:** Trendy, animated, gradient-heavy +- **Sections:** Animated hero, feature cards with hover effects, stats +- **Best for:** Modern, tech-forward branding + +### 2. Content Page Template + +**Template:** `platform/content-page.html` + +Used for all content pages (About, FAQ, Contact, etc.) + +**Features:** +- Breadcrumb navigation +- Responsive design +- Enhanced prose styling for content +- Context-aware CTAs (for about/contact pages) +- Last updated timestamp +- Dark mode support + +--- + +## Usage + +### Admin CMS Interface (Recommended) + +#### Platform Homepage Manager (`/admin/platform-homepage`) + +The easiest way to manage your platform homepage is through the admin interface: + +1. **Login to Admin Panel:** + ``` + http://localhost:8000/admin/login + ``` + +2. **Navigate to Platform Homepage:** + - Click "Content Management" in the sidebar + - Click "Platform Homepage" + +3. **Customize Homepage:** + - **Template Selection:** Choose between Default, Minimal, or Modern templates with visual previews + - **Page Title:** Edit the main heading + - **Content:** Add HTML content for the hero section + - **SEO Settings:** Set meta description and keywords + - **Publishing:** Toggle published status + - **Preview:** Click "Preview" button to see live homepage + - **Save:** Click "Save Changes" to update + +**Features:** +- āœ… Visual template selector with previews +- āœ… Real-time save with success/error feedback +- āœ… Character counter for SEO fields +- āœ… One-click preview +- āœ… Dark mode support + +#### Content Pages Manager (`/admin/content-pages`) + +Manage all platform content pages from a single interface: + +1. **Navigate to Content Pages:** + - Click "Content Management" in the sidebar + - Click "Content Pages" + +2. **View All Pages:** + - **Tabs:** Switch between All Pages, Platform Defaults, or Vendor Overrides + - **Search:** Type to filter by title, slug, or vendor name + - **Table View:** See status, navigation settings, and last updated + +3. **Edit Existing Page:** + - Click the edit icon (pencil) next to any page + - Modify content, SEO, navigation settings + - Click "Update Page" to save + +4. **Create New Page:** + - Click "Create Page" button + - Fill in: + - Page title and URL slug + - Content format (HTML or Markdown) + - Content (large textarea) + - SEO metadata + - Navigation settings (header/footer visibility) + - Display order + - Click "Create Page" + +5. **Delete Page:** + - Click the delete icon (trash) next to any page + - Confirm deletion + +**Features:** +- āœ… Tabbed interface for easy filtering +- āœ… Real-time search +- āœ… Status badges (Published/Draft, Platform/Vendor) +- āœ… Navigation badges (Header/Footer) +- āœ… Quick edit and delete actions +- āœ… Empty state with helpful CTAs + +### Creating Platform Pages + +#### Method 1: Using the Seeder Script + +```bash +# Create all default platform pages +python scripts/create_platform_pages.py +``` + +This creates: +- Platform Homepage (with modern template) +- About Us +- FAQ +- Contact Us +- Terms of Service +- Privacy Policy + +#### Method 2: Via API + +**Create Platform Homepage:** +```bash +POST /api/v1/admin/content-pages/platform +{ + "slug": "platform_homepage", + "title": "Welcome to Our Marketplace", + "content": "

Your custom content...

", + "template": "modern", + "vendor_id": null, + "is_published": true, + "show_in_header": false, + "show_in_footer": false +} +``` + +**Create Content Page:** +```bash +POST /api/v1/admin/content-pages/platform +{ + "slug": "about", + "title": "About Us", + "content": "

Our Story

...

", + "vendor_id": null, + "is_published": true, + "show_in_header": true, + "show_in_footer": true, + "display_order": 1 +} +``` + +#### Method 3: Programmatically + +```python +from app.core.database import SessionLocal +from app.services.content_page_service import content_page_service + +db = SessionLocal() + +# Create homepage +homepage = content_page_service.create_page( + db, + slug="platform_homepage", + title="Welcome", + content="

Content...

", + template="modern", # default, minimal, or modern + vendor_id=None, + is_published=True, + show_in_header=False, + show_in_footer=False +) + +# Create content page +about = content_page_service.create_page( + db, + slug="about", + title="About Us", + content="

Our Story

", + vendor_id=None, + is_published=True, + show_in_header=True, # Show in top nav + show_in_footer=True, # Show in footer + display_order=1 +) + +db.close() +``` + +--- + +## Customization + +### Changing Homepage Template + +Update the `template` field in the database: + +```sql +UPDATE content_pages +SET template = 'minimal' -- or 'default', 'modern' +WHERE slug = 'platform_homepage' AND vendor_id IS NULL; +``` + +Or via API: +```bash +PUT /api/v1/admin/content-pages/{id} +{ + "template": "minimal" +} +``` + +### Customizing Navigation + +**Add page to header menu:** +```python +content_page_service.update_page( + db, + page_id=page.id, + show_in_header=True, + display_order=2 # Position in menu +) +``` + +**Remove page from footer:** +```python +content_page_service.update_page( + db, + page_id=page.id, + show_in_footer=False +) +``` + +### Updating Page Content + +```python +content_page_service.update_page( + db, + page_id=page.id, + title="New Title", + content="

Updated Content

", + meta_description="New SEO description", + template="modern" # Change template +) +``` + +--- + +## How It Works + +### 1. Request Flow + +``` +User visits: http://localhost:8000/ + ↓ +VendorContextMiddleware (no vendor detected, platform mode) + ↓ +ContextMiddleware (context = unknown) + ↓ +Route: platform_homepage() in main.py:284 + ↓ +Load page from CMS (slug='platform_homepage', vendor_id=NULL) + ↓ +Load header/footer navigation pages + ↓ +Render template: platform/homepage-{template}.html + ↓ +Response with navigation menu +``` + +### 2. CMS Lookup Logic + +**For Homepage (`/`):** +1. Query: `SELECT * FROM content_pages WHERE slug='platform_homepage' AND vendor_id IS NULL` +2. If found → Render with selected template (default/minimal/modern) +3. If not found → Render fallback static template + +**For Content Pages (`/about`, `/faq`, etc.):** +1. Query: `SELECT * FROM content_pages WHERE slug='{slug}' AND vendor_id IS NULL` +2. If found → Render `platform/content-page.html` +3. If not found → Return 404 + +**Navigation Loading:** +```python +# Header pages (show_in_header=True) +header_pages = content_page_service.list_pages_for_vendor( + db, vendor_id=None, header_only=True +) + +# Footer pages (show_in_footer=True) +footer_pages = content_page_service.list_pages_for_vendor( + db, vendor_id=None, footer_only=True +) +``` + +### 3. Template Rendering + +**Homepage:** +```python +# In main.py:284 +if homepage: + template_name = homepage.template or "default" # Get from CMS + template_path = f"platform/homepage-{template_name}.html" + return templates.TemplateResponse(template_path, context) +``` + +**Content Page:** +```python +# In main.py:349 +return templates.TemplateResponse( + "platform/content-page.html", + { + "request": request, + "page": page, + "header_pages": header_pages, + "footer_pages": footer_pages + } +) +``` + +--- + +## Navigation Menu Example + +Given these pages in the database: + +| Slug | Title | show_in_header | show_in_footer | display_order | +|------|-------|----------------|----------------|---------------| +| `about` | About Us | āœ… | āœ… | 1 | +| `faq` | FAQ | āœ… | āœ… | 2 | +| `contact` | Contact Us | āœ… | āœ… | 3 | +| `terms` | Terms of Service | āŒ | āœ… | 10 | +| `privacy` | Privacy Policy | āŒ | āœ… | 11 | + +**Header Navigation:** +``` +Marketplace | About Us | FAQ | Contact Us | šŸŒ™ +``` + +**Footer Navigation:** +``` +Quick Links + - About Us + - FAQ + - Contact Us + - Terms of Service + - Privacy Policy +``` + +--- + +## SEO Optimization + +All pages support SEO meta tags: + +```python +content_page_service.create_page( + db, + slug="about", + title="About Our Platform", + meta_description="Learn about our mission to democratize e-commerce...", + meta_keywords="about us, mission, vision, values, company", + # ... +) +``` + +**Rendered in template:** +```html +About Our Platform - Marketplace + + +``` + +--- + +## Testing + +### Manual Testing + +1. **Visit homepage:** + ``` + http://localhost:8000/ + ``` + Should show platform homepage with selected template. + +2. **Visit content pages:** + ``` + http://localhost:8000/about + http://localhost:8000/faq + http://localhost:8000/contact + http://localhost:8000/terms + http://localhost:8000/privacy + ``` + +3. **Check navigation:** + - Header should show: About Us, FAQ, Contact Us + - Footer should show all pages + +4. **Test dark mode:** + - Click moon icon in header + - Verify dark mode works on all pages + +5. **Test responsive design:** + - Resize browser window + - Verify mobile menu works + - Check layouts on different screen sizes + +### API Testing + +**Get page content:** +```bash +GET /api/v1/shop/content-pages/about +``` + +**Get navigation:** +```bash +GET /api/v1/shop/content-pages/navigation +``` + +--- + +## Advanced Features + +### Multiple Homepage Templates + +Create custom homepage templates: + +1. Create template file: + ``` + app/templates/platform/homepage-custom.html + ``` + +2. Update CMS page: + ```python + content_page_service.update_page( + db, + page_id=homepage.id, + template="custom" + ) + ``` + +3. Visit homepage → Renders `platform/homepage-custom.html` + +### Dynamic Content Loading + +Homepage templates can load dynamic data: + +```jinja2 +{# In template #} +{% if featured_vendors %} + {% for vendor in featured_vendors %} +
{{ vendor.name }}
+ {% endfor %} +{% endif %} +``` + +Pass data in route handler: + +```python +# In main.py +featured_vendors = db.query(Vendor).filter(Vendor.is_featured==True).all() + +return templates.TemplateResponse( + template_path, + { + "request": request, + "page": homepage, + "header_pages": header_pages, + "footer_pages": footer_pages, + "featured_vendors": featured_vendors, # Additional data + } +) +``` + +--- + +## Troubleshooting + +### Homepage shows 404 + +**Problem:** Platform homepage not rendering + +**Solutions:** +1. Run seeder script: + ```bash + python scripts/create_platform_pages.py + ``` + +2. Verify page exists: + ```sql + SELECT * FROM content_pages + WHERE slug='platform_homepage' AND vendor_id IS NULL; + ``` + +3. Check page is published: + ```sql + UPDATE content_pages + SET is_published=true + WHERE slug='platform_homepage'; + ``` + +### Navigation menu is empty + +**Problem:** No pages showing in header/footer + +**Solutions:** +1. Check navigation flags: + ```sql + SELECT slug, title, show_in_header, show_in_footer + FROM content_pages + WHERE vendor_id IS NULL; + ``` + +2. Update flags: + ```sql + UPDATE content_pages + SET show_in_header=true, show_in_footer=true + WHERE slug='about' AND vendor_id IS NULL; + ``` + +### Content page returns 404 + +**Problem:** `/about` or other pages not found + +**Solutions:** +1. Verify slug: + ```sql + SELECT slug FROM content_pages WHERE vendor_id IS NULL; + ``` + +2. Check published status: + ```sql + UPDATE content_pages + SET is_published=true + WHERE slug='about'; + ``` + +### Wrong template loads + +**Problem:** Homepage uses wrong template + +**Solution:** +```sql +UPDATE content_pages +SET template='modern' +WHERE slug='platform_homepage' AND vendor_id IS NULL; +``` + +--- + +## Best Practices + +1. **Always set SEO meta tags:** + ```python + meta_description="Clear 150-160 char description", + meta_keywords="relevant, keywords, comma, separated" + ``` + +2. **Use semantic HTML in content:** + ```html +

Main Heading

+

Paragraph text...

+
  • List item
+ ``` + +3. **Set appropriate display_order:** + ```python + display_order=1 # First in menu + display_order=2 # Second in menu + display_order=10 # Legal pages (lower priority) + ``` + +4. **Use navigation flags wisely:** + - `show_in_header`: Only 3-5 main pages + - `show_in_footer`: Can include more pages + +5. **Keep homepage content concise:** + - Use templates for structure + - Add key messaging only + - Link to detailed content pages + +--- + +## API Reference + +### Admin Endpoints + +``` +POST /api/v1/admin/content-pages/platform # Create platform page +GET /api/v1/admin/content-pages/platform # List platform pages +GET /api/v1/admin/content-pages/{id} # Get specific page +PUT /api/v1/admin/content-pages/{id} # Update page +DELETE /api/v1/admin/content-pages/{id} # Delete page +``` + +### Shop (Public) Endpoints + +``` +GET /api/v1/shop/content-pages/navigation # Get nav links +GET /api/v1/shop/content-pages/{slug} # Get page content +``` + +--- + +## Related Documentation + +- [Content Management System](./content-management-system.md) - Full CMS documentation +- [CMS Implementation Guide](./cms-implementation-guide.md) - Technical implementation +- [Admin Frontend Guide](../frontend/admin/page-templates.md) - Admin UI patterns + +--- + +## Summary + +The Platform Homepage system provides: + +āœ… **Customizable homepage** with 3 template options +āœ… **Multiple content pages** (About, FAQ, Contact, Terms, Privacy) +āœ… **CMS-driven** with full CRUD support +āœ… **Dynamic navigation** loaded from database +āœ… **SEO-optimized** with meta tags +āœ… **Responsive** with dark mode support +āœ… **Easy to extend** with custom templates + +All pages are managed through the existing CMS system, allowing admins to customize content without touching code. diff --git a/docs/getting-started/platform-homepage-quick-start.md b/docs/getting-started/platform-homepage-quick-start.md new file mode 100644 index 00000000..e3ed6c6a --- /dev/null +++ b/docs/getting-started/platform-homepage-quick-start.md @@ -0,0 +1,316 @@ +# Platform Homepage - Quick Start Guide + +Quick reference for setting up and customizing the platform homepage and content pages. + +--- + +## šŸš€ Quick Setup + +### Step 1: Create Platform Pages + +Run the seeder script to create all default platform pages: + +```bash +python scripts/create_platform_pages.py +``` + +This creates: +- āœ… Platform Homepage (modern template) +- āœ… About Us +- āœ… FAQ +- āœ… Contact Us +- āœ… Terms of Service +- āœ… Privacy Policy + +### Step 2: Verify Pages + +Visit your platform homepage: +``` +http://localhost:8000/ +``` + +Visit content pages: +``` +http://localhost:8000/about +http://localhost:8000/faq +http://localhost:8000/contact +http://localhost:8000/terms +http://localhost:8000/privacy +``` + +### Step 3: Customize (Optional) + +**Change homepage template:** +```sql +UPDATE content_pages +SET template = 'minimal' -- or 'default', 'modern' +WHERE slug = 'platform_homepage' AND vendor_id IS NULL; +``` + +**Update homepage content:** +```sql +UPDATE content_pages +SET content = '

Your custom homepage content...

' +WHERE slug = 'platform_homepage'; +``` + +--- + +## šŸ“„ Available Templates + +### Homepage Templates + +| Template | Style | Best For | +|----------|-------|----------| +| `default` | Professional, feature-rich | Comprehensive showcase | +| `minimal` | Clean, simple | Minimalist branding | +| `modern` | Animated, gradient-heavy | Tech-forward platforms | + +### Content Page Template + +All content pages use `platform/content-page.html`: +- Breadcrumb navigation +- Responsive design +- Enhanced prose styling +- Dark mode support + +--- + +## šŸŽÆ Common Tasks + +### Add New Content Page + +```python +from app.core.database import SessionLocal +from app.services.content_page_service import content_page_service + +db = SessionLocal() + +page = content_page_service.create_page( + db, + slug="careers", + title="Careers", + content="

Join Our Team

...

", + vendor_id=None, # Platform page + is_published=True, + show_in_header=True, + show_in_footer=True, + display_order=4 +) + +db.close() +``` + +### Update Page Content + +```python +content_page_service.update_page( + db, + page_id=page.id, + title="New Title", + content="

Updated Content

", + meta_description="New description" +) +``` + +### Change Navigation Visibility + +```python +# Show in header menu +content_page_service.update_page( + db, + page_id=page.id, + show_in_header=True, + display_order=2 +) + +# Remove from footer +content_page_service.update_page( + db, + page_id=page.id, + show_in_footer=False +) +``` + +--- + +## šŸ” Verification + +### Check Database + +```sql +-- List all platform pages +SELECT id, slug, title, template, is_published, show_in_header, show_in_footer +FROM content_pages +WHERE vendor_id IS NULL +ORDER BY display_order; +``` + +### Test Navigation + +1. Visit homepage: `http://localhost:8000/` +2. Check header menu (should show: About, FAQ, Contact) +3. Scroll to footer (should show all pages) +4. Click links to verify they work + +### Test Dark Mode + +1. Click moon icon in header +2. Verify all pages render correctly in dark mode +3. Toggle back to light mode + +--- + +## šŸ“ Page Content Examples + +### Homepage Content + +```html +

+ Welcome to our multi-vendor marketplace platform. + Connect with thousands of vendors and discover amazing products. +

+

+ Join our growing community of successful online businesses today. +

+``` + +### About Us Content + +```html +

Our Mission

+

We're democratizing e-commerce...

+ +

Our Values

+
    +
  • Innovation: Constantly improving
  • +
  • Transparency: No hidden fees
  • +
+``` + +### FAQ Content + +```html +

Getting Started

+ +

How do I create an account?

+

Contact our sales team...

+ +

What are your pricing plans?

+

We offer flexible pricing...

+``` + +--- + +## šŸŽØ Customization Tips + +### Custom Homepage Template + +1. Create new template: + ``` + app/templates/platform/homepage-custom.html + ``` + +2. Extend base template: + ```jinja2 + {% extends "platform/base.html" %} + + {% block content %} + + {% endblock %} + ``` + +3. Update database: + ```sql + UPDATE content_pages + SET template = 'custom' + WHERE slug = 'platform_homepage'; + ``` + +### Customize Navigation Order + +```sql +UPDATE content_pages +SET display_order = 1 +WHERE slug = 'about'; + +UPDATE content_pages +SET display_order = 2 +WHERE slug = 'faq'; + +UPDATE content_pages +SET display_order = 3 +WHERE slug = 'contact'; +``` + +Result in header: `About | FAQ | Contact` + +--- + +## šŸ› Troubleshooting + +### Homepage shows 404 + +**Fix:** Run seeder script +```bash +python scripts/create_platform_pages.py +``` + +### Navigation menu is empty + +**Fix:** Update navigation flags +```sql +UPDATE content_pages +SET show_in_header = true, show_in_footer = true +WHERE slug IN ('about', 'faq', 'contact') +AND vendor_id IS NULL; +``` + +### Content not updating + +**Fix:** Clear any caching and restart server +```bash +# If using uvicorn with reload +# Changes should auto-reload + +# If manual restart needed +pkill -f uvicorn +uvicorn main:app --reload +``` + +--- + +## šŸ“š Full Documentation + +For complete details, see: +- [Platform Homepage Documentation](../features/platform-homepage.md) +- [CMS Feature Documentation](../features/content-management-system.md) +- [CMS Implementation Guide](../features/cms-implementation-guide.md) + +--- + +## āœ… Checklist + +After setup, verify: + +- [ ] Homepage loads at `http://localhost:8000/` +- [ ] All content pages are accessible +- [ ] Header navigation shows correct pages +- [ ] Footer navigation shows all pages +- [ ] Dark mode works +- [ ] Mobile responsive design works +- [ ] SEO meta tags are present +- [ ] Links in navigation work correctly + +--- + +## šŸŽ‰ You're Done! + +Your platform homepage and content pages are now set up and ready to customize! + +**Next Steps:** +1. Customize homepage content via admin panel at `/admin/platform-homepage` +2. Manage all content pages at `/admin/content-pages` +3. Add your own branding and colors +4. Create additional content pages as needed +5. Set up analytics tracking diff --git a/main.py b/main.py index 7262407c..4f306a30 100644 --- a/main.py +++ b/main.py @@ -272,6 +272,138 @@ async def vendor_root_path(vendor_code: str, request: Request, db: Session = Dep # No landing page - redirect to shop return RedirectResponse(url=f"/vendors/{vendor_code}/shop/", status_code=302) + +# ============================================================================ +# PLATFORM PUBLIC PAGES (Platform Homepage, About, FAQ, etc.) +# ============================================================================ +logger.info("Registering platform public page routes:") +logger.info(" - / (platform homepage)") +logger.info(" - /{slug} (platform content pages: /about, /faq, /terms, /contact)") + + +@app.get("/", response_class=HTMLResponse, include_in_schema=False) +async def platform_homepage(request: Request, db: Session = Depends(get_db)): + """ + Platform homepage at localhost:8000 or platform.com + + Looks for CMS page with slug='platform_homepage' (vendor_id=NULL) + Falls back to default static template if not found. + """ + from app.services.content_page_service import content_page_service + + logger.debug("[PLATFORM] Homepage requested") + + # Try to load platform homepage from CMS + homepage = content_page_service.get_page_for_vendor( + db, + slug="platform_homepage", + vendor_id=None, # Platform-level page + include_unpublished=False + ) + + # Load header and footer navigation + header_pages = content_page_service.list_pages_for_vendor( + db, + vendor_id=None, + header_only=True, + include_unpublished=False + ) + + footer_pages = content_page_service.list_pages_for_vendor( + db, + vendor_id=None, + footer_only=True, + include_unpublished=False + ) + + if homepage: + # Use template selection from CMS + template_name = homepage.template or "default" + template_path = f"platform/homepage-{template_name}.html" + + logger.info(f"[PLATFORM] Rendering CMS homepage with template: {template_path}") + + return templates.TemplateResponse( + template_path, + { + "request": request, + "page": homepage, + "header_pages": header_pages, + "footer_pages": footer_pages, + } + ) + else: + # Fallback to default static template + logger.info("[PLATFORM] No CMS homepage found, using default template") + + return templates.TemplateResponse( + "platform/homepage-default.html", + { + "request": request, + "header_pages": header_pages, + "footer_pages": footer_pages, + } + ) + + +@app.get("/{slug}", response_class=HTMLResponse, include_in_schema=False) +async def platform_content_page( + request: Request, + slug: str, + db: Session = Depends(get_db) +): + """ + Platform content pages: /about, /faq, /terms, /contact, etc. + + Loads content from CMS with slug (vendor_id=NULL for platform pages). + Returns 404 if page not found. + + This route MUST be defined LAST to avoid conflicts with other routes. + """ + from app.services.content_page_service import content_page_service + + logger.debug(f"[PLATFORM] Content page requested: /{slug}") + + # Load page from CMS + page = content_page_service.get_page_for_vendor( + db, + slug=slug, + vendor_id=None, # Platform pages only + include_unpublished=False + ) + + if not page: + logger.warning(f"[PLATFORM] Content page not found: {slug}") + raise HTTPException(status_code=404, detail=f"Page not found: {slug}") + + # Load header and footer navigation + header_pages = content_page_service.list_pages_for_vendor( + db, + vendor_id=None, + header_only=True, + include_unpublished=False + ) + + footer_pages = content_page_service.list_pages_for_vendor( + db, + vendor_id=None, + footer_only=True, + include_unpublished=False + ) + + logger.info(f"[PLATFORM] Rendering content page: {page.title} (/{slug})") + + return templates.TemplateResponse( + "platform/content-page.html", + { + "request": request, + "page": page, + "header_pages": header_pages, + "footer_pages": footer_pages, + } + ) + + logger.info("=" * 80) # Log all registered routes diff --git a/mkdocs.yml b/mkdocs.yml index 54e51eb3..b0e3ace2 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -21,6 +21,7 @@ nav: - Complete Setup Guide: getting-started/DATABASE_SETUP_GUIDE.md - Quick Reference: getting-started/DATABASE_QUICK_REFERENCE.md - CMS Quick Start: getting-started/cms-quick-start.md + - Platform Homepage Quick Start: getting-started/platform-homepage-quick-start.md - Configuration: getting-started/configuration.md # ============================================ @@ -149,6 +150,7 @@ nav: - Content Management System: - Overview: features/content-management-system.md - Implementation Guide: features/cms-implementation-guide.md + - Platform Homepage: features/platform-homepage.md - Vendor Landing Pages: features/vendor-landing-pages.md # ============================================ diff --git a/scripts/create_platform_pages.py b/scripts/create_platform_pages.py new file mode 100755 index 00000000..e757beb4 --- /dev/null +++ b/scripts/create_platform_pages.py @@ -0,0 +1,491 @@ +#!/usr/bin/env python3 +""" +Create Platform Content Pages + +This script creates default platform-level content pages: +- Platform Homepage (slug='platform_homepage') +- About Us (slug='about') +- FAQ (slug='faq') +- Terms of Service (slug='terms') +- Privacy Policy (slug='privacy') +- Contact Us (slug='contact') + +All pages are created with vendor_id=NULL (platform-level defaults). + +Usage: + python scripts/create_platform_pages.py +""" + +import sys +from pathlib import Path + +# Add project root to path +project_root = Path(__file__).resolve().parent.parent +sys.path.insert(0, str(project_root)) + +from app.core.database import SessionLocal +from app.services.content_page_service import content_page_service + + +def create_platform_pages(): + """Create default platform content pages.""" + db = SessionLocal() + + try: + print("=" * 80) + print("CREATING PLATFORM CONTENT PAGES") + print("=" * 80) + print() + + # Import ContentPage for checking existing pages + from models.database.content_page import ContentPage + + # ======================================================================== + # 1. PLATFORM HOMEPAGE + # ======================================================================== + print("1. Creating Platform Homepage...") + + # Check if already exists + existing = db.query(ContentPage).filter_by(vendor_id=None, slug="platform_homepage").first() + if existing: + print(f" āš ļø Skipped: Platform Homepage - already exists (ID: {existing.id})") + else: + try: + homepage = content_page_service.create_page( + db, + slug="platform_homepage", + title="Welcome to Our Multi-Vendor Marketplace", + content=""" +

+ Connect vendors with customers worldwide. Build your online store and reach millions of shoppers. +

+

+ Our platform empowers entrepreneurs to launch their own branded e-commerce stores + with minimal effort and maximum impact. +

+ """, + template="modern", # Uses platform/homepage-modern.html + vendor_id=None, # Platform-level page + is_published=True, + show_in_header=False, # Homepage is not in menu (it's the root) + show_in_footer=False, + display_order=0, + meta_description="Leading multi-vendor marketplace platform. Connect with thousands of vendors and discover millions of products.", + meta_keywords="marketplace, multi-vendor, e-commerce, online shopping, platform" + ) + print(f" āœ… Created: {homepage.title} (/{homepage.slug})") + except Exception as e: + print(f" āš ļø Error: Platform Homepage - {str(e)}") + + # ======================================================================== + # 2. ABOUT US + # ======================================================================== + print("2. Creating About Us page...") + + existing = db.query(ContentPage).filter_by(vendor_id=None, slug="about").first() + if existing: + print(f" āš ļø Skipped: About Us - already exists (ID: {existing.id})") + else: + try: + about = content_page_service.create_page( + db, + slug="about", + title="About Us", + content=""" +

Our Mission

+

+ We're on a mission to democratize e-commerce by providing powerful, + easy-to-use tools for entrepreneurs worldwide. +

+ +

Our Story

+

+ Founded in 2024, our platform has grown to serve over 10,000 active vendors + and millions of customers around the globe. We believe that everyone should + have the opportunity to build and grow their own online business. +

+ +

Why Choose Us?

+
    +
  • Easy to Start: Launch your store in minutes, not months
  • +
  • Powerful Tools: Everything you need to succeed in one platform
  • +
  • Scalable: Grow from startup to enterprise seamlessly
  • +
  • Reliable: 99.9% uptime guarantee with 24/7 support
  • +
+ +

Our Values

+
    +
  • Innovation: We constantly improve and evolve our platform
  • +
  • Transparency: No hidden fees, no surprises
  • +
  • Community: We succeed when our vendors succeed
  • +
  • Excellence: We strive for the highest quality in everything we do
  • +
+ """, + vendor_id=None, + is_published=True, + show_in_header=True, # Show in header navigation + show_in_footer=True, # Show in footer + display_order=1, + meta_description="Learn about our mission to democratize e-commerce and empower entrepreneurs worldwide.", + meta_keywords="about us, mission, vision, values, company" + ) + print(f" āœ… Created: {about.title} (/{about.slug})") + except Exception as e: + print(f" āš ļø Error: About Us - {str(e)}") + + # ======================================================================== + # 3. FAQ + # ======================================================================== + print("3. Creating FAQ page...") + + existing = db.query(ContentPage).filter_by(vendor_id=None, slug="faq").first() + if existing: + print(f" āš ļø Skipped: FAQ - already exists (ID: {existing.id})") + else: + try: + faq = content_page_service.create_page( + db, + slug="faq", + title="Frequently Asked Questions", + content=""" +

Getting Started

+ +

How do I create a vendor account?

+

+ Contact our sales team to get started. We'll set up your account and provide + you with everything you need to launch your store. +

+ +

How long does it take to set up my store?

+

+ Most vendors can launch their store in less than 24 hours. Our team will guide + you through the setup process step by step. +

+ +

Pricing & Payment

+ +

What are your pricing plans?

+

+ We offer flexible pricing plans based on your business needs. Contact us for + detailed pricing information and to find the plan that's right for you. +

+ +

When do I get paid?

+

+ Payments are processed weekly, with funds typically reaching your account + within 2-3 business days. +

+ +

Features & Support

+ +

Can I customize my store's appearance?

+

+ Yes! Our platform supports full theme customization including colors, fonts, + logos, and layouts. Make your store truly yours. +

+ +

What kind of support do you provide?

+

+ We offer 24/7 email support for all vendors, with priority phone support + available for enterprise plans. +

+ +

Technical Questions

+ +

Do I need technical knowledge to use the platform?

+

+ No! Our platform is designed to be user-friendly for everyone. However, if you + want to customize advanced features, our documentation and support team are here to help. +

+ +

Can I integrate with other tools?

+

+ Yes, we support integrations with popular payment gateways, shipping providers, + and marketing tools. +

+ """, + vendor_id=None, + is_published=True, + show_in_header=True, # Show in header navigation + show_in_footer=True, + display_order=2, + meta_description="Find answers to common questions about our marketplace platform.", + meta_keywords="faq, frequently asked questions, help, support" + ) + print(f" āœ… Created: {faq.title} (/{faq.slug})") + except Exception as e: + print(f" āš ļø Error: FAQ - {str(e)}") + + # ======================================================================== + # 4. CONTACT US + # ======================================================================== + print("4. Creating Contact Us page...") + + existing = db.query(ContentPage).filter_by(vendor_id=None, slug="contact").first() + if existing: + print(f" āš ļø Skipped: Contact Us - already exists (ID: {existing.id})") + else: + try: + contact = content_page_service.create_page( + db, + slug="contact", + title="Contact Us", + content=""" +

Get in Touch

+

+ We'd love to hear from you! Whether you have questions about our platform, + need technical support, or want to discuss partnership opportunities, our + team is here to help. +

+ +

Contact Information

+
    +
  • Email: support@marketplace.com
  • +
  • Phone: +1 (555) 123-4567
  • +
  • Hours: Monday - Friday, 9 AM - 6 PM PST
  • +
+ +

Office Address

+

+ 123 Business Street, Suite 100
+ San Francisco, CA 94102
+ United States +

+ +

Sales Inquiries

+

+ Interested in launching your store on our platform?
+ Email: sales@marketplace.com +

+ +

Technical Support

+

+ Need help with your store?
+ Email: support@marketplace.com
+ 24/7 email support for all vendors +

+ +

Media & Press

+

+ For media inquiries and press releases:
+ Email: press@marketplace.com +

+ """, + vendor_id=None, + is_published=True, + show_in_header=True, # Show in header navigation + show_in_footer=True, + display_order=3, + meta_description="Get in touch with our team. We're here to help you succeed.", + meta_keywords="contact, support, email, phone, address" + ) + print(f" āœ… Created: {contact.title} (/{contact.slug})") + except Exception as e: + print(f" āš ļø Error: Contact Us - {str(e)}") + + # ======================================================================== + # 5. TERMS OF SERVICE + # ======================================================================== + print("5. Creating Terms of Service page...") + + existing = db.query(ContentPage).filter_by(vendor_id=None, slug="terms").first() + if existing: + print(f" āš ļø Skipped: Terms of Service - already exists (ID: {existing.id})") + else: + try: + terms = content_page_service.create_page( + db, + slug="terms", + title="Terms of Service", + content=""" +

Last updated: January 1, 2024

+ +

1. Acceptance of Terms

+

+ By accessing and using this marketplace platform, you accept and agree to be + bound by the terms and provisions of this agreement. +

+ +

2. Use License

+

+ Permission is granted to temporarily access the materials on our platform for + personal, non-commercial transitory viewing only. +

+ +

3. Account Terms

+
    +
  • You must be at least 18 years old to use our platform
  • +
  • You must provide accurate and complete registration information
  • +
  • You are responsible for maintaining the security of your account
  • +
  • You are responsible for all activities under your account
  • +
+ +

4. Vendor Responsibilities

+
    +
  • Provide accurate product information and pricing
  • +
  • Honor all orders and commitments made through the platform
  • +
  • Comply with all applicable laws and regulations
  • +
  • Maintain appropriate customer service standards
  • +
+ +

5. Prohibited Activities

+

You may not use our platform to:

+
    +
  • Engage in any fraudulent or illegal activities
  • +
  • Violate any intellectual property rights
  • +
  • Transmit harmful code or malware
  • +
  • Interfere with platform operations
  • +
+ +

6. Termination

+

+ We reserve the right to terminate or suspend your account at any time for + violation of these terms. +

+ +

7. Limitation of Liability

+

+ In no event shall our company be liable for any damages arising out of the + use or inability to use our platform. +

+ +

8. Changes to Terms

+

+ We reserve the right to modify these terms at any time. We will notify users + of any changes via email. +

+ +

9. Contact

+

+ If you have any questions about these Terms, please contact us at + legal@marketplace.com. +

+ """, + vendor_id=None, + is_published=True, + show_in_header=False, # Too legal for header + show_in_footer=True, # Show in footer + display_order=10, + meta_description="Read our terms of service and platform usage policies.", + meta_keywords="terms of service, terms, legal, policy, agreement" + ) + print(f" āœ… Created: {terms.title} (/{terms.slug})") + except Exception as e: + print(f" āš ļø Error: Terms of Service - {str(e)}") + + # ======================================================================== + # 6. PRIVACY POLICY + # ======================================================================== + print("6. Creating Privacy Policy page...") + + existing = db.query(ContentPage).filter_by(vendor_id=None, slug="privacy").first() + if existing: + print(f" āš ļø Skipped: Privacy Policy - already exists (ID: {existing.id})") + else: + try: + privacy = content_page_service.create_page( + db, + slug="privacy", + title="Privacy Policy", + content=""" +

Last updated: January 1, 2024

+ +

1. Information We Collect

+

We collect information you provide directly to us, including:

+
    +
  • Name, email address, and contact information
  • +
  • Payment and billing information
  • +
  • Store and product information
  • +
  • Communications with us
  • +
+ +

2. How We Use Your Information

+

We use the information we collect to:

+
    +
  • Provide, maintain, and improve our services
  • +
  • Process transactions and send related information
  • +
  • Send technical notices and support messages
  • +
  • Respond to your comments and questions
  • +
  • Monitor and analyze trends and usage
  • +
+ +

3. Information Sharing

+

+ We do not sell your personal information. We may share information with: +

+
    +
  • Service providers who help us operate our platform
  • +
  • Law enforcement when required by law
  • +
  • Other parties with your consent
  • +
+ +

4. Data Security

+

+ We implement appropriate security measures to protect your personal information. + However, no method of transmission over the internet is 100% secure. +

+ +

5. Your Rights

+

You have the right to:

+
    +
  • Access your personal information
  • +
  • Correct inaccurate information
  • +
  • Request deletion of your information
  • +
  • Opt-out of marketing communications
  • +
+ +

6. Cookies

+

+ We use cookies and similar tracking technologies to track activity on our + platform and hold certain information. You can instruct your browser to + refuse cookies. +

+ +

7. Changes to This Policy

+

+ We may update this privacy policy from time to time. We will notify you of + any changes by posting the new policy on this page. +

+ +

8. Contact Us

+

+ If you have questions about this Privacy Policy, please contact us at + privacy@marketplace.com. +

+ """, + vendor_id=None, + is_published=True, + show_in_header=False, # Too legal for header + show_in_footer=True, # Show in footer + display_order=11, + meta_description="Learn how we collect, use, and protect your personal information.", + meta_keywords="privacy policy, privacy, data protection, gdpr, personal information" + ) + print(f" āœ… Created: {privacy.title} (/{privacy.slug})") + except Exception as e: + print(f" āš ļø Error: Privacy Policy - {str(e)}") + + print() + print("=" * 80) + print("āœ… Platform pages creation completed successfully!") + print("=" * 80) + print() + print("Created pages:") + print(" - Platform Homepage: http://localhost:8000/") + print(" - About Us: http://localhost:8000/about") + print(" - FAQ: http://localhost:8000/faq") + print(" - Contact Us: http://localhost:8000/contact") + print(" - Terms of Service: http://localhost:8000/terms") + print(" - Privacy Policy: http://localhost:8000/privacy") + print() + + except Exception as e: + print(f"\nāŒ Error: {e}") + db.rollback() + raise + finally: + db.close() + + +if __name__ == "__main__": + create_platform_pages() diff --git a/static/admin/js/content-page-edit.js b/static/admin/js/content-page-edit.js new file mode 100644 index 00000000..1e769a1e --- /dev/null +++ b/static/admin/js/content-page-edit.js @@ -0,0 +1,171 @@ +// static/admin/js/content-page-edit.js + +// Use centralized logger +const contentPageEditLog = window.LogConfig.loggers.contentPageEdit || window.LogConfig.createLogger('contentPageEdit'); + +// ============================================ +// CONTENT PAGE EDITOR FUNCTION +// ============================================ +function contentPageEditor(pageId) { + return { + // Inherit base layout functionality from init-alpine.js + ...data(), + + // Page identifier for sidebar active state + currentPage: 'content-pages', + + // Editor state + pageId: pageId, + form: { + slug: '', + title: '', + content: '', + content_format: 'html', + template: 'default', + meta_description: '', + meta_keywords: '', + is_published: false, + show_in_header: false, + show_in_footer: true, + display_order: 0, + vendor_id: null + }, + loading: false, + saving: false, + error: null, + successMessage: null, + + // Initialize + async init() { + contentPageEditLog.info('=== CONTENT PAGE EDITOR INITIALIZING ==='); + contentPageEditLog.info('Page ID:', this.pageId); + + // Prevent multiple initializations + if (window._contentPageEditInitialized) { + contentPageEditLog.warn('Content page editor already initialized, skipping...'); + return; + } + window._contentPageEditInitialized = true; + + if (this.pageId) { + // Edit mode - load existing page + contentPageEditLog.group('Loading page for editing'); + await this.loadPage(); + contentPageEditLog.groupEnd(); + } else { + // Create mode - use default values + contentPageEditLog.info('Create mode - using default form values'); + } + + contentPageEditLog.info('=== CONTENT PAGE EDITOR INITIALIZATION COMPLETE ==='); + }, + + // Load existing page + async loadPage() { + this.loading = true; + this.error = null; + + try { + contentPageEditLog.info(`Fetching page ${this.pageId}...`); + + const response = await apiClient.get(`/admin/content-pages/${this.pageId}`); + + contentPageEditLog.debug('API Response:', response); + + if (!response) { + throw new Error('Invalid API response'); + } + + // Handle response - API returns object directly + const page = response.data || response; + this.form = { + slug: page.slug || '', + title: page.title || '', + content: page.content || '', + content_format: page.content_format || 'html', + template: page.template || 'default', + meta_description: page.meta_description || '', + meta_keywords: page.meta_keywords || '', + is_published: page.is_published || false, + show_in_header: page.show_in_header || false, + show_in_footer: page.show_in_footer !== undefined ? page.show_in_footer : true, + display_order: page.display_order || 0, + vendor_id: page.vendor_id + }; + + contentPageEditLog.info('Page loaded successfully'); + + } catch (err) { + contentPageEditLog.error('Error loading page:', err); + this.error = err.message || 'Failed to load page'; + } finally { + this.loading = false; + } + }, + + // Save page (create or update) + async savePage() { + if (this.saving) return; + + this.saving = true; + this.error = null; + this.successMessage = null; + + try { + contentPageEditLog.info(this.pageId ? 'Updating page...' : 'Creating page...'); + + const payload = { + slug: this.form.slug, + title: this.form.title, + content: this.form.content, + content_format: this.form.content_format, + template: this.form.template, + meta_description: this.form.meta_description, + meta_keywords: this.form.meta_keywords, + is_published: this.form.is_published, + show_in_header: this.form.show_in_header, + show_in_footer: this.form.show_in_footer, + display_order: this.form.display_order, + vendor_id: this.form.vendor_id + }; + + contentPageEditLog.debug('Payload:', payload); + + let response; + if (this.pageId) { + // Update existing page + response = await apiClient.put(`/admin/content-pages/${this.pageId}`, payload); + this.successMessage = 'Page updated successfully!'; + contentPageEditLog.info('Page updated'); + } else { + // Create new page + response = await apiClient.post('/admin/content-pages/platform', payload); + this.successMessage = 'Page created successfully!'; + contentPageEditLog.info('Page created'); + + // Redirect to edit page after creation + const pageData = response.data || response; + if (pageData && pageData.id) { + setTimeout(() => { + window.location.href = `/admin/content-pages/${pageData.id}/edit`; + }, 1500); + } + } + + // Clear success message after 3 seconds + setTimeout(() => { + this.successMessage = null; + }, 3000); + + } catch (err) { + contentPageEditLog.error('Error saving page:', err); + this.error = err.message || 'Failed to save page'; + + // Scroll to top to show error + window.scrollTo({ top: 0, behavior: 'smooth' }); + } finally { + this.saving = false; + } + } + }; +} diff --git a/static/admin/js/content-pages.js b/static/admin/js/content-pages.js new file mode 100644 index 00000000..257a3b67 --- /dev/null +++ b/static/admin/js/content-pages.js @@ -0,0 +1,161 @@ +// static/admin/js/content-pages.js + +// Use centralized logger +const contentPagesLog = window.LogConfig.loggers.contentPages || window.LogConfig.createLogger('contentPages'); + +// ============================================ +// CONTENT PAGES MANAGER FUNCTION +// ============================================ +function contentPagesManager() { + return { + // Inherit base layout functionality from init-alpine.js + ...data(), + + // Page identifier for sidebar active state + currentPage: 'content-pages', + + // Content pages specific state + allPages: [], + loading: false, + error: null, + + // Tabs and filters + activeTab: 'all', // all, platform, vendor + searchQuery: '', + + // Initialize + async init() { + contentPagesLog.info('=== CONTENT PAGES MANAGER INITIALIZING ==='); + + // Prevent multiple initializations + if (window._contentPagesInitialized) { + contentPagesLog.warn('Content pages manager already initialized, skipping...'); + return; + } + window._contentPagesInitialized = true; + + contentPagesLog.group('Loading content pages'); + await this.loadPages(); + contentPagesLog.groupEnd(); + + contentPagesLog.info('=== CONTENT PAGES MANAGER INITIALIZATION COMPLETE ==='); + }, + + // Computed: Platform pages + get platformPages() { + return this.allPages.filter(page => page.is_platform_default); + }, + + // Computed: Vendor pages + get vendorPages() { + return this.allPages.filter(page => page.is_vendor_override); + }, + + // Computed: Filtered pages based on active tab and search + get filteredPages() { + let pages = []; + + // Filter by tab + if (this.activeTab === 'platform') { + pages = this.platformPages; + } else if (this.activeTab === 'vendor') { + pages = this.vendorPages; + } else { + pages = this.allPages; + } + + // Filter by search query + if (this.searchQuery) { + const query = this.searchQuery.toLowerCase(); + pages = pages.filter(page => + page.title.toLowerCase().includes(query) || + page.slug.toLowerCase().includes(query) || + (page.vendor_name && page.vendor_name.toLowerCase().includes(query)) + ); + } + + // Sort by display_order, then title + return pages.sort((a, b) => { + if (a.display_order !== b.display_order) { + return a.display_order - b.display_order; + } + return a.title.localeCompare(b.title); + }); + }, + + // Load all content pages + async loadPages() { + this.loading = true; + this.error = null; + + try { + contentPagesLog.info('Fetching all content pages...'); + + // Fetch all pages (platform + vendor, published + unpublished) + const response = await apiClient.get('/admin/content-pages/?include_unpublished=true'); + + contentPagesLog.debug('API Response:', response); + + if (!response) { + throw new Error('Invalid API response'); + } + + // Handle response - API returns array directly + this.allPages = Array.isArray(response) ? response : (response.data || response.items || []); + contentPagesLog.info(`Loaded ${this.allPages.length} pages`); + + } catch (err) { + contentPagesLog.error('Error loading content pages:', err); + this.error = err.message || 'Failed to load content pages'; + } finally { + this.loading = false; + } + }, + + // Delete a page + async deletePage(page) { + if (!confirm(`Are you sure you want to delete "${page.title}"?`)) { + return; + } + + try { + contentPagesLog.info(`Deleting page: ${page.id}`); + + await apiClient.delete(`/admin/content-pages/${page.id}`); + + // Remove from local array + this.allPages = this.allPages.filter(p => p.id !== page.id); + + contentPagesLog.info('Page deleted successfully'); + + } catch (err) { + contentPagesLog.error('Error deleting page:', err); + alert(`Failed to delete page: ${err.message}`); + } + }, + + // Format date helper + formatDate(dateString) { + if (!dateString) return '—'; + + const date = new Date(dateString); + const now = new Date(); + const diffMs = now - date; + const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24)); + + if (diffDays === 0) { + return 'Today'; + } else if (diffDays === 1) { + return 'Yesterday'; + } else if (diffDays < 7) { + return `${diffDays} days ago`; + } else { + return date.toLocaleDateString('en-US', { + year: 'numeric', + month: 'short', + day: 'numeric' + }); + } + } + }; +} diff --git a/static/admin/js/platform-homepage.js b/static/admin/js/platform-homepage.js new file mode 100644 index 00000000..14c86f4e --- /dev/null +++ b/static/admin/js/platform-homepage.js @@ -0,0 +1,154 @@ +// static/admin/js/platform-homepage.js + +// Use centralized logger +const platformHomepageLog = window.LogConfig.loggers.platformHomepage || window.LogConfig.createLogger('platformHomepage'); + +// ============================================ +// PLATFORM HOMEPAGE MANAGER FUNCTION +// ============================================ +function platformHomepageManager() { + return { + // Inherit base layout functionality from init-alpine.js + ...data(), + + // Page identifier for sidebar active state + currentPage: 'platform-homepage', + + // Platform homepage specific state + page: null, + loading: false, + saving: false, + error: null, + successMessage: null, + + // Initialize + async init() { + platformHomepageLog.info('=== PLATFORM HOMEPAGE MANAGER INITIALIZING ==='); + + // Prevent multiple initializations + if (window._platformHomepageInitialized) { + platformHomepageLog.warn('Platform homepage manager already initialized, skipping...'); + return; + } + window._platformHomepageInitialized = true; + + platformHomepageLog.group('Loading platform homepage'); + await this.loadPlatformHomepage(); + platformHomepageLog.groupEnd(); + + platformHomepageLog.info('=== PLATFORM HOMEPAGE MANAGER INITIALIZATION COMPLETE ==='); + }, + + // Load platform homepage from API + async loadPlatformHomepage() { + this.loading = true; + this.error = null; + + try { + platformHomepageLog.info('Fetching platform homepage...'); + + // Fetch all platform pages + const response = await apiClient.get('/admin/content-pages/platform?include_unpublished=true'); + + platformHomepageLog.debug('API Response:', response); + + if (!response) { + throw new Error('Invalid API response'); + } + + // Handle response - API returns array directly + const pages = Array.isArray(response) ? response : (response.data || response.items || []); + + // Find the platform_homepage page + const homepage = pages.find(page => page.slug === 'platform_homepage'); + + if (!homepage) { + platformHomepageLog.warn('Platform homepage not found, creating default...'); + // Initialize with default values + this.page = { + id: null, + slug: 'platform_homepage', + title: 'Welcome to Our Multi-Vendor Marketplace', + content: '

Connect vendors with customers worldwide. Build your online store and reach millions of shoppers.

', + template: 'default', + content_format: 'html', + meta_description: 'Leading multi-vendor marketplace platform. Connect with thousands of vendors and discover millions of products.', + meta_keywords: 'marketplace, multi-vendor, e-commerce, online shopping', + is_published: false, + show_in_header: false, + show_in_footer: false, + display_order: 0 + }; + } else { + this.page = { ...homepage }; + platformHomepageLog.info('Platform homepage loaded:', this.page); + } + + } catch (err) { + platformHomepageLog.error('Error loading platform homepage:', err); + this.error = err.message || 'Failed to load platform homepage'; + } finally { + this.loading = false; + } + }, + + // Save platform homepage + async savePage() { + if (this.saving) return; + + this.saving = true; + this.error = null; + this.successMessage = null; + + try { + platformHomepageLog.info('Saving platform homepage...'); + + const payload = { + slug: 'platform_homepage', + title: this.page.title, + content: this.page.content, + content_format: this.page.content_format || 'html', + template: this.page.template, + meta_description: this.page.meta_description, + meta_keywords: this.page.meta_keywords, + is_published: this.page.is_published, + show_in_header: false, // Homepage never in header + show_in_footer: false, // Homepage never in footer + display_order: 0, + vendor_id: null // Platform default + }; + + platformHomepageLog.debug('Payload:', payload); + + let response; + if (this.page.id) { + // Update existing page + response = await apiClient.put(`/admin/content-pages/${this.page.id}`, payload); + platformHomepageLog.info('Platform homepage updated'); + } else { + // Create new page + response = await apiClient.post('/admin/content-pages/platform', payload); + platformHomepageLog.info('Platform homepage created'); + } + + if (response) { + // Handle response - API returns object directly + const pageData = response.data || response; + this.page = { ...pageData }; + this.successMessage = 'Platform homepage saved successfully!'; + + // Clear success message after 3 seconds + setTimeout(() => { + this.successMessage = null; + }, 3000); + } + + } catch (err) { + platformHomepageLog.error('Error saving platform homepage:', err); + this.error = err.message || 'Failed to save platform homepage'; + } finally { + this.saving = false; + } + } + }; +}