diff --git a/moderation/mixins.py b/moderation/mixins.py index 28008ff5..9dc8ecf1 100644 --- a/moderation/mixins.py +++ b/moderation/mixins.py @@ -6,7 +6,7 @@ from django.utils import timezone import json from .models import EditSubmission, PhotoSubmission -class EditSubmissionMixin(LoginRequiredMixin): +class EditSubmissionMixin: """ Mixin for handling edit submissions with proper moderation. """ @@ -67,6 +67,12 @@ class EditSubmissionMixin(LoginRequiredMixin): def post(self, request, *args, **kwargs): """Handle POST requests for editing""" + if not request.user.is_authenticated: + return JsonResponse({ + 'status': 'error', + 'message': 'You must be logged in to make edits.' + }, status=403) + try: data = json.loads(request.body) changes = data.get('changes', {}) @@ -101,12 +107,18 @@ class EditSubmissionMixin(LoginRequiredMixin): 'message': str(e) }, status=500) -class PhotoSubmissionMixin(LoginRequiredMixin): +class PhotoSubmissionMixin: """ Mixin for handling photo submissions with proper moderation. """ def handle_photo_submission(self, request): """Handle a photo submission based on user's role""" + if not request.user.is_authenticated: + return JsonResponse({ + 'status': 'error', + 'message': 'You must be logged in to upload photos.' + }, status=403) + if not request.FILES.get('photo'): return JsonResponse({ 'status': 'error', diff --git a/parks/__pycache__/urls.cpython-312.pyc b/parks/__pycache__/urls.cpython-312.pyc index 47b164f7..f9125555 100644 Binary files a/parks/__pycache__/urls.cpython-312.pyc and b/parks/__pycache__/urls.cpython-312.pyc differ diff --git a/parks/__pycache__/views.cpython-312.pyc b/parks/__pycache__/views.cpython-312.pyc index a665879b..12a837fb 100644 Binary files a/parks/__pycache__/views.cpython-312.pyc and b/parks/__pycache__/views.cpython-312.pyc differ diff --git a/parks/urls.py b/parks/urls.py index 62bbe7b9..89ff7afc 100644 --- a/parks/urls.py +++ b/parks/urls.py @@ -1,6 +1,5 @@ from django.urls import path from . import views -from rides.views import RideDetailView app_name = 'parks' @@ -8,5 +7,4 @@ urlpatterns = [ path('', views.ParkListView.as_view(), name='park_list'), path('create/', views.ParkCreateView.as_view(), name='park_create'), path('/', views.ParkDetailView.as_view(), name='park_detail'), - path('//', RideDetailView.as_view(), name='ride_detail'), ] diff --git a/parks/views.py b/parks/views.py index 15165f54..2dbcf5ce 100644 --- a/parks/views.py +++ b/parks/views.py @@ -37,10 +37,10 @@ class ParkCreateView(LoginRequiredMixin, CreateView): reason=self.request.POST.get('reason', ''), source=self.request.POST.get('source', '') ) - return HttpResponseRedirect(reverse('parks:park_list')) + return HttpResponseRedirect(reverse('park_list')) def get_success_url(self): - return reverse('parks:park_detail', kwargs={'slug': self.object.slug}) + return reverse('park_detail', kwargs={'slug': self.object.slug}) class ParkDetailView(SlugRedirectMixin, EditSubmissionMixin, PhotoSubmissionMixin, InlineEditMixin, HistoryMixin, DetailView): model = Park @@ -63,7 +63,7 @@ class ParkDetailView(SlugRedirectMixin, EditSubmissionMixin, PhotoSubmissionMixi return context def get_redirect_url_pattern(self): - return 'parks:park_detail' + return 'park_detail' class ParkAreaDetailView(SlugRedirectMixin, EditSubmissionMixin, PhotoSubmissionMixin, InlineEditMixin, HistoryMixin, DetailView): model = ParkArea @@ -90,7 +90,7 @@ class ParkAreaDetailView(SlugRedirectMixin, EditSubmissionMixin, PhotoSubmission return context def get_redirect_url_pattern(self): - return 'parks:area_detail' + return 'park_detail' def get_redirect_url_kwargs(self): return { diff --git a/rides/__pycache__/urls.cpython-312.pyc b/rides/__pycache__/urls.cpython-312.pyc index e77dfb0c..e5ed3298 100644 Binary files a/rides/__pycache__/urls.cpython-312.pyc and b/rides/__pycache__/urls.cpython-312.pyc differ diff --git a/rides/__pycache__/views.cpython-312.pyc b/rides/__pycache__/views.cpython-312.pyc index 8205004c..e15de14f 100644 Binary files a/rides/__pycache__/views.cpython-312.pyc and b/rides/__pycache__/views.cpython-312.pyc differ diff --git a/rides/urls.py b/rides/urls.py index 0f21d5e2..e7a90588 100644 --- a/rides/urls.py +++ b/rides/urls.py @@ -6,5 +6,4 @@ app_name = 'rides' urlpatterns = [ path('', views.RideListView.as_view(), name='ride_list'), path('create/', views.RideCreateView.as_view(), name='ride_create'), - path('//', views.RideDetailView.as_view(), name='ride_detail'), ] diff --git a/rides/views.py b/rides/views.py index c8ca8366..be3e22a5 100644 --- a/rides/views.py +++ b/rides/views.py @@ -43,10 +43,10 @@ class RideCreateView(LoginRequiredMixin, CreateView): reason=self.request.POST.get('reason', ''), source=self.request.POST.get('source', '') ) - return HttpResponseRedirect(reverse('rides:ride_list')) + return HttpResponseRedirect(reverse('ride_list')) def get_success_url(self): - return reverse('rides:ride_detail', kwargs={ + return reverse('ride_detail', kwargs={ 'park_slug': self.object.park.slug, 'ride_slug': self.object.slug }) @@ -75,7 +75,7 @@ class RideDetailView(SlugRedirectMixin, EditSubmissionMixin, PhotoSubmissionMixi return context def get_redirect_url_pattern(self): - return 'rides:ride_detail' + return 'ride_detail' def get_redirect_url_kwargs(self): return { diff --git a/static/css/tailwind.css b/static/css/tailwind.css index c92493cb..790cbd27 100644 --- a/static/css/tailwind.css +++ b/static/css/tailwind.css @@ -2943,14 +2943,14 @@ select { --tw-gradient-stops: var(--tw-gradient-from), #eff6ff var(--tw-gradient-via-position), var(--tw-gradient-to); } -.to-secondary { - --tw-gradient-to: #e11d48 var(--tw-gradient-to-position); -} - .to-indigo-50 { --tw-gradient-to: #eef2ff var(--tw-gradient-to-position); } +.to-secondary { + --tw-gradient-to: #e11d48 var(--tw-gradient-to-position); +} + .bg-clip-text { -webkit-background-clip: text; background-clip: text; diff --git a/templates/accounts/turnstile_widget.html b/templates/accounts/turnstile_widget.html index 28be5ce4..4723c9f6 100644 --- a/templates/accounts/turnstile_widget.html +++ b/templates/accounts/turnstile_widget.html @@ -8,17 +8,15 @@ id="turnstile-widget" class="cf-turnstile" data-sitekey="{{ site_key }}" - data-theme="dark" > diff --git a/templates/base/base.html b/templates/base/base.html index 681b94a8..b3de5d28 100644 --- a/templates/base/base.html +++ b/templates/base/base.html @@ -4,7 +4,7 @@ - + {% block title %}ThrillWiki{% endblock %} @@ -101,78 +101,74 @@ - {% if user.is_authenticated %} - {% if has_moderation_access %} - - - Moderation - - {% endif %} -
- - - + {% if user.is_authenticated %} {% if has_moderation_access %} + + + Moderation + + {% endif %} +
+ - + {{ user.username.0|upper }}
+ {% endif %} + {{ user.username }} + + + +
+ + + Profile + + + + Settings + + {% if has_admin_access %} + + + Admin + + {% endif %} +
+ {% csrf_token %} + +
+
{% else %} - - + + {% endif %} diff --git a/templates/home.html b/templates/home.html index 7f80deed..08b3ae78 100644 --- a/templates/home.html +++ b/templates/home.html @@ -5,21 +5,21 @@ {% block content %} -
-
-

+
+
+

Welcome to ThrillWiki

-

+

Your ultimate guide to theme parks and attractions worldwide

@@ -27,10 +27,10 @@
-
+
-
-
+
+
{{ stats.total_parks }}
@@ -39,8 +39,8 @@
-
-
+
+
{{ stats.total_rides }}
@@ -49,8 +49,8 @@
-
-
+
+
{{ stats.total_roller_coasters }}
@@ -60,15 +60,15 @@
-
+
- diff --git a/templates/parks/park_list.html b/templates/parks/park_list.html index 489ffc84..4bb3fcf9 100644 --- a/templates/parks/park_list.html +++ b/templates/parks/park_list.html @@ -8,7 +8,7 @@

Parks

{% if user.is_authenticated %} - + Add Park {% endif %} @@ -70,7 +70,7 @@ {% endif %}

- {{ park.name }} diff --git a/templates/rides/ride_detail.html b/templates/rides/ride_detail.html index c17e758b..c48d808c 100644 --- a/templates/rides/ride_detail.html +++ b/templates/rides/ride_detail.html @@ -275,6 +275,22 @@ {% endfor %}

+ + + {% if ride.photos.exists %} +
+

Photos

+
+ {% for photo in ride.photos.all %} +
+ {{ photo.caption|default:ride.name }} +
+ {% endfor %} +
+
+ {% endif %}
diff --git a/templates/rides/ride_list.html b/templates/rides/ride_list.html index 648b5e6e..80725383 100644 --- a/templates/rides/ride_list.html +++ b/templates/rides/ride_list.html @@ -83,7 +83,7 @@

- + {{ ride.get_category_display }} +
-

Search Results

+

Search Results

{% if request.GET.q %} Results for "{{ request.GET.q }}" @@ -19,36 +19,36 @@ {% if request.GET.q %} -

-

Theme Parks

-
+
+

Theme Parks

+
{% for park in parks %} -
+
{% if park.photos.exists %} {{ park.name }} + class="object-cover w-full h-48"> {% else %} -
+
No image available
{% endif %}
-

+

+ class="text-blue-600 hover:underline dark:text-blue-400"> {{ park.name }}

-

{{ park.location }}

-
+

{{ park.location }}

+
{{ park.rides.count }} attractions {% if park.average_rating %}
- + {{ park.average_rating|floatformat:1 }}/10
{% endif %} @@ -56,7 +56,7 @@
{% empty %} -
+

No parks found matching your search.

{% endfor %} @@ -64,39 +64,39 @@
-
-

Rides & Attractions

-
+
+

Rides & Attractions

+
{% for ride in rides %} -
+
{% if ride.photos.exists %} {{ ride.name }} + class="object-cover w-full h-48"> {% else %} -
+
No image available
{% endif %}
-

+

+ class="text-blue-600 hover:underline dark:text-blue-400"> {{ ride.name }}

-

+

at {{ ride.park.name }}

- + {{ ride.get_category_display }} {% if ride.average_rating %}
- + {{ ride.average_rating|floatformat:1 }}/10
{% endif %} @@ -104,7 +104,7 @@
{% empty %} -
+

No rides found matching your search.

{% endfor %} @@ -112,26 +112,26 @@
-
-

Companies

-
+
+

Companies

+
{% for company in companies %} -
-

+
+

+ class="text-blue-600 hover:underline dark:text-blue-400"> {{ company.name }}

{% if company.headquarters %} -

{{ company.headquarters }}

+

{{ company.headquarters }}

{% endif %}
{{ company.parks.count }} parks owned
{% empty %} -
+

No companies found matching your search.

{% endfor %} diff --git a/thrillwiki/__pycache__/urls.cpython-312.pyc b/thrillwiki/__pycache__/urls.cpython-312.pyc index 46791067..d50711a0 100644 Binary files a/thrillwiki/__pycache__/urls.cpython-312.pyc and b/thrillwiki/__pycache__/urls.cpython-312.pyc differ diff --git a/thrillwiki/urls.py b/thrillwiki/urls.py index a3cd2916..94870535 100644 --- a/thrillwiki/urls.py +++ b/thrillwiki/urls.py @@ -11,8 +11,12 @@ urlpatterns = [ # Main app URLs path('', HomeView.as_view(), name='home'), - path('parks/', include('parks.urls')), - path('rides/', include('rides.urls')), + + # Parks URLs + path('parks/', include('parks.urls', namespace='parks')), + path('rides/', include('rides.urls', namespace='rides')), + + # Other URLs path('reviews/', include('reviews.urls')), path('companies/', include('companies.urls')), path('search/', SearchView.as_view(), name='search'), @@ -28,8 +32,7 @@ urlpatterns = [ path('accounts/email-required/', accounts_views.email_required, name='email_required'), # User profile URLs - path('users//', accounts_views.ProfileView.as_view(), name='user_profile'), - path('user//', accounts_views.ProfileView.as_view(), name='single_user_profile'), + path('user//', accounts_views.ProfileView.as_view(), name='user_profile'), path('profile//', accounts_views.ProfileView.as_view(), name='profile'), path('settings/', accounts_views.SettingsView.as_view(), name='settings'),