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:
parent
727daf0cfd
commit
25ed72afbc
4 changed files with 81 additions and 20 deletions
|
@ -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:
|
||||||
|
|
|
@ -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.",
|
||||||
|
|
|
@ -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')}`
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue