156 lines
5.8 KiB
Python
Executable File
156 lines
5.8 KiB
Python
Executable File
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,
|
|
}) |