Files
aggios.app/front-end-agency/components/layout/FaviconUpdater.tsx
Erik Silva 2f1cf2bb2a v1.4: Segurança multi-tenant, file serving via API e UX humanizada
-  Validação cross-tenant no login e rotas protegidas
-  File serving via /api/files/{bucket}/{path} (eliminação DNS)
-  Mensagens de erro humanizadas inline (sem pop-ups)
-  Middleware tenant detection via headers customizados
-  Upload de logos retorna URLs via API
-  README atualizado com changelog v1.4 completo
2025-12-13 15:05:51 -03:00

55 lines
1.7 KiB
TypeScript

'use client';
import { useEffect, useState } from 'react';
import { getUser } from '@/lib/auth';
export function FaviconUpdater() {
const [mounted, setMounted] = useState(false);
useEffect(() => {
setMounted(true);
}, []);
useEffect(() => {
if (!mounted) return;
const updateFavicon = () => {
const user = getUser();
if (user?.logoUrl) {
// Usar requestAnimationFrame para garantir que o DOM esteja estável após hidratação
requestAnimationFrame(() => {
const link: HTMLLinkElement = document.querySelector("link[rel*='icon']") || document.createElement('link');
link.type = 'image/x-icon';
link.rel = 'shortcut icon';
link.href = user.logoUrl!;
if (!link.parentNode) {
document.getElementsByTagName('head')[0].appendChild(link);
}
});
}
};
// Atraso pequeno para garantir que a hidratação terminou
const timer = setTimeout(() => {
updateFavicon();
}, 0);
// Ouve mudanças no localStorage
const handleStorage = () => {
requestAnimationFrame(() => updateFavicon());
};
window.addEventListener('storage', handleStorage);
// Custom event para atualização interna na mesma aba
window.addEventListener('auth-update', handleStorage);
return () => {
clearTimeout(timer);
window.removeEventListener('storage', handleStorage);
window.removeEventListener('auth-update', handleStorage);
};
}, [mounted]);
return null;
}