trail save fix
This commit is contained in:
@@ -1,37 +1,33 @@
|
||||
<script lang="ts">
|
||||
import { toast } from "$lib/stores/toast_store";
|
||||
import { closeToast, toastStore } from "$lib/stores/toast_store.svelte";
|
||||
import { fade } from "svelte/transition";
|
||||
|
||||
function closeToast() {
|
||||
toast.set(null);
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if $toast}
|
||||
{#each toastStore.toasts as t, i}
|
||||
<div
|
||||
class="fixed px-4 py-3 shadow-xl rounded-xl border bottom-4 right-4 bg-white text-gray-500 flex items-center max-w-md"
|
||||
style="z-index: 1001;"
|
||||
class="fixed px-4 py-3 shadow-xl rounded-xl border right-4 bg-white text-gray-500 flex items-center max-w-md"
|
||||
style="z-index: 1001; bottom: {16 + i * 72}px"
|
||||
in:fade={{ duration: 250 }}
|
||||
out:fade={{ duration: 250 }}
|
||||
>
|
||||
<i
|
||||
class="fa fa-{$toast.icon} p-3 mr-2 rounded-lg"
|
||||
class:success-toast={$toast.type == "success"}
|
||||
class:error-toast={$toast.type == "error"}
|
||||
class="fa fa-{t.icon} p-3 mr-2 rounded-lg"
|
||||
class:success-toast={t.type == "success"}
|
||||
class:error-toast={t.type == "error"}
|
||||
></i>
|
||||
<p class="mr-4">
|
||||
{$toast.text}
|
||||
{t.text}
|
||||
</p>
|
||||
<button
|
||||
type="button"
|
||||
class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center dark:hover:bg-gray-600 dark:hover:text-white ml-6"
|
||||
onclick={closeToast}
|
||||
onclick={() => closeToast(t)}
|
||||
>
|
||||
<i class="fa fa-close"></i>
|
||||
<span class="sr-only">Close modal</span>
|
||||
</button>
|
||||
</div>
|
||||
{/if}
|
||||
{/each}
|
||||
|
||||
<style>
|
||||
.success-toast {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
import { onMount } from "svelte";
|
||||
import { _ } from "svelte-i18n";
|
||||
import TextField from "../base/text_field.svelte";
|
||||
import { show_toast } from "$lib/stores/toast_store";
|
||||
import { show_toast } from "$lib/stores/toast_store.svelte";
|
||||
|
||||
let modal: Modal;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { show_toast } from "$lib/stores/toast_store";
|
||||
import { show_toast } from "$lib/stores/toast_store.svelte";
|
||||
import { getFileURL, readAsDataURLAsync } from "$lib/util/file_util";
|
||||
import { _ } from "svelte-i18n";
|
||||
import PhotoCard from "../photo_card.svelte";
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
lists_index,
|
||||
lists_remove_trail,
|
||||
} from "$lib/stores/list_store";
|
||||
import { show_toast } from "$lib/stores/toast_store";
|
||||
import { show_toast } from "$lib/stores/toast_store.svelte";
|
||||
import { trails_delete } from "$lib/stores/trail_store";
|
||||
import { trail2gpx } from "$lib/util/gpx_util";
|
||||
import { gpx } from "$lib/vendor/toGeoJSON/toGeoJSON";
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
import emptyStateTrailLight from "$lib/assets/svgs/empty_states/empty_state_trail_light.svg";
|
||||
import { pb } from "$lib/pocketbase";
|
||||
import { theme } from "$lib/stores/theme_store";
|
||||
import { show_toast } from "$lib/stores/toast_store";
|
||||
import { show_toast } from "$lib/stores/toast_store.svelte";
|
||||
import * as M from "maplibre-gl";
|
||||
import "photoswipe/style.css";
|
||||
import { onMount } from "svelte";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import type { User } from "$lib/models/user";
|
||||
import { show_toast } from "$lib/stores/toast_store";
|
||||
import { show_toast } from "$lib/stores/toast_store.svelte";
|
||||
import { users_search } from "$lib/stores/user_store";
|
||||
import { getFileURL } from "$lib/util/file_util";
|
||||
import Search, { type SearchItem } from "./base/search.svelte";
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
import { WaypointCreateSchema } from "$lib/models/api/waypoint_schema";
|
||||
import { convertDMSToDD } from "$lib/models/gpx/utils";
|
||||
import { show_toast } from "$lib/stores/toast_store";
|
||||
import { show_toast } from "$lib/stores/toast_store.svelte";
|
||||
import { waypoint } from "$lib/stores/waypoint_store";
|
||||
import { cloneDeep } from "$lib/util/deep_util";
|
||||
import { icons } from "$lib/util/icon_util";
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
"comment": "{n, plural, =1 {Kommentar} other {Kommentare}}",
|
||||
"completed": "Abgeschlossen",
|
||||
"completed-a-trail": "hat eine Route abgeschlossen",
|
||||
"completed-tours": "",
|
||||
"completion-status": "Abschlussstatus",
|
||||
"confirm": "Bestätigen",
|
||||
"confirm-deletion": "Löschen bestätigen",
|
||||
@@ -226,6 +227,7 @@
|
||||
"photos": "Fotos",
|
||||
"pick-a-trail": "Route auswählen",
|
||||
"planned-a-trail": "hat eine Route geplant",
|
||||
"planned-tours": "",
|
||||
"polish": "Polnisch",
|
||||
"portuguese": "Portugiesisch",
|
||||
"print": "Drucken",
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
"comment": "{n, plural, =1 {Comment} other {Comments}}",
|
||||
"completed": "Completed",
|
||||
"completed-a-trail": "completed a trail",
|
||||
"completed-tours": "Completed tours",
|
||||
"completion-status": "Completion Status",
|
||||
"confirm": "Confirm",
|
||||
"confirm-deletion": "Confirm Deletion",
|
||||
@@ -148,8 +149,8 @@
|
||||
"integration-description-komoot": "Syncs your komoot tours with wanderer in regular intervals.",
|
||||
"integration-description-strava": "Syncs your strava routes & activities with wanderer in regular intervals.",
|
||||
"integration-disabled": "integration disabled",
|
||||
"integrations": "Integrations",
|
||||
"integration-enabled": "integration enabled",
|
||||
"integrations": "Integrations",
|
||||
"invalid-date": "Invalid Date",
|
||||
"invalid-username": "Invalid username",
|
||||
"italian": "Italian",
|
||||
@@ -226,6 +227,7 @@
|
||||
"photos": "Photos",
|
||||
"pick-a-trail": "Pick a trail",
|
||||
"planned-a-trail": "planned a trail",
|
||||
"planned-tours": "Planned tours",
|
||||
"polish": "Polish",
|
||||
"portuguese": "Portuguese",
|
||||
"print": "Print",
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
"comment": "{n, plural, one {}=1 {Comentario} other {Comentarios}}",
|
||||
"completed": "Completado",
|
||||
"completed-a-trail": "ruta completada",
|
||||
"completed-tours": "",
|
||||
"completion-status": "Estado de avance",
|
||||
"confirm": "Confirmar",
|
||||
"confirm-deletion": "Confirmar Borrado",
|
||||
@@ -148,8 +149,8 @@
|
||||
"integration-description-komoot": "Syncs your komoot tours with wanderer in regular intervals.",
|
||||
"integration-description-strava": "Syncs your strava routes & activities with wanderer in regular intervals.",
|
||||
"integration-disabled": "integration disabled",
|
||||
"integrations": "Integrations",
|
||||
"integration-enabled": "integration enabled",
|
||||
"integrations": "Integrations",
|
||||
"invalid-date": "Fecha no válida",
|
||||
"invalid-username": "Usuario no válido",
|
||||
"italian": "Italiano",
|
||||
@@ -226,6 +227,7 @@
|
||||
"photos": "Fotos",
|
||||
"pick-a-trail": "Escoge una ruta",
|
||||
"planned-a-trail": "planificada una ruta",
|
||||
"planned-tours": "",
|
||||
"polish": "Polaco",
|
||||
"portuguese": "Portugués",
|
||||
"print": "Imprimir",
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
"comment": "{n, plural, =1 {Commentaire} other {Commentaires}}",
|
||||
"completed": "Terminé",
|
||||
"completed-a-trail": "a terminé un parcours",
|
||||
"completed-tours": "",
|
||||
"completion-status": "Statut",
|
||||
"confirm": "Confirmer",
|
||||
"confirm-deletion": "Confirmer la suppression",
|
||||
@@ -148,8 +149,8 @@
|
||||
"integration-description-komoot": "Syncs your komoot tours with wanderer in regular intervals.",
|
||||
"integration-description-strava": "Syncs your strava routes & activities with wanderer in regular intervals.",
|
||||
"integration-disabled": "integration disabled",
|
||||
"integrations": "Integrations",
|
||||
"integration-enabled": "integration enabled",
|
||||
"integrations": "Integrations",
|
||||
"invalid-date": "Date invalide",
|
||||
"invalid-username": "Nom d'utilisateur invalide",
|
||||
"italian": "Italien",
|
||||
@@ -226,6 +227,7 @@
|
||||
"photos": "Photos",
|
||||
"pick-a-trail": "Choisir un itinéraire",
|
||||
"planned-a-trail": "a plannifié un itinéraire",
|
||||
"planned-tours": "",
|
||||
"polish": "polonais",
|
||||
"portuguese": "Portugais",
|
||||
"print": "Imprimer",
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
"comment": "{n, plural, =1 {Megjegyzés} other {Megjegyzés}}",
|
||||
"completed": "Teljesítve",
|
||||
"completed-a-trail": "completed a trail",
|
||||
"completed-tours": "",
|
||||
"completion-status": "Befejezés állapota",
|
||||
"confirm": "Confirm",
|
||||
"confirm-deletion": "Confirm Deletion",
|
||||
@@ -148,8 +149,8 @@
|
||||
"integration-description-komoot": "Syncs your komoot tours with wanderer in regular intervals.",
|
||||
"integration-description-strava": "Syncs your strava routes & activities with wanderer in regular intervals.",
|
||||
"integration-disabled": "integration disabled",
|
||||
"integrations": "Integrations",
|
||||
"integration-enabled": "integration enabled",
|
||||
"integrations": "Integrations",
|
||||
"invalid-date": "Érvénytelen dátum",
|
||||
"invalid-username": "Érvénytelen felhasználó",
|
||||
"italian": "Olasz",
|
||||
@@ -226,6 +227,7 @@
|
||||
"photos": "Képek",
|
||||
"pick-a-trail": "Válasszon útvonalat",
|
||||
"planned-a-trail": "planned a trail",
|
||||
"planned-tours": "",
|
||||
"polish": "Lengyel",
|
||||
"portuguese": "Portugál",
|
||||
"print": "Print",
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
"comment": "{n, plural, =1 {Commento} other {Commenti}}",
|
||||
"completed": "Completato",
|
||||
"completed-a-trail": "percorso completato",
|
||||
"completed-tours": "",
|
||||
"completion-status": "Stato di completamento",
|
||||
"confirm": "Confermare",
|
||||
"confirm-deletion": "Conferma eliminazione",
|
||||
@@ -148,8 +149,8 @@
|
||||
"integration-description-komoot": "Syncs your komoot tours with wanderer in regular intervals.",
|
||||
"integration-description-strava": "Syncs your strava routes & activities with wanderer in regular intervals.",
|
||||
"integration-disabled": "integration disabled",
|
||||
"integrations": "Integrations",
|
||||
"integration-enabled": "integration enabled",
|
||||
"integrations": "Integrations",
|
||||
"invalid-date": "Data non valida",
|
||||
"invalid-username": "Nome utente non valido",
|
||||
"italian": "Italiano",
|
||||
@@ -226,6 +227,7 @@
|
||||
"photos": "Foto",
|
||||
"pick-a-trail": "Scegli un percorso",
|
||||
"planned-a-trail": "percorso pianificato",
|
||||
"planned-tours": "",
|
||||
"polish": "Polacco",
|
||||
"portuguese": "Portoghese",
|
||||
"print": "Stampa",
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
"comment": "{n, plural, =1 {Opmerking} other {Opmerkingen}}",
|
||||
"completed": "Voltooid",
|
||||
"completed-a-trail": "completed a trail",
|
||||
"completed-tours": "",
|
||||
"completion-status": "Voltooiingsstatus",
|
||||
"confirm": "Confirm",
|
||||
"confirm-deletion": "Confirm Deletion",
|
||||
@@ -148,8 +149,8 @@
|
||||
"integration-description-komoot": "Syncs your komoot tours with wanderer in regular intervals.",
|
||||
"integration-description-strava": "Syncs your strava routes & activities with wanderer in regular intervals.",
|
||||
"integration-disabled": "integration disabled",
|
||||
"integrations": "Integrations",
|
||||
"integration-enabled": "integration enabled",
|
||||
"integrations": "Integrations",
|
||||
"invalid-date": "Ongeldige datum",
|
||||
"invalid-username": "Ongeldige gebruikersnaam",
|
||||
"italian": "Italiaans",
|
||||
@@ -226,6 +227,7 @@
|
||||
"photos": "Foto's",
|
||||
"pick-a-trail": "Kies een wandelroute",
|
||||
"planned-a-trail": "planned a trail",
|
||||
"planned-tours": "",
|
||||
"polish": "Pools",
|
||||
"portuguese": "Portugees",
|
||||
"print": "Afdrukken",
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
"comment": "{n, plural, =1 {Komentarz} other {Komentarze}}",
|
||||
"completed": "Zakończono",
|
||||
"completed-a-trail": "ukończono szlak",
|
||||
"completed-tours": "",
|
||||
"completion-status": "Stan ukończenia",
|
||||
"confirm": "Potwierdź",
|
||||
"confirm-deletion": "Potwierdź usunięcie",
|
||||
@@ -148,8 +149,8 @@
|
||||
"integration-description-komoot": "Syncs your komoot tours with wanderer in regular intervals.",
|
||||
"integration-description-strava": "Syncs your strava routes & activities with wanderer in regular intervals.",
|
||||
"integration-disabled": "integration disabled",
|
||||
"integrations": "Integrations",
|
||||
"integration-enabled": "integration enabled",
|
||||
"integrations": "Integrations",
|
||||
"invalid-date": "Nieprawidłowa data",
|
||||
"invalid-username": "Błędna nazwa użytkownika",
|
||||
"italian": "Włoski",
|
||||
@@ -226,6 +227,7 @@
|
||||
"photos": "Zdjęcia",
|
||||
"pick-a-trail": "Wybierz szlak",
|
||||
"planned-a-trail": "zaplanowano szlak",
|
||||
"planned-tours": "",
|
||||
"polish": "Polski",
|
||||
"portuguese": "Portugalski",
|
||||
"print": "Drukuj",
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
"comment": "{n, plural, =1 {Comentário} other {Comentários}}",
|
||||
"completed": "Completada",
|
||||
"completed-a-trail": "completed a trail",
|
||||
"completed-tours": "",
|
||||
"completion-status": "Estado de conclusão",
|
||||
"confirm": "Confirmar",
|
||||
"confirm-deletion": "Confirmar eliminação",
|
||||
@@ -148,8 +149,8 @@
|
||||
"integration-description-komoot": "Syncs your komoot tours with wanderer in regular intervals.",
|
||||
"integration-description-strava": "Syncs your strava routes & activities with wanderer in regular intervals.",
|
||||
"integration-disabled": "integration disabled",
|
||||
"integrations": "Integrations",
|
||||
"integration-enabled": "integration enabled",
|
||||
"integrations": "Integrations",
|
||||
"invalid-date": "Data inválida",
|
||||
"invalid-username": "Nome de usuário inválido",
|
||||
"italian": "Italiano",
|
||||
@@ -226,6 +227,7 @@
|
||||
"photos": "Fotos",
|
||||
"pick-a-trail": "Escolha uma trilha",
|
||||
"planned-a-trail": "planned a trail",
|
||||
"planned-tours": "",
|
||||
"polish": "Polonês",
|
||||
"portuguese": "Português",
|
||||
"print": "Imprimir",
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
"comment": "{n, plural, =1 {评论} other {评论}}",
|
||||
"completed": "已完成",
|
||||
"completed-a-trail": "completed a trail",
|
||||
"completed-tours": "",
|
||||
"completion-status": "完成状态",
|
||||
"confirm": "确认",
|
||||
"confirm-deletion": "确认删除",
|
||||
@@ -148,8 +149,8 @@
|
||||
"integration-description-komoot": "Syncs your komoot tours with wanderer in regular intervals.",
|
||||
"integration-description-strava": "Syncs your strava routes & activities with wanderer in regular intervals.",
|
||||
"integration-disabled": "integration disabled",
|
||||
"integrations": "Integrations",
|
||||
"integration-enabled": "integration enabled",
|
||||
"integrations": "Integrations",
|
||||
"invalid-date": "无效日期",
|
||||
"invalid-username": "无效用户名",
|
||||
"italian": "意大利语",
|
||||
@@ -226,6 +227,7 @@
|
||||
"photos": "图片",
|
||||
"pick-a-trail": "选择一个路线",
|
||||
"planned-a-trail": "planned a trail",
|
||||
"planned-tours": "",
|
||||
"polish": "波兰语",
|
||||
"portuguese": "葡萄牙语",
|
||||
"print": "打印",
|
||||
|
||||
@@ -12,7 +12,9 @@ const StravaSchema = z.object({
|
||||
const KomootSchema = z.object({
|
||||
email: z.string().email(),
|
||||
password: z.string(),
|
||||
active: z.boolean()
|
||||
completed: z.boolean(),
|
||||
planned: z.boolean(),
|
||||
active: z.boolean(),
|
||||
})
|
||||
|
||||
const IntegrationCreateSchema = z.object({
|
||||
|
||||
@@ -16,6 +16,8 @@ export interface StravaIntegration extends BaseIntegration {
|
||||
export interface KomootIntegration extends BaseIntegration {
|
||||
email: string,
|
||||
password: string,
|
||||
completed: boolean,
|
||||
planned: boolean
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -150,7 +150,6 @@ export async function searchLocationReverse(lat: number, lon: number) {
|
||||
|
||||
function getLocationDescription(address: Address) {
|
||||
let description = ""
|
||||
console.log(address);
|
||||
|
||||
if (address.country) {
|
||||
description += address.country;
|
||||
|
||||
31
web/src/lib/stores/toast_store.svelte.ts
Normal file
31
web/src/lib/stores/toast_store.svelte.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import cryptoRandomString from "crypto-random-string";
|
||||
|
||||
export type Toast = {
|
||||
id?: string;
|
||||
type: "info" | "success" | "warning" | "error"
|
||||
icon: string;
|
||||
text: string;
|
||||
}
|
||||
|
||||
class ToastStore {
|
||||
toasts: Toast[] = $state([]);
|
||||
}
|
||||
|
||||
export const toastStore = new ToastStore()
|
||||
|
||||
|
||||
export function show_toast(newToast: Toast, duration: number = 3000) {
|
||||
newToast.id = cryptoRandomString({ length: 15 })
|
||||
toastStore.toasts.push(newToast);
|
||||
|
||||
setTimeout(() => {
|
||||
closeToast(newToast)
|
||||
}, duration);
|
||||
}
|
||||
|
||||
export function closeToast(toast: Toast) {
|
||||
const toastIndex = toastStore.toasts.findIndex(t => t.id == toast.id)
|
||||
console.log(toastIndex);
|
||||
|
||||
toastStore.toasts.splice(toastIndex, 1)
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
import { writable, type Writable } from "svelte/store";
|
||||
|
||||
export type Toast = {
|
||||
type: "info" | "success" | "warning" | "error"
|
||||
icon: string;
|
||||
text: string;
|
||||
}
|
||||
|
||||
|
||||
export const toast: Writable<Toast | null> = writable();
|
||||
|
||||
|
||||
export function show_toast(newToast: Toast, duration: number = 3000) {
|
||||
toast.set(newToast);
|
||||
|
||||
setTimeout(() => toast.set(null), duration);
|
||||
}
|
||||
@@ -304,7 +304,10 @@ export async function trails_update(oldTrail: Trail, newTrail: Trail, photos?: F
|
||||
throw new APIError(r.status, response.message, response.detail)
|
||||
}
|
||||
|
||||
const response: Trail = await r.json();
|
||||
|
||||
model.photos = response.photos
|
||||
model.gpx = response.gpx
|
||||
|
||||
trail.set(model);
|
||||
|
||||
@@ -460,7 +463,7 @@ async function searchResultToTrailList(hits: Hits<TrailSearchResult>, loadGPX: b
|
||||
const gpxData: string = await fetchGPX(t);
|
||||
t.expand!.gpx_data = gpxData;
|
||||
}
|
||||
|
||||
|
||||
trails.push(t)
|
||||
}
|
||||
return trails
|
||||
|
||||
@@ -35,7 +35,7 @@ export async function gpx2trail(gpxString: string, fallbackName?: string) {
|
||||
wp.id = cryptoRandomString({ length: 15 });
|
||||
wp.name = wpt.name ?? ""
|
||||
wp.description = wpt.desc;
|
||||
trail.expand!.waypoints.push(wp);
|
||||
trail.expand!.waypoints?.push(wp);
|
||||
}
|
||||
|
||||
const totals = gpx.features
|
||||
@@ -158,7 +158,7 @@ export async function fromFIT(fitData: ArrayBuffer) {
|
||||
return new Promise<string>((resolve, reject) => easyFit.parse(fitData, function (error, data) {
|
||||
|
||||
if (error) {
|
||||
console.log(error);
|
||||
console.error(error);
|
||||
reject(error)
|
||||
}
|
||||
|
||||
|
||||
@@ -72,9 +72,7 @@ export class ElevationProfileControl implements IControl {
|
||||
this.settings = { ...options };
|
||||
}
|
||||
|
||||
toggleTheme(options: ElevationProfileControlOptions) {
|
||||
console.log(options);
|
||||
|
||||
toggleTheme(options: ElevationProfileControlOptions) {
|
||||
this.settings = { ...this.settings, ...options };
|
||||
this.elevationProfileChart?.toggleTheme(this.settings)
|
||||
}
|
||||
|
||||
14
web/src/routes/api/v1/integration/komoot/login/+server.ts
Normal file
14
web/src/routes/api/v1/integration/komoot/login/+server.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { pb } from "$lib/pocketbase";
|
||||
import { handleError } from "$lib/util/api_util";
|
||||
import { json } from "@sveltejs/kit";
|
||||
|
||||
export async function GET() {
|
||||
try {
|
||||
const r = await pb.send("/integration/komoot/login", {
|
||||
method: "GET",
|
||||
});
|
||||
return json(r);
|
||||
} catch (e: any) {
|
||||
throw handleError(e)
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ export async function POST(event: RequestEvent) {
|
||||
const r = await event.locals.ms.index(event.params.index as string).search(data.q, data.options);
|
||||
return json(r);
|
||||
} catch (e: any) {
|
||||
console.log(e);
|
||||
console.error(e);
|
||||
|
||||
throw error(e.httpStatus, e)
|
||||
}
|
||||
|
||||
@@ -16,17 +16,7 @@ export async function GET(event: RequestEvent) {
|
||||
}
|
||||
|
||||
// remove time from dates
|
||||
r.date = r.date?.substring(0, 10) ?? ""
|
||||
for (const log of r.expand?.summit_logs ?? []) {
|
||||
log.date = log.date.substring(0, 10)
|
||||
|
||||
if (!log.expand) {
|
||||
log.expand = {} as any
|
||||
}
|
||||
if (log.author) {
|
||||
log.expand!.author = await pb.collection("users_anonymous").getOne(log.author);
|
||||
}
|
||||
}
|
||||
await enrichRecord(r);
|
||||
|
||||
// sort waypoints by distance
|
||||
r.expand?.waypoints?.sort((a, b) => (a.distance_from_start ?? 0) - (b.distance_from_start ?? 0))
|
||||
@@ -36,10 +26,10 @@ export async function GET(event: RequestEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export async function POST(event: RequestEvent) {
|
||||
try {
|
||||
const r = await update<Trail>(event, TrailUpdateSchema, Collection.trails)
|
||||
await enrichRecord(r)
|
||||
return json(r);
|
||||
} catch (e: any) {
|
||||
throw handleError(e)
|
||||
@@ -54,3 +44,19 @@ export async function DELETE(event: RequestEvent) {
|
||||
throw handleError(e)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
async function enrichRecord(r: Trail) {
|
||||
r.date = r.date?.substring(0, 10) ?? "";
|
||||
for (const log of r.expand?.summit_logs ?? []) {
|
||||
log.date = log.date.substring(0, 10);
|
||||
|
||||
if (!log.expand) {
|
||||
log.expand = {} as any;
|
||||
}
|
||||
if (log.author) {
|
||||
log.expand!.author = await pb.collection("users_anonymous").getOne(log.author);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -50,7 +50,7 @@ export async function PUT(event: RequestEvent) {
|
||||
const fileName = (data.get("name") as string | null)?.length ? data.get("name") as string : "file"
|
||||
log._gpx = new File([gpxFile], fileName);
|
||||
|
||||
trail.expand!.summit_logs.push(log);
|
||||
trail.expand!.summit_logs?.push(log);
|
||||
|
||||
|
||||
try {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import LogoTextTwoLineDark from "$lib/components/logo/logo_text_two_line_dark.svelte";
|
||||
import LogoTextTwoLineLight from "$lib/components/logo/logo_text_two_line_light.svelte";
|
||||
import { theme } from "$lib/stores/theme_store";
|
||||
import { show_toast } from "$lib/stores/toast_store";
|
||||
import { show_toast } from "$lib/stores/toast_store.svelte";
|
||||
import { users_confirm_reset } from "$lib/stores/user_store";
|
||||
import { validator } from "@felte/validator-zod";
|
||||
import { createForm } from "felte";
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
import LogoTextTwoLineDark from "$lib/components/logo/logo_text_two_line_dark.svelte";
|
||||
import LogoTextTwoLineLight from "$lib/components/logo/logo_text_two_line_light.svelte";
|
||||
import { theme } from "$lib/stores/theme_store";
|
||||
import { show_toast } from "$lib/stores/toast_store";
|
||||
import { show_toast } from "$lib/stores/toast_store.svelte";
|
||||
import { users_reset_password } from "$lib/stores/user_store";
|
||||
import { validator } from "@felte/validator-zod";
|
||||
import { createForm } from "felte";
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
import { TrailShare } from "$lib/models/trail_share.js";
|
||||
import { lists_create, lists_update } from "$lib/stores/list_store.js";
|
||||
import { theme } from "$lib/stores/theme_store.js";
|
||||
import { show_toast } from "$lib/stores/toast_store.js";
|
||||
import { show_toast } from "$lib/stores/toast_store.svelte.js";
|
||||
import {
|
||||
trail_share_create,
|
||||
trail_share_index,
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
import LogoTextTwoLineLight from "$lib/components/logo/logo_text_two_line_light.svelte";
|
||||
import type { User } from "$lib/models/user";
|
||||
import { theme } from "$lib/stores/theme_store";
|
||||
import { show_toast } from "$lib/stores/toast_store";
|
||||
import { show_toast } from "$lib/stores/toast_store.svelte";
|
||||
import { login } from "$lib/stores/user_store";
|
||||
import { APIError } from "$lib/util/api_util";
|
||||
import { validator } from "@felte/validator-zod";
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
import LogoText from "$lib/components/logo/logo_text.svelte";
|
||||
import MapWithElevationMaplibre from "$lib/components/trail/map_with_elevation_maplibre.svelte";
|
||||
import type { Settings } from "$lib/models/settings";
|
||||
import { show_toast } from "$lib/stores/toast_store";
|
||||
import { show_toast } from "$lib/stores/toast_store.svelte";
|
||||
import { trail } from "$lib/stores/trail_store";
|
||||
import {
|
||||
formatDistance,
|
||||
|
||||
@@ -11,7 +11,7 @@ export const load: Load = async ({ params, fetch }) => {
|
||||
message: e.status == 404 ? 'Not found' : e.message
|
||||
});
|
||||
}
|
||||
console.log(e);
|
||||
console.error(e);
|
||||
|
||||
}
|
||||
};
|
||||
@@ -9,7 +9,7 @@
|
||||
import type { User } from "$lib/models/user";
|
||||
import { settings_update } from "$lib/stores/settings_store";
|
||||
import { theme } from "$lib/stores/theme_store";
|
||||
import { show_toast } from "$lib/stores/toast_store";
|
||||
import { show_toast } from "$lib/stores/toast_store.svelte";
|
||||
import { login, users_create } from "$lib/stores/user_store";
|
||||
import { validator } from "@felte/validator-zod";
|
||||
import { createForm } from "felte";
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import ConfirmModal from "$lib/components/confirm_modal.svelte";
|
||||
import EmailModal from "$lib/components/settings/email_modal.svelte";
|
||||
import PasswordModal from "$lib/components/settings/password_modal.svelte";
|
||||
import { show_toast } from "$lib/stores/toast_store";
|
||||
import { show_toast } from "$lib/stores/toast_store.svelte";
|
||||
import {
|
||||
currentUser,
|
||||
logout,
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
import { } from "$lib/components/settings/upload_dialog.svelte";
|
||||
import TrailExportModal from "$lib/components/trail/trail_export_modal.svelte";
|
||||
import { theme } from "$lib/stores/theme_store";
|
||||
import { show_toast } from "$lib/stores/toast_store";
|
||||
import { show_toast } from "$lib/stores/toast_store.svelte";
|
||||
import { fetchGPX, trails_index, trails_upload } from "$lib/stores/trail_store";
|
||||
import { processUploadQueue, uploadStore, type Upload } from "$lib/stores/upload_store.svelte";
|
||||
import { getFileURL, saveAs } from "$lib/util/file_util";
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
integrations_create,
|
||||
integrations_update,
|
||||
} from "$lib/stores/integration_store.js";
|
||||
import { show_toast } from "$lib/stores/toast_store.js";
|
||||
import { show_toast } from "$lib/stores/toast_store.svelte.js";
|
||||
import { _ } from "svelte-i18n";
|
||||
|
||||
let { data } = $props();
|
||||
@@ -102,9 +102,7 @@
|
||||
}
|
||||
|
||||
show_toast({
|
||||
text:
|
||||
"strava " +
|
||||
$_("integration-disabled"),
|
||||
text: "strava " + $_("integration-disabled"),
|
||||
icon: "check",
|
||||
type: "success",
|
||||
});
|
||||
@@ -117,9 +115,13 @@
|
||||
}
|
||||
if (value) {
|
||||
try {
|
||||
await pb.send("/integration/komoot/login", {
|
||||
const r = await fetch("/api/v1/integration/komoot/login", {
|
||||
method: "GET",
|
||||
});
|
||||
|
||||
if (!r.ok) {
|
||||
throw Error();
|
||||
}
|
||||
} catch (e) {
|
||||
komootToggleValue = false;
|
||||
show_toast({
|
||||
@@ -127,6 +129,7 @@
|
||||
icon: "close",
|
||||
type: "error",
|
||||
});
|
||||
return;
|
||||
}
|
||||
integration.komoot.active = true;
|
||||
} else {
|
||||
@@ -140,6 +143,7 @@
|
||||
icon: "close",
|
||||
type: "error",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
show_toast({
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import Textarea from "$lib/components/base/textarea.svelte";
|
||||
import type { Category } from "$lib/models/category.js";
|
||||
import { settings_update } from "$lib/stores/settings_store";
|
||||
import { show_toast } from "$lib/stores/toast_store";
|
||||
import { show_toast } from "$lib/stores/toast_store.svelte.js";
|
||||
import { currentUser, users_update } from "$lib/stores/user_store";
|
||||
import { getFileURL } from "$lib/util/file_util";
|
||||
import { _ } from "svelte-i18n";
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
lists_remove_trail,
|
||||
} from "$lib/stores/list_store";
|
||||
import { summitLog } from "$lib/stores/summit_log_store";
|
||||
import { show_toast } from "$lib/stores/toast_store";
|
||||
import { show_toast } from "$lib/stores/toast_store.svelte.js";
|
||||
import {
|
||||
trail,
|
||||
trails_create,
|
||||
@@ -106,12 +106,12 @@
|
||||
expand: z
|
||||
.object({
|
||||
gpx_data: z.string().optional(),
|
||||
summit_logs: z.array(SummitLogCreateSchema),
|
||||
summit_logs: z.array(SummitLogCreateSchema).optional(),
|
||||
waypoints: z.array(
|
||||
WaypointCreateSchema.extend({
|
||||
marker: z.any().optional(),
|
||||
}),
|
||||
),
|
||||
).optional(),
|
||||
})
|
||||
.optional(),
|
||||
});
|
||||
@@ -188,12 +188,13 @@
|
||||
);
|
||||
form.id = createdTrail.id;
|
||||
} else {
|
||||
await trails_update(
|
||||
const updatedTrail = await trails_update(
|
||||
$trail,
|
||||
form as Trail,
|
||||
photoFiles,
|
||||
gpxFile,
|
||||
);
|
||||
setFields(updatedTrail)
|
||||
}
|
||||
|
||||
listAddEnabled = true;
|
||||
@@ -294,7 +295,7 @@
|
||||
type: selectedFile.type,
|
||||
});
|
||||
|
||||
$formData.expand!.summit_logs.push(log);
|
||||
$formData.expand!.summit_logs?.push(log);
|
||||
|
||||
if (parseResult.gpx.rte?.length && !parseResult.gpx.trk) {
|
||||
parseResult.gpx.trk = [
|
||||
@@ -328,7 +329,7 @@
|
||||
}
|
||||
|
||||
function clearWaypoints() {
|
||||
for (const waypoint of $formData.expand!.waypoints) {
|
||||
for (const waypoint of $formData.expand!.waypoints ?? []) {
|
||||
waypoint.marker?.remove();
|
||||
}
|
||||
$formData.expand!.waypoints = [];
|
||||
@@ -395,23 +396,23 @@
|
||||
}
|
||||
|
||||
function deleteWaypoint(index: number) {
|
||||
$formData.expand!.waypoints.splice(index, 1);
|
||||
$formData.expand!.waypoints?.splice(index, 1);
|
||||
$formData.waypoints.splice(index, 1);
|
||||
$formData.expand!.waypoints = $formData.expand!.waypoints;
|
||||
// updateTrailOnMap();
|
||||
}
|
||||
|
||||
function saveWaypoint(savedWaypoint: Waypoint) {
|
||||
let editedWaypointIndex = $formData.expand!.waypoints.findIndex(
|
||||
let editedWaypointIndex = $formData.expand!.waypoints?.findIndex(
|
||||
(s) => s.id == savedWaypoint.id,
|
||||
);
|
||||
) ?? -1;
|
||||
|
||||
if (editedWaypointIndex >= 0) {
|
||||
$formData.expand!.waypoints[editedWaypointIndex] = savedWaypoint;
|
||||
$formData.expand!.waypoints![editedWaypointIndex] = savedWaypoint;
|
||||
} else {
|
||||
savedWaypoint.id = cryptoRandomString({ length: 15 });
|
||||
$formData.expand!.waypoints = [
|
||||
...$formData.expand!.waypoints,
|
||||
...$formData.expand!.waypoints ?? [],
|
||||
savedWaypoint,
|
||||
];
|
||||
|
||||
@@ -421,17 +422,17 @@
|
||||
|
||||
function moveMarker(marker: M.Marker, wpId?: string) {
|
||||
const position = marker.getLngLat();
|
||||
const editableWaypointIndex = $formData.expand!.waypoints.findIndex(
|
||||
const editableWaypointIndex = $formData.expand!.waypoints?.findIndex(
|
||||
(w) => w.id == wpId,
|
||||
);
|
||||
) ?? -1;
|
||||
const editableWaypoint =
|
||||
$formData.expand!.waypoints[editableWaypointIndex];
|
||||
$formData.expand!.waypoints![editableWaypointIndex];
|
||||
if (!editableWaypoint) {
|
||||
return;
|
||||
}
|
||||
editableWaypoint.lat = position.lat;
|
||||
editableWaypoint.lon = position.lng;
|
||||
$formData.expand!.waypoints = [...$formData.expand!.waypoints];
|
||||
$formData.expand!.waypoints = [...$formData.expand!.waypoints ?? []];
|
||||
// updateTrailOnMap();
|
||||
}
|
||||
|
||||
@@ -441,16 +442,16 @@
|
||||
}
|
||||
|
||||
function saveSummitLog(log: SummitLog) {
|
||||
let editedSummitLogIndex = $formData.expand!.summit_logs.findIndex(
|
||||
let editedSummitLogIndex = $formData.expand!.summit_logs?.findIndex(
|
||||
(s) => s.id == log.id,
|
||||
);
|
||||
|
||||
if (editedSummitLogIndex >= 0) {
|
||||
$formData.expand!.summit_logs[editedSummitLogIndex] = log;
|
||||
if (editedSummitLogIndex ?? 0 >= 0) {
|
||||
$formData.expand!.summit_logs![editedSummitLogIndex!] = log;
|
||||
} else {
|
||||
log.id = cryptoRandomString({ length: 15 });
|
||||
$formData.expand!.summit_logs = [
|
||||
...$formData.expand!.summit_logs,
|
||||
...$formData.expand!.summit_logs ?? [],
|
||||
log,
|
||||
];
|
||||
}
|
||||
@@ -465,7 +466,7 @@
|
||||
summitLog.set(currentSummitLog);
|
||||
summitLogModal.openModal();
|
||||
} else if (item.value === "delete") {
|
||||
$formData.expand!.summit_logs.splice(index, 1);
|
||||
$formData.expand!.summit_logs?.splice(index, 1);
|
||||
$formData.summit_logs.splice(index, 1);
|
||||
$formData.expand!.summit_logs = $formData.expand!.summit_logs;
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ export const load: Load = async ({ params, fetch }) => {
|
||||
message: e.status == 404 ? 'Not found' : e.message
|
||||
});
|
||||
}
|
||||
console.log(e);
|
||||
console.error(e);
|
||||
}
|
||||
|
||||
};
|
||||
@@ -16,7 +16,7 @@ setup('create user', async ({ page }) => {
|
||||
|
||||
} catch (e) {
|
||||
if (e instanceof Error && e.message.includes("No resource with given identifier found")) {
|
||||
console.log("Already logged in!")
|
||||
console.error("Already logged in!")
|
||||
} else {
|
||||
throw e
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user