from django import forms from django.contrib import admin from django.utils.translation import gettext_lazy as _ from unfold.admin import ModelAdmin, TabularInline from unfold.contrib.forms.widgets import WysiwygWidget from unfold.decorators import display, action from utils.json_editor_field import JsonEditorWidget import json from utils.admin import project_admin_site from ..models import ( Hadis, HadisReference, HadisTag, HadisStatus, ReferenceImage, HadisCollection, HadisInCollection ) # Custom Forms for JSON Fields class HadisAdminForm(forms.ModelForm): """Custom form for Hadis with JSON editor widgets""" class Meta: model = Hadis fields = '__all__' widgets = { 'explanation': WysiwygWidget(), } def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # Schema for translation JSON field translation_schema = { "type": "array", "title": "Translations", "items": { "type": "object", "title": "Translation", "properties": { "language_code": { "type": "string", "title": "Language Code", "enum": ["en", "fa", "ar", "ur"], "options": { "enum_titles": ["English", "Persian", "Arabic", "Urdu"] } }, "text": { # <‑‑ use text, not title "type": "string", "title": "Translation Text" } }, "required": ["language_code", "text"] # <‑‑ update required key } } # Schema for links JSON field (array of objects with title and link) links_schema = { "type": "array", "title": "Links", "items": { "type": "object", "title": "Link", "properties": { "title": { "type": "string", "title": "Link Title" }, "link": { "type": "string", "title": "URL", "format": "uri" } }, "required": ["title", "link"] } } # Apply JSON editor widgets self.fields['translation'].widget = JsonEditorWidget(attrs={ 'schema': json.dumps(translation_schema), 'title': 'Translations' }) self.fields['links'].widget = JsonEditorWidget(attrs={ 'schema': json.dumps(links_schema), 'title': 'Links' }) # Inline Admin Classes class ReferenceImageInline(TabularInline): """Inline for ReferenceImage in HadisReference admin""" model = ReferenceImage extra = 0 fields = ('thumbnail', 'priority') ordering = ('priority',) class HadisReferenceInline(TabularInline): """Inline for HadisReference in Hadis admin""" model = HadisReference extra = 0 fields = ('book_reference',) readonly_fields = ('created_at',) # Main Admin Classes class HadisTagAdmin(ModelAdmin): """Admin for HadisTag model""" list_display = ('title', 'status', 'created_at') list_filter = ('status', 'created_at') search_fields = ('title',) readonly_fields = ('created_at', 'updated_at') fieldsets = ( (None, { 'fields': ('title', 'status') }), (_('Timestamps'), { 'fields': ('created_at', 'updated_at'), 'classes': ('collapse',) }), ) class HadisStatusAdmin(ModelAdmin): """Admin for HadisStatus model""" list_display = ('title', 'color', 'order') list_filter = ('color',) search_fields = ('title',) ordering = ('order',) fieldsets = ( (None, { 'fields': ('title', 'color', 'order') }), ) class HadisAdmin(ModelAdmin): """Admin for Hadis model""" form = HadisAdminForm list_display = ('number', 'title', 'category', 'status', 'hadis_status', 'created_at') list_filter = ('status', 'hadis_status', 'category', 'created_at') search_fields = ('title', 'text', 'category__title') readonly_fields = ('created_at', 'updated_at', 'share_link') ordering = ('category', 'number') inlines = [HadisReferenceInline] filter_horizontal = ('tags',) fieldsets = ( (None, { 'fields': ('category', 'number', 'title', 'status') }), (_('Content'), { 'fields': ('text', 'translation', 'explanation') }), (_('Status & Classification'), { 'fields': ('hadis_status', 'hadis_status_text', 'tags') }), (_('Additional Information'), { 'fields': ('address', 'links', 'share_link'), 'classes': ('collapse',) }), (_('Timestamps'), { 'fields': ('created_at', 'updated_at'), 'classes': ('collapse',) }), ) class HadisReferenceAdmin(ModelAdmin): """Admin for HadisReference model""" list_display = ('hadis', 'book_reference', 'created_at') list_filter = ('created_at', 'book_reference') search_fields = ('hadis__title', 'book_reference__title') readonly_fields = ('created_at',) inlines = [ReferenceImageInline] fieldsets = ( (None, { 'fields': ('hadis', 'book_reference') }), (_('Timestamps'), { 'fields': ('created_at',), 'classes': ('collapse',) }), ) class ReferenceImageAdmin(ModelAdmin): """Admin for ReferenceImage model""" list_display = ('reference', 'thumbnail', 'priority') list_filter = ('priority',) search_fields = ('reference__hadis__title', 'reference__book__title') ordering = ('reference', 'priority') fieldsets = ( (None, { 'fields': ('reference', 'thumbnail', 'priority') }), ) class HadisInCollectionInline(TabularInline): """Inline for HadisInCollection in HadisCollection admin""" model = HadisInCollection extra = 0 fields = ('hadis', 'order') ordering = ('order',) class HadisCollectionAdmin(ModelAdmin): """Admin for HadisCollection model""" list_display = ('title', 'slug', 'status', 'order', 'created_at') list_filter = ('status', 'created_at') search_fields = ('title', 'slug', 'summary') readonly_fields = ('slug', 'created_at', 'updated_at') ordering = ('order',) inlines = [HadisInCollectionInline] fieldsets = ( (None, { 'fields': ('title', 'slug', 'summary', 'status', 'order', 'thumbnail') }), (_('Timestamps'), { 'fields': ('created_at', 'updated_at'), 'classes': ('collapse',) }), ) # Register models with the custom admin site project_admin_site.register(HadisTag, HadisTagAdmin) project_admin_site.register(HadisStatus, HadisStatusAdmin) project_admin_site.register(Hadis, HadisAdmin) project_admin_site.register(HadisReference, HadisReferenceAdmin) project_admin_site.register(ReferenceImage, ReferenceImageAdmin) project_admin_site.register(HadisCollection, HadisCollectionAdmin)