Implement Site Builder Metadata and Enhance Wizard Functionality

- Introduced new models for Site Builder options, including BusinessType, AudienceProfile, BrandPersonality, and HeroImageryDirection.
- Added serializers and views to handle metadata for dropdowns in the Site Builder wizard.
- Updated the SiteBuilderWizard component to load and display metadata, improving user experience with dynamic options.
- Enhanced BusinessDetailsStep and StyleStep components to utilize new metadata for business types and brand personalities.
- Refactored state management in builderStore to include metadata loading and error handling.
- Updated API service to fetch Site Builder metadata, ensuring seamless integration with the frontend.
This commit is contained in:
IGNY8 VPS (Salman)
2025-11-18 12:31:59 +00:00
parent 5d97ab6e49
commit 26ec2ae03e
13 changed files with 1062 additions and 96 deletions

View File

@@ -0,0 +1,159 @@
from django.db import migrations, models
def seed_site_builder_metadata(apps, schema_editor):
BusinessType = apps.get_model('site_building', 'BusinessType')
AudienceProfile = apps.get_model('site_building', 'AudienceProfile')
BrandPersonality = apps.get_model('site_building', 'BrandPersonality')
HeroImageryDirection = apps.get_model('site_building', 'HeroImageryDirection')
business_types = [
("Productized Services", "Standardized service offering with clear deliverables."),
("B2B SaaS Platform", "Subscription software platform targeting business teams."),
("eCommerce Brand", "Direct-to-consumer catalog with premium merchandising."),
("Marketplace / Platform", "Two-sided marketplace connecting buyers and sellers."),
("Advisory / Consulting", "Expert advisory firm or boutique consultancy."),
("Education / Training", "Learning platform, cohort, or academy."),
("Community / Membership", "Member-driven experience with gated content."),
("Mission-Driven / Nonprofit", "Impact-focused organization or foundation."),
]
audience_profiles = [
("Enterprise Operations Leaders", "COO / Ops executives at scale-ups."),
("Marketing Directors & CMOs", "Growth and brand owners across industries."),
("Founders & Executive Teams", "Visionaries leading fast-moving companies."),
("Revenue & Sales Leaders", "CROs, VPs of Sales, and GTM owners."),
("Product & Innovation Teams", "Product managers and innovation leaders."),
("IT & Engineering Teams", "Technical buyers evaluating new platforms."),
("HR & People Leaders", "People ops and talent professionals."),
("Healthcare Administrators", "Clinical and operational healthcare leads."),
("Financial Services Professionals", "Banking, fintech, and investment teams."),
("Consumers / Prospects", "End-user or prospect-focused experience."),
]
brand_personalities = [
("Bold Visionary", "Decisive, future-forward, and thought-leading."),
("Trusted Advisor", "Calm, credible, and risk-aware guidance."),
("Analytical Expert", "Data-backed, precise, and rigorous."),
("Friendly Guide", "Welcoming, warm, and supportive tone."),
("Luxe & Premium", "High-touch, elevated, and detail-obsessed."),
("Playful Creative", "Vibrant, unexpected, and energetic."),
("Minimalist Modern", "Clean, refined, and confident."),
("Fearless Innovator", "Experimental, edgy, and fast-moving."),
]
hero_imagery = [
("Real team collaboration photography", "Documentary-style shots of real teams."),
("Product close-ups with UI overlays", "Focus on interfaces and feature highlights."),
("Lifestyle scenes featuring customers", "Story-driven photography of real scenarios."),
("Abstract gradients & motion graphics", "Modern, colorful abstract compositions."),
("Illustration + iconography blend", "Custom illustrations paired with icon systems."),
]
for order, (name, description) in enumerate(business_types):
BusinessType.objects.update_or_create(
name=name,
defaults={'description': description, 'order': order, 'is_active': True},
)
for order, (name, description) in enumerate(audience_profiles):
AudienceProfile.objects.update_or_create(
name=name,
defaults={'description': description, 'order': order, 'is_active': True},
)
for order, (name, description) in enumerate(brand_personalities):
BrandPersonality.objects.update_or_create(
name=name,
defaults={'description': description, 'order': order, 'is_active': True},
)
for order, (name, description) in enumerate(hero_imagery):
HeroImageryDirection.objects.update_or_create(
name=name,
defaults={'description': description, 'order': order, 'is_active': True},
)
class Migration(migrations.Migration):
dependencies = [
('site_building', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='AudienceProfile',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=120, unique=True)),
('description', models.CharField(blank=True, max_length=255)),
('is_active', models.BooleanField(default=True)),
('order', models.PositiveIntegerField(default=0)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
],
options={
'verbose_name': 'Audience Profile',
'verbose_name_plural': 'Audience Profiles',
'db_table': 'igny8_site_builder_audience_profiles',
'ordering': ['order', 'name'],
},
),
migrations.CreateModel(
name='BrandPersonality',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=120, unique=True)),
('description', models.CharField(blank=True, max_length=255)),
('is_active', models.BooleanField(default=True)),
('order', models.PositiveIntegerField(default=0)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
],
options={
'verbose_name': 'Brand Personality',
'verbose_name_plural': 'Brand Personalities',
'db_table': 'igny8_site_builder_brand_personalities',
'ordering': ['order', 'name'],
},
),
migrations.CreateModel(
name='BusinessType',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=120, unique=True)),
('description', models.CharField(blank=True, max_length=255)),
('is_active', models.BooleanField(default=True)),
('order', models.PositiveIntegerField(default=0)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
],
options={
'verbose_name': 'Business Type',
'verbose_name_plural': 'Business Types',
'db_table': 'igny8_site_builder_business_types',
'ordering': ['order', 'name'],
},
),
migrations.CreateModel(
name='HeroImageryDirection',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=120, unique=True)),
('description', models.CharField(blank=True, max_length=255)),
('is_active', models.BooleanField(default=True)),
('order', models.PositiveIntegerField(default=0)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
],
options={
'verbose_name': 'Hero Imagery Direction',
'verbose_name_plural': 'Hero Imagery Directions',
'db_table': 'igny8_site_builder_hero_imagery',
'ordering': ['order', 'name'],
},
),
migrations.RunPython(seed_site_builder_metadata, migrations.RunPython.noop),
]

View File

@@ -166,3 +166,55 @@ class PageBlueprint(SiteSectorBaseModel):
return f"{self.title} ({self.site_blueprint.name})"
class SiteBuilderOption(models.Model):
"""
Base model for Site Builder dropdown metadata.
"""
name = models.CharField(max_length=120, unique=True)
description = models.CharField(max_length=255, blank=True)
is_active = models.BooleanField(default=True)
order = models.PositiveIntegerField(default=0)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
abstract = True
ordering = ['order', 'name']
def __str__(self):
return self.name
class BusinessType(SiteBuilderOption):
class Meta(SiteBuilderOption.Meta):
app_label = 'site_building'
db_table = 'igny8_site_builder_business_types'
verbose_name = 'Business Type'
verbose_name_plural = 'Business Types'
class AudienceProfile(SiteBuilderOption):
class Meta(SiteBuilderOption.Meta):
app_label = 'site_building'
db_table = 'igny8_site_builder_audience_profiles'
verbose_name = 'Audience Profile'
verbose_name_plural = 'Audience Profiles'
class BrandPersonality(SiteBuilderOption):
class Meta(SiteBuilderOption.Meta):
app_label = 'site_building'
db_table = 'igny8_site_builder_brand_personalities'
verbose_name = 'Brand Personality'
verbose_name_plural = 'Brand Personalities'
class HeroImageryDirection(SiteBuilderOption):
class Meta(SiteBuilderOption.Meta):
app_label = 'site_building'
db_table = 'igny8_site_builder_hero_imagery'
verbose_name = 'Hero Imagery Direction'
verbose_name_plural = 'Hero Imagery Directions'