Einstellungen per Zahnrad erreichbar, verwirrenden Sync-Punkt entfernt [apk]
- AppHeader: farbiger Sync-Ampel-Punkt raus (war nicht selbsterklaerend), stattdessen Zahnrad-Icon -> Einstellungen, von jeder Seite erreichbar - Einstellungen neu gegliedert: App (Version + Update-Button) zuerst, dann Synchronisierung (Status in Klartext + manueller Sync), Konto, Abmelden Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
280a973476
commit
fca59545cc
2 changed files with 70 additions and 49 deletions
|
|
@ -1,7 +1,6 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { goto } from '$app/navigation';
|
import { page } from '$app/stores';
|
||||||
import { sync } from '$lib/sync.svelte';
|
import { ChevronLeft, Settings } from 'lucide-svelte';
|
||||||
import { ChevronLeft, RefreshCw } from 'lucide-svelte';
|
|
||||||
|
|
||||||
let {
|
let {
|
||||||
title,
|
title,
|
||||||
|
|
@ -9,14 +8,8 @@
|
||||||
subtitle = '',
|
subtitle = '',
|
||||||
}: { title: string; back?: boolean; subtitle?: string } = $props();
|
}: { title: string; back?: boolean; subtitle?: string } = $props();
|
||||||
|
|
||||||
// Sync-Ampel: grün=ok, gelb=läuft/offen, rot=Fehler
|
// Zahnrad auf der Einstellungs-Seite selbst ausblenden
|
||||||
const dot = $derived(
|
const onSettings = $derived($page.url.pathname.startsWith('/einstellungen'));
|
||||||
sync.status === 'error'
|
|
||||||
? 'bg-red-500'
|
|
||||||
: sync.pendingCount > 0 || sync.status === 'syncing'
|
|
||||||
? 'bg-amber-400'
|
|
||||||
: 'bg-emerald-500',
|
|
||||||
);
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<header class="flex items-center gap-2 border-b border-zinc-800 bg-zinc-900 px-3 pb-3 safe-top">
|
<header class="flex items-center gap-2 border-b border-zinc-800 bg-zinc-900 px-3 pb-3 safe-top">
|
||||||
|
|
@ -31,13 +24,13 @@
|
||||||
<p class="truncate text-xs text-zinc-400">{subtitle}</p>
|
<p class="truncate text-xs text-zinc-400">{subtitle}</p>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<button
|
{#if !onSettings}
|
||||||
class="flex items-center gap-1 rounded px-2 py-1 text-xs text-zinc-300 active:bg-zinc-800"
|
<a
|
||||||
onclick={() => sync.syncManual()}
|
class="rounded p-1.5 text-zinc-300 active:bg-zinc-800"
|
||||||
title="Synchronisieren"
|
href="/einstellungen/"
|
||||||
>
|
aria-label="Einstellungen"
|
||||||
<span class="h-2.5 w-2.5 rounded-full {dot}"></span>
|
>
|
||||||
{#if sync.pendingCount > 0}<span>{sync.pendingCount}</span>{/if}
|
<Settings size={22} />
|
||||||
<RefreshCw size={14} class={sync.status === 'syncing' ? 'animate-spin' : ''} />
|
</a>
|
||||||
</button>
|
{/if}
|
||||||
</header>
|
</header>
|
||||||
|
|
|
||||||
|
|
@ -9,11 +9,18 @@
|
||||||
|
|
||||||
let checking = $state(false);
|
let checking = $state(false);
|
||||||
|
|
||||||
async function logout() {
|
// Sync-Status in Klartext
|
||||||
await auth.logout();
|
const syncLabel = $derived(
|
||||||
sync.stop();
|
sync.status === 'syncing'
|
||||||
goto('/login/');
|
? 'Wird synchronisiert …'
|
||||||
}
|
: sync.status === 'error'
|
||||||
|
? 'Letzter Sync fehlgeschlagen'
|
||||||
|
: sync.status === 'offline'
|
||||||
|
? 'Offline'
|
||||||
|
: sync.pendingCount > 0
|
||||||
|
? `${sync.pendingCount} Protokoll(e) noch nicht übertragen`
|
||||||
|
: 'Alles synchronisiert',
|
||||||
|
);
|
||||||
|
|
||||||
async function checkUpdate() {
|
async function checkUpdate() {
|
||||||
checking = true;
|
checking = true;
|
||||||
|
|
@ -22,11 +29,52 @@
|
||||||
if (upd) openUpdate(upd);
|
if (upd) openUpdate(upd);
|
||||||
else toast.show('App ist aktuell', 'success');
|
else toast.show('App ist aktuell', 'success');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function logout() {
|
||||||
|
await auth.logout();
|
||||||
|
sync.stop();
|
||||||
|
goto('/login/');
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<AppHeader title="Einstellungen" back />
|
<AppHeader title="Einstellungen" back />
|
||||||
|
|
||||||
<div class="flex flex-1 flex-col gap-4 overflow-y-auto p-4">
|
<div class="flex flex-1 flex-col gap-4 overflow-y-auto p-4">
|
||||||
|
<!-- App / Version / Update -->
|
||||||
|
<section class="rounded-lg bg-zinc-900 p-4">
|
||||||
|
<h2 class="mb-2 text-sm font-semibold text-zinc-300">App</h2>
|
||||||
|
<p class="text-sm">
|
||||||
|
Version <span class="font-mono text-zinc-400">{APP_VERSION}</span>
|
||||||
|
</p>
|
||||||
|
<p class="mt-0.5 text-xs text-zinc-500">
|
||||||
|
Der Zeitstempel zeigt, welcher Build installiert ist.
|
||||||
|
</p>
|
||||||
|
<button
|
||||||
|
class="mt-3 w-full rounded bg-zinc-800 px-3 py-2 text-sm active:bg-zinc-700 disabled:opacity-50"
|
||||||
|
onclick={checkUpdate}
|
||||||
|
disabled={checking}
|
||||||
|
>
|
||||||
|
{checking ? 'Prüfe …' : 'Auf Update prüfen'}
|
||||||
|
</button>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Synchronisierung -->
|
||||||
|
<section class="rounded-lg bg-zinc-900 p-4">
|
||||||
|
<h2 class="mb-2 text-sm font-semibold text-zinc-300">Synchronisierung</h2>
|
||||||
|
<p class="text-sm text-zinc-300">{syncLabel}</p>
|
||||||
|
<p class="mt-0.5 break-all text-xs text-zinc-500">
|
||||||
|
Server: {getServerUrl() || '(Browser-Proxy)'}
|
||||||
|
</p>
|
||||||
|
<button
|
||||||
|
class="mt-3 w-full rounded bg-zinc-800 px-3 py-2 text-sm active:bg-zinc-700 disabled:opacity-50"
|
||||||
|
onclick={() => sync.syncManual()}
|
||||||
|
disabled={sync.status === 'syncing'}
|
||||||
|
>
|
||||||
|
Jetzt synchronisieren
|
||||||
|
</button>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Konto -->
|
||||||
<section class="rounded-lg bg-zinc-900 p-4">
|
<section class="rounded-lg bg-zinc-900 p-4">
|
||||||
<h2 class="mb-2 text-sm font-semibold text-zinc-300">Konto</h2>
|
<h2 class="mb-2 text-sm font-semibold text-zinc-300">Konto</h2>
|
||||||
<p class="text-sm">{auth.user?.name ?? '—'}</p>
|
<p class="text-sm">{auth.user?.name ?? '—'}</p>
|
||||||
|
|
@ -36,30 +84,10 @@
|
||||||
</p>
|
</p>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="rounded-lg bg-zinc-900 p-4">
|
<button
|
||||||
<h2 class="mb-2 text-sm font-semibold text-zinc-300">Server</h2>
|
class="mt-2 rounded-lg bg-red-700 py-2.5 font-semibold text-white active:bg-red-800"
|
||||||
<p class="break-all text-sm text-zinc-400">{getServerUrl() || '(Browser-Proxy)'}</p>
|
onclick={logout}
|
||||||
<p class="mt-2 text-xs text-zinc-500">
|
>
|
||||||
Offene Protokolle: {sync.pendingCount} · Status: {sync.status}
|
|
||||||
</p>
|
|
||||||
<button class="mt-2 rounded bg-zinc-800 px-3 py-1.5 text-sm" onclick={() => sync.syncNow()}>
|
|
||||||
Jetzt synchronisieren
|
|
||||||
</button>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="rounded-lg bg-zinc-900 p-4">
|
|
||||||
<h2 class="mb-2 text-sm font-semibold text-zinc-300">App</h2>
|
|
||||||
<p class="text-sm text-zinc-400">Version {APP_VERSION}</p>
|
|
||||||
<button
|
|
||||||
class="mt-2 rounded bg-zinc-800 px-3 py-1.5 text-sm"
|
|
||||||
onclick={checkUpdate}
|
|
||||||
disabled={checking}
|
|
||||||
>
|
|
||||||
{checking ? 'Prüfe …' : 'Auf Update prüfen'}
|
|
||||||
</button>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<button class="mt-2 rounded-lg bg-red-700 py-2.5 font-semibold text-white" onclick={logout}>
|
|
||||||
Abmelden
|
Abmelden
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue