Adicionada compressão Brotli/Gzip, auto-import de Vue e PrimeVue, e análise visual do bundle para otimização de produção e Remove AppLayout duplicado de cada área (therapist, admin, configuracoes, account, supervisor, billing, features) e consolida sob um único pai no router/index.js. Adiciona RouterPassthrough para grupos de rota sem layout intermediário. Remove debug ativo (console.trace em router.push e queries Supabase em todo watch de rota) que degradava performance para todos os usuários.
This commit is contained in:
+39
-63
@@ -1,56 +1,42 @@
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Agência PSI
|
||||
|--------------------------------------------------------------------------
|
||||
| Criado e desenvolvido por Leonardo Nohama
|
||||
|
|
||||
| Tecnologia aplicada à escuta.
|
||||
| Estrutura para o cuidado.
|
||||
|
|
||||
| Arquivo: src/main.js
|
||||
| Data: 2026
|
||||
| Local: São Carlos/SP — Brasil
|
||||
|--------------------------------------------------------------------------
|
||||
| © 2026 — Todos os direitos reservados
|
||||
| Agência PSI (OTIMIZADO)
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
import { pinia } from '@/plugins/pinia';
|
||||
import router from '@/router';
|
||||
import { createApp } from 'vue';
|
||||
import App from './App.vue';
|
||||
import router from '@/router';
|
||||
import { pinia } from '@/plugins/pinia'; // ← singleton criado antes do router
|
||||
import { setOnSignedOut, initSession, listenAuthChanges, refreshSession } from '@/app/session';
|
||||
|
||||
import { initSession, listenAuthChanges, refreshSession, setOnSignedOut } from '@/app/session';
|
||||
|
||||
// PrimeVue core
|
||||
import Aura from '@primeuix/themes/aura';
|
||||
import PrimeVue from 'primevue/config';
|
||||
|
||||
// serviços (ok global)
|
||||
import ConfirmationService from 'primevue/confirmationservice';
|
||||
import ToastService from 'primevue/toastservice';
|
||||
|
||||
// ✅ SOMENTE COMPONENTES LEVES GLOBAIS
|
||||
import Button from 'primevue/button';
|
||||
import Divider from 'primevue/divider';
|
||||
import InputText from 'primevue/inputtext';
|
||||
import Tag from 'primevue/tag';
|
||||
import Toast from 'primevue/toast';
|
||||
|
||||
// seus componentes leves
|
||||
import AppLoadingPhrases from '@/components/ui/AppLoadingPhrases.vue';
|
||||
import LoadedPhraseBlock from '@/components/ui/LoadedPhraseBlock.vue';
|
||||
|
||||
// ── Componentes PrimeVue globais (≥ 10 usos no projeto) ──────────────────────
|
||||
import Button from 'primevue/button';
|
||||
import InputText from 'primevue/inputtext';
|
||||
import Tag from 'primevue/tag';
|
||||
import FloatLabel from 'primevue/floatlabel';
|
||||
import Toast from 'primevue/toast';
|
||||
import IconField from 'primevue/iconfield';
|
||||
import InputIcon from 'primevue/inputicon';
|
||||
import Divider from 'primevue/divider';
|
||||
import Card from 'primevue/card';
|
||||
import SelectButton from 'primevue/selectbutton';
|
||||
import Dialog from 'primevue/dialog';
|
||||
import DataTable from 'primevue/datatable';
|
||||
import Column from 'primevue/column';
|
||||
import ConfirmDialog from 'primevue/confirmdialog';
|
||||
import Menu from 'primevue/menu';
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
import '@/assets/tailwind.css';
|
||||
// estilos
|
||||
import '@/assets/styles.scss';
|
||||
import '@/assets/tailwind.css';
|
||||
|
||||
import { supabase } from '@/lib/supabase/client';
|
||||
|
||||
// ✅ pt-BR (PrimeVue locale global)
|
||||
// locale
|
||||
const ptBR = {
|
||||
firstDayOfWeek: 1,
|
||||
dayNames: ['domingo', 'segunda-feira', 'terça-feira', 'quarta-feira', 'quinta-feira', 'sexta-feira', 'sábado'],
|
||||
@@ -64,15 +50,16 @@ const ptBR = {
|
||||
dateFormat: 'dd/mm/yy'
|
||||
};
|
||||
|
||||
// theme antecipado
|
||||
async function applyUserThemeEarly() {
|
||||
try {
|
||||
const { data } = await supabase.auth.getUser();
|
||||
const user = data?.user;
|
||||
if (!user) return;
|
||||
|
||||
const { data: settings, error } = await supabase.from('user_settings').select('theme_mode').eq('user_id', user.id).maybeSingle();
|
||||
const { data: settings } = await supabase.from('user_settings').select('theme_mode').eq('user_id', user.id).maybeSingle();
|
||||
|
||||
if (error || !settings?.theme_mode) return;
|
||||
if (!settings?.theme_mode) return;
|
||||
|
||||
const isDark = settings.theme_mode === 'dark';
|
||||
document.documentElement.classList.toggle('app-dark', isDark);
|
||||
@@ -80,15 +67,15 @@ async function applyUserThemeEarly() {
|
||||
} catch {}
|
||||
}
|
||||
|
||||
// logout
|
||||
setOnSignedOut(() => {
|
||||
router.replace('/auth/login');
|
||||
});
|
||||
|
||||
// ===== flags globais (debug/controle) =====
|
||||
// flags
|
||||
window.__sessionRefreshing = false;
|
||||
window.__fromVisibilityRefresh = false;
|
||||
window.__appBootstrapped = false;
|
||||
// ========================================
|
||||
|
||||
let lastVisibilityRefreshAt = 0;
|
||||
|
||||
@@ -97,7 +84,7 @@ document.addEventListener('visibilitychange', async () => {
|
||||
if (!window.__appBootstrapped) return;
|
||||
|
||||
const now = Date.now();
|
||||
if (now - lastVisibilityRefreshAt < 10_000) return;
|
||||
if (now - lastVisibilityRefreshAt < 10000) return;
|
||||
if (window.__sessionRefreshing) return;
|
||||
|
||||
try {
|
||||
@@ -106,7 +93,6 @@ document.addEventListener('visibilitychange', async () => {
|
||||
} catch {}
|
||||
|
||||
lastVisibilityRefreshAt = now;
|
||||
console.log('[VISIBILITY] Aba voltou -> refreshSession()');
|
||||
|
||||
try {
|
||||
window.__sessionRefreshing = true;
|
||||
@@ -114,16 +100,16 @@ document.addEventListener('visibilitychange', async () => {
|
||||
|
||||
await refreshSession();
|
||||
|
||||
try {
|
||||
const path = router.currentRoute.value?.path || '';
|
||||
const isTenantArea = path.startsWith('/admin') || path.startsWith('/therapist') || path.startsWith('/saas');
|
||||
const path = router.currentRoute.value?.path || '';
|
||||
const isTenantArea = path.startsWith('/admin') || path.startsWith('/therapist') || path.startsWith('/saas');
|
||||
|
||||
if (isTenantArea) {
|
||||
window.dispatchEvent(new CustomEvent('app:session-refreshed', { detail: { source: 'visibility' } }));
|
||||
} else {
|
||||
console.log('[VISIBILITY] refresh ok (skip event) - area não-tenant:', path);
|
||||
}
|
||||
} catch {}
|
||||
if (isTenantArea) {
|
||||
window.dispatchEvent(
|
||||
new CustomEvent('app:session-refreshed', {
|
||||
detail: { source: 'visibility' }
|
||||
})
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
window.__fromVisibilityRefresh = false;
|
||||
window.__sessionRefreshing = false;
|
||||
@@ -133,12 +119,10 @@ document.addEventListener('visibilitychange', async () => {
|
||||
async function bootstrap() {
|
||||
await initSession({ initial: true });
|
||||
listenAuthChanges();
|
||||
|
||||
await applyUserThemeEarly();
|
||||
|
||||
const app = createApp(App);
|
||||
|
||||
// ✅ usa o pinia singleton — o mesmo que o router/guards já conhecem
|
||||
app.use(pinia);
|
||||
app.use(router);
|
||||
|
||||
@@ -155,21 +139,13 @@ async function bootstrap() {
|
||||
app.use(ToastService);
|
||||
app.use(ConfirmationService);
|
||||
|
||||
// ✅ globais leves
|
||||
app.component('Button', Button);
|
||||
app.component('InputText', InputText);
|
||||
app.component('Tag', Tag);
|
||||
app.component('FloatLabel', FloatLabel);
|
||||
app.component('Toast', Toast);
|
||||
app.component('IconField', IconField);
|
||||
app.component('InputIcon', InputIcon);
|
||||
app.component('Divider', Divider);
|
||||
app.component('Card', Card);
|
||||
app.component('SelectButton', SelectButton);
|
||||
app.component('Dialog', Dialog);
|
||||
app.component('DataTable', DataTable);
|
||||
app.component('Column', Column);
|
||||
app.component('ConfirmDialog', ConfirmDialog);
|
||||
app.component('Menu', Menu);
|
||||
app.component('Toast', Toast);
|
||||
|
||||
app.component('AppLoadingPhrases', AppLoadingPhrases);
|
||||
app.component('LoadedPhraseBlock', LoadedPhraseBlock);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user