102 lines
3.2 KiB
Vue
102 lines
3.2 KiB
Vue
<!--
|
|
|--------------------------------------------------------------------------
|
|
| Agência PSI
|
|
|--------------------------------------------------------------------------
|
|
| Criado e desenvolvido por Leonardo Nohama
|
|
|
|
|
| Tecnologia aplicada à escuta.
|
|
| Estrutura para o cuidado.
|
|
|
|
|
| Arquivo: src/App.vue
|
|
| Data: 2026
|
|
| Local: São Carlos/SP — Brasil
|
|
|--------------------------------------------------------------------------
|
|
| © 2026 — Todos os direitos reservados
|
|
|--------------------------------------------------------------------------
|
|
-->
|
|
<script setup>
|
|
import { onMounted, watch } from 'vue';
|
|
import { useRoute, useRouter } from 'vue-router';
|
|
import { supabase } from '@/lib/supabase/client';
|
|
import { useTenantStore } from '@/stores/tenantStore';
|
|
import { fetchDocsForPath } from '@/composables/useAjuda';
|
|
|
|
import AjudaDrawer from '@/components/AjudaDrawer.vue';
|
|
import AppOfflineOverlay from '@/components/AppOfflineOverlay.vue';
|
|
|
|
const route = useRoute();
|
|
const router = useRouter();
|
|
const tenantStore = useTenantStore();
|
|
|
|
function isTenantArea(path = '') {
|
|
return path.startsWith('/admin') || path.startsWith('/therapist') || path.startsWith('/configuracoes');
|
|
}
|
|
|
|
// ── Setup Wizard redirect ────────────────────────────────────────
|
|
// Cache por sessão: uma vez confirmado, não verifica de novo
|
|
let _setupClearedUid = null;
|
|
let _setupClearedIsClinic = null;
|
|
|
|
async function checkSetupWizard() {
|
|
if (!isTenantArea(route.path)) return;
|
|
if (route.path.includes('/setup')) return;
|
|
|
|
const uid = tenantStore.user?.id;
|
|
if (!uid) return;
|
|
|
|
const activeMembership = tenantStore.memberships?.find((m) => m.tenant_id === tenantStore.activeTenantId);
|
|
const kind = activeMembership?.kind ?? tenantStore.activeRole ?? '';
|
|
const isClinic = kind.startsWith('clinic');
|
|
|
|
// Se já confirmamos que este uid passou o setup, não verifica de novo
|
|
if (_setupClearedUid === uid && _setupClearedIsClinic === isClinic) return;
|
|
|
|
const { data } = await supabase
|
|
.from('agenda_configuracoes')
|
|
.select('setup_concluido, setup_clinica_concluido, atendimento_mode')
|
|
.eq('owner_id', uid)
|
|
.maybeSingle();
|
|
|
|
if (!data) return; // sem linha = setup nunca iniciado, não redireciona
|
|
|
|
// Considera completo se qualquer flag de conclusão estiver setada
|
|
const setupDone = data.setup_concluido || data.setup_clinica_concluido || !!data.atendimento_mode;
|
|
|
|
if (setupDone) {
|
|
// Grava cache: não verifica mais nesta sessão
|
|
_setupClearedUid = uid;
|
|
_setupClearedIsClinic = isClinic;
|
|
return;
|
|
}
|
|
|
|
const dest = isClinic ? '/admin/setup' : '/therapist/setup';
|
|
router.push(dest);
|
|
}
|
|
|
|
onMounted(() => {
|
|
fetchDocsForPath(route.path);
|
|
});
|
|
|
|
watch(
|
|
() => route.fullPath,
|
|
() => {
|
|
fetchDocsForPath(route.path);
|
|
if (isTenantArea(route.path) && tenantStore.loaded) {
|
|
checkSetupWizard();
|
|
}
|
|
}
|
|
);
|
|
</script>
|
|
|
|
<template>
|
|
<router-view />
|
|
|
|
<!-- Drawer de ajuda global — fora de qualquer layout, sempre disponível -->
|
|
<Teleport to="body">
|
|
<AjudaDrawer />
|
|
</Teleport>
|
|
|
|
<!-- Overlay de sem conexão -->
|
|
<AppOfflineOverlay />
|
|
</template>
|