from at_django_boilerplate.communications.models import FeedbackModel,AppointmentModel from at_django_boilerplate.core.models import Subscriber from django.shortcuts import render, redirect,get_object_or_404 from django.contrib import messages from django.views import View from .models import SEOConfiguration from .forms import SEOConfigurationForm from django.contrib.auth.decorators import login_required, user_passes_test from django.contrib.auth import get_user_model from django.utils.decorators import method_decorator from django.views.generic import ListView from django.db.models import Q from .utils import * from django.utils import timezone from django.contrib.auth.mixins import UserPassesTestMixin from django.http import HttpResponseForbidden # Keep your custom decorator def superuser_required(view_func): def wrapper(request, *args, **kwargs): if not request.user.is_authenticated: return redirect('login') if not request.user.is_superuser: return HttpResponseForbidden() return view_func(request, *args, **kwargs) return wrapper class SuperuserRequiredMixin(UserPassesTestMixin): def test_func(self): return self.request.user.is_superuser User = get_user_model() @superuser_required def admin_dashboard(request): return render(request, "admin_dashboard.html") class ContactListView(SuperuserRequiredMixin ,ListView): model = FeedbackModel template_name = 'contact_list.html' context_object_name = 'contacts' paginate_by = 50 def get_queryset(self): queryset = FeedbackModel.objects.all().order_by("-created_at") search = self.request.GET.get("search") status = self.request.GET.get("status") # NEW if search: queryset = queryset.filter( Q(name__icontains=search) | Q(email__icontains=search) | Q(message__icontains=search) ) # ================= JUNK FILTER ================= if status == "junk": queryset = queryset.filter(is_junk=True) elif status == "inbox": queryset = queryset.filter(is_junk=False) return queryset @superuser_required def set_message_to_junk(request, pk): # Change parameter from 'uuid' to 'pk' contact = get_object_or_404(FeedbackModel, pk=pk) # Use 'id=pk' instead of 'uuid=uuid' contact.is_junk = True contact.save(update_fields=["is_junk"]) messages.success(request, "Message marked as junk.") return redirect(request.META.get("HTTP_REFERER", "contact_list")) # Better fallback @superuser_required # Show all subscribers def subscriber_list(request): subscribers = Subscriber.objects.all().order_by("-subscribed_at") return render(request, "subscriber.html", {"subscribers": subscribers}) @superuser_required def toggle_subscriber(request, pk): # Changed from pk to uuid subscriber = get_object_or_404(Subscriber, pk=pk) # Assuming Subscriber also uses UUID as PK subscriber.is_active = not subscriber.is_active subscriber.save() return redirect("subscriber_list") class SEOConfigView(View): template_name = "seo_config.html" def get(self, request): seo_config = SEOConfiguration.objects.first() if not seo_config: seo_config = SEOConfiguration.objects.create() # ensure one record exists form = SEOConfigurationForm(instance=seo_config) return render(request, self.template_name, {"form": form}) def post(self, request): seo_config = SEOConfiguration.objects.first() form = SEOConfigurationForm(request.POST, instance=seo_config) if form.is_valid(): form.save() messages.success(request, "SEO configuration updated successfully.") return redirect("seo_config") return render(request, self.template_name, {"form": form}) @superuser_required def appointment_list(request): if request.method == "POST": appointment_id = request.POST.get("appointment_id") action = request.POST.get("action") appointment = get_object_or_404(AppointmentModel, id=appointment_id) if action == "update_status": new_status = request.POST.get("status") if new_status in dict(AppointmentModel.STATUS_CHOICES): appointment.status = new_status appointment.save() messages.success(request, f"Status updated to '{appointment.get_status_display()}' for {appointment.full_name}") elif action == "reschedule": date_str = request.POST.get("new_date") time_str = request.POST.get("new_time") if date_str and time_str: try: new_datetime_str = f"{date_str} {time_str}" new_datetime = timezone.datetime.strptime(new_datetime_str, "%Y-%m-%d %H:%M") new_datetime = timezone.make_aware(new_datetime) if new_datetime > timezone.now(): appointment.appointment_datetime = new_datetime appointment.status = 'rescheduled' appointment.save() messages.success(request, f"Appointment rescheduled to {new_datetime.strftime('%d %B %Y, %I:%M %p')}") else: messages.error(request, "New time must be in the future.") except ValueError: messages.error(request, "Invalid date/time format.") else: messages.error(request, "Please select both date and time.") return redirect('appointment_list') appointments = AppointmentModel.objects.all().order_by('-appointment_datetime') status_choices = AppointmentModel.STATUS_CHOICES return render(request, "appointment_list.html", { "appointments": appointments, "status_choices": status_choices, })