From 25ed72afbce06382d3991434d1d44754e065a815 Mon Sep 17 00:00:00 2001 From: Sean Morley Date: Thu, 31 Oct 2024 09:59:56 -0400 Subject: [PATCH] Add is_visited filtering to AdventureViewSet and update frontend components --- backend/server/adventures/views.py | 34 +++++++--- frontend/src/locales/en.json | 1 + .../src/routes/adventures/+page.server.ts | 3 +- frontend/src/routes/adventures/+page.svelte | 63 +++++++++++++++---- 4 files changed, 81 insertions(+), 20 deletions(-) diff --git a/backend/server/adventures/views.py b/backend/server/adventures/views.py index 2131dff..76a6a41 100644 --- a/backend/server/adventures/views.py +++ b/backend/server/adventures/views.py @@ -105,7 +105,9 @@ class AdventureViewSet(viewsets.ModelViewSet): @action(detail=False, methods=['get']) def filtered(self, request): types = request.query_params.get('types', '').split(',') - # handle case where types is all + is_visited = request.query_params.get('is_visited', 'all') + + # Handle case where types is all if 'all' in types: types = [t[0] for t in ADVENTURE_TYPES] valid_types = [t[0] for t in ADVENTURE_TYPES] @@ -114,17 +116,35 @@ class AdventureViewSet(viewsets.ModelViewSet): if not types: return Response({"error": "No valid types provided"}, status=400) - queryset = Adventure.objects.none() + queryset = Adventure.objects.filter( + type__in=types, + user_id=request.user.id + ) - for adventure_type in types: - if adventure_type in valid_types: - queryset |= Adventure.objects.filter( - type=adventure_type, user_id=request.user.id) + # Handle is_visited filtering + if is_visited.lower() == 'true': + serializer = self.get_serializer(queryset, many=True) + filtered_ids = [ + adventure.id for adventure, serialized_adventure in zip(queryset, serializer.data) + if serialized_adventure['is_visited'] + ] + queryset = queryset.filter(id__in=filtered_ids) + elif is_visited.lower() == 'false': + serializer = self.get_serializer(queryset, many=True) + filtered_ids = [ + adventure.id for adventure, serialized_adventure in zip(queryset, serializer.data) + if not serialized_adventure['is_visited'] + ] + queryset = queryset.filter(id__in=filtered_ids) + # If is_visited is 'all' or any other value, we don't apply additional filtering + # Apply sorting queryset = self.apply_sorting(queryset) + + # Paginate and respond adventures = self.paginate_and_respond(queryset, request) return adventures - + @action(detail=False, methods=['get']) def all(self, request): if not request.user.is_authenticated: diff --git a/frontend/src/locales/en.json b/frontend/src/locales/en.json index 657f8d6..4cc28c5 100644 --- a/frontend/src/locales/en.json +++ b/frontend/src/locales/en.json @@ -151,6 +151,7 @@ "visited": "Visited", "planned": "Planned", "duration": "Duration", + "all": "All", "image_removed_success": "Image removed successfully!", "image_removed_error": "Error removing image", "no_image_url": "No image found at that URL.", diff --git a/frontend/src/routes/adventures/+page.server.ts b/frontend/src/routes/adventures/+page.server.ts index 25be557..1223493 100644 --- a/frontend/src/routes/adventures/+page.server.ts +++ b/frontend/src/routes/adventures/+page.server.ts @@ -27,9 +27,10 @@ export const load = (async (event) => { const order_by = event.url.searchParams.get('order_by') || 'updated_at'; const order_direction = event.url.searchParams.get('order_direction') || 'asc'; const page = event.url.searchParams.get('page') || '1'; + const is_visited = event.url.searchParams.get('is_visited') || 'all'; let initialFetch = await fetch( - `${serverEndpoint}/api/adventures/filtered?types=${typeString}&order_by=${order_by}&order_direction=${order_direction}&include_collections=${include_collections}&page=${page}`, + `${serverEndpoint}/api/adventures/filtered?types=${typeString}&order_by=${order_by}&order_direction=${order_direction}&include_collections=${include_collections}&page=${page}&is_visited=${is_visited}`, { headers: { Cookie: `${event.cookies.get('auth')}` diff --git a/frontend/src/routes/adventures/+page.svelte b/frontend/src/routes/adventures/+page.svelte index ca0a457..b42d024 100644 --- a/frontend/src/routes/adventures/+page.svelte +++ b/frontend/src/routes/adventures/+page.svelte @@ -21,7 +21,8 @@ order: '', visited: true, planned: true, - includeCollections: true + includeCollections: true, + is_visited: 'all' }; let resultsPerPage: number = 25; @@ -120,6 +121,10 @@ currentSort.visited = true; currentSort.planned = true; } + + if (url.searchParams.get('is_visited')) { + currentSort.is_visited = url.searchParams.get('is_visited') || 'all'; + } } let adventureToEdit: Adventure | null = null; @@ -314,19 +319,53 @@ /> -
-

{$t('adventures.sources')}

-