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

refactor: Add property filter to adventure search functionality

This commit is contained in:
Sean Morley 2024-08-01 10:02:00 -04:00
parent 0685065bf6
commit b380b55942
3 changed files with 124 additions and 18 deletions

View file

@ -151,12 +151,46 @@ class AdventureViewSet(viewsets.ModelViewSet):
@action(detail=False, methods=['get']) @action(detail=False, methods=['get'])
def search(self, request): def search(self, request):
query = self.request.query_params.get('query', '') query = self.request.query_params.get('query', '')
property = self.request.query_params.get('property', 'all')
if len(query) < 2: if len(query) < 2:
return Response({"error": "Query must be at least 2 characters long"}, status=400) return Response({"error": "Query must be at least 2 characters long"}, status=400)
queryset = Adventure.objects.filter(
(Q(name__icontains=query) | Q(description__icontains=query) | Q(location__icontains=query) | Q(activity_types__icontains=query)) & if property not in ['name', 'type', 'location', 'description', 'activity_types']:
(Q(user_id=request.user.id) | Q(is_public=True)) property = 'all'
)
queryset = Adventure.objects.none()
if property == 'name':
queryset = Adventure.objects.filter(
(Q(name__icontains=query)) &
(Q(user_id=request.user.id) | Q(is_public=True))
)
elif property == 'type':
queryset = Adventure.objects.filter(
(Q(type__icontains=query)) &
(Q(user_id=request.user.id) | Q(is_public=True))
)
elif property == 'location':
queryset = Adventure.objects.filter(
(Q(location__icontains=query)) &
(Q(user_id=request.user.id) | Q(is_public=True))
)
elif property == 'description':
queryset = Adventure.objects.filter(
(Q(description__icontains=query)) &
(Q(user_id=request.user.id) | Q(is_public=True))
)
elif property == 'activity_types':
queryset = Adventure.objects.filter(
(Q(activity_types__icontains=query)) &
(Q(user_id=request.user.id) | Q(is_public=True))
)
else:
queryset = Adventure.objects.filter(
(Q(name__icontains=query) | Q(description__icontains=query) | Q(location__icontains=query) | Q(activity_types__icontains=query)) &
(Q(user_id=request.user.id) | Q(is_public=True))
)
queryset = self.apply_sorting(queryset) queryset = self.apply_sorting(queryset)
serializer = self.get_serializer(queryset, many=True) serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data) return Response(serializer.data)

View file

@ -7,17 +7,21 @@ const serverEndpoint = PUBLIC_SERVER_URL || 'http://localhost:8000';
export const load = (async (event) => { export const load = (async (event) => {
// get url param query // get url param query
const query = event.url.searchParams.get('query'); const query = event.url.searchParams.get('query');
const property = event.url.searchParams.get('property') || 'all';
if (!query) { if (!query) {
return { data: [] }; return { data: [] };
} }
let res = await fetch(`${serverEndpoint}/api/adventures/search/?query=${query}`, { let res = await fetch(
headers: { `${serverEndpoint}/api/adventures/search/?query=${query}&property=${property}`,
'Content-Type': 'application/json', {
Cookie: `${event.cookies.get('auth')}` headers: {
'Content-Type': 'application/json',
Cookie: `${event.cookies.get('auth')}`
}
} }
}); );
if (res.ok) { if (res.ok) {
let data = await res.json(); let data = await res.json();

View file

@ -6,6 +6,7 @@
import type { PageData } from './$types'; import type { PageData } from './$types';
import EditAdventure from '$lib/components/EditAdventure.svelte'; import EditAdventure from '$lib/components/EditAdventure.svelte';
import { appVersion } from '$lib/config'; import { appVersion } from '$lib/config';
import { goto, invalidate } from '$app/navigation';
export let data: PageData; export let data: PageData;
@ -18,6 +19,15 @@
let publicAdventures: Adventure[] = []; let publicAdventures: Adventure[] = [];
let query: string | null = ''; let query: string | null = '';
let property: string = 'all';
// on chage of property, console log the property
function filterByProperty() {
let url = new URL(window.location.href);
url.searchParams.set('property', property);
goto(url.toString(), { invalidateAll: true });
}
onMount(() => { onMount(() => {
const urlParams = new URLSearchParams(window.location.search); const urlParams = new URLSearchParams(window.location.search);
@ -47,18 +57,23 @@
}); });
console.log(data); console.log(data);
$: {
if (data.props) {
myAdventures = data.props.adventures;
publicAdventures = data.props.adventures;
if (data.props) { if (data.user?.pk != null) {
myAdventures = data.props.adventures; myAdventures = myAdventures.filter(
publicAdventures = data.props.adventures; (adventure) => adventure.user_id === data.user?.pk ?? -1
);
} else {
myAdventures = [];
}
if (data.user?.pk != null) { publicAdventures = publicAdventures.filter(
myAdventures = myAdventures.filter((adventure) => adventure.user_id === data.user?.pk ?? -1); (adventure) => adventure.user_id !== data.user?.pk
} else { );
myAdventures = [];
} }
publicAdventures = publicAdventures.filter((adventure) => adventure.user_id !== data.user?.pk);
} }
let adventureToEdit: Adventure; let adventureToEdit: Adventure;
@ -97,6 +112,59 @@
<h2 class="text-center font-bold text-2xl mb-4">AdventureLog Results</h2> <h2 class="text-center font-bold text-2xl mb-4">AdventureLog Results</h2>
{/if} {/if}
<div class="join">
<input
class="join-item btn"
type="radio"
name="filter"
aria-label="All"
id="all"
checked
on:change={() => (property = 'all')}
/>
<input
class="join-item btn"
type="radio"
name="filter"
aria-label="Name"
id="name"
on:change={() => (property = 'name')}
/>
<input
class="join-item btn"
type="radio"
name="filter"
aria-label="Type"
id="type"
on:change={() => (property = 'type')}
/>
<input
class="join-item btn"
type="radio"
name="filter"
aria-label="Location"
id="location"
on:change={() => (property = 'location')}
/>
<input
class="join-item btn"
type="radio"
name="filter"
aria-label="Description"
id="description"
on:change={() => (property = 'description')}
/>
<input
class="join-item btn"
type="radio"
name="filter"
aria-label="Activity Types"
id="activity_types"
on:change={() => (property = 'activity_types')}
/>
</div>
<button class="btn btn-primary ml-2" type="button" on:click={filterByProperty}>Filter</button>
{#if myAdventures.length > 0} {#if myAdventures.length > 0}
<h2 class="text-center font-bold text-2xl mb-4">My Adventures</h2> <h2 class="text-center font-bold text-2xl mb-4">My Adventures</h2>
<div class="flex flex-wrap gap-4 mr-4 justify-center content-center"> <div class="flex flex-wrap gap-4 mr-4 justify-center content-center">