diff options
| author | zwlucas <lucas.fariamo08@gmail.com> | 2026-05-29 21:24:59 +0000 |
|---|---|---|
| committer | zwlucas <lucas.fariamo08@gmail.com> | 2026-05-29 21:24:59 +0000 |
| commit | bf8b1d0d49703e82cf8162399405984bd0b3fe88 (patch) | |
| tree | af4ed5fb7feae49cb3ebe1c8c3f87831e53b8273 /frontend/src/routes/login/+page.svelte | |
| parent | 17b159c563278c3b3b8b3884be37f8d5025ce0c7 (diff) | |
| download | yaum-bf8b1d0d49703e82cf8162399405984bd0b3fe88.tar.gz yaum-bf8b1d0d49703e82cf8162399405984bd0b3fe88.zip | |
feat: implement static file serving and Docker support, update frontend build process
Signed-off-by: zwlucas <lucas.fariamo08@gmail.com>
Diffstat (limited to 'frontend/src/routes/login/+page.svelte')
| -rw-r--r-- | frontend/src/routes/login/+page.svelte | 61 |
1 files changed, 55 insertions, 6 deletions
diff --git a/frontend/src/routes/login/+page.svelte b/frontend/src/routes/login/+page.svelte index a472c89..2b12a75 100644 --- a/frontend/src/routes/login/+page.svelte +++ b/frontend/src/routes/login/+page.svelte @@ -1,5 +1,53 @@ <script lang="ts"> - let { form }: { form?: { error?: string } } = $props(); + import { onMount } from 'svelte'; + import { goto } from '$app/navigation'; + + let errorMsg = $state(''); + let loading = $state(false); + + async function handleSubmit(e: Event) { + e.preventDefault(); + loading = true; + errorMsg = ''; + const formData = new FormData(e.target as HTMLFormElement); + try { + const res = await fetch('/api/auth/login', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + username: formData.get('username'), + password: formData.get('password') + }) + }); + if (!res.ok) { + const err = await res.json().catch(() => ({})); + errorMsg = err.error || 'Credenciais inválidas'; + return; + } + const { token } = await res.json(); + document.cookie = `auth_token=${token}; path=/; max-age=${7 * 24 * 60 * 60}; SameSite=Lax`; + goto('/admin'); + } catch { + errorMsg = 'Erro de conexão com o servidor'; + } finally { + loading = false; + } + } + + onMount(async () => { + const hasToken = document.cookie.split(';').some(c => c.trim().startsWith('auth_token=')); + if (!hasToken) return; + try { + const res = await fetch('/api/auth/verify', { + headers: { Authorization: `Bearer ${getCookie('auth_token')}` } + }); + if (res.ok) goto('/admin'); + } catch { /* ignore */ } + }); + + function getCookie(name: string) { + return document.cookie.split('; ').find(r => r.startsWith(name + '='))?.split('=')[1] ?? ''; + } </script> <svelte:head> @@ -14,7 +62,7 @@ </div> <div class="rounded-2xl border border-[var(--border-color)] bg-[var(--bg-card)] p-6"> - <form method="POST" class="space-y-4"> + <form onsubmit={handleSubmit} class="space-y-4"> <div> <label for="username" class="mb-1.5 block text-xs font-medium text-[var(--text-secondary)]">Usuário</label> <input @@ -41,15 +89,16 @@ /> </div> - {#if form?.error} - <p class="rounded-lg bg-[var(--red)]/5 px-3 py-2 text-xs text-[var(--red)]">{form.error}</p> + {#if errorMsg} + <p class="rounded-lg bg-[var(--red)]/5 px-3 py-2 text-xs text-[var(--red)]">{errorMsg}</p> {/if} <button type="submit" - class="w-full rounded-xl border border-[var(--green)]/50 bg-[var(--green)]/10 px-4 py-2.5 text-sm font-medium text-[var(--green)] transition-all hover:bg-[var(--green)]/20" + disabled={loading} + class="w-full rounded-xl border border-[var(--green)]/50 bg-[var(--green)]/10 px-4 py-2.5 text-sm font-medium text-[var(--green)] transition-all hover:bg-[var(--green)]/20 disabled:opacity-50" > - Entrar + {loading ? 'Entrando…' : 'Entrar'} </button> </form> </div> |