1
0
Fork 0
mirror of https://github.com/seanmorley15/AdventureLog.git synced 2025-07-19 12:59:36 +02:00

Add is_visited filtering to AdventureViewSet and update frontend components

This commit is contained in:
Sean Morley 2024-10-31 09:59:56 -04:00
parent 727daf0cfd
commit 25ed72afbc
4 changed files with 81 additions and 20 deletions

View file

@ -105,7 +105,9 @@ class AdventureViewSet(viewsets.ModelViewSet):
@action(detail=False, methods=['get']) @action(detail=False, methods=['get'])
def filtered(self, request): def filtered(self, request):
types = request.query_params.get('types', '').split(',') 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: if 'all' in types:
types = [t[0] for t in ADVENTURE_TYPES] types = [t[0] for t in ADVENTURE_TYPES]
valid_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: if not types:
return Response({"error": "No valid types provided"}, status=400) 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: # Handle is_visited filtering
if adventure_type in valid_types: if is_visited.lower() == 'true':
queryset |= Adventure.objects.filter( serializer = self.get_serializer(queryset, many=True)
type=adventure_type, user_id=request.user.id) 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) queryset = self.apply_sorting(queryset)
# Paginate and respond
adventures = self.paginate_and_respond(queryset, request) adventures = self.paginate_and_respond(queryset, request)
return adventures return adventures
@action(detail=False, methods=['get']) @action(detail=False, methods=['get'])
def all(self, request): def all(self, request):
if not request.user.is_authenticated: if not request.user.is_authenticated:

View file

@ -151,6 +151,7 @@
"visited": "Visited", "visited": "Visited",
"planned": "Planned", "planned": "Planned",
"duration": "Duration", "duration": "Duration",
"all": "All",
"image_removed_success": "Image removed successfully!", "image_removed_success": "Image removed successfully!",
"image_removed_error": "Error removing image", "image_removed_error": "Error removing image",
"no_image_url": "No image found at that URL.", "no_image_url": "No image found at that URL.",

View file

@ -27,9 +27,10 @@ export const load = (async (event) => {
const order_by = event.url.searchParams.get('order_by') || 'updated_at'; const order_by = event.url.searchParams.get('order_by') || 'updated_at';
const order_direction = event.url.searchParams.get('order_direction') || 'asc'; const order_direction = event.url.searchParams.get('order_direction') || 'asc';
const page = event.url.searchParams.get('page') || '1'; const page = event.url.searchParams.get('page') || '1';
const is_visited = event.url.searchParams.get('is_visited') || 'all';
let initialFetch = await fetch( 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: { headers: {
Cookie: `${event.cookies.get('auth')}` Cookie: `${event.cookies.get('auth')}`

View file

@ -21,7 +21,8 @@
order: '', order: '',
visited: true, visited: true,
planned: true, planned: true,
includeCollections: true includeCollections: true,
is_visited: 'all'
}; };
let resultsPerPage: number = 25; let resultsPerPage: number = 25;
@ -120,6 +121,10 @@
currentSort.visited = true; currentSort.visited = true;
currentSort.planned = true; currentSort.planned = true;
} }
if (url.searchParams.get('is_visited')) {
currentSort.is_visited = url.searchParams.get('is_visited') || 'all';
}
} }
let adventureToEdit: Adventure | null = null; let adventureToEdit: Adventure | null = null;
@ -314,19 +319,53 @@
/> />
</div> </div>
<br /> <!-- is visited true false or all -->
<p class="text-lg font-semibold mt-2 mb-2">{$t('adventures.sources')}</p> <p class="text-lg font-semibold mt-2 mb-2">{$t('adventures.visited')}</p>
<label class="label cursor-pointer"> <div class="join">
<span class="label-text">{$t('adventures.collection_adventures')}</span>
<input <input
type="checkbox" class="join-item btn btn-neutral"
name="include_collections" type="radio"
id="include_collections" name="is_visited"
class="checkbox checkbox-primary" id="all"
checked={currentSort.includeCollections} value="all"
aria-label={$t('adventures.all')}
checked={currentSort.is_visited === 'all'}
/> />
</label> <input
<button type="submit" class="btn btn-success mt-4">{$t('adventures.filter')}</button> class="join-item btn btn-neutral"
type="radio"
name="is_visited"
id="true"
value="true"
aria-label={$t('adventures.visited')}
checked={currentSort.is_visited === 'true'}
/>
<input
class="join-item btn btn-neutral"
type="radio"
name="is_visited"
id="false"
value="false"
aria-label={$t('adventures.not_visited')}
checked={currentSort.is_visited === 'false'}
/>
</div>
<div class="divider"></div>
<div class="form-control">
<br />
<p class="text-lg font-semibold mt-2 mb-2">{$t('adventures.sources')}</p>
<label class="label cursor-pointer">
<span class="label-text">{$t('adventures.collection_adventures')}</span>
<input
type="checkbox"
name="include_collections"
id="include_collections"
class="checkbox checkbox-primary"
checked={currentSort.includeCollections}
/>
</label>
<button type="submit" class="btn btn-success mt-4">{$t('adventures.filter')}</button>
</div>
</form> </form>
</div> </div>
</ul> </ul>