const { useState, useEffect } = React;
// --- Funcões Auxilares e Máscaras ---
function validarCPF(cpf) {
cpf = cpf.replace(/[^\d]+/g, '');
if (cpf.length !== 11 || !!cpf.match(/(\d)\1{10}/)) return false;
let soma = 0, resto;
for (let i = 1; i <= 9; i++) soma += parseInt(cpf.substring(i - 1, i)) * (11 - i);
resto = (soma * 10) % 11;
if (resto === 10 || resto === 11) resto = 0;
if (resto !== parseInt(cpf.substring(9, 10))) return false;
soma = 0;
for (let i = 1; i <= 10; i++) soma += parseInt(cpf.substring(i - 1, i)) * (12 - i);
resto = (soma * 10) % 11;
if (resto === 10 || resto === 11) resto = 0;
if (resto !== parseInt(cpf.substring(10, 11))) return false;
return true;
}
function formatCPF(value) {
if (!value) return '';
return value.replace(/\D/g, '')
.replace(/(\d{3})(\d)/, '$1.$2')
.replace(/(\d{3})(\d)/, '$1.$2')
.replace(/(\d{3})(\d{1,2})/, '$1-$2')
.replace(/(-\d{2})\d+?$/, '$1');
}
function formatCNPJ(value) {
if (!value) return '';
return value.replace(/\D/g, '')
.replace(/(\d{2})(\d)/, '$1.$2')
.replace(/(\d{3})(\d)/, '$1.$2')
.replace(/(\d{3})(\d)/, '$1/$2')
.replace(/(\d{4})(\d{1,2})/, '$1-$2')
.replace(/(-\d{2})\d+?$/, '$1');
}
function formatCardNumber(value) {
return value.replace(/\D/g, '').replace(/(\d{4})/g, '$1 ').trim().substring(0, 19);
}
function formatExpiry(value) {
const v = value.replace(/\D/g, '');
if (v.length >= 2) return v.substring(0, 2) + '/' + v.substring(2, 4);
return v;
}
function validarSenha(senha) {
const minLength = 8;
const hasUpperCase = /[A-Z]/.test(senha);
const hasNumber = /[0-9]/.test(senha);
const hasSpecial = /[!@#$%^&*(),.?":{}|<>]/.test(senha);
if (senha.length < minLength) return "A senha deve ter pelo menos 8 caracteres.";
if (!hasUpperCase) return "A senha deve conter pelo menos uma letra maiúscula.";
if (!hasNumber) return "A senha deve conter pelo menos um número.";
if (!hasSpecial) return "A senha deve conter pelo menos um caractere especial.";
return null;
}
// RemovidonotasDB mock e integrado com MariaDB via backend.
const API_URL = 'https://api.iaagro.app/api';
function App() {
const [view, setView] = useState('landing');
const [user, setUser] = useState(null);
const [theme, setTheme] = useState('dark');
const [notification, setNotification] = useState({ show: false, msg: '', type: 'info' });
const notify = (msg, type = 'info') => {
setNotification({ show: true, msg, type });
setTimeout(() => setNotification({ show: false, msg: '', type: 'info' }), 4000);
};
// --- Sistema de Temas ---
useEffect(() => {
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
const applyTheme = (isDark) => {
const newTheme = isDark ? 'dark' : 'light';
setTheme(newTheme);
document.documentElement.setAttribute('data-theme', newTheme);
};
applyTheme(mediaQuery.matches);
const handleChange = (e) => applyTheme(e.matches);
mediaQuery.addEventListener('change', handleChange);
// Persistência de Login: Recuperar do localStorage
const savedUser = localStorage.getItem('iaagro_user');
if (savedUser) {
try {
const parsedUser = JSON.parse(savedUser);
setUser(parsedUser);
setView('portal');
} catch (e) {
localStorage.removeItem('iaagro_user');
}
}
return () => mediaQuery.removeEventListener('change', handleChange);
}, []);
// --- Observador para Animações de Scroll (Reveal) ---
useEffect(() => {
const observerOptions = {
threshold: 0.15,
rootMargin: '0px 0px -50px 0px'
};
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('active');
// Opcional: parar de observar após animar uma vez
// observer.unobserve(entry.target);
}
});
}, observerOptions);
const revealElements = document.querySelectorAll('.reveal');
revealElements.forEach(el => observer.observe(el));
// Re-observar se a view mudar (importante p/ SPA)
return () => {
revealElements.forEach(el => observer.unobserve(el));
};
}, [view]); // Dispara novamente ao trocar de tela (landing -> portal etc)
const switchTheme = () => {
const newTheme = theme === 'dark' ? 'light' : 'dark';
setTheme(newTheme);
document.documentElement.setAttribute('data-theme', newTheme);
};
const handleLogin = (userData) => {
localStorage.setItem('iaagro_user', JSON.stringify(userData));
setUser(userData);
setView('portal');
};
const handleLogout = () => {
localStorage.removeItem('iaagro_user');
setUser(null);
setView('landing');
};
return (
{/* Botão Global de Tema - Efeito Glass Fixo */}
{view === 'landing' && }
{view === 'login' && }
{view === 'register' && }
{view === 'portal' && }
{/* Botão de WhatsApp Flutuante */}
{/* Sistema de Notificação Customizado */}
{notification.msg}
);
}
// === LANDING PAGE ===
function Landing({ onNavigate, theme, onSwitchTheme }) {
const logoSrc = theme === 'dark' ? 'assets/logo-dark.svg' : 'assets/logo-light.svg';
const [menuOpen, setMenuOpen] = React.useState(false);
const [activeDots, setActiveDots] = React.useState(1); // Foco no meio (index 1)
const plansRef = React.useRef(null);
React.useEffect(() => {
// Focar no item do meio (Profissional) ao carregar se for mobile
if (window.innerWidth <= 768 && plansRef.current) {
const scrollWidth = plansRef.current.scrollWidth;
plansRef.current.scrollLeft = (scrollWidth / 3);
}
}, []);
const handleScroll = (e) => {
if (window.innerWidth > 768) return;
const scrollLeft = e.target.scrollLeft;
const scrollWidth = e.target.scrollWidth - e.target.clientWidth;
const percentage = scrollLeft / scrollWidth;
let index = 1;
if (percentage < 0.25) index = 0;
else if (percentage > 0.75) index = 2;
if (index !== activeDots) setActiveDots(index);
};
return (
Revolucione a Emissão de Notas Fiscais
Esqueça os sistemas complexos. Envie os dados direto pelo WhatsApp e nossa Inteligência Artificial preenche, valida e emite sua nota na hora.
{/* RECURSOS */}
Como a IAAGRO trabalha?
Um fluxo completo e automatizado, do campo até a Receita Federal.
1. Envio de Dados Simplificado
Mande uma mensagem de texto simples dos produtos vendidos e do comprador para o nosso WhatsApp.
2. Extração via IA
Nosso motor de PNL entende a linguagem rural, define os NCMs corretos, as alíquotas aplicáveis e as tributações exigidas.
3. Armazenamento Blindado (5 Anos)
Os XMLs e DANFEs são armazenados com segurança nos servidores da nuuv.cloud pelo tempo exigido por lei.
4. Painel para Contabilidade
Compartilhe acessos limitados para que seu contador consiga exportar relatórios instantâneos de todo período via portal web.
{/* PLANOS */}
Escolha seu Plano
Flexibilidade para todos os tamanhos de negócios e produtores rurais.
Iniciante
R$49
/mês
50 Emissões mensais
Bot Básico do WhatsApp
Suporte por E-mail em 24h
Mais Escolhido
Profissional
R$129
/mês
Emissões Ilimitadas
Integração Inteligente via Texto
Armazenamento Legal (5 anos)
Sincronização Sefaz Direta
Cooperativa
R$299
/mês
Tudo do plano Profissional
Emissão Múltiplos CNPJs
Exportação p/ Lotes Contábeis
Relatórios Analíticos Gerenciais
{/* Paginação do Carrossel (Mobile Only) */}
{/* DEPOIMENTOS */}
O que dizem os produtores
Opiniões reais de quem já eliminou processos ultrapassados no agronegócio.
CA
Carlos Almeida
Fazenda Boa Esperança
“Antigamente eu perdia horas no computador puxando XML, era horrível estar no pasto e ter que voltar. Hoje eu mando um texto rápido pelo WhatsApp com os dados da carga, e a nota desponta no e-mail do cliente na mesma hora. Fantástico.”
MF
Marta Fidelis
Cooperativa Agrosul
“Conseguimos alocar a IAAGRO para operar notas de mais de 12 caminhões por dia. Basta digitar o pedido e a IA faz a conversão tributária exata, zeramos multas por esquecimento de regras estaduais complexas.”
RR
Rafael Rios
Engenheiro Agrônomo Independente
“A facilidade de emitir receitas técnicas e vincular faturamento apenas digitando no chat é surreal. A IA reconhece corretamente a descrição dos produtos fitossanitários com poucos caracteres. Recomendo muito.”
{/* FAQ E DUVIDAS */}
Dúvidas Frequentes
Nossa equipe está pronta para lhe integrar à nova era fiscal.
Preciso de um certificado digital para que funcione?
Sim. É requisito legal da Secretaria da Fazenda que toda empresa possua certificado A1 (.pfx) para gerar a assinatura digital nas transações financeiras. Após o upload o robô assume esta etapa por você.
É seguro enviar os dados das vendas pelo WhatsApp?
Absolutamente. Nosso tráfego emprega criptografia E2EE (ponta-a-ponta) e descartamos históricos temporais de conversão em áudio em servidores imediatamente após a geração do Danfe.
O bot do WhatsApp funciona aos finais de semana?
Sim! A automação operada em infraestrutura da IAAGRO está disponível 24 horas por dia, 7 dias por semana, sem intervenção humana, incluindo feriados nacionais.
E se a nota gerar um erro por informações enviadas erradas (Cancelamento)?
Você pode cancelar a NF-e solicitando por mensagem no chat. O próprio bot faz os testes com o Portal Sefaz, caso alguma variável (como valor e CPF incompatíveis) aconteça, o sistema vai pedir confirmação antes da emissão definitiva (draft).
{/* FOOTER OFICIAL NUUV*/}
);
}
// === LOGIN ===
function Login({ onNavigate, onLogin, theme, notify }) {
const logoSrc = theme === 'dark' ? 'assets/logo-dark.svg' : 'assets/logo-light.svg';
const [phone, setPhone] = useState('');
const [password, setPassword] = useState('');
const [showPass, setShowPass] = useState(false);
const handleSubmit = async (e) => {
e.preventDefault();
if (!phone || !password) return notify("Preencha todos os campos.", "error");
try {
const response = await fetch(`${API_URL}/login`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ phone: phone.replace(/\D/g, ''), password })
});
const data = await response.json();
if (response.ok) {
onLogin(data);
notify("Bem-vindo ao IAAGRO!", "success");
} else {
notify(data.error || "Erro ao fazer login.", "error");
}
} catch (err) {
notify("Erro ao conectar com o servidor.", "error");
}
};
return (