import json from django import forms from django.conf import settings from django.contrib.humanize.templatetags.humanize import intcomma from django.urls import reverse, path from django.utils.safestring import mark_safe from django.utils.translation import gettext_lazy as _ from django.views.generic import RedirectView from django.utils.translation import get_language from django.http import JsonResponse from django.views.decorators.http import require_POST # --- Unicode slugify override for Unfold tabs --- import django.utils.text from django.template.defaultfilters import register _original_slugify = django.utils.text.slugify def _unicode_slugify(value, allow_unicode=True): return _original_slugify(value, allow_unicode=True) django.utils.text.slugify = _unicode_slugify @register.filter(is_safe=True) def slugify(value): return _unicode_slugify(value) # Unfold Imports from unfold.sites import UnfoldAdminSite # --------------------------------------------------------- # 1. Helper Functions # --------------------------------------------------------- def admin_url_generator(request, url_name): """ Dynamically generates admin URLs for the active admin site namespace. """ namespace = 'admin' full_view_name = f"{namespace}:{url_name}" try: return reverse(full_view_name) except Exception: return "#" def variables(request): return {"plausible_domain": getattr(settings, 'PLAUSIBLE_DOMAIN', '')} @require_POST def toggle_sidebar(request): """Toggle sidebar state for Unfold admin interface""" return JsonResponse({'status': 'success'}) # --------------------------------------------------------- # 2. Custom Login Form # --------------------------------------------------------- class LoginForm: """Lazy login form to avoid circular imports during settings loading""" @staticmethod def get_form(): from unfold.forms import AuthenticationForm class CustomLoginForm(AuthenticationForm): password = forms.CharField(widget=forms.PasswordInput(render_value=True)) def __init__(self, request=None, *args, **kwargs): super().__init__(request, *args, **kwargs) self.fields["username"].label = _("Email") return CustomLoginForm # --------------------------------------------------------- # 3. Unified Admin Site Definition # --------------------------------------------------------- class AppAdminSite(UnfoldAdminSite): """Unified Modern Admin Site with Unfold Theme""" site_header = _("Management Dashboard") site_title = _("Admin Portal") index_title = _("System Administration") site_subheader = _("Application Console") def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.login_form = LoginForm.get_form() def get_urls(self): urls = super().get_urls() custom_urls = [ path('toggle_sidebar/', toggle_sidebar, name='toggle_sidebar'), ] return custom_urls + urls def _get_colors(self, key, *args): if key != "COLORS": return super()._get_colors(key, *args) # Modern, sleek slate-indigo color palette return { "base": { "50": "248 250 252", "100": "241 245 249", "200": "226 232 240", "300": "203 213 225", "400": "148 163 184", "500": "100 116 139", "600": "71 85 105", "700": "51 65 85", "800": "30 41 59", "900": "15 23 42", "950": "2 6 23", }, "primary": { "50": "238 242 255", "100": "224 231 255", "200": "199 210 254", "300": "165 180 252", "400": "129 140 248", "500": "99 102 241", "600": "79 70 229", "700": "67 56 202", "800": "55 48 163", "900": "49 46 129", "950": "30 27 75", }, "font": { "subtle-light": "var(--color-base-500)", "subtle-dark": "var(--color-base-400)", "default-light": "var(--color-base-700)", "default-dark": "var(--color-base-200)", "important-light": "var(--color-base-900)", "important-dark": "255 255 255", }, } class LazyAdminSite(UnfoldAdminSite): def __init__(self, site_class, name): self._site_class = site_class self._name = name self._instance = None self.name = name def _ensure_instance(self): if self._instance is None: self._instance = self._site_class(name=self._name) essential_attrs = ['site_header', 'site_title', 'index_title', 'site_url', 'login_template'] for attr in essential_attrs: if hasattr(self._instance, attr): setattr(self, attr, getattr(self._instance, attr)) def _get_instance(self): self._ensure_instance() return self._instance def __getattr__(self, name): self._ensure_instance() return getattr(self._instance, name) def __call__(self, *args, **kwargs): return self._get_instance()(*args, **kwargs) @property def urls(self): return self._get_instance().urls def get_urls(self): return self._get_instance().get_urls() def each_context(self, request): return self._get_instance().each_context(request) def register(self, model_or_iterable, admin_class=None, **options): self._ensure_instance() return self._instance.register(model_or_iterable, admin_class, **options) # Singleton instances project_admin_site = LazyAdminSite(AppAdminSite, 'admin') # Compatibility alias dovoodi_admin_site = project_admin_site class HomeView(RedirectView): def get_redirect_url(self, *args, **kwargs): language = get_language() or 'en' return f'/{language}/admin/' # --------------------------------------------------------- # 4. Dynamic Custom Dashboard # --------------------------------------------------------- def dashboard_callback(request, context): """Generic Dashboard KPI statistics""" from django.apps import apps if context is None: context = {} context.update({ "navigation": [{"title": _("Dashboard"), "link": "/admin/", "active": True}], "kpi": [], }) if not hasattr(request, "user") or not request.user.is_authenticated: return context try: User = apps.get_model('account', 'User') LoginHistory = apps.get_model('account', 'LoginHistory') total_users = User.objects.count() active_users = User.objects.filter(is_active=True).count() staff_users = User.objects.filter(is_staff=True).count() total_logins = LoginHistory.objects.count() context["kpi"] = [ {"title": _("Total Users"), "metric": f"{total_users:,}"}, {"title": _("Active Users"), "metric": f"{active_users:,}"}, {"title": _("Staff Members"), "metric": f"{staff_users:,}"}, {"title": _("Total Logins"), "metric": f"{total_logins:,}"}, ] except Exception as e: pass return context