Files
lic/front-end/app/pages/login.vue
Junior 9d4cb5b996 feat: tela de cadastro /register e configurações com perfil completo
- register.vue: cadastro PF/PJ com nome fantasia, razão social, CPF/CNPJ, slug
  - auto-gera slug a partir do nome fantasia
  - toggle PF/PJ muda label dos campos dinamicamente
- configuracoes.vue: exibe e edita todos os campos do perfil do tenant
- auth.global.ts: /register liberado sem autenticação
- login.vue: link para /register + remove erro duplicado

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 15:38:44 -03:00

109 lines
2.8 KiB
Vue

<!-- front-end/app/pages/login.vue -->
<script setup lang="ts">
definePageMeta({ layout: 'auth' })
const { login } = useAuth()
const email = ref('')
const password = ref('')
const slug = ref('')
const error = ref('')
const loading = ref(false)
async function handleSubmit() {
error.value = ''
loading.value = true
const result = await login(email.value, password.value, slug.value)
loading.value = false
if (result.success) {
navigateTo('/')
} else {
error.value = result.error ?? 'Erro ao autenticar.'
}
}
</script>
<template>
<div class="login-card">
<div class="login-header">
<h1>Bem-vindo de volta</h1>
<p>Informe suas credenciais para acessar o sistema</p>
</div>
<form @submit.prevent="handleSubmit">
<UFormField label="E-mail" class="field">
<UInput
v-model="email"
type="email"
placeholder="usuario@orgao.gov.br"
size="md"
required
/>
</UFormField>
<UFormField label="Senha" class="field">
<UInput
v-model="password"
type="password"
placeholder="••••••••"
size="md"
required
/>
</UFormField>
<UFormField label="Organização" class="field">
<UInput
v-model="slug"
type="text"
placeholder="minha-empresa"
size="md"
required
/>
</UFormField>
<div class="forgot">
<a href="#">Esqueceu a senha?</a>
</div>
<p v-if="error" class="error-msg">{{ error }}</p>
<UButton
type="submit"
block
size="md"
:loading="loading"
class="btn-login"
>
Entrar
</UButton>
<p class="register-link">
Não tem conta? <NuxtLink to="/register">Criar conta</NuxtLink>
</p>
</form>
</div>
</template>
<style scoped>
.login-card {
background: white;
border-radius: 20px;
padding: 48px 40px;
width: 100%;
max-width: 420px;
box-shadow: 0 25px 60px rgba(0, 0, 0, 0.25);
}
.login-header { margin-bottom: 32px; }
.login-header h1 { font-size: 24px; font-weight: 700; color: #0f172a; letter-spacing: -0.5px; }
.login-header p { font-size: 14px; color: #64748b; margin-top: 4px; }
.field { margin-bottom: 18px; }
.forgot { text-align: right; margin-top: -10px; margin-bottom: 20px; }
.forgot a { font-size: 12px; color: #667eea; text-decoration: none; font-weight: 500; }
.error-msg { color: #dc2626; font-size: 13px; margin-bottom: 12px; }
.btn-login {
background: linear-gradient(135deg, #667eea, #764ba2) !important;
box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4);
}
.register-link { text-align: center; font-size: 13px; color: #64748b; margin-top: 16px; }
.register-link a { color: #667eea; font-weight: 600; text-decoration: none; }
</style>