'use client'; import { useEffect, useState } from 'react'; /** * LoginBranding - Aplica cor primária da agência na página de login * Busca cor do localStorage ou da API se não houver cache */ export function LoginBranding() { const [mounted, setMounted] = useState(false); useEffect(() => { setMounted(true); }, []); useEffect(() => { if (!mounted) return; const hexToRgb = (hex: string) => { const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); return result ? `${parseInt(result[1], 16)} ${parseInt(result[2], 16)} ${parseInt(result[3], 16)}` : null; }; const applyTheme = (primary: string) => { if (!primary) return; const root = document.documentElement; const primaryRgb = hexToRgb(primary); root.style.setProperty('--brand-color', primary); root.style.setProperty('--gradient', `linear-gradient(135deg, ${primary}, ${primary})`); if (primaryRgb) { root.style.setProperty('--brand-rgb', primaryRgb); root.style.setProperty('--brand-strong-rgb', primaryRgb); root.style.setProperty('--brand-hover-rgb', primaryRgb); } }; const updateFavicon = (url: string) => { if (typeof window === 'undefined' || typeof document === 'undefined') return; try { console.log('🎨 LoginBranding: Atualizando favicon para:', url); const newHref = `${url}${url.includes('?') ? '&' : '?'}v=${Date.now()}`; // Buscar TODOS os links de ícone existentes const existingLinks = document.querySelectorAll("link[rel*='icon']"); if (existingLinks.length > 0) { // Atualizar href de todos os links existentes (SEM REMOVER) existingLinks.forEach(link => { link.setAttribute('href', newHref); }); console.log(`✅ ${existingLinks.length} favicons atualizados`); } else { // Criar novo link apenas se não existir nenhum const newLink = document.createElement('link'); newLink.rel = 'icon'; newLink.type = 'image/x-icon'; newLink.href = newHref; document.head.appendChild(newLink); console.log('✅ Novo favicon criado'); } } catch (error) { console.error('❌ Erro ao atualizar favicon:', error); } }; const loadBranding = async () => { if (typeof window === 'undefined') return; const hostname = window.location.hostname; const subdomain = hostname.split('.')[0]; // Para dash.localhost ou localhost sem subdomínio, não buscar if (!subdomain || subdomain === 'localhost' || subdomain === 'www' || subdomain === 'dash') { return; } try { // 1. Buscar DIRETO do backend (bypass da rota Next.js que está com problema) console.log('LoginBranding: Buscando cores para:', subdomain); const apiUrl = `/api/tenant/config?subdomain=${subdomain}`; console.log('LoginBranding: URL:', apiUrl); const response = await fetch(apiUrl); if (response.ok) { const data = await response.json(); console.log('LoginBranding: Dados recebidos:', data); if (data.primary_color) { applyTheme(data.primary_color); localStorage.setItem('agency-primary-color', data.primary_color); console.log('LoginBranding: Cor aplicada!'); } if (data.logo_url) { updateFavicon(data.logo_url); localStorage.setItem('agency-logo-url', data.logo_url); console.log('LoginBranding: Favicon aplicado!'); } return; } else { console.error('LoginBranding: API retornou:', response.status); } // 2. Fallback para cache console.log('LoginBranding: Tentando cache'); const cachedPrimary = localStorage.getItem('agency-primary-color'); const cachedLogo = localStorage.getItem('agency-logo-url'); if (cachedPrimary) { applyTheme(cachedPrimary); } if (cachedLogo) { updateFavicon(cachedLogo); } } catch (error) { console.error('LoginBranding: Erro:', error); const cachedPrimary = localStorage.getItem('agency-primary-color'); const cachedLogo = localStorage.getItem('agency-logo-url'); if (cachedPrimary) { applyTheme(cachedPrimary); } if (cachedLogo) { updateFavicon(cachedLogo); } } }; loadBranding(); }, [mounted]); return null; }