first commit
This commit is contained in:
@@ -0,0 +1,293 @@
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { supabase } from '../../lib/supabase/client' // ajuste se o caminho for outro
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
const checking = ref(true)
|
||||
const userEmail = ref('')
|
||||
const role = ref(null)
|
||||
|
||||
const TEST_ACCOUNTS = {
|
||||
admin: { email: 'admin@agenciapsi.com.br', password: '123Mudar@' },
|
||||
therapist: { email: 'therapist@agenciapsi.com.br', password: '123Mudar@' },
|
||||
patient: { email: 'patient@agenciapsi.com.br', password: '123Mudar@' }
|
||||
}
|
||||
|
||||
|
||||
function roleToPath(r) {
|
||||
if (r === 'admin') return '/admin'
|
||||
if (r === 'therapist') return '/therapist'
|
||||
if (r === 'patient') return '/patient'
|
||||
return '/'
|
||||
}
|
||||
|
||||
async function fetchMyRole() {
|
||||
const { data: userData, error: userErr } = await supabase.auth.getUser()
|
||||
if (userErr) return null
|
||||
const user = userData?.user
|
||||
if (!user) return null
|
||||
|
||||
userEmail.value = user.email || ''
|
||||
|
||||
const { data, error } = await supabase
|
||||
.from('profiles')
|
||||
.select('role')
|
||||
.eq('id', user.id)
|
||||
.single()
|
||||
|
||||
if (error) return null
|
||||
return data?.role || null
|
||||
}
|
||||
|
||||
async function go(area) {
|
||||
// Se já estiver logado, respeita role real (não o card)
|
||||
const { data: sessionData } = await supabase.auth.getSession()
|
||||
const session = sessionData?.session
|
||||
|
||||
if (session) {
|
||||
const r = role.value || (await fetchMyRole())
|
||||
if (!r) return router.push('/auth/login')
|
||||
return router.push(roleToPath(r))
|
||||
}
|
||||
|
||||
// Se não estiver logado, manda pro login guardando a intenção
|
||||
sessionStorage.setItem('intended_area', area) // admin/therapist/patient
|
||||
|
||||
// ✅ Prefill de login (apenas DEV)
|
||||
const DEV_PREFILL = import.meta.env.DEV
|
||||
if (DEV_PREFILL) {
|
||||
const TEST_ACCOUNTS = {
|
||||
admin: { email: 'admin@agenciapsi.com.br', password: '123Mudar@' },
|
||||
therapist: { email: 'therapist@agenciapsi.com.br', password: '123Mudar@' },
|
||||
patient: { email: 'patient@agenciapsi.com.br', password: '123Mudar@' }
|
||||
}
|
||||
|
||||
const acc = TEST_ACCOUNTS[area]
|
||||
if (acc) {
|
||||
sessionStorage.setItem('login_prefill_email', acc.email)
|
||||
sessionStorage.setItem('login_prefill_password', acc.password)
|
||||
} else {
|
||||
sessionStorage.removeItem('login_prefill_email')
|
||||
sessionStorage.removeItem('login_prefill_password')
|
||||
}
|
||||
}
|
||||
|
||||
router.push('/auth/login')
|
||||
}
|
||||
|
||||
async function goMyPanel() {
|
||||
if (!role.value) return
|
||||
router.push(roleToPath(role.value))
|
||||
}
|
||||
|
||||
async function logout() {
|
||||
await supabase.auth.signOut()
|
||||
role.value = null
|
||||
userEmail.value = ''
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
try {
|
||||
const { data: sessionData } = await supabase.auth.getSession()
|
||||
const session = sessionData?.session
|
||||
|
||||
if (session) {
|
||||
role.value = await fetchMyRole()
|
||||
|
||||
// Se está logado e tem role, manda direto pro painel
|
||||
if (role.value) {
|
||||
router.replace(roleToPath(role.value))
|
||||
return
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
checking.value = false
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- Estado carregando sessão -->
|
||||
<div
|
||||
v-if="checking"
|
||||
class="relative min-h-screen flex items-center justify-center bg-[var(--surface-ground)]"
|
||||
>
|
||||
<div class="text-[var(--text-color-secondary)] text-sm animate-pulse">
|
||||
Verificando sessão…
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Página -->
|
||||
<div
|
||||
v-else
|
||||
class="relative min-h-screen overflow-hidden bg-[var(--surface-ground)]"
|
||||
>
|
||||
<!-- fundo conceitual -->
|
||||
<div class="pointer-events-none absolute inset-0">
|
||||
<!-- grid sutil -->
|
||||
<div
|
||||
class="absolute inset-0 opacity-70"
|
||||
style="
|
||||
background-image:
|
||||
linear-gradient(to right, rgba(255,255,255,.05) 1px, transparent 1px),
|
||||
linear-gradient(to bottom, rgba(255,255,255,.05) 1px, transparent 1px);
|
||||
background-size: 40px 40px;
|
||||
mask-image: radial-gradient(ellipse at 50% 15%, rgba(0,0,0,.95), transparent 70%);
|
||||
"
|
||||
/>
|
||||
<!-- halos -->
|
||||
<div class="absolute -top-32 -right-32 h-[28rem] w-[28rem] rounded-full blur-3xl bg-indigo-400/10" />
|
||||
<div class="absolute top-20 -left-32 h-[32rem] w-[32rem] rounded-full blur-3xl bg-emerald-400/10" />
|
||||
<div class="absolute -bottom-36 right-24 h-[28rem] w-[28rem] rounded-full blur-3xl bg-fuchsia-400/10" />
|
||||
</div>
|
||||
|
||||
<div class="relative flex items-center justify-center min-h-screen p-6">
|
||||
<div class="w-full max-w-6xl">
|
||||
<div class="overflow-hidden rounded-[2.75rem] border border-[var(--surface-border)] bg-[var(--surface-card)] shadow-2xl">
|
||||
|
||||
<!-- HEADER -->
|
||||
<div class="px-8 pt-10 pb-8">
|
||||
<div class="flex items-start justify-between gap-6">
|
||||
<div>
|
||||
<div class="text-3xl md:text-4xl font-semibold text-[var(--text-color)]">
|
||||
Agência PSI
|
||||
</div>
|
||||
<div class="mt-2 text-[var(--text-color-secondary)] text-sm md:text-base">
|
||||
Ambiente de acesso e testes de perfis
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hidden md:flex items-center gap-2 text-xs text-[var(--text-color-secondary)]">
|
||||
<span class="inline-block h-1.5 w-1.5 rounded-full bg-primary/60" />
|
||||
Dev Mode
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-8 h-px w-full bg-[var(--surface-border)] opacity-70" />
|
||||
</div>
|
||||
|
||||
<!-- SE JÁ ESTIVER LOGADO -->
|
||||
<div
|
||||
v-if="role"
|
||||
class="mx-8 mb-6 rounded-2xl border border-[var(--surface-border)] bg-[var(--surface-ground)] p-5 flex flex-col md:flex-row md:items-center md:justify-between gap-4"
|
||||
>
|
||||
<div>
|
||||
<div class="font-semibold text-[var(--text-color)]">
|
||||
Sessão ativa
|
||||
</div>
|
||||
<div class="text-sm text-[var(--text-color-secondary)] mt-1">
|
||||
{{ userEmail }} — perfil: <span class="font-medium">{{ role }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-3">
|
||||
<Button
|
||||
label="Ir para meu painel"
|
||||
icon="pi pi-arrow-right"
|
||||
@click="goMyPanel"
|
||||
/>
|
||||
<Button
|
||||
label="Sair"
|
||||
severity="secondary"
|
||||
outlined
|
||||
@click="logout"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- CARDS -->
|
||||
<div class="px-8 pb-10">
|
||||
<div class="grid grid-cols-12 gap-6">
|
||||
|
||||
<!-- ADMIN -->
|
||||
<div class="col-span-12 md:col-span-4">
|
||||
<div
|
||||
class="group h-full cursor-pointer rounded-2xl border border-[var(--surface-border)] bg-[var(--surface-ground)] p-6 transition-all hover:shadow-xl hover:-translate-y-1"
|
||||
@click="go('admin')"
|
||||
>
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<div class="text-xl font-semibold text-[var(--text-color)]">
|
||||
Admin
|
||||
</div>
|
||||
<i class="pi pi-building text-sm opacity-70" />
|
||||
</div>
|
||||
|
||||
<div class="text-sm text-[var(--text-color-secondary)] leading-relaxed">
|
||||
Gestão da clínica, controle de usuários, permissões, planos e configurações globais.
|
||||
</div>
|
||||
|
||||
<div class="mt-6 text-sm font-medium text-primary opacity-80 group-hover:opacity-100 transition">
|
||||
Acessar painel →
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- TERAPEUTA -->
|
||||
<div class="col-span-12 md:col-span-4">
|
||||
<div
|
||||
class="group h-full cursor-pointer rounded-2xl border border-[var(--surface-border)] bg-[var(--surface-ground)] p-6 transition-all hover:shadow-xl hover:-translate-y-1"
|
||||
@click="go('therapist')"
|
||||
>
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<div class="text-xl font-semibold text-[var(--text-color)]">
|
||||
Terapeuta
|
||||
</div>
|
||||
<i class="pi pi-calendar text-sm opacity-70" />
|
||||
</div>
|
||||
|
||||
<div class="text-sm text-[var(--text-color-secondary)] leading-relaxed">
|
||||
Agenda, prontuários, evolução clínica, gestão de pacientes e atendimentos.
|
||||
</div>
|
||||
|
||||
<div class="mt-6 text-sm font-medium text-primary opacity-80 group-hover:opacity-100 transition">
|
||||
Acessar painel →
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PACIENTE -->
|
||||
<div class="col-span-12 md:col-span-4">
|
||||
<div
|
||||
class="group h-full cursor-pointer rounded-2xl border border-[var(--surface-border)] bg-[var(--surface-ground)] p-6 transition-all hover:shadow-xl hover:-translate-y-1"
|
||||
@click="go('patient')"
|
||||
>
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<div class="text-xl font-semibold text-[var(--text-color)]">
|
||||
Paciente
|
||||
</div>
|
||||
<i class="pi pi-user text-sm opacity-70" />
|
||||
</div>
|
||||
|
||||
<div class="text-sm text-[var(--text-color-secondary)] leading-relaxed">
|
||||
Visualização de informações pessoais, documentos e interações com a clínica.
|
||||
</div>
|
||||
|
||||
<div class="mt-6 text-sm font-medium text-primary opacity-80 group-hover:opacity-100 transition">
|
||||
Acessar painel →
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Rodapé explicativo -->
|
||||
<div class="mt-10 text-center text-xs text-[var(--text-color-secondary)] opacity-80">
|
||||
Você será redirecionado para o login (se necessário) e, após autenticação,
|
||||
encaminhado automaticamente ao painel correspondente.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- assinatura visual -->
|
||||
<div class="mt-6 flex items-center justify-center gap-2 text-xs text-[var(--text-color-secondary)] opacity-70">
|
||||
<span class="inline-block h-1.5 w-1.5 rounded-full bg-primary/60" />
|
||||
<span>Ambiente de desenvolvimento</span>
|
||||
<span class="inline-block h-1.5 w-1.5 rounded-full bg-primary/60" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
Reference in New Issue
Block a user