adds search api

This commit is contained in:
Christian Beutel
2024-03-10 00:52:45 +01:00
parent 963b589b2d
commit 01e1053569
25 changed files with 271 additions and 87 deletions

View File

@@ -3,12 +3,12 @@
import Toast from "$lib/components/base/toast.svelte";
import Footer from "$lib/components/footer.svelte";
import NavBar from "$lib/components/nav_bar.svelte";
import { currentUser } from "$lib/stores/user_store";
import { isRouteProtected } from "$lib/util/authorization_util";
import "@fortawesome/fontawesome-free/css/all.min.css";
import "../css/app.css";
import "../css/components.css";
import "../css/theme.css";
import { currentUser } from "$lib/stores/user_store";
beforeNavigate((n) => {
if (!$currentUser && isRouteProtected(n.to?.url?.pathname ?? "")) {

View File

@@ -36,20 +36,26 @@
const response = await r.json();
const trailItems = response.results[0].hits.map((t: Record<string, any>) => ({
text: t.name,
description: `Trail | ${t.location}`,
value: t.id,
icon: "route",
}));
const cityItems = response.results[1].hits.map((c: Record<string, any>) => ({
text: c.name,
description: `City | ${
country_codes[c["country code"] as keyof typeof country_codes]
}`,
value: c,
icon: "city",
}));
const trailItems = response.results[0].hits.map(
(t: Record<string, any>) => ({
text: t.name,
description: `Trail | ${t.location}`,
value: t.id,
icon: "route",
}),
);
const cityItems = response.results[1].hits.map(
(c: Record<string, any>) => ({
text: c.name,
description: `City | ${
country_codes[
c["country code"] as keyof typeof country_codes
]
}`,
value: c,
icon: "city",
}),
);
searchDropdownItems = [...trailItems, ...cityItems];
}
@@ -102,15 +108,15 @@
id="trails"
class="flex flex-wrap justify-items-center gap-8 py-8 order-1 md:order-none"
>
{#each $trails.splice(0, 5) as trail}
<a href="/trail/view/{trail.id}">
<TrailCard {trail}></TrailCard></a
{#each { length: Math.min($trails.length, 4) } as _, i}
<a href="/trail/view/{$trails[i].id}">
<TrailCard trail={$trails[i]}></TrailCard></a
>
{/each}
</div>
<div class="max-w-md md:mx-auto space-y-8">
<h2 class="text-4xl md:text-5xl font-bold">
{$currentUser ? "Trails for you" : "Explore some trails"}
{$currentUser ? $_("trails-for-you") : $_("explore-some-trails")}
</h2>
<h5>
{$_("hero_section_1_text")}
@@ -118,6 +124,7 @@
<a
class="inline-block btn-primary btn-large"
href="/trails"
data-sveltekit-preload-data="off"
role="button">{$_("explore")}</a
>
</div>

View File

@@ -4,5 +4,5 @@ import type { ServerLoad } from "@sveltejs/kit";
export const load: ServerLoad = async ({ params, locals, fetch }) => {
await trails_index({perPage: 20, random: true, f: fetch})
await categories_index()
await categories_index(fetch)
};

View File

@@ -0,0 +1,13 @@
import type { Category } from "$lib/models/category";
import { pb } from "$lib/pocketbase";
import { error, json, type RequestEvent } from "@sveltejs/kit";
export async function GET(event: RequestEvent) {
try {
const r: Category[] = await pb.collection('categories').getFullList<Category>()
return json(r)
} catch (e: any) {
throw error(e.status, e);
}
}

View File

@@ -0,0 +1,23 @@
import { pb } from "$lib/pocketbase";
import { error, text, type RequestEvent } from "@sveltejs/kit";
export async function GET(event: RequestEvent) {
const parts = [];
parts.push("api");
parts.push("files");
parts.push(encodeURIComponent(event.params.collection as string));
parts.push(encodeURIComponent(event.params.record as string));
parts.push(encodeURIComponent(event.params.file as string));
let fileURL = pb.buildUrl(parts.join("/"));
try {
const r = await event.fetch(fileURL)
return new Response(r.body, {headers: r.headers});
} catch (e: any) {
console.log(e);
throw error(500, e);
}
}

View File

@@ -8,6 +8,8 @@ export async function POST(event: RequestEvent) {
const r = await ms.index(event.params.index as string).search(data.q, data.options);
return json(r);
} catch (e: any) {
throw error(e.status, e)
console.log(e);
throw error(e.httpStatus, e)
}
}

View File

@@ -10,6 +10,6 @@ export async function POST(event: RequestEvent) {
});
return json(r);
} catch (e: any) {
throw error(e.status, e)
throw error(e.httpStatus, e)
}
}

View File

@@ -2,16 +2,6 @@ import { pb } from '$lib/pocketbase';
import type { User } from '$lib/stores/user_store';
import { error, json, type RequestEvent } from '@sveltejs/kit'
export async function POST(event: RequestEvent) {
const data = await event.request.json()
try {
const r = await pb.collection('lists').update<User>(data.id, data.user)
return json(r);
} catch (e: any) {
throw error(e.status, e)
}
}
export async function PUT(event: RequestEvent) {
const data = await event.request.json()
try {
@@ -22,12 +12,3 @@ export async function PUT(event: RequestEvent) {
}
}
export async function DELETE(event: RequestEvent) {
const data = await event.request.json()
try {
const r = await pb.collection('users').delete(data.id)
return json(r);
} catch (e: any) {
throw error(e.status, e)
}
}

View File

@@ -0,0 +1,22 @@
import { pb } from '$lib/pocketbase';
import type { User } from '$lib/stores/user_store';
import { error, json, type RequestEvent } from '@sveltejs/kit'
export async function POST(event: RequestEvent) {
const data = await event.request.json()
try {
const r = await pb.collection('users').update<User>(event.params.id as string, data)
return json(r);
} catch (e: any) {
throw error(e.status, e)
}
}
export async function DELETE(event: RequestEvent) {
try {
const r = await pb.collection('users').delete(event.params.id as string)
return json(r);
} catch (e: any) {
throw error(e.status, e)
}
}

View File

@@ -85,7 +85,7 @@
<h5 class="text-xl font-semibold">{$_("create-new-list")}</h5>
</button>
<hr class="border-separator my-2" />
<div class="max-h-[512px] md:max-h-none overflow-y-auto">
<div>
{#each $lists as item, i}
<li on:click={() => list.set(item)} role="presentation">
<ListCard

View File

@@ -2,8 +2,8 @@ import { categories_index } from "$lib/stores/category_store";
import { trails } from "$lib/stores/trail_store";
import type { ServerLoad } from "@sveltejs/kit";
export const load: ServerLoad = async ({ params, locals }) => {
await categories_index()
export const load: ServerLoad = async ({ params, locals, fetch }) => {
await categories_index(fetch)
trails.set([])
};

View File

@@ -75,7 +75,7 @@
<svelte:head>
<title>{$trail.name} | {$_("map")} | wanderer</title>
</svelte:head>
<main class="grid grid-cols-1 md:grid-cols-[452px_1fr] gap-x-1 gap-y-4">
<main class="grid grid-cols-1 md:grid-cols-[458px_1fr] gap-x-1 gap-y-4">
<div
id="trail-details"
class="md:overflow-y-auto md:overflow-x-hidden flex flex-col items-stretch gap-4 rounded-xl"

View File

@@ -7,7 +7,7 @@ export const load: Load = async ({ params, fetch }) => {
if (!params.id) {
return error(400, "Bad Request")
}
const categories = await categories_index()
const categories = await categories_index(fetch)
let trail: Trail;
if (params.id === "new") {

View File

@@ -4,13 +4,17 @@
import TrailList from "$lib/components/trail/trail_list.svelte";
import type { TrailFilter } from "$lib/models/trail";
import { categories } from "$lib/stores/category_store";
import { trails, trails_search_filter } from "$lib/stores/trail_store";
import {
trails,
trails_search_filter,
} from "$lib/stores/trail_store";
import { onMount } from "svelte";
import { _ } from "svelte-i18n";
let filterExpanded: boolean = true;
const filter: TrailFilter = $page.data.filter;
const pagination: {page: number, totalPages: number} = $page.data.pagination
onMount(() => {
if (window.innerWidth < 768) {
@@ -19,7 +23,14 @@
});
async function handleFilterUpdate() {
await trails_search_filter(filter);
const response= await trails_search_filter(filter, 1);
pagination.page = response.page
pagination.totalPages = response.totalPages;
}
async function paginate(page: number) {
pagination.page = page;
const response = await trails_search_filter(filter, page);
}
</script>
@@ -39,6 +50,8 @@
<TrailList
{filter}
trails={$trails}
on:update={async () => await trails_search_filter(filter)}
pagination={pagination}
on:update={() => handleFilterUpdate()}
on:pagination={(e) => paginate(e.detail)}
></TrailList>
</main>

View File

@@ -21,8 +21,10 @@ export const load: ServerLoad = async ({ params, locals, url, fetch }) => {
if (paramCategory) {
filter.category.push(paramCategory);
}
await trails_search_filter(filter, fetch);
await categories_index()
const response = await trails_search_filter(filter, 1, fetch);
await categories_index(fetch)
return {filter};
return {
filter: filter, pagination: { page: response.page, totalPages: response.totalPages }
};
};