diff --git a/src/routes/einstellungen/+page.svelte b/src/routes/einstellungen/+page.svelte index 7dffee3..065b04e 100644 --- a/src/routes/einstellungen/+page.svelte +++ b/src/routes/einstellungen/+page.svelte @@ -2,7 +2,8 @@ import { goto } from '$app/navigation'; import AppHeader from '$lib/components/AppHeader.svelte'; import { auth } from '$lib/auth.svelte'; - import { getServerUrl } from '$lib/api'; + import { getServerUrl, setServerUrl } from '$lib/api'; + import { Capacitor } from '@capacitor/core'; import { sync } from '$lib/sync.svelte'; import { toast } from '$lib/toast.svelte'; import { APP_VERSION, checkForUpdate, installUpdate, type UpdateInfo } from '$lib/updater'; @@ -62,6 +63,33 @@ sync.stop(); goto('/login/'); } + + /* --- Server-Adresse ändern ------------------------------------------- */ + // Nur auf dem Gerät sinnvoll: im Browser läuft alles über den Vite-Proxy. + const canEditServer = Capacitor.isNativePlatform(); + let editServer = $state(false); + let serverInput = $state(getServerUrl()); + + /** + * Neue Server-Adresse übernehmen. Das Token gilt nur beim alten Server, + * deshalb wird bewusst abgemeldet statt so zu tun, als liefe alles weiter. + */ + async function saveServer() { + const url = serverInput.trim(); + if (!url) { + toast.show('Server-Adresse fehlt', 'error'); + return; + } + if (!/^https?:\/\//i.test(url)) { + toast.show('Adresse muss mit http:// oder https:// beginnen', 'error', 5000); + return; + } + await setServerUrl(url); + await auth.logout(); + sync.stop(); + toast.show('Server geändert — bitte neu anmelden', 'info', 5000); + goto('/login/'); + } @@ -113,9 +141,54 @@ Synchronisierung {syncLabel} - - Server: {getServerUrl() || '(Browser-Proxy)'} - + {#if editServer} + + + + { + editServer = false; + serverInput = getServerUrl(); + }} + > + Abbrechen + + + Speichern + + + + Ein Wechsel meldet ab — das Token gilt nur beim bisherigen Server. + + + {:else} + + Server: {getServerUrl() || '(Browser-Proxy)'} + {#if canEditServer} + { + serverInput = getServerUrl(); + editServer = true; + }} + > + ändern + + {/if} + + {/if} sync.syncManual()} diff --git a/src/routes/login/+page.svelte b/src/routes/login/+page.svelte index ac73150..8f20963 100644 --- a/src/routes/login/+page.svelte +++ b/src/routes/login/+page.svelte @@ -5,6 +5,7 @@ import { getServerUrl, setServerUrl, ApiError } from '$lib/api'; import { toast } from '$lib/toast.svelte'; import { Capacitor } from '@capacitor/core'; + import { Eye, EyeOff } from 'lucide-svelte'; let server = $state(getServerUrl()); let loginName = $state(''); @@ -14,6 +15,21 @@ // Server-URL nur auf dem Gerät nötig (im Browser läuft der Vite-Proxy) const needsServer = Capacitor.isNativePlatform(); + /** + * Passwort ein-/ausblenden. + * + * Der Typ wird imperativ am Element gesetzt: Svelte 5 verbietet ein + * dynamisches `type` an einem Feld mit `bind:value`. Grund für den Schalter: + * bei falschem Tastaturlayout tippt man sich sonst blind fest. + */ + let pwEl: HTMLInputElement; + let pwVisible = $state(false); + + function togglePw() { + pwVisible = !pwVisible; + if (pwEl) pwEl.type = pwVisible ? 'text' : 'password'; + } + async function submit(e: Event) { e.preventDefault(); if (busy) return; @@ -28,7 +44,14 @@ toast.show('Angemeldet', 'success'); goto('/auftraege/'); } catch (err) { - toast.show(err instanceof ApiError ? err.message : 'Anmeldung fehlgeschlagen', 'error'); + // Servermeldung im Wortlaut zeigen und stehen lassen — bei 429 steht dort + // die Wartezeit, bei 403 der Grund. Eine Meldung, die nach 3 s verschwindet, + // ist auf der Baustelle wertlos. + toast.show( + err instanceof ApiError ? err.message : 'Anmeldung fehlgeschlagen', + 'error', + 8000, + ); } finally { busy = false; } @@ -66,13 +89,30 @@ Passwort - + + + + + {#if pwVisible} + + {:else} + + {/if} + +
{syncLabel}
- Server: {getServerUrl() || '(Browser-Proxy)'} -
+ Ein Wechsel meldet ab — das Token gilt nur beim bisherigen Server. +
+ Server: {getServerUrl() || '(Browser-Proxy)'} + {#if canEditServer} + { + serverInput = getServerUrl(); + editServer = true; + }} + > + ändern + + {/if} +