from __future__ import annotations from typing import Any, Dict, List from django.db.models import Q from django.http import HttpRequest, HttpResponse from django.views import View from django.views.generic.detail import SingleObjectMixin from django.views.generic.list import MultipleObjectMixin from inertia import render from labs.models import LabFeedback from .base import PermissionRequiredAdminMixin class LabFeedbackListView(PermissionRequiredAdminMixin, MultipleObjectMixin, View): """List view for lab feedbacks.""" model = LabFeedback permission_required = "labs.view_labfeedback" paginate_by = 10 page_kwarg = "page" ordering = "-updated_at" search_fields = ["email", "lab_code"] component = "lab-feedbacks/Index" def get_queryset(self): queryset = self.model._default_manager.all() if self.ordering: queryset = queryset.order_by(self.ordering) query = self.request.GET.get("q", "").strip() if query: conditions = Q() for field in self.search_fields: conditions |= Q(**{f"{field}__icontains": query}) queryset = queryset.filter(conditions) return queryset def serialize_feedback(self, feedback: LabFeedback) -> Dict[str, Any]: return { "id": feedback.id, "email": feedback.email, "lab_code": feedback.lab_code, "rating_score": feedback.rating_score, "comment": feedback.comment, "created_at": feedback.created_at.isoformat(), "updated_at": feedback.updated_at.isoformat(), } def get(self, request: HttpRequest) -> HttpResponse: self.object_list = self.get_queryset() paginate_by = self.get_paginate_by(self.object_list) if paginate_by: paginator, page, object_list, is_paginated = self.paginate_queryset( self.object_list, paginate_by ) else: paginator = None page = None object_list = self.object_list is_paginated = False feedbacks: List[Dict[str, Any]] = [ self.serialize_feedback(fb) for fb in object_list ] pagination: Dict[str, Any] | None = None if paginator and page: pagination = { "page": page.number, "per_page": paginator.per_page, "total": paginator.count, "num_pages": paginator.num_pages, "is_paginated": is_paginated, } return render( request, self.component, { "feedbacks": feedbacks, "filters": { "q": request.GET.get("q", "").strip(), }, "pagination": pagination, }, ) class LabFeedbackDetailView(PermissionRequiredAdminMixin, SingleObjectMixin, View): """Detail view for lab feedback (read-only).""" model = LabFeedback permission_required = "labs.view_labfeedback" component = "lab-feedbacks/Detail" def serialize_feedback(self, feedback: LabFeedback) -> Dict[str, Any]: return { "id": feedback.id, "email": feedback.email, "lab_code": feedback.lab_code, "rating_score": feedback.rating_score, "comment": feedback.comment, "created_at": feedback.created_at.isoformat(), "updated_at": feedback.updated_at.isoformat(), } def get(self, request: HttpRequest, pk: int) -> HttpResponse: self.object = self.get_object() return render( request, self.component, { "feedback": self.serialize_feedback(self.object), }, )