chore: snapshot before agency split

This commit is contained in:
Erik Silva
2025-12-09 17:21:25 -03:00
parent 6ec29c7eef
commit 053e180321
27 changed files with 428 additions and 234 deletions

View File

@@ -31,8 +31,8 @@ export default function CadastroPage() {
const [subdomain, setSubdomain] = useState("");
const [domainAvailable, setDomainAvailable] = useState<boolean | null>(null);
const [checkingDomain, setCheckingDomain] = useState(false);
const [primaryColor, setPrimaryColor] = useState("#FF3A05");
const [secondaryColor, setSecondaryColor] = useState("#FF0080");
const [primaryColor, setPrimaryColor] = useState("#ff3a05");
const [secondaryColor, setSecondaryColor] = useState("#ff0080");
const [logoUrl, setLogoUrl] = useState<string>("");
const [showPreviewMobile, setShowPreviewMobile] = useState(false);
@@ -52,8 +52,8 @@ export default function CadastroPage() {
setCepData(data.cepData || { state: "", city: "", neighborhood: "", street: "" });
setSubdomain(data.subdomain || "");
setDomainAvailable(data.domainAvailable ?? null);
setPrimaryColor(data.primaryColor || "#FF3A05");
setSecondaryColor(data.secondaryColor || "#FF0080");
setPrimaryColor(data.primaryColor || "#ff3a05");
setSecondaryColor(data.secondaryColor || "#ff0080");
setLogoUrl(data.logoUrl || "");
} catch (error) {
console.error('Erro ao carregar dados:', error);
@@ -323,7 +323,7 @@ export default function CadastroPage() {
console.log('📤 Enviando cadastro completo:', payload);
toast.loading('Criando sua conta...', { id: 'register' });
const response = await fetch('/api/admin/agencies', {
const response = await fetch(API_ENDPOINTS.adminAgencyRegister, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
@@ -332,8 +332,15 @@ export default function CadastroPage() {
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.message || 'Erro ao criar conta');
let errorMessage = 'Erro ao criar conta';
try {
const error = await response.json();
errorMessage = error.message || error.error || errorMessage;
} catch (e) {
const text = await response.text();
if (text) errorMessage = text;
}
throw new Error(errorMessage);
}
const data = await response.json();
@@ -365,9 +372,10 @@ export default function CadastroPage() {
},
});
// Redirecionar para o painel da agência no subdomínio
// Redirecionar para o painel da agência no subdomínio, enviando o gradiente escolhido
setTimeout(() => {
const agencyUrl = `http://${data.subdomain}.localhost/login`;
const gradient = `linear-gradient(135deg, ${primaryColor}, ${secondaryColor})`;
const agencyUrl = `http://${data.subdomain}.localhost/login?theme=${encodeURIComponent(gradient)}`;
window.location.href = agencyUrl;
}, 2000);
@@ -406,8 +414,8 @@ export default function CadastroPage() {
setContacts([{ id: 1, whatsapp: "(11) 98765-4321" }]);
setSubdomain("idealpages");
setDomainAvailable(true);
setPrimaryColor("#FF3A05");
setSecondaryColor("#FF0080");
setPrimaryColor("#ff3a05");
setSecondaryColor("#ff0080");
// Marcar todos os steps como completos e ir pro step 5
setCompletedSteps([1, 2, 3, 4]);
@@ -529,9 +537,9 @@ export default function CadastroPage() {
const getPasswordStrengthColor = () => {
if (passwordStrength <= 1) return "#EF4444";
if (passwordStrength === 2) return "#F59E0B";
if (passwordStrength === 3) return "#3B82F6";
if (passwordStrength === 4) return "#10B981";
return "#059669";
if (passwordStrength === 3) return "#ff3a05";
if (passwordStrength === 4) return "#ff3a05";
return "#ff3a05";
};
const fetchCnpjData = async (cnpj: string) => {
@@ -607,7 +615,7 @@ export default function CadastroPage() {
error: {
icon: '⚠️',
style: {
background: '#ff3a05',
background: '#ef4444',
color: '#FFFFFF',
border: 'none',
},
@@ -660,8 +668,8 @@ export default function CadastroPage() {
/>
<defs>
<linearGradient id="gradient" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" stopColor="#FF3A05" />
<stop offset="100%" stopColor="#FF0080" />
<stop offset="0%" stopColor="#ff3a05" />
<stop offset="100%" stopColor="#ff0080" />
</linearGradient>
</defs>
</svg>
@@ -763,7 +771,11 @@ export default function CadastroPage() {
label={
<span>
Concordo com os{" "}
<Link href="/termos" className="bg-linear-to-r from-[#FF3A05] to-[#FF0080] bg-clip-text text-transparent hover:underline cursor-pointer font-medium">
<Link
href="/termos"
className="font-medium hover:underline cursor-pointer"
style={{ color: 'var(--brand-color)' }}
>
Termos de Uso
</Link>
</span>
@@ -779,7 +791,11 @@ export default function CadastroPage() {
{/* Link para login */}
<p className="text-center mt-6 text-[14px] text-[#7D7D7D]">
possui uma conta?{" "}
<Link href="/login" className="bg-linear-to-r from-[#FF3A05] to-[#FF0080] bg-clip-text text-transparent font-medium hover:underline cursor-pointer">
<Link
href="/login"
className="font-medium hover:underline cursor-pointer"
style={{ color: 'var(--brand-color)' }}
>
Fazer login
</Link>
</p>
@@ -829,13 +845,13 @@ export default function CadastroPage() {
disabled
/>
<div>
<label className="block text-[13px] font-semibold text-[#000000] mb-2">
Descrição Breve<span className="text-[#FF3A05] ml-1">*</span>
<label className="block text-[13px] font-semibold text-zinc-900 mb-2">
Descrição Breve<span className="ml-1" style={{ color: 'var(--brand-color)' }}>*</span>
</label>
<textarea
name="description"
placeholder="Apresente sua empresa em poucas palavras (máx 300 caracteres)"
className="w-full px-3.5 py-3 text-[14px] font-normal border rounded-md bg-white placeholder:text-[#7D7D7D] border-[#E5E5E5] focus:border-[#FF3A05] outline-none ring-0 focus:ring-0 shadow-none focus:shadow-none resize-none"
className="w-full px-3.5 py-3 text-[14px] font-normal border rounded-md bg-white placeholder:text-zinc-500 border-zinc-200 outline-none ring-0 shadow-none focus:shadow-none resize-none focus:border-[var(--brand-color)]"
rows={4}
maxLength={300}
value={formData.description || ''}
@@ -989,19 +1005,19 @@ export default function CadastroPage() {
</div>
{/* Contatos da Empresa */}
<div className="pt-4 border-t border-[#E5E5E5]">
<div className="pt-4 border-t border-zinc-200">
<div className="space-y-4">
<div className="flex items-center justify-between">
<h3 className="text-sm font-semibold text-[#000000]">Contatos da Empresa</h3>
<h3 className="text-sm font-semibold text-zinc-900">Contatos da Empresa</h3>
</div>
{contacts.map((contact, index) => (
<div key={contact.id} className="space-y-4 p-4 border border-[#E5E5E5] rounded-md bg-white">
<div key={contact.id} className="space-y-4 p-4 border border-zinc-200 rounded-md bg-white">
{contacts.length > 1 && (
<div className="flex items-center justify-end -mt-2 -mr-2">
<button
type="button"
onClick={() => removeContact(contact.id)}
className="text-[#7D7D7D] hover:text-[#FF3A05] transition-colors"
className="text-zinc-500 transition-colors hover:text-[var(--brand-color)]"
>
<i className="ri-close-line text-[18px]" />
</button>
@@ -1044,8 +1060,8 @@ export default function CadastroPage() {
<div className="space-y-6">
{/* Subdomínio Aggios */}
<div className="space-y-2">
<label className="block text-sm font-medium text-[#000000]">
Subdomínio Aggios <span className="text-[#FF3A05]">*</span>
<label className="block text-sm font-medium text-zinc-900">
Subdomínio Aggios <span style={{ color: 'var(--brand-color)' }}>*</span>
</label>
<div className="relative">
<div className="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
@@ -1061,12 +1077,12 @@ export default function CadastroPage() {
}}
onBlur={() => subdomain && checkDomainAvailability(subdomain)}
placeholder="minhaempresa"
className="w-full pl-10 pr-4 py-2 text-sm border border-[#E5E5E5] rounded-md focus:border-[#FF3A05] transition-colors"
className="w-full pl-10 pr-4 py-2 text-sm border border-zinc-200 rounded-md transition-colors focus:border-[var(--brand-color)]"
required
/>
{checkingDomain && (
<div className="absolute inset-y-0 right-0 flex items-center pr-3">
<div className="w-4 h-4 border-2 border-[#FF3A05] border-t-transparent rounded-full animate-spin" />
<div className="w-4 h-4 border-2 border-[var(--brand-color)] border-t-transparent rounded-full animate-spin" />
</div>
)}
{!checkingDomain && domainAvailable === true && (
@@ -1076,13 +1092,13 @@ export default function CadastroPage() {
)}
{!checkingDomain && domainAvailable === false && (
<div className="absolute inset-y-0 right-0 flex items-center pr-3">
<i className="ri-close-circle-fill text-[#FF3A05] text-[20px]" />
<i className="ri-close-circle-fill text-red-500 text-[20px]" />
</div>
)}
</div>
<p className="text-xs text-[#7D7D7D] flex items-center gap-1">
<p className="text-xs text-zinc-600 flex items-center gap-1">
<i className="ri-information-line" />
Seu painel ficará em: <span className="font-medium text-[#000000]">{subdomain || 'seu-dominio'}.aggios.app</span>
Seu painel ficará em: <span className="font-medium text-zinc-900">{subdomain || 'seu-dominio'}.aggios.app</span>
</p>
{domainAvailable === true && (
<p className="text-xs text-[#10B981] flex items-center gap-1">
@@ -1091,7 +1107,7 @@ export default function CadastroPage() {
</p>
)}
{domainAvailable === false && (
<p className="text-xs text-[#FF3A05] flex items-center gap-1">
<p className="text-xs text-red-500 flex items-center gap-1">
<i className="ri-error-warning-line" />
Indisponível. Este subdomínio está em uso.
</p>
@@ -1100,11 +1116,11 @@ export default function CadastroPage() {
{/* Informações Adicionais */}
<div className="p-6 bg-[#F5F5F5] rounded-md space-y-3">
<h4 className="text-sm font-semibold text-[#000000] flex items-center gap-2">
<i className="ri-lightbulb-line text-[#FF3A05]" />
<h4 className="text-sm font-semibold text-zinc-900 flex items-center gap-2">
<i className="ri-lightbulb-line" style={{ color: 'var(--brand-color)' }} />
Dicas para escolher seu domínio
</h4>
<ul className="text-xs text-[#7D7D7D] space-y-1 ml-6">
<ul className="text-xs text-zinc-600 space-y-1 ml-6">
<li className="list-disc">Use o nome da sua empresa</li>
<li className="list-disc">Evite números e hífens quando possível</li>
<li className="list-disc">Escolha algo fácil de lembrar e digitar</li>
@@ -1121,7 +1137,14 @@ export default function CadastroPage() {
<button
type="button"
onClick={() => setShowPreviewMobile(!showPreviewMobile)}
className="w-full flex items-center justify-center gap-2 px-4 py-3 rounded-lg border-2 border-[#FF3A05] text-[#FF3A05] font-medium hover:bg-[#FF3A05]/5 transition-colors"
className="w-full flex items-center justify-center gap-2 px-4 py-3 rounded-lg border-2 font-medium transition-colors"
style={{
borderColor: 'var(--brand-color)',
color: 'var(--brand-color)',
backgroundColor: showPreviewMobile ? 'transparent' : undefined
}}
onMouseEnter={(e) => (e.currentTarget.style.backgroundColor = 'color-mix(in srgb, var(--brand-color) 10%, transparent)')}
onMouseLeave={(e) => (e.currentTarget.style.backgroundColor = 'transparent')}
>
<i className={`${showPreviewMobile ? 'ri-edit-line' : 'ri-eye-line'} text-xl`} />
{showPreviewMobile ? 'Voltar ao Formulário' : 'Ver Preview do Painel'}
@@ -1177,7 +1200,7 @@ export default function CadastroPage() {
/>
<label
htmlFor="logo-upload"
className="inline-flex items-center gap-2 px-4 py-2 border border-[#E5E5E5] rounded-md text-sm font-medium text-[#000000] hover:bg-[#F5F5F5] transition-colors cursor-pointer"
className="inline-flex items-center gap-2 px-4 py-2 border border-zinc-200 rounded-md text-sm font-medium text-zinc-900 hover:bg-zinc-50 transition-colors cursor-pointer"
>
<i className="ri-upload-2-line" />
Escolher arquivo
@@ -1186,12 +1209,13 @@ export default function CadastroPage() {
<button
type="button"
onClick={() => setLogoUrl('')}
className="ml-2 text-sm bg-linear-to-r from-[#FF3A05] to-[#FF0080] bg-clip-text text-transparent hover:underline font-medium"
className="ml-2 text-sm hover:underline font-medium"
style={{ color: 'var(--brand-color)' }}
>
Remover
</button>
)}
<p className="text-xs text-[#7D7D7D] mt-2">
<p className="text-xs text-zinc-600 mt-2">
PNG, JPG ou SVG. Tamanho recomendado: 200x200px
</p>
</div>
@@ -1202,13 +1226,13 @@ export default function CadastroPage() {
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
{/* Cor Primária */}
<div>
<label className="block text-sm font-medium text-[#000000] mb-3">
Cor Primária <span className="text-[#FF3A05]">*</span>
<label className="block text-sm font-medium text-zinc-900 mb-3">
Cor Primária <span style={{ color: 'var(--brand-color)' }}>*</span>
</label>
<div className="flex gap-3">
<div className="relative flex-1">
<div className="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
<i className="ri-palette-line text-[#7D7D7D] text-[18px]" />
<i className="ri-palette-line text-zinc-500 text-[18px]" />
</div>
<input
type="text"
@@ -1219,18 +1243,18 @@ export default function CadastroPage() {
setPrimaryColor(value);
}
}}
placeholder="#FF3A05"
className="w-full pl-10 pr-4 py-2 text-sm border border-[#E5E5E5] rounded-md focus:border-[#FF3A05] transition-colors font-mono"
placeholder="#ff3a05"
className="w-full pl-10 pr-4 py-2 text-sm border border-zinc-200 rounded-md transition-colors font-mono focus:border-[var(--brand-color)]"
/>
</div>
<input
type="color"
value={primaryColor}
onChange={(e) => setPrimaryColor(e.target.value)}
className="w-14 h-10 border-2 border-[#E5E5E5] rounded-md cursor-pointer"
className="w-14 h-10 border-2 border-zinc-200 rounded-md cursor-pointer"
/>
</div>
<p className="text-xs text-[#7D7D7D] mt-1 flex items-center gap-1">
<p className="text-xs text-zinc-600 mt-1 flex items-center gap-1">
<i className="ri-information-line" />
Usada em menus, botões e destaques
</p>
@@ -1238,13 +1262,13 @@ export default function CadastroPage() {
{/* Cor Secundária */}
<div>
<label className="block text-sm font-medium text-[#000000] mb-3">
Cor Secundária <span className="text-[#7D7D7D]">(opcional)</span>
<label className="block text-sm font-medium text-zinc-900 mb-3">
Cor Secundária <span className="text-zinc-500">(opcional)</span>
</label>
<div className="flex gap-3">
<div className="relative flex-1">
<div className="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
<i className="ri-brush-line text-[#7D7D7D] text-[18px]" />
<i className="ri-brush-line text-zinc-500 text-[18px]" />
</div>
<input
type="text"
@@ -1255,18 +1279,18 @@ export default function CadastroPage() {
setSecondaryColor(value);
}
}}
placeholder="#FF0080"
className="w-full pl-10 pr-4 py-2 text-sm border border-[#E5E5E5] rounded-md focus:border-[#FF3A05] transition-colors font-mono"
placeholder="#ff0080"
className="w-full pl-10 pr-4 py-2 text-sm border border-zinc-200 rounded-md transition-colors font-mono focus:border-[var(--brand-color)]"
/>
</div>
<input
type="color"
value={secondaryColor}
onChange={(e) => setSecondaryColor(e.target.value)}
className="w-14 h-10 border-2 border-[#E5E5E5] rounded-md cursor-pointer"
className="w-14 h-10 border-2 border-zinc-200 rounded-md cursor-pointer"
/>
</div>
<p className="text-xs text-[#7D7D7D] mt-1 flex items-center gap-1">
<p className="text-xs text-zinc-600 mt-1 flex items-center gap-1">
<i className="ri-information-line" />
Usada em cards e elementos secundários
</p>
@@ -1275,10 +1299,10 @@ export default function CadastroPage() {
{/* Paletas Sugeridas */}
<div>
<h4 className="text-sm font-semibold text-[#000000] mb-4">Paletas Sugeridas</h4>
<h4 className="text-sm font-semibold text-zinc-900 mb-4">Paletas Sugeridas</h4>
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
{[
{ name: 'Fogo', primary: '#FF3A05', secondary: '#FF0080' },
{ name: 'Marca', primary: '#FF3A05', secondary: '#FF0080' },
{ name: 'Oceano', primary: '#0EA5E9', secondary: '#3B82F6' },
{ name: 'Natureza', primary: '#10B981', secondary: '#059669' },
{ name: 'Elegante', primary: '#8B5CF6', secondary: '#A78BFA' },
@@ -1294,7 +1318,8 @@ export default function CadastroPage() {
setPrimaryColor(palette.primary);
setSecondaryColor(palette.secondary);
}}
className="flex items-center gap-2 p-2 rounded-md border border-[#E5E5E5] hover:border-[#FF3A05] transition-colors group cursor-pointer"
className="flex items-center gap-2 p-2 rounded-md border border-zinc-200 transition-colors group cursor-pointer"
style={{ borderColor: palette.name === 'Marca' ? 'var(--brand-color)' : undefined }}
>
<div className="flex gap-1">
<div
@@ -1306,7 +1331,7 @@ export default function CadastroPage() {
style={{ backgroundColor: palette.secondary }}
/>
</div>
<span className="text-xs font-medium text-[#7D7D7D] group-hover:text-[#000000]">
<span className="text-xs font-medium text-zinc-600 group-hover:text-zinc-900">
{palette.name}
</span>
</button>
@@ -1317,7 +1342,7 @@ export default function CadastroPage() {
{/* Informações */}
<div className="p-6 bg-[#F0F9FF] border border-[#BAE6FD] rounded-md">
<div className="flex gap-4">
<i className="ri-information-line text-[#0EA5E9] text-xl mt-0.5" />
<i className="ri-information-line text-[#ff3a05] text-xl mt-0.5" />
<div>
<h4 className="text-sm font-semibold text-[#000000] mb-1">
Você pode alterar depois
@@ -1337,7 +1362,7 @@ export default function CadastroPage() {
</div>
{/* Rodapé - botão voltar à esquerda, etapas e botão ação à direita */}
<div className="border-t border-[#E5E5E5] bg-white px-4 sm:px-12 py-4">
<div className="border-t border-zinc-200 bg-white px-4 sm:px-12 py-4">
{/* Desktop: Linha única com tudo */}
<div className="hidden md:flex items-center justify-between">
{/* Botão voltar à esquerda */}
@@ -1363,21 +1388,21 @@ export default function CadastroPage() {
? "bg-[#10B981] text-white"
: currentStep === step.number
? "text-white"
: "bg-[#E5E5E5] text-[#7D7D7D] group-hover:bg-[#D5D5D5]"
: "bg-zinc-200 text-zinc-500 group-hover:bg-zinc-300"
}`}
style={currentStep === step.number ? { background: 'linear-gradient(90deg, #FF3A05, #FF0080)' } : undefined}
style={currentStep === step.number ? { background: 'var(--gradient-primary)' } : undefined}
>
{step.number}
</div>
<span className={`text-xs transition-colors ${currentStep === step.number
? "text-[#000000] font-semibold"
: "text-[#7D7D7D] group-hover:text-[#000000]"
? "text-zinc-900 font-semibold"
: "text-zinc-500 group-hover:text-zinc-900"
}`}>
{step.title}
</span>
</button>
{index < steps.length - 1 && (
<div className="w-12 h-0.5 bg-[#E5E5E5] mb-5" />
<div className="w-12 h-0.5 bg-zinc-200 mb-5" />
)}
</div>
))}
@@ -1407,9 +1432,9 @@ export default function CadastroPage() {
? "w-2 bg-[#10B981]"
: currentStep === step.number
? "w-8"
: "w-2 bg-[#E5E5E5] hover:bg-[#D5D5D5]"
: "w-2 bg-zinc-200 hover:bg-zinc-300"
}`}
style={currentStep === step.number ? { background: 'linear-gradient(90deg, #FF3A05, #FF0080)' } : undefined}
style={currentStep === step.number ? { background: 'var(--gradient-primary)' } : undefined}
aria-label={`Ir para ${step.title}`}
/>
))}
@@ -1442,7 +1467,7 @@ export default function CadastroPage() {
</div>
{/* Lado Direito - Branding Dinâmico */}
<div className="hidden lg:flex lg:w-[50%] relative overflow-hidden" style={{ background: 'linear-gradient(90deg, #FF3A05, #FF0080)' }}>
<div className="hidden lg:flex lg:w-[50%] relative overflow-hidden" style={{ background: 'var(--gradient-primary)' }}>
<DynamicBranding
currentStep={currentStep}
companyName={formData.companyName}

View File

@@ -56,7 +56,7 @@ export default function RecuperarSenhaPage() {
error: {
icon: '⚠️',
style: {
background: '#ff3a05',
background: '#ef4444',
color: '#FFFFFF',
border: 'none',
},
@@ -150,7 +150,7 @@ export default function RecuperarSenhaPage() {
<div className="p-6 bg-[#F0F9FF] border border-[#BAE6FD] rounded-md text-left mb-6">
<div className="flex gap-4">
<i className="ri-information-line text-[#0EA5E9] text-xl mt-0.5" />
<i className="ri-information-line text-[#ff3a05] text-xl mt-0.5" />
<div>
<h4 className="text-sm font-semibold text-zinc-900 dark:text-white mb-1">
Verifique sua caixa de entrada