adds svelte API

This commit is contained in:
Christian Beutel
2024-03-09 16:46:02 +01:00
parent 33c3b273ab
commit 1b493f576e
114 changed files with 1574 additions and 2528 deletions

View File

@@ -1,5 +1,6 @@
<script lang="ts">
import type { List } from "$lib/models/list";
import { getFileURL } from "$lib/util/file_util";
import Dropdown, { type DropdownItem } from "../base/dropdown.svelte";
import { _ } from "svelte-i18n";
export let list: List;
@@ -17,8 +18,8 @@
>
{#if list.avatar}
<img
class="w-16 md:w-24 aspect-square rounded-full"
src={list.avatar}
class="w-16 md:w-24 aspect-square rounded-full object-cover"
src={getFileURL(list, list.avatar)}
alt="avatar"
/>
{:else}

View File

@@ -10,6 +10,7 @@
import Modal from "../base/modal.svelte";
import TextField from "../base/text_field.svelte";
import Textarea from "../base/textarea.svelte";
import { getFileURL } from "$lib/util/file_util";
export let openModal: (() => void) | undefined = undefined;
export let closeModal: (() => void) | undefined = undefined;
@@ -21,12 +22,7 @@
initialValues: $list,
validationSchema: listSchema,
onSubmit: async (submittedList) => {
const htmlForm = document.getElementById(
"list-form",
) as HTMLFormElement;
const formData = new FormData(htmlForm);
dispatch("save", { list: submittedList, formData: formData });
dispatch("save", { list: submittedList, avatar: (document.getElementById("avatar") as HTMLInputElement).files![0] });
(document.getElementById("avatar") as HTMLInputElement).value = "";
closeModal!();
},
@@ -48,7 +44,7 @@
}
$: if (browser) {
form.set(util.cloneDeep($list));
previewURL = $list.avatar ?? "";
previewURL = getFileURL($list, $list.avatar) ?? "";
}
</script>
@@ -78,7 +74,7 @@
<div class="flex items-center gap-4">
{#if previewURL.length > 0}
<img
class="w-32 aspect-square rounded-full"
class="w-32 aspect-square rounded-full object-cover"
alt="avatar"
src={previewURL}
/>

View File

@@ -6,6 +6,7 @@
import { trail } from "$lib/stores/trail_store";
import { _ } from "svelte-i18n";
import Modal from "../base/modal.svelte";
import { getFileURL } from "$lib/util/file_util";
export let openModal: (() => void) | undefined = undefined;
export let closeModal: (() => void) | undefined = undefined;
@@ -42,7 +43,7 @@
{#if list.avatar}
<img
class="w-12 aspect-square rounded-full"
src={list.avatar}
src={getFileURL(list, list.avatar)}
alt="avatar"
/>
{:else}

View File

@@ -26,7 +26,7 @@
></i>
{/if}
<div
class="flex opacity-0 group-hover:opacity-100 absolute top-0 w-full h-full bg-white bg-opacity-75 items-center justify-center gap-6 transition-all"
class="flex opacity-0 group-hover:opacity-100 absolute top-0 w-full h-full bg-white/75 rounded-xl items-center justify-center gap-6 transition-all"
>
<button
type="button"

View File

@@ -1,10 +1,13 @@
<script lang="ts">
import type { Trail } from "$lib/models/trail";
import { getFileURL } from "$lib/util/file_util";
import { formatDistance, formatElevation, formatTimeHHMM } from "$lib/util/format_util";
import {
formatDistance,
formatElevation,
formatTimeHHMM,
} from "$lib/util/format_util";
export let trail: Trail;
</script>
<div
@@ -14,7 +17,7 @@
role="listitem"
>
<div class="w-full min-h-40 max-h-48 overflow-hidden rounded-t-2xl">
<img src={getFileURL(trail, trail.thumbnail)} alt="" />
<img src={getFileURL(trail, trail.photos[trail.thumbnail])} alt="" />
</div>
<div class="p-4">
<div>

View File

@@ -12,7 +12,7 @@
<div class="shrink-0">
<img
class="h-28 w-28 object-cover rounded-xl"
src={getFileURL(trail, trail.thumbnail)}
src={getFileURL(trail, trail.photos[trail.thumbnail])}
alt=""
/>
</div>

View File

@@ -13,10 +13,13 @@ class Trail {
duration?: number;
lat?: number;
lon?: number;
thumbnail?: string;
thumbnail: number;
photos: string[];
gpx?: string;
created?: string;
category?: string;
waypoints: string[];
summit_logs: string[];
expand: {
category?: Category;
waypoints: Waypoint[]
@@ -27,8 +30,6 @@ class Trail {
description?: string;
author?: string;
_photoFiles: File[]
constructor(name: string,
params?: {
id?: string,
@@ -39,7 +40,7 @@ class Trail {
duration?: number,
lat?:number,
lon?: number,
thumbnail?: string,
thumbnail?: number,
photos?: string[],
gpx?: string,
category?: Category,
@@ -60,8 +61,10 @@ class Trail {
this.duration = params?.duration;
this.lat = params?.lat;
this.lon = params?.lon;
this.thumbnail = params?.thumbnail;
this.thumbnail = params?.thumbnail ?? 0;
this.photos = params?.photos ?? [];
this.waypoints = [];
this.summit_logs = [];
this.gpx = params?.gpx;
this.expand = {
category: params?.category,
@@ -71,7 +74,6 @@ class Trail {
this.tags = params?.tags ?? []
this.description = params?.description ?? "";
this.created = params?.created;
this._photoFiles = [];
}
}

View File

@@ -2,66 +2,130 @@ import { List, type ListFilter } from "$lib/models/list";
import type { Trail } from "$lib/models/trail";
import { pb } from "$lib/pocketbase";
import { getFileURL } from "$lib/util/file_util";
import { ClientResponseError } from "pocketbase";
import { writable, type Writable } from "svelte/store";
export const lists: Writable<List[]> = writable([])
export const list: Writable<List> = writable(new List("", []))
export async function lists_index(filter?: ListFilter) {
const dbResponse: List[] = (await pb.collection('lists').getFullList<List>({
expand: "trails",
sort: `${filter?.sortOrder ?? "+"}${filter?.sort ?? "name"}`
}))
export async function lists_index(filter?: ListFilter, f: (url: RequestInfo | URL, config?: RequestInit) => Promise<Response> = fetch) {
const r = await f('/api/v1/list?' + new URLSearchParams({
sort: `${filter?.sortOrder ?? "-"}${filter?.sort ?? "name"}`,
}), {
method: 'GET',
})
for (const list of dbResponse) {
list.avatar = getFileURL(list, list.avatar);
if (!r.ok) {
throw new ClientResponseError(await r.json())
}
lists.set(dbResponse);
const fetchedLists: List[] = await r.json();
if (dbResponse.length > 0) {
list.set(dbResponse[0])
lists.set(fetchedLists);
if (fetchedLists.length > 0) {
list.set(fetchedLists[0])
}
return dbResponse;
return fetchedLists;
}
export async function lists_create(formData: { [key: string]: any; } | FormData) {
export async function lists_create(list: List, avatar?: File) {
if (!pb.authStore.model) {
throw new Error("Unauthenticated");
}
formData.append("author", pb.authStore.model!.id);
list.author = pb.authStore.model!.id;
let model = await pb
.collection("lists")
.create<List>(formData);
}
let r = await fetch('/api/v1/list', {
method: 'PUT',
body: JSON.stringify(list),
})
export async function lists_update(list: List, formData: { [key: string]: any; } | FormData) {
if ((formData.get("avatar") as File).size == 0) {
formData.delete("avatar");
if (!r.ok) {
throw new ClientResponseError(await r.json())
}
const model: List = await r.json();
const formData = new FormData();
if (avatar) {
formData.append("avatar", avatar);
}
r = await fetch(`/api/v1/list/${model.id!}/file`, {
method: 'POST',
body: formData,
})
if (!r.ok) {
throw new ClientResponseError(await r.json())
}
let model = await pb
.collection("lists")
.update<List>(list.id!, formData);
}
export async function lists_delete(list: List) {
let success = await pb
.collection("lists")
.delete(list.id!);
export async function lists_update(list: List, avatar?: File) {
let r = await fetch('/api/v1/list/' + list.id, {
method: 'POST',
body: JSON.stringify(list),
})
if (!r.ok) {
throw new ClientResponseError(await r.json())
}
const model: List = await r.json();
const formData = new FormData();
if (avatar) {
formData.append("avatar", avatar);
}
r = await fetch(`/api/v1/list/${model.id!}/file`, {
method: 'POST',
body: formData,
})
if (!r.ok) {
throw new ClientResponseError(await r.json())
}
}
export async function lists_add_trail(list: List, trail: Trail) {
let model = await pb
.collection("lists")
.update(list.id!, { "trails+": trail.id });
const r = await fetch('/api/v1/list/' + list.id, {
method: 'POST',
body: JSON.stringify({
"trails+": trail.id
}),
})
if (!r.ok) {
throw new ClientResponseError(await r.json())
}
}
export async function lists_remove_trail(list: List, trail: Trail) {
let model = await pb
.collection("lists")
.update(list.id!, { "trails-": trail.id });
const r = await fetch('/api/v1/list/' + list.id, {
method: 'POST',
body: JSON.stringify({
"trails-": trail.id
}),
})
if (!r.ok) {
throw new ClientResponseError(await r.json())
}
}
export async function lists_delete(list: List) {
const r = await fetch('/api/v1/list/' + list.id, {
method: 'DELETE',
})
if (!r.ok) {
throw new ClientResponseError(await r.json())
}
}

View File

@@ -1,29 +1,43 @@
import { pb } from "$lib/pocketbase";
import { SummitLog } from "$lib/models/summit_log";
import { ClientResponseError } from "pocketbase";
import { writable, type Writable } from "svelte/store";
export const summitLog: Writable<SummitLog> = writable(new SummitLog(new Date().toISOString()));
export async function summit_logs_create(bodyParams?: { [key: string]: any; } | FormData) {
const model = await pb
.collection("summit_logs")
.create<SummitLog>(bodyParams);
export async function summit_logs_create(summitLog: SummitLog) {
const r = await fetch('/api/v1/summit-log', {
method: 'PUT',
body: JSON.stringify(summitLog),
})
return model;
if (r.ok) {
return await r.json();
} else {
throw new ClientResponseError(await r.json())
}
}
export async function summit_logs_update(updatedSummitLog: SummitLog) {
const model = await pb
.collection("summit_logs")
.update(updatedSummitLog.id!, updatedSummitLog);
export async function summit_logs_update(summitLog: SummitLog) {
const r = await fetch('/api/v1/summit-log/' + summitLog.id, {
method: 'POST',
body: JSON.stringify(summitLog),
})
return model;
if (r.ok) {
return await r.json();
} else {
throw new ClientResponseError(await r.json())
}
}
export async function summit_logs_delete(id: string) {
const success = await pb
.collection("summit_logs")
.delete(id);
export async function summit_logs_delete(summitLog: SummitLog) {
const r = await fetch('/api/v1/summit-log/' + summitLog.id, {
method: 'DELETE',
})
return success;
if (r.ok) {
return await r.json();
} else {
throw new ClientResponseError(await r.json())
}
}

View File

@@ -9,25 +9,31 @@ import { summit_logs_create, summit_logs_delete, summit_logs_update } from "./su
import { waypoints_create, waypoints_delete, waypoints_update } from "./waypoint_store";
import { ms } from "$lib/meilisearch";
import type { LatLng } from "leaflet";
import { ClientResponseError } from "pocketbase";
export const trails: Writable<Trail[]> = writable([])
export const trail: Writable<Trail> = writable(new Trail(""));
export const editTrail: Writable<Trail> = writable(new Trail(""));
export async function trails_index(data: { perPage: number, random?: boolean } = { perPage: 5, random: false }) {
const response: Trail[] = (await pb.collection('trails').getList<Trail>(1, data.perPage, { expand: "category,waypoints,summit_logs", sort: data.random ? "@random" : "" })).items
export async function trails_index(data: { perPage: number, random?: boolean, f: (url: RequestInfo | URL, config?: RequestInit) => Promise<Response> } = { perPage: 5, random: false, f: fetch }) {
const r = await data.f('/api/v1/trail?' + new URLSearchParams({
expand: "category,waypoints,summit_logs",
sort: data.random ? "@random" : ""
}), {
method: 'GET',
})
const response = await r.json()
for (const trail of response) {
setFileURLs(trail);
if (r.ok) {
trails.set(response.items);
return response.items;
} else {
throw new ClientResponseError(response)
}
trails.set(response);
return response;
}
export async function trails_search_filter(filter: TrailFilter) {
export async function trails_search_filter(filter: TrailFilter, f: (url: RequestInfo | URL, config?: RequestInit) => Promise<Response> = fetch) {
let filterText: string = `distance >= ${filter.distanceMin} AND distance <= ${filter.distanceMax} AND elevation_gain >= ${filter.elevationGainMin} AND elevation_gain <= ${filter.elevationGainMax}`;
if (filter.category.length > 0) {
@@ -49,18 +55,21 @@ export async function trails_search_filter(filter: TrailFilter) {
return [];
}
const dbResponse: Trail[] = (await pb.collection('trails').getList<Trail>(1, 5, {
filter: trailIds.map((id) => `id="${id}"`).join('||'), expand: "category,waypoints,summit_logs",
const r = await f('/api/v1/trail?' + new URLSearchParams({
expand: "category,waypoints,summit_logs",
filter: trailIds.map((id) => `id="${id}"`).join('||'),
sort: `${filter.sortOrder}${filter.sort}`
})).items
}), {
method: 'GET',
})
const response = await r.json()
for (const trail of dbResponse) {
setFileURLs(trail);
if (r.ok) {
trails.set(response.items);
return response.items;
} else {
throw new ClientResponseError(response)
}
trails.set(dbResponse);
return dbResponse;
}
export async function trails_search_bounding_box(northEast: LatLng, southWest: LatLng, filter?: TrailFilter) {
@@ -78,13 +87,13 @@ export async function trails_search_bounding_box(northEast: LatLng, southWest: L
}
}
const response = await ms.index("trails").search("", {
const indexResponse = await ms.index("trails").search("", {
filter: [
`_geoBoundingBox([${northEast.lat}, ${northEast.lng}], [${southWest.lat}, ${southWest.lng}])`,
filterText
],
});
const trailIds = response.hits.map((h) => h.id);
const trailIds = indexResponse.hits.map((h) => h.id);
if (trailIds.length == 0) {
const currentTrails: Trail[] = get(trails);
@@ -92,96 +101,111 @@ export async function trails_search_bounding_box(northEast: LatLng, southWest: L
return compareObjectArrays<Trail>(currentTrails, []);
}
const dbResponse: Trail[] = (
await pb.collection("trails").getList<Trail>(1, 5, {
filter: trailIds.map((id) => `id="${id}"`).join("||"),
expand: "category,waypoints,summit_logs",
sort: `+name`,
})
).items;
const r = await fetch('/api/v1/trail?' + new URLSearchParams({
filter: trailIds.map((id) => `id="${id}"`).join("||"),
expand: "category,waypoints,summit_logs",
sort: `+name`,
}), {
method: 'GET',
})
const response = await r.json()
for (const trail of dbResponse) {
setFileURLs(trail);
const gpxData: string = await fetchGPX(trail);
trail.expand.gpx_data = gpxData;
if (r.ok) {
for (const trail of response.items) {
const gpxData: string = await fetchGPX(trail);
trail.expand.gpx_data = gpxData;
}
const comparison = compareObjectArrays<Trail>(get(trails), response.items)
trails.set(response.items);
return comparison;
} else {
throw new ClientResponseError(response)
}
const comparison = compareObjectArrays<Trail>(get(trails), dbResponse)
trails.set(dbResponse);
return comparison;
}
export async function trails_show(id: string, loadGPX?: boolean) {
const response: Trail = await pb.collection('trails').getOne<Trail>(id, { expand: "category,waypoints,summit_logs" })
export async function trails_show(id: string, loadGPX?: boolean, f: (url: RequestInfo | URL, config?: RequestInit) => Promise<Response> = fetch) {
const r = await f(`/api/v1/trail/${id}?` + new URLSearchParams({
expand: "category,waypoints,summit_logs",
}), {
method: 'GET',
})
const response = await r.json()
if (!r.ok) {
throw new ClientResponseError(response)
}
if (loadGPX) {
const gpxData: string = await fetchGPX(response);
response.expand.gpx_data = gpxData;
}
setFileURLs(response);
response.expand.waypoints = response.expand.waypoints || [];
response.expand.summit_logs = response.expand.summit_logs || [];
response._photoFiles = [];
trail.set(response);
return response;
}
export async function trails_create(trail: Trail, formData: { [key: string]: any; } | FormData) {
export async function trails_create(trail: Trail, photos: File[], gpx: File | null) {
if (!pb.authStore.model) {
throw new Error("Unauthenticated");
}
formData.set("category", trail.expand.category!.id);
for (const file of trail._photoFiles) {
formData.append("photos", file);
}
for (const waypoint of trail.expand.waypoints) {
const model = await waypoints_create({
...waypoint,
marker: undefined,
});
formData.append("waypoints", model.id!);
trail.waypoints.push(model.id!);
}
for (const summitLog of trail.expand.summit_logs) {
const model = await summit_logs_create(summitLog);
formData.append("summit_logs", model.id!);
trail.summit_logs.push(model.id!);
}
if (!formData.get("public")) {
formData.set("public", 0);
trail.author = pb.authStore.model!.id
let r = await fetch('/api/v1/trail', {
method: 'PUT',
body: JSON.stringify({ ...trail, expand: undefined }),
})
if (!r.ok) {
throw new ClientResponseError(await r.json())
}
formData.append("author", pb.authStore.model!.id);
let model: Trail = await r.json();
let model = await pb
.collection("trails")
.create<Trail>(formData);
const thumbnailIndex = trail.photos.findIndex(
(p) => p == trail.thumbnail,
);
let thumbnail: string | undefined = "/imgs/thumbnail.jpg";
if (thumbnailIndex >= 0) {
thumbnail = model.photos.at(thumbnailIndex);
const formData = new FormData()
if (gpx) {
formData.append("gpx", gpx);
}
model = await pb
.collection("trails")
.update<Trail>(model.id!, { thumbnail: thumbnail }, { expand: "category" });
for (const photo of photos) {
formData.append("photos", photo)
}
return model;
r = await fetch(`/api/v1/trail/${model.id!}/file`, {
method: 'POST',
body: formData,
})
if (r.ok) {
return await r.json();
} else {
throw new ClientResponseError(await r.json())
}
}
export async function trails_update(oldTrail: Trail, newTrail: Trail, formData: { [key: string]: any; } | FormData) {
export async function trails_update(oldTrail: Trail, newTrail: Trail, photos: File[], gpx: File | null) {
const waypointUpdates = compareObjectArrays<Waypoint>(oldTrail.expand.waypoints ?? [], newTrail.expand.waypoints ?? []);
@@ -190,7 +214,7 @@ export async function trails_update(oldTrail: Trail, newTrail: Trail, formData:
...addedWaypoint,
marker: undefined,
});
formData.append("waypoints", model.id!);
newTrail.waypoints.push(model.id!);
}
for (const updatedWaypoint of waypointUpdates.updated) {
@@ -198,39 +222,45 @@ export async function trails_update(oldTrail: Trail, newTrail: Trail, formData:
...updatedWaypoint,
marker: undefined,
});
formData.append("waypoints", model.id!);
}
for (const deletedWaypoint of waypointUpdates.deleted) {
const success = await waypoints_delete(deletedWaypoint.id!);
}
for (const unchangedWaypoint of waypointUpdates.unchanged) {
formData.append("waypoints", unchangedWaypoint.id!);
const success = await waypoints_delete(deletedWaypoint);
}
const summitLogUpdates = compareObjectArrays<SummitLog>(oldTrail.expand.summit_logs ?? [], newTrail.expand.summit_logs ?? []);
for (const summitLog of summitLogUpdates.added) {
const model = await summit_logs_create(summitLog);
formData.append("summit_logs", model.id!);
newTrail.summit_logs.push(model.id!);
}
for (const updatedSummitLog of summitLogUpdates.updated) {
const model = await summit_logs_update(updatedSummitLog);
formData.append("summit_logs", model.id!);
}
for (const deletedSummitLog of summitLogUpdates.deleted) {
const success = await summit_logs_delete(deletedSummitLog.id!);
const success = await summit_logs_delete(deletedSummitLog);
}
for (const unchangedSummitLog of summitLogUpdates.unchanged) {
formData.append("summit_logs", unchangedSummitLog.id!);
let r = await fetch('/api/v1/trail/' + newTrail.id, {
method: 'POST',
body: JSON.stringify({ ...newTrail, expand: undefined }),
})
if (!r.ok) {
throw new ClientResponseError(await r.json())
}
for (const file of newTrail._photoFiles) {
formData.append("photos", file);
let model: Trail = await r.json();
const formData = new FormData()
if (gpx) {
formData.append("gpx", gpx);
}
for (const photo of photos) {
formData.append("photos", photo)
}
const deletedPhotos = oldTrail.photos.filter(oldPhoto => !newTrail.photos.find(newPhoto => newPhoto === oldPhoto));
@@ -239,30 +269,15 @@ export async function trails_update(oldTrail: Trail, newTrail: Trail, formData:
formData.append("photos-", deletedPhoto.replace(/^.*[\\/]/, ''));
}
if (formData.get("gpx").size == 0) {
formData.delete("gpx");
r = await fetch(`/api/v1/trail/${newTrail.id!}/file`, {
method: 'POST',
body: formData,
})
if (!r.ok) {
throw new ClientResponseError(await r.json())
}
if (!formData.get("public")) {
formData.set("public", 0);
}
const thumbnailIndex = newTrail.photos.findIndex(
(p) => p == newTrail.thumbnail,
);
let model = await pb
.collection("trails")
.update<Trail>(newTrail.id!, formData);
let thumbnail: string | undefined = oldTrail.thumbnail;
if (thumbnailIndex >= 0) {
thumbnail = model.photos.at(thumbnailIndex);
}
model = await pb
.collection("trails")
.update<Trail>(model.id!, { thumbnail: thumbnail }, { expand: "category,waypoints,summit_logs" });
trail.set(model);
@@ -273,20 +288,24 @@ export async function trails_update(oldTrail: Trail, newTrail: Trail, formData:
export async function trails_delete(trail: Trail) {
if (trail.expand.waypoints) {
for (const waypoint of trail.expand.waypoints) {
waypoints_delete(waypoint.id!);
waypoints_delete(waypoint);
}
}
if (trail.expand.summit_logs) {
for (const summit_log of trail.expand.summit_logs) {
summit_logs_delete(summit_log.id!);
summit_logs_delete(summit_log);
}
}
const success = await pb
.collection("trails")
.delete(trail.id!);
const r = await fetch('/api/v1/trail/' + trail.id, {
method: 'DELETE',
})
return success;
if (r.ok) {
return await r.json();
} else {
throw new ClientResponseError(await r.json())
}
}
async function fetchGPX(trail: Trail) {

View File

@@ -1,5 +1,6 @@
import { regenerateInstance } from "$lib/meilisearch";
import { pb } from "$lib/pocketbase";
import { ClientResponseError } from "pocketbase";
import { writable, type Writable } from "svelte/store";
export type User = {
@@ -10,20 +11,38 @@ export type User = {
avatar?: string;
unit?: "metric" | "imperial";
language?: "en" | "de";
location?: {name: string, lat: number, lon: number}
location?: { name: string, lat: number, lon: number }
}
export const currentUser: Writable<User | null> = writable<User | null>()
export async function users_create(user: User) {
const model = await pb.collection('users').create({ ...user, passwordConfirm: user.password });
const r = await fetch('/api/v1/user', {
method: 'PUT',
body: JSON.stringify({ ...user, passwordConfirm: user.password })
})
if (r.ok) {
return await r.json();
} else {
throw new ClientResponseError(await r.json())
}
return model;
}
export async function login(user: User) {
const authData = await pb.collection('users').authWithPassword(user.email ?? user.username!, user.password);
regenerateInstance()
const r = await fetch('/api/v1/auth/login', {
method: 'POST',
body: JSON.stringify(user),
})
if (r.ok) {
pb.authStore.loadFromCookie(document.cookie)
regenerateInstance()
} else {
throw new ClientResponseError(await r.json())
}
}
export async function logout() {
@@ -32,15 +51,27 @@ export async function logout() {
}
export async function users_update(id: string, user: User | { [K in keyof User]?: User[K] } | FormData) {
let model = await pb
.collection("users")
.update<User>(id, user);
const r = await fetch('/api/v1/user', {
method: 'POST',
body: JSON.stringify({ id: id, user: user })
})
currentUser.set(model);
if (r.ok) {
const model = await r.json();
currentUser.set(model);
} else {
throw new ClientResponseError(await r.json())
}
}
export async function users_delete(user: User) {
let success = await pb
.collection("users")
.delete(user.id);
const r = await fetch('/api/v1/user', {
method: 'DELETE',
body: JSON.stringify({ id: user.id })
})
if (!r.ok) {
throw new ClientResponseError(await r.json())
}
}

View File

@@ -1,30 +1,43 @@
import { pb } from "$lib/pocketbase";
import { Waypoint } from "$lib/models/waypoint";
import { ClientResponseError } from "pocketbase";
import { writable, type Writable } from "svelte/store";
export const waypoint: Writable<Waypoint> = writable(new Waypoint(0, 0));
export async function waypoints_create(bodyParams?: { [key: string]: any; } | FormData) {
export async function waypoints_create(waypoint: Waypoint) {
const r = await fetch('/api/v1/waypoint', {
method: 'PUT',
body: JSON.stringify(waypoint),
})
const model = await pb
.collection("waypoints")
.create<Waypoint>(bodyParams);
return model;
if (r.ok) {
return await r.json();
} else {
throw new ClientResponseError(await r.json())
}
}
export async function waypoints_update(updatedWaypoint: Waypoint) {
const model = await pb
.collection("waypoints")
.update(updatedWaypoint.id!, updatedWaypoint);
export async function waypoints_update(waypoint: Waypoint) {
const r = await fetch('/api/v1/waypoint/' + waypoint.id, {
method: 'POST',
body: JSON.stringify(waypoint),
})
return model;
if (r.ok) {
return await r.json();
} else {
throw new ClientResponseError(await r.json())
}
}
export async function waypoints_delete(id: string) {
const success = await pb
.collection("waypoints")
.delete(id);
export async function waypoints_delete(waypoint: Waypoint) {
const r = await fetch('/api/v1/waypoint/' + waypoint.id, {
method: 'DELETE',
})
return success;
if (r.ok) {
return await r.json();
} else {
throw new ClientResponseError(await r.json())
}
}