refactor: redesign planos interface with design system patterns

- Create CreatePlanModal component with Headless UI Dialog
- Implement dark mode support throughout plans UI
- Update plans/page.tsx with professional card layout
- Update plans/[id]/page.tsx with consistent styling
- Add proper spacing, typography, and color consistency
- Implement smooth animations and transitions
- Add success/error message feedback
- Improve form UX with better input styling
This commit is contained in:
Erik Silva
2025-12-13 19:26:38 -03:00
parent 2f1cf2bb2a
commit 2a112f169d
26 changed files with 2580 additions and 119 deletions

View File

@@ -1,20 +1,13 @@
'use client';
import { useEffect, useState } from 'react';
import { useEffect } 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);
@@ -41,26 +34,19 @@ export function LoginBranding() {
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);
@@ -88,18 +74,15 @@ export function LoginBranding() {
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 {
@@ -107,7 +90,6 @@ export function LoginBranding() {
}
// 2. Fallback para cache
console.log('LoginBranding: Tentando cache');
const cachedPrimary = localStorage.getItem('agency-primary-color');
const cachedLogo = localStorage.getItem('agency-logo-url');
@@ -132,7 +114,7 @@ export function LoginBranding() {
};
loadBranding();
}, [mounted]);
}, []);
return null;
}