115 lines
4.5 KiB
Vue
115 lines
4.5 KiB
Vue
<script setup>
|
|
import { computed } from 'vue'
|
|
import { useRoute, useRouter } from 'vue-router'
|
|
|
|
|
|
const router = useRouter()
|
|
const route = useRoute()
|
|
|
|
const attemptedPath = computed(() => route.fullPath || '')
|
|
|
|
function goDashboard () {
|
|
// Em muitos projetos, '/' redireciona para o dashboard correto conforme role.
|
|
router.push('/admin')
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="relative min-h-screen overflow-hidden bg-[var(--surface-ground)] text-[var(--text-color)]">
|
|
<!-- fundo conceitual: grid + halos -->
|
|
<div class="pointer-events-none absolute inset-0 opacity-80">
|
|
<!-- grid sutil -->
|
|
<div
|
|
class="absolute inset-0"
|
|
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: 36px 36px;
|
|
mask-image: radial-gradient(ellipse at center, rgba(0,0,0,.9), transparent 70%);
|
|
"
|
|
/>
|
|
<!-- halos -->
|
|
<div class="absolute -top-24 -right-24 h-80 w-80 rounded-full blur-3xl bg-primary/10" />
|
|
<div class="absolute -bottom-28 -left-28 h-96 w-96 rounded-full blur-3xl bg-purple-500/10" />
|
|
</div>
|
|
|
|
<div class="relative flex min-h-screen items-center justify-center p-6">
|
|
<div class="w-full max-w-xl">
|
|
<div
|
|
class="overflow-hidden rounded-3xl border border-[var(--surface-border)] bg-[var(--surface-card)] shadow-2xl"
|
|
>
|
|
<!-- faixa superior -->
|
|
<div class="relative px-8 pt-10 pb-7">
|
|
<div class="flex items-start justify-between gap-6">
|
|
<div class="flex flex-col">
|
|
<div class="tracking-tight font-semibold text-5xl sm:text-6xl leading-none">
|
|
<span class="text-primary">404</span>
|
|
</div>
|
|
<div class="mt-3 text-xl sm:text-2xl font-medium text-[var(--text-color)]">
|
|
Página não encontrada
|
|
</div>
|
|
<p class="mt-3 text-[var(--text-color-secondary)] leading-relaxed">
|
|
A rota que você tentou acessar não existe (ou foi movida).
|
|
Se você chegou aqui por um link interno, vale revisar o caminho.
|
|
</p>
|
|
</div>
|
|
|
|
<!-- “selo” minimalista -->
|
|
<div
|
|
class="shrink-0 rounded-2xl border border-[var(--surface-border)] bg-[var(--surface-ground)] p-4"
|
|
>
|
|
<div class="flex items-center gap-3">
|
|
<span
|
|
class="flex h-11 w-11 items-center justify-center rounded-xl border border-primary/30 bg-primary/10"
|
|
aria-hidden="true"
|
|
>
|
|
<i class="pi pi-compass text-xl text-primary" />
|
|
</span>
|
|
<div class="leading-tight">
|
|
<div class="text-sm font-semibold">Rota</div>
|
|
<div class="max-w-[12rem] truncate text-sm text-[var(--text-color-secondary)]" :title="attemptedPath">
|
|
{{ attemptedPath || '—' }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- linha suave -->
|
|
<div class="mt-8 h-px w-full bg-[var(--surface-border)] opacity-70" />
|
|
</div>
|
|
|
|
<!-- ações -->
|
|
<div class="px-8 pb-10">
|
|
<div class="flex flex-col sm:flex-row items-stretch sm:items-center justify-between gap-3">
|
|
<div class="text-sm text-[var(--text-color-secondary)]">
|
|
Dica: você pode voltar ao fluxo principal do sistema pelo dashboard.
|
|
</div>
|
|
|
|
<Button
|
|
label="Voltar ao Dashboard"
|
|
icon="pi pi-home"
|
|
class="w-full sm:w-auto"
|
|
@click="goDashboard"
|
|
/>
|
|
</div>
|
|
|
|
<!-- rodapé “noir” discreto -->
|
|
<div class="mt-6 text-xs text-[var(--text-color-secondary)] opacity-80">
|
|
Se isso estiver acontecendo com frequência, pode ser um problema de rota ou permissão.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- assinatura visual sutil -->
|
|
<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>Agência Psi Quasar</span>
|
|
<span class="inline-block h-1.5 w-1.5 rounded-full bg-primary/60" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|