"""Dashboard API & view – visualization panel for the school meal planner.""" import json from collections import Counter from django.http import JsonResponse from django.shortcuts import render from django.db.models import Avg, Count, Max, Min, Sum from .models import Dish def _dashboard_stats(): """Return aggregate statistics for the dashboard.""" total = Dish.objects.count() active = Dish.objects.filter(is_active=True).count() inactive = total - active # Count by type type_counts = dict( Dish.objects.values_list('dish_type').annotate(c=Count('id')).values_list('dish_type', 'c') ) # Count by cuisine cuisine_counts = dict( Dish.objects.values_list('cuisine').annotate(c=Count('id')).values_list('cuisine', 'c') ) # Nutrition averages (active dishes only, meat + veg only for meaningful stats) nutrition = Dish.objects.filter(is_active=True, dish_type__in=('meat', 'veg')).aggregate( avg_protein=Avg('protein'), avg_fat=Avg('fat'), avg_calorie=Avg('calorie'), max_calorie=Max('calorie'), min_calorie=Min('calorie'), ) # Per-type nutrition averages type_nutrition = {} for dt in ('meat', 'veg', 'soup', 'staple'): agg = Dish.objects.filter(is_active=True, dish_type=dt).aggregate( avg_protein=Avg('protein'), avg_fat=Avg('fat'), avg_calorie=Avg('calorie'), count=Count('id'), ) type_nutrition[dt] = agg # Recent 10 dishes recent = list( Dish.objects.order_by('-created_at')[:10].values( 'id', 'name', 'dish_type', 'cuisine', 'protein', 'fat', 'calorie', 'is_active', 'created_at', ) ) for r in recent: r['created_at'] = r['created_at'].strftime('%Y-%m-%d %H:%M') if r['created_at'] else '' return { 'total': total, 'active': active, 'inactive': inactive, 'type_counts': type_counts, 'cuisine_counts': cuisine_counts, 'nutrition': { 'avg_protein': round(float(nutrition['avg_protein'] or 0), 1), 'avg_fat': round(float(nutrition['avg_fat'] or 0), 1), 'avg_calorie': round(float(nutrition['avg_calorie'] or 0)), 'max_calorie': int(nutrition['max_calorie'] or 0), 'min_calorie': int(nutrition['min_calorie'] or 0), }, 'type_nutrition': { k: { 'avg_protein': round(float(v['avg_protein'] or 0), 1), 'avg_fat': round(float(v['avg_fat'] or 0), 1), 'avg_calorie': round(float(v['avg_calorie'] or 0)), 'count': v['count'], } for k, v in type_nutrition.items() }, 'recent': recent, } def dashboard_api(request): """GET /api/dashboard/ -> JSON stats for the dashboard.""" return JsonResponse(_dashboard_stats()) def dashboard_view(request): """GET /dashboard/ -> serve the dashboard HTML page.""" return render(request, 'dashboard.html')