This commit is contained in:
alorig
2025-11-18 22:17:45 +05:00
parent 11766454e9
commit 7ff73122c7
4 changed files with 264 additions and 2 deletions

View File

@@ -45,6 +45,8 @@ class Igny8AdminSite(admin.AdminSite):
('igny8_core_auth', 'User'),
('igny8_core_auth', 'SiteUserAccess'),
('igny8_core_auth', 'PasswordResetToken'),
('site_building', 'SiteBlueprint'),
('site_building', 'PageBlueprint'),
],
},
'Global Reference Data': {
@@ -52,6 +54,10 @@ class Igny8AdminSite(admin.AdminSite):
('igny8_core_auth', 'Industry'),
('igny8_core_auth', 'IndustrySector'),
('igny8_core_auth', 'SeedKeyword'),
('site_building', 'BusinessType'),
('site_building', 'AudienceProfile'),
('site_building', 'BrandPersonality'),
('site_building', 'HeroImageryDirection'),
],
},
'Planner': {

View File

@@ -0,0 +1,250 @@
"""
Admin interface for Site Builder models
"""
from django.contrib import admin
from django.utils.html import format_html
from django.urls import reverse
from igny8_core.admin.base import SiteSectorAdminMixin
from .models import (
SiteBlueprint,
PageBlueprint,
BusinessType,
AudienceProfile,
BrandPersonality,
HeroImageryDirection,
)
class PageBlueprintInline(admin.TabularInline):
"""Inline admin for Page Blueprints within Site Blueprint"""
model = PageBlueprint
extra = 0
fields = ['slug', 'title', 'type', 'status', 'order']
readonly_fields = ['slug', 'title', 'type', 'status', 'order']
can_delete = False
show_change_link = True
@admin.register(SiteBlueprint)
class SiteBlueprintAdmin(SiteSectorAdminMixin, admin.ModelAdmin):
"""Admin interface for Site Blueprints"""
list_display = [
'name',
'get_site_display',
'get_sector_display',
'status',
'hosting_type',
'version',
'get_pages_count',
'created_at',
]
list_filter = ['status', 'hosting_type', 'site', 'sector', 'account', 'created_at']
search_fields = ['name', 'description', 'site__name', 'sector__name']
readonly_fields = ['created_at', 'updated_at', 'version', 'deployed_version']
ordering = ['-created_at']
inlines = [PageBlueprintInline]
fieldsets = (
('Basic Information', {
'fields': ('name', 'description', 'account', 'site', 'sector')
}),
('Status & Configuration', {
'fields': ('status', 'hosting_type', 'version', 'deployed_version')
}),
('Configuration Data', {
'fields': ('config_json',),
'classes': ('collapse',),
}),
('Structure Data', {
'fields': ('structure_json',),
'classes': ('collapse',),
}),
('Timestamps', {
'fields': ('created_at', 'updated_at'),
'classes': ('collapse',),
}),
)
def get_site_display(self, obj):
"""Safely get site name"""
try:
if obj.site:
url = reverse('admin:igny8_core_auth_site_change', args=[obj.site.id])
return format_html('<a href="{}">{}</a>', url, obj.site.name)
return '-'
except:
return '-'
get_site_display.short_description = 'Site'
def get_sector_display(self, obj):
"""Safely get sector name"""
try:
return obj.sector.name if obj.sector else '-'
except:
return '-'
get_sector_display.short_description = 'Sector'
def get_pages_count(self, obj):
"""Get count of pages for this blueprint"""
try:
count = obj.pages.count()
if count > 0:
url = reverse('admin:site_building_pageblueprint_changelist')
return format_html('<a href="{}?site_blueprint__id__exact={}">{} pages</a>', url, obj.id, count)
return '0 pages'
except:
return '0 pages'
get_pages_count.short_description = 'Pages'
@admin.register(PageBlueprint)
class PageBlueprintAdmin(SiteSectorAdminMixin, admin.ModelAdmin):
"""Admin interface for Page Blueprints"""
list_display = [
'title',
'slug',
'get_site_blueprint_display',
'type',
'status',
'order',
'get_site_display',
'get_sector_display',
'created_at',
]
list_filter = ['status', 'type', 'site_blueprint', 'site', 'sector', 'created_at']
search_fields = ['title', 'slug', 'site_blueprint__name', 'site__name']
readonly_fields = ['created_at', 'updated_at']
ordering = ['site_blueprint', 'order', 'created_at']
fieldsets = (
('Basic Information', {
'fields': ('site_blueprint', 'title', 'slug', 'type', 'status', 'order')
}),
('Account & Site', {
'fields': ('account', 'site', 'sector'),
'classes': ('collapse',),
}),
('Content Blocks', {
'fields': ('blocks_json',),
'classes': ('collapse',),
}),
('Timestamps', {
'fields': ('created_at', 'updated_at'),
'classes': ('collapse',),
}),
)
def get_site_blueprint_display(self, obj):
"""Safely get site blueprint name with link"""
try:
if obj.site_blueprint:
url = reverse('admin:site_building_siteblueprint_change', args=[obj.site_blueprint.id])
return format_html('<a href="{}">{}</a>', url, obj.site_blueprint.name)
return '-'
except:
return '-'
get_site_blueprint_display.short_description = 'Site Blueprint'
def get_site_display(self, obj):
"""Safely get site name"""
try:
if obj.site:
url = reverse('admin:igny8_core_auth_site_change', args=[obj.site.id])
return format_html('<a href="{}">{}</a>', url, obj.site.name)
return '-'
except:
return '-'
get_site_display.short_description = 'Site'
def get_sector_display(self, obj):
"""Safely get sector name"""
try:
return obj.sector.name if obj.sector else '-'
except:
return '-'
get_sector_display.short_description = 'Sector'
@admin.register(BusinessType)
class BusinessTypeAdmin(admin.ModelAdmin):
"""Admin interface for Business Types"""
list_display = ['name', 'description', 'is_active', 'order', 'created_at']
list_filter = ['is_active', 'created_at']
search_fields = ['name', 'description']
list_editable = ['is_active', 'order']
ordering = ['order', 'name']
fieldsets = (
('Basic Information', {
'fields': ('name', 'description', 'is_active', 'order')
}),
('Timestamps', {
'fields': ('created_at', 'updated_at'),
'classes': ('collapse',),
}),
)
readonly_fields = ['created_at', 'updated_at']
@admin.register(AudienceProfile)
class AudienceProfileAdmin(admin.ModelAdmin):
"""Admin interface for Audience Profiles"""
list_display = ['name', 'description', 'is_active', 'order', 'created_at']
list_filter = ['is_active', 'created_at']
search_fields = ['name', 'description']
list_editable = ['is_active', 'order']
ordering = ['order', 'name']
fieldsets = (
('Basic Information', {
'fields': ('name', 'description', 'is_active', 'order')
}),
('Timestamps', {
'fields': ('created_at', 'updated_at'),
'classes': ('collapse',),
}),
)
readonly_fields = ['created_at', 'updated_at']
@admin.register(BrandPersonality)
class BrandPersonalityAdmin(admin.ModelAdmin):
"""Admin interface for Brand Personalities"""
list_display = ['name', 'description', 'is_active', 'order', 'created_at']
list_filter = ['is_active', 'created_at']
search_fields = ['name', 'description']
list_editable = ['is_active', 'order']
ordering = ['order', 'name']
fieldsets = (
('Basic Information', {
'fields': ('name', 'description', 'is_active', 'order')
}),
('Timestamps', {
'fields': ('created_at', 'updated_at'),
'classes': ('collapse',),
}),
)
readonly_fields = ['created_at', 'updated_at']
@admin.register(HeroImageryDirection)
class HeroImageryDirectionAdmin(admin.ModelAdmin):
"""Admin interface for Hero Imagery Directions"""
list_display = ['name', 'description', 'is_active', 'order', 'created_at']
list_filter = ['is_active', 'created_at']
search_fields = ['name', 'description']
list_editable = ['is_active', 'order']
ordering = ['order', 'name']
fieldsets = (
('Basic Information', {
'fields': ('name', 'description', 'is_active', 'order')
}),
('Timestamps', {
'fields': ('created_at', 'updated_at'),
'classes': ('collapse',),
}),
)
readonly_fields = ['created_at', 'updated_at']

View File

@@ -6,4 +6,11 @@ class SiteBuildingConfig(AppConfig):
name = 'igny8_core.business.site_building'
verbose_name = 'Site Building'
def ready(self):
"""Import admin to register models"""
try:
import igny8_core.business.site_building.admin # noqa
except ImportError:
pass

View File

@@ -231,7 +231,6 @@ export default function SiteBuilderBlueprints() {
{blueprint.description}
</p>
)}
</div>
<div className="flex items-center justify-between rounded-2xl bg-gray-50 px-4 py-3 text-sm font-semibold text-gray-700 dark:bg-white/[0.04] dark:text-white/80">
<span>Status</span>
<span className="capitalize">{blueprint.status}</span>