diff options
| author | zwlucas <lucas.fariamo08@gmail.com> | 2026-05-29 18:57:37 +0000 |
|---|---|---|
| committer | zwlucas <lucas.fariamo08@gmail.com> | 2026-05-29 18:57:37 +0000 |
| commit | 6cc0bfd1d79074df790272b8091b1f0226d14283 (patch) | |
| tree | cab18b0f708cf3b0eaeeeb98e2cf81459365b33e /frontend/src/routes/login | |
| download | yaum-6cc0bfd1d79074df790272b8091b1f0226d14283.tar.gz yaum-6cc0bfd1d79074df790272b8091b1f0226d14283.zip | |
feat: upload project
Signed-off-by: zwlucas <lucas.fariamo08@gmail.com>
Diffstat (limited to 'frontend/src/routes/login')
| -rw-r--r-- | frontend/src/routes/login/+page.server.js | 51 | ||||
| -rw-r--r-- | frontend/src/routes/login/+page.svelte | 61 |
2 files changed, 112 insertions, 0 deletions
diff --git a/frontend/src/routes/login/+page.server.js b/frontend/src/routes/login/+page.server.js new file mode 100644 index 0000000..4272ef7 --- /dev/null +++ b/frontend/src/routes/login/+page.server.js @@ -0,0 +1,51 @@ +import { redirect } from '@sveltejs/kit'; + +const API = 'http://localhost:8080/api'; + +export async function load({ cookies }) { + const token = cookies.get('auth_token'); + if (token) { + const res = await fetch(`${API}/auth/verify`, { + headers: { Authorization: `Bearer ${token}` } + }); + if (res.ok) { + throw redirect(302, '/admin'); + } + } + return {}; +} + +export const actions = { + default: async ({ request, cookies }) => { + const data = await request.formData(); + const username = data.get('username'); + const password = data.get('password'); + + if (!username || !password) { + return { error: 'Preencha todos os campos' }; + } + + const res = await fetch(`${API}/auth/login`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ username, password }) + }); + + if (!res.ok) { + const err = await res.json().catch(() => ({})); + return { error: err.error || 'Credenciais inválidas' }; + } + + const { token } = await res.json(); + + cookies.set('auth_token', token, { + httpOnly: true, + secure: process.env.NODE_ENV === 'production', + sameSite: 'lax', + path: '/', + maxAge: 7 * 24 * 60 * 60 + }); + + throw redirect(302, '/admin'); + } +}; diff --git a/frontend/src/routes/login/+page.svelte b/frontend/src/routes/login/+page.svelte new file mode 100644 index 0000000..a472c89 --- /dev/null +++ b/frontend/src/routes/login/+page.svelte @@ -0,0 +1,61 @@ +<script lang="ts"> + let { form }: { form?: { error?: string } } = $props(); +</script> + +<svelte:head> + <title>Login — YAUM</title> +</svelte:head> + +<div class="flex min-h-screen items-start justify-center pt-36"> + <div class="w-full max-w-sm"> + <div class="mb-8 text-center"> + <h1 class="text-xl font-semibold tracking-tight text-white">YAUM</h1> + <p class="mt-1 text-sm text-[var(--text-muted)]">Yet Another Uptime Monitor</p> + </div> + + <div class="rounded-2xl border border-[var(--border-color)] bg-[var(--bg-card)] p-6"> + <form method="POST" 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 + id="username" + name="username" + type="text" + required + autocomplete="username" + placeholder="admin" + class="w-full rounded-xl border border-[var(--border-color)] bg-[var(--bg-secondary)] px-3.5 py-2.5 text-sm text-white outline-none transition-all placeholder:text-[var(--text-muted)] focus:border-[var(--green)]/50 focus:ring-1 focus:ring-[var(--green)]/20" + /> + </div> + + <div> + <label for="password" class="mb-1.5 block text-xs font-medium text-[var(--text-secondary)]">Senha</label> + <input + id="password" + name="password" + type="password" + required + autocomplete="current-password" + placeholder="••••••••" + class="w-full rounded-xl border border-[var(--border-color)] bg-[var(--bg-secondary)] px-3.5 py-2.5 text-sm text-white outline-none transition-all placeholder:text-[var(--text-muted)] focus:border-[var(--green)]/50 focus:ring-1 focus:ring-[var(--green)]/20" + /> + </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} + + <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" + > + Entrar + </button> + </form> + </div> + + <p class="mt-6 text-center text-xs text-[var(--text-muted)]"> + <a href="/" class="underline transition-colors hover:text-white">← Voltar ao Dashboard</a> + </p> + </div> +</div> |