diff --git a/frontend/src/lib/api.ts b/frontend/src/lib/api.ts index e8f2e24..96ce2fc 100644 --- a/frontend/src/lib/api.ts +++ b/frontend/src/lib/api.ts @@ -24,6 +24,7 @@ export function isAuthenticated(): boolean { } async function refreshAccessToken(): Promise { + if (typeof window === 'undefined') return false; const refreshToken = localStorage.getItem('refresh_token'); if (!refreshToken) return false; diff --git a/frontend/src/lib/auth.svelte.ts b/frontend/src/lib/auth.svelte.ts index 8bd190c..c2d8bf2 100644 --- a/frontend/src/lib/auth.svelte.ts +++ b/frontend/src/lib/auth.svelte.ts @@ -32,8 +32,9 @@ export async function loadUser() { } catch { user = null; clearTokens(); + } finally { + loading = false; } - loading = false; } export async function login(username: string, password: string) { diff --git a/frontend/src/routes/+layout.svelte b/frontend/src/routes/+layout.svelte index d6570b7..543cfd5 100644 --- a/frontend/src/routes/+layout.svelte +++ b/frontend/src/routes/+layout.svelte @@ -28,8 +28,12 @@ }); -{#if isAuthPage || auth.loading} +{#if isAuthPage} {@render children()} +{:else if auth.loading} +
+

Loading...

+
{:else if auth.user}
diff --git a/frontend/src/routes/servers/+page.svelte b/frontend/src/routes/servers/+page.svelte index a34392a..eeb9754 100644 --- a/frontend/src/routes/servers/+page.svelte +++ b/frontend/src/routes/servers/+page.svelte @@ -31,8 +31,10 @@ async function remove(id: number) { if (!confirm('Delete this server?')) return; - await api(`/servers/${id}`, { method: 'DELETE' }); - await load(); + try { + await api(`/servers/${id}`, { method: 'DELETE' }); + await load(); + } catch (err: any) { error = err.message; } } diff --git a/frontend/src/routes/targets/+page.svelte b/frontend/src/routes/targets/+page.svelte index 6f5c05b..3a615ee 100644 --- a/frontend/src/routes/targets/+page.svelte +++ b/frontend/src/routes/targets/+page.svelte @@ -20,10 +20,10 @@ async function create(e: SubmitEvent) { e.preventDefault(); error = ''; - const config = formType === 'telegram' - ? { bot_token: form.bot_token, chat_id: form.chat_id } - : { url: form.url, headers: form.headers ? JSON.parse(form.headers) : {} }; try { + const config = formType === 'telegram' + ? { bot_token: form.bot_token, chat_id: form.chat_id } + : { url: form.url, headers: form.headers ? JSON.parse(form.headers) : {} }; await api('/targets', { method: 'POST', body: JSON.stringify({ type: formType, name: form.name, config }) }); showForm = false; form = { name: '', bot_token: '', chat_id: '', url: '', headers: '' }; diff --git a/frontend/src/routes/templates/+page.svelte b/frontend/src/routes/templates/+page.svelte index 11acaf0..67383b9 100644 --- a/frontend/src/routes/templates/+page.svelte +++ b/frontend/src/routes/templates/+page.svelte @@ -8,6 +8,7 @@ let showForm = $state(false); let form = $state({ name: '', body: '{{ added_count }} new item(s) added to album "{{ album_name }}".' }); let preview = $state(''); + let previewId = $state(null); let editing = $state(null); let error = $state(''); @@ -33,6 +34,7 @@ } async function doPreview(id: number) { + previewId = id; try { const res = await api<{ rendered: string }>(`/templates/${id}/preview`, { method: 'POST' }); preview = res.rendered; @@ -48,8 +50,10 @@ async function remove(id: number) { if (!confirm('Delete this template?')) return; - await api(`/templates/${id}`, { method: 'DELETE' }); - await load(); + try { + await api(`/templates/${id}`, { method: 'DELETE' }); + await load(); + } catch (err: any) { error = err.message; } } @@ -94,8 +98,10 @@

{template.name}

{template.body.slice(0, 200)}{template.body.length > 200 ? '...' : ''}
- {#if preview && editing === null} - + {#if preview && previewId === template.id && !showForm} +
+
{preview}
+
{/if}
@@ -107,10 +113,4 @@ {/each}
- {#if preview && !showForm} - -

Preview

-
{preview}
-
- {/if} {/if} diff --git a/frontend/src/routes/trackers/+page.svelte b/frontend/src/routes/trackers/+page.svelte index fafb74c..e1a15c1 100644 --- a/frontend/src/routes/trackers/+page.svelte +++ b/frontend/src/routes/trackers/+page.svelte @@ -15,9 +15,11 @@ onMount(load); async function load() { - [trackers, servers, targets] = await Promise.all([ - api('/trackers'), api('/servers'), api('/targets') - ]); + try { + [trackers, servers, targets] = await Promise.all([ + api('/trackers'), api('/servers'), api('/targets') + ]); + } catch { /* handled by api redirect on 401 */ } } async function loadAlbums() { @@ -45,8 +47,10 @@ async function remove(id: number) { if (!confirm('Delete this tracker?')) return; - await api(`/trackers/${id}`, { method: 'DELETE' }); - await load(); + try { + await api(`/trackers/${id}`, { method: 'DELETE' }); + await load(); + } catch (err: any) { error = err.message; } } function toggleAlbum(albumId: string) {