Documentos Pacientes, Template Documentos Pacientes Saas, Documentos prontuários, Documentos Externos, Visualização Externa, Permissão de Visualização, Render Otimização
This commit is contained in:
+67
-48
@@ -1,9 +1,18 @@
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Agência PSI (OTIMIZADO)
|
||||
| Agência PSI — main.js
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
(function applyDarkModeImmediate() {
|
||||
try {
|
||||
const saved = localStorage.getItem('ui_theme_mode');
|
||||
if (saved === 'dark' || saved === 'light') {
|
||||
document.documentElement.classList.toggle('app-dark', saved === 'dark');
|
||||
}
|
||||
} catch { }
|
||||
})();
|
||||
|
||||
import { pinia } from '@/plugins/pinia';
|
||||
import router from '@/router';
|
||||
import { createApp } from 'vue';
|
||||
@@ -11,32 +20,25 @@ import App from './App.vue';
|
||||
|
||||
import { initSession, listenAuthChanges, refreshSession, setOnSignedOut } from '@/app/session';
|
||||
|
||||
// PrimeVue core
|
||||
import Aura from '@primeuix/themes/aura';
|
||||
import PrimeVue from 'primevue/config';
|
||||
import { applyThemeEngine } from '@/theme/theme.options';
|
||||
import { useLayout } from '@/layout/composables/layout';
|
||||
|
||||
// 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';
|
||||
|
||||
// estilos
|
||||
import '@/assets/styles.scss';
|
||||
import '@/assets/tailwind.css';
|
||||
|
||||
import { supabase } from '@/lib/supabase/client';
|
||||
|
||||
// locale
|
||||
const ptBR = {
|
||||
firstDayOfWeek: 1,
|
||||
dayNames: ['domingo', 'segunda-feira', 'terça-feira', 'quarta-feira', 'quinta-feira', 'sexta-feira', 'sábado'],
|
||||
@@ -50,29 +52,49 @@ 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;
|
||||
function syncThemeFromDB() {
|
||||
const run = async () => {
|
||||
try {
|
||||
const { data } = await supabase.auth.getUser();
|
||||
if (!data?.user) return;
|
||||
|
||||
const { data: settings } = 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, preset, primary_color, surface_color, menu_mode')
|
||||
.eq('user_id', data.user.id)
|
||||
.maybeSingle();
|
||||
|
||||
if (!settings?.theme_mode) return;
|
||||
if (!settings) return;
|
||||
|
||||
const isDark = settings.theme_mode === 'dark';
|
||||
document.documentElement.classList.toggle('app-dark', isDark);
|
||||
localStorage.setItem('ui_theme_mode', settings.theme_mode);
|
||||
} catch {}
|
||||
if (settings.theme_mode) {
|
||||
document.documentElement.classList.toggle('app-dark', settings.theme_mode === 'dark');
|
||||
localStorage.setItem('ui_theme_mode', settings.theme_mode);
|
||||
}
|
||||
|
||||
const cfg = {};
|
||||
if (settings.preset) cfg.preset = settings.preset;
|
||||
if (settings.primary_color) cfg.primary = settings.primary_color;
|
||||
if (settings.surface_color) cfg.surface = settings.surface_color;
|
||||
if (settings.menu_mode) cfg.menuMode = settings.menu_mode;
|
||||
|
||||
if (Object.keys(cfg).length) {
|
||||
try {
|
||||
const prev = JSON.parse(localStorage.getItem('ui_theme_config') || '{}');
|
||||
localStorage.setItem('ui_theme_config', JSON.stringify({ ...prev, ...cfg }));
|
||||
} catch { }
|
||||
}
|
||||
} catch { }
|
||||
};
|
||||
|
||||
if ('requestIdleCallback' in window) {
|
||||
requestIdleCallback(run, { timeout: 4000 });
|
||||
} else {
|
||||
setTimeout(run, 300);
|
||||
}
|
||||
}
|
||||
|
||||
// logout
|
||||
setOnSignedOut(() => {
|
||||
router.replace('/auth/login');
|
||||
});
|
||||
setOnSignedOut(() => router.replace('/auth/login'));
|
||||
|
||||
// flags
|
||||
window.__sessionRefreshing = false;
|
||||
window.__fromVisibilityRefresh = false;
|
||||
window.__appBootstrapped = false;
|
||||
@@ -84,13 +106,15 @@ document.addEventListener('visibilitychange', async () => {
|
||||
if (!window.__appBootstrapped) return;
|
||||
|
||||
const now = Date.now();
|
||||
if (now - lastVisibilityRefreshAt < 10000) return;
|
||||
if (now - lastVisibilityRefreshAt < 10_000) return;
|
||||
if (window.__sessionRefreshing) return;
|
||||
|
||||
try {
|
||||
const { data } = await supabase.auth.getUser();
|
||||
if (!data?.user) return;
|
||||
} catch {}
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
|
||||
lastVisibilityRefreshAt = now;
|
||||
|
||||
@@ -100,15 +124,14 @@ document.addEventListener('visibilitychange', async () => {
|
||||
|
||||
await refreshSession();
|
||||
|
||||
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' }
|
||||
})
|
||||
);
|
||||
window.dispatchEvent(new CustomEvent('app:session-refreshed', { detail: { source: 'visibility' } }));
|
||||
}
|
||||
} finally {
|
||||
window.__fromVisibilityRefresh = false;
|
||||
@@ -118,39 +141,35 @@ document.addEventListener('visibilitychange', async () => {
|
||||
|
||||
async function bootstrap() {
|
||||
await initSession({ initial: true });
|
||||
listenAuthChanges();
|
||||
await applyUserThemeEarly();
|
||||
|
||||
const app = createApp(App);
|
||||
|
||||
app.use(pinia);
|
||||
app.use(router);
|
||||
|
||||
await router.isReady();
|
||||
|
||||
listenAuthChanges();
|
||||
syncThemeFromDB();
|
||||
|
||||
const { layoutConfig } = useLayout();
|
||||
|
||||
app.use(PrimeVue, {
|
||||
locale: ptBR,
|
||||
theme: {
|
||||
preset: Aura,
|
||||
options: { darkModeSelector: '.app-dark' }
|
||||
}
|
||||
theme: { options: { darkModeSelector: '.app-dark' } }
|
||||
});
|
||||
|
||||
applyThemeEngine(layoutConfig);
|
||||
|
||||
app.use(ToastService);
|
||||
app.use(ConfirmationService);
|
||||
|
||||
// ✅ globais leves
|
||||
app.component('Button', Button);
|
||||
app.component('InputText', InputText);
|
||||
app.component('Tag', Tag);
|
||||
app.component('Divider', Divider);
|
||||
app.component('Toast', Toast);
|
||||
|
||||
app.component('AppLoadingPhrases', AppLoadingPhrases);
|
||||
app.component('LoadedPhraseBlock', LoadedPhraseBlock);
|
||||
|
||||
app.mount('#app');
|
||||
|
||||
window.__appBootstrapped = true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user