| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- <script setup>
- import { computed, ref, watch } from "vue";
- import { useRoute, useRouter } from "vue-router";
- import BotaoAlterarTema from "../../components/BotaoAlterarTema.vue";
- import { useAuth } from "../../composables/useAuth.js";
- const router = useRouter();
- const route = useRoute();
- const { login } = useAuth();
- const form = ref({
- login: "",
- senha: "",
- rememberMe: false
- });
- const loading = ref(false);
- const error = ref("");
- const canSubmit = computed(() => {
- return Boolean(form.value.login.trim() && form.value.senha);
- });
- watch(() => [form.value.login, form.value.senha], () => {
- if (error.value) error.value = "";
- });
- async function onSubmit() {
- if (!canSubmit.value || loading.value) return;
- loading.value = true;
- error.value = "";
- try {
- await login(form.value);
- const raw = typeof route.query.redirect === "string" ? route.query.redirect : "";
- const redirect = raw.startsWith("/") && !raw.startsWith("//") ? raw : "/";
- await router.replace(redirect);
- } catch (err) {
- error.value = err?.message || "Falha ao realizar login.";
- } finally {
- loading.value = false;
- }
- }
- </script>
- <template>
- <div class="relative min-h-screen overflow-hidden bg-background text-foreground">
- <div
- aria-hidden="true"
- class="pointer-events-none absolute inset-0 z-0 bg-[radial-gradient(900px_520px_at_20%_10%,rgba(37,99,235,0.12),transparent_60%),radial-gradient(700px_520px_at_85%_35%,rgba(162,102,255,0.10),transparent_60%)] dark:hidden"
- />
- <div
- aria-hidden="true"
- class="pointer-events-none absolute inset-0 z-0 hidden bg-[radial-gradient(900px_520px_at_20%_10%,rgba(91,140,255,0.18),transparent_60%),radial-gradient(700px_520px_at_85%_35%,rgba(162,102,255,0.14),transparent_60%)] dark:block"
- />
- <header class="relative z-10 flex items-center justify-between px-6 py-5">
- <div>
- <div class="text-[16px] font-extrabold tracking-[0.14em]">ORÁCULO</div>
- <div class="mt-1 text-sm text-gray-500 dark:text-gray-400">
- Acesso ao assistente interno
- </div>
- </div>
- <BotaoAlterarTema />
- </header>
- <main class="relative z-10 flex min-h-[calc(100vh-88px)] items-center justify-center px-4 pb-8">
- <div
- class="w-full max-w-md rounded-[28px] border border-gray-300 bg-white/80 p-6 shadow-sm backdrop-blur-md dark:border-white/[0.18] dark:bg-gradient-to-b dark:from-[#101827] dark:to-[#070b16] dark:shadow-[0_18px_50px_rgba(0,0,0,0.35)]"
- >
- <div class="text-2xl font-extrabold tracking-tight">Entrar</div>
- <div class="mt-2 text-sm text-gray-500 dark:text-gray-400">
- Informe seu usuario ou email e sua senha para acessar o sistema.
- </div>
- <form class="mt-6 grid gap-4" @submit.prevent="onSubmit">
- <label class="grid gap-1.5">
- <span class="text-sm font-medium">Usuario ou email</span>
- <input
- v-model="form.login"
- type="text"
- name="username"
- autocomplete="username"
- placeholder="Digite seu login"
- required
- aria-required="true"
- />
- </label>
- <label class="grid gap-1.5">
- <span class="text-sm font-medium">Senha</span>
- <input
- v-model="form.senha"
- type="password"
- name="password"
- autocomplete="current-password"
- placeholder="Digite sua senha"
- required
- aria-required="true"
- />
- </label>
- <label class="flex items-center gap-2 text-sm text-gray-600 dark:text-gray-300">
- <input
- v-model="form.rememberMe"
- type="checkbox"
- class="!h-4 !w-4 rounded border-gray-300 !p-0"
- />
- <span>Manter conectado neste navegador</span>
- </label>
- <div
- v-if="error"
- class="rounded-xl border border-red-300 bg-red-50 px-3 py-2 text-sm text-red-700 dark:border-red-500/40 dark:bg-red-500/10 dark:text-red-200"
- >
- {{ error }}
- </div>
- <button
- type="submit"
- class="mt-2 inline-flex items-center justify-center rounded-xl border border-primary bg-primary px-4 py-2.5 text-sm font-semibold text-primary-foreground transition-colors hover:border-[var(--primary-600)] hover:bg-[var(--primary-600)] focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed"
- :disabled="!canSubmit || loading"
- >
- {{ loading ? "Entrando..." : "Entrar" }}
- </button>
- </form>
- </div>
- </main>
- </div>
- </template>
|