ARG_AutonomIA / app.js
Lukeetah's picture
Upload 19 files
3992900 verified
// SoberanIA Argentina 2025 - App.js
// Ecosistema Fintech Cooperativo
// Datos de la aplicaci贸n
const appData = {
usuarios: {
total: 783173,
jubilados: 274211,
vulnerables: 195793,
generales: 313169
},
redistribucion: {
total_acumulado: 45320780000,
mes_actual: 8500000
},
transacciones: {
volumen_mensual: 32654892300,
p2p: 45,
marketplace: 35,
inversiones: 15,
creditos: 5
},
sorteos: {
fondo_actual: 12500000,
ganadores_mes: {
jubilados: 23,
vulnerables: 8,
generales: 5
},
proximo_sorteo: "2025-06-15T20:00:00"
},
impacto: {
soberania_economica: 45,
inclusion_financiera: 67,
mejora_jubilados: 73,
ahorro_comisiones: 4500000000
},
cooperativas: {
comercios_adheridos: 8742,
provincias_activas: 24,
municipios_participantes: 1247
}
};
// DOM Elements
const domElements = {
// Navegaci贸n
navLinks: document.querySelectorAll('.nav__link'),
navToggle: document.getElementById('navToggle'),
navMenu: document.getElementById('navMenu'),
// Secciones
sections: document.querySelectorAll('.section'),
// Tema
themeToggle: document.getElementById('themeToggle'),
// Login
loginBtn: document.getElementById('loginBtn'),
registerBtn: document.getElementById('registerBtn'),
loginModal: document.getElementById('loginModal'),
closeModal: document.getElementById('closeModal'),
biometricLogin: document.getElementById('biometricLogin'),
// Contadores
counters: document.querySelectorAll('.metric-card__number'),
// Simulador de inversiones
investmentAmount: document.getElementById('investmentAmount'),
investmentTerm: document.getElementById('investmentTerm'),
simulateBtn: document.getElementById('simulateBtn'),
simulationResult: document.getElementById('simulationResult'),
estimatedReturn: document.getElementById('estimatedReturn'),
annualRate: document.getElementById('annualRate'),
totalReturn: document.getElementById('totalReturn'),
// Sorteo Countdown
days: document.getElementById('days'),
hours: document.getElementById('hours'),
minutes: document.getElementById('minutes'),
seconds: document.getElementById('seconds'),
sorteoCountdown: document.getElementById('sorteoCountdown'),
// Calculadora de probabilidades
userCategory: document.getElementById('userCategory'),
// Contenedor de notificaciones
notificationContainer: document.getElementById('notificationContainer'),
// Aprendizaje
learnMoreBtn: document.getElementById('learnMoreBtn')
};
// Inicializaci贸n de la aplicaci贸n
document.addEventListener('DOMContentLoaded', () => {
// Inicializar navegaci贸n
initNavigation();
// Inicializar tema
initTheme();
// Inicializar contadores
initCounters();
// Inicializar simulador
initSimulator();
// Inicializar cuenta regresiva
initCountdown();
// Inicializar modales
initModals();
// Inicializar calculadora de probabilidades
initProbabilityCalculator();
// Inicializar funcionalidades del marketplace
initMarketplace();
// Inicializar funcionalidades del DAO
initDAO();
// Mostrar notificaci贸n de bienvenida despu茅s de 3 segundos
setTimeout(() => {
showNotification({
type: 'success',
title: '隆Bienvenido a SoberanIA Argentina 2025!',
message: 'Juntos construimos la primera econom铆a digitalmente soberana'
});
}, 3000);
});
// Funci贸n para inicializar la navegaci贸n
function initNavigation() {
// Manejar clic en enlaces de navegaci贸n
domElements.navLinks.forEach(link => {
link.addEventListener('click', (e) => {
e.preventDefault();
// Remover clase activa de todos los enlaces
domElements.navLinks.forEach(item => item.classList.remove('active'));
// Agregar clase activa al enlace clickeado
link.classList.add('active');
// Obtener el ID de la secci贸n a mostrar
const targetId = link.getAttribute('href').substring(1);
// Ocultar todas las secciones
domElements.sections.forEach(section => {
section.classList.remove('section--active');
});
// Mostrar la secci贸n seleccionada
document.getElementById(targetId).classList.add('section--active');
// Si el men煤 m贸vil est谩 abierto, cerrarlo
if (domElements.navMenu && domElements.navMenu.classList.contains('active')) {
domElements.navMenu.classList.remove('active');
toggleHamburgerIcon();
}
// Scroll al inicio de la secci贸n
window.scrollTo({ top: 0, behavior: 'smooth' });
});
});
// Manejar toggle del men煤 en m贸vil
if (domElements.navToggle) {
domElements.navToggle.addEventListener('click', () => {
if (domElements.navMenu) {
domElements.navMenu.classList.toggle('active');
toggleHamburgerIcon();
}
});
}
// Funci贸n para animar el 铆cono hamburguesa
function toggleHamburgerIcon() {
if (!domElements.navToggle) return;
const spans = domElements.navToggle.querySelectorAll('span');
spans.forEach(span => span.classList.toggle('active'));
if (spans[0].classList.contains('active')) {
spans[0].style.transform = 'rotate(45deg) translate(5px, 5px)';
spans[1].style.opacity = '0';
spans[2].style.transform = 'rotate(-45deg) translate(7px, -7px)';
} else {
spans[0].style.transform = 'none';
spans[1].style.opacity = '1';
spans[2].style.transform = 'none';
}
}
}
// Funci贸n para inicializar el tema
function initTheme() {
if (!domElements.themeToggle) return;
// Verificar si hay un tema guardado en localStorage
const savedTheme = 'light'; // Por defecto usamos claro debido a las restricciones de localStorage
// Aplicar tema guardado o detectar preferencia del sistema
if (savedTheme) {
document.documentElement.setAttribute('data-color-scheme', savedTheme);
updateThemeIcon(savedTheme);
} else {
// Detectar preferencia del sistema
const prefersDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches;
const theme = prefersDarkMode ? 'dark' : 'light';
document.documentElement.setAttribute('data-color-scheme', theme);
updateThemeIcon(theme);
}
// Manejar cambio de tema
domElements.themeToggle.addEventListener('click', () => {
const currentTheme = document.documentElement.getAttribute('data-color-scheme');
const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
document.documentElement.setAttribute('data-color-scheme', newTheme);
updateThemeIcon(newTheme);
// Simulaci贸n de guardado en localStorage (no usado realmente por las restricciones)
console.log(`Tema cambiado a: ${newTheme}`);
// Mostrar notificaci贸n
showNotification({
type: 'info',
title: 'Tema cambiado',
message: `Has cambiado al tema ${newTheme === 'dark' ? 'oscuro' : 'claro'}`
});
});
// Actualizar 铆cono seg煤n el tema
function updateThemeIcon(theme) {
if (theme === 'dark') {
domElements.themeToggle.innerHTML = '<i class="fas fa-sun"></i>';
} else {
domElements.themeToggle.innerHTML = '<i class="fas fa-moon"></i>';
}
}
}
// Funci贸n para inicializar los contadores animados
function initCounters() {
domElements.counters.forEach(counter => {
if (!counter) return;
const target = parseInt(counter.getAttribute('data-target').replace(/,/g, ''));
const prefix = counter.getAttribute('data-prefix') || '';
const suffix = counter.getAttribute('data-suffix') || '';
const formatter = new Intl.NumberFormat('es-AR');
// Duraci贸n de la animaci贸n en ms
const duration = 2000;
const frameRate = 1000 / 60; // 60 fps
const frames = duration / frameRate;
// Incremento por frame
const increment = target / frames;
let currentCount = 0;
// Funci贸n de animaci贸n
function animate() {
currentCount += increment;
if (currentCount < target) {
counter.textContent = prefix + formatter.format(Math.floor(currentCount)) + suffix;
requestAnimationFrame(animate);
} else {
counter.textContent = prefix + formatter.format(target) + suffix;
}
}
// Iniciar animaci贸n cuando el elemento est茅 en el viewport
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
animate();
observer.disconnect();
}
});
}, { threshold: 0.1 });
observer.observe(counter);
});
}
// Funci贸n para inicializar el simulador de inversiones
function initSimulator() {
if (!domElements.simulateBtn) return;
domElements.simulateBtn.addEventListener('click', () => {
const amount = parseFloat(domElements.investmentAmount.value);
const term = parseInt(domElements.investmentTerm.value);
// Validaci贸n
if (isNaN(amount) || amount <= 0) {
showNotification({
type: 'error',
title: 'Error en la simulaci贸n',
message: 'Ingrese un monto v谩lido para la inversi贸n'
});
return;
}
// Tasas de inter茅s seg煤n plazo (simuladas)
const rates = {
30: 65, // 65% anual para 30 d铆as
90: 70, // 70% anual para 90 d铆as
180: 75, // 75% anual para 180 d铆as
365: 80 // 80% anual para 365 d铆as
};
const annualRate = rates[term];
const periodRate = annualRate * (term / 365);
const interest = amount * (periodRate / 100);
const total = amount + interest;
// Formatear valores
const formatter = new Intl.NumberFormat('es-AR', {
style: 'currency',
currency: 'ARS'
});
// Actualizar resultados
if (domElements.estimatedReturn) {
domElements.estimatedReturn.textContent = formatter.format(interest);
}
if (domElements.annualRate) {
domElements.annualRate.textContent = annualRate + '%';
}
if (domElements.totalReturn) {
domElements.totalReturn.textContent = formatter.format(total);
}
// Mostrar resultados
if (domElements.simulationResult) {
domElements.simulationResult.style.display = 'block';
}
// Mostrar notificaci贸n
showNotification({
type: 'success',
title: 'Simulaci贸n completa',
message: `Rendimiento estimado: ${formatter.format(interest)}`
});
});
}
// Funci贸n para inicializar la cuenta regresiva del sorteo
function initCountdown() {
// Fecha del pr贸ximo sorteo desde los datos
const targetDate = new Date(appData.sorteos.proximo_sorteo);
// Actualizar la cuenta regresiva cada segundo
function updateCountdown() {
const currentDate = new Date();
const difference = targetDate - currentDate;
// Calcular d铆as, horas, minutos y segundos
const days = Math.floor(difference / (1000 * 60 * 60 * 24));
const hours = Math.floor((difference % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
const minutes = Math.floor((difference % (1000 * 60 * 60)) / (1000 * 60));
const seconds = Math.floor((difference % (1000 * 60)) / 1000);
// Actualizar elementos DOM
if (domElements.days) domElements.days.textContent = days;
if (domElements.hours) domElements.hours.textContent = hours;
if (domElements.minutes) domElements.minutes.textContent = minutes;
if (domElements.seconds) domElements.seconds.textContent = seconds;
// Formato compacto para el contador peque帽o
if (domElements.sorteoCountdown) {
domElements.sorteoCountdown.innerHTML = `<span>${days}d ${hours}h ${minutes}m</span>`;
}
// Continuar actualizando
if (difference > 0) {
setTimeout(updateCountdown, 1000);
}
}
// Iniciar cuenta regresiva
updateCountdown();
}
// Funci贸n para inicializar modales
function initModals() {
// Modal de login
if (domElements.loginBtn && domElements.loginModal) {
// Abrir modal
domElements.loginBtn.addEventListener('click', () => {
domElements.loginModal.classList.add('active');
});
// Tambi茅n abrir con el bot贸n de registro
if (domElements.registerBtn) {
domElements.registerBtn.addEventListener('click', () => {
domElements.loginModal.classList.add('active');
});
}
// Cerrar modal
if (domElements.closeModal) {
domElements.closeModal.addEventListener('click', () => {
domElements.loginModal.classList.remove('active');
});
}
// Cerrar al hacer clic fuera del contenido
domElements.loginModal.addEventListener('click', (e) => {
if (e.target === domElements.loginModal) {
domElements.loginModal.classList.remove('active');
}
});
// Simulaci贸n de autenticaci贸n biom茅trica
if (domElements.biometricLogin) {
domElements.biometricLogin.addEventListener('click', () => {
const scannerCircle = document.querySelector('.scanner-circle');
scannerCircle.classList.add('scanning');
domElements.biometricLogin.disabled = true;
domElements.biometricLogin.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Escaneando...';
// Simular proceso de escaneo
setTimeout(() => {
scannerCircle.classList.remove('scanning');
domElements.biometricLogin.disabled = false;
domElements.biometricLogin.innerHTML = '<i class="fas fa-fingerprint"></i> Autenticar';
// Cerrar modal
domElements.loginModal.classList.remove('active');
// Mostrar notificaci贸n de 茅xito
showNotification({
type: 'success',
title: '隆Autenticaci贸n exitosa!',
message: 'Bienvenido de nuevo, Usuario'
});
// Simulaci贸n de usuario logueado
if (domElements.loginBtn) {
domElements.loginBtn.innerHTML = '<i class="fas fa-user-circle"></i> Mi Cuenta';
}
}, 3000);
});
}
}
// Modal de aprendizaje
if (domElements.learnMoreBtn) {
domElements.learnMoreBtn.addEventListener('click', () => {
showNotification({
type: 'info',
title: 'Video explicativo',
message: 'El video tutorial se est谩 cargando...'
});
// Simular carga de video
setTimeout(() => {
const targetSection = document.getElementById('impacto');
// Cambiar a la secci贸n de impacto
domElements.sections.forEach(section => {
section.classList.remove('section--active');
});
targetSection.classList.add('section--active');
// Actualizar navegaci贸n
domElements.navLinks.forEach(link => {
link.classList.remove('active');
if (link.getAttribute('href') === '#impacto') {
link.classList.add('active');
}
});
// Scroll al inicio de la secci贸n
window.scrollTo({ top: 0, behavior: 'smooth' });
showNotification({
type: 'success',
title: 'Conoce nuestro impacto',
message: 'Descubre c贸mo estamos transformando Argentina'
});
}, 1500);
});
}
}
// Funci贸n para inicializar la calculadora de probabilidades
function initProbabilityCalculator() {
if (!domElements.userCategory) return;
// Actualizar probabilidad al cambiar la categor铆a
domElements.userCategory.addEventListener('change', updateProbability);
// Actualizar inicialmente
updateProbability();
function updateProbability() {
const category = domElements.userCategory.value;
let probability, boost;
switch (category) {
case 'jubilado':
probability = '1 en 4,608';
boost = '70% mayor que usuarios generales';
break;
case 'vulnerable':
probability = '1 en 9,790';
boost = '20% mayor que usuarios generales';
break;
case 'general':
probability = '1 en 15,658';
boost = '0%';
break;
default:
probability = '1 en 12,000';
boost = 'est谩ndar';
}
// Actualizar en la interfaz
const probabilityNumber = document.querySelector('.probability-number');
const probabilityBoost = document.querySelector('.probability-boost');
if (probabilityNumber) {
probabilityNumber.textContent = probability;
}
if (probabilityBoost) {
probabilityBoost.innerHTML = category !== 'general'
? `<i class="fas fa-arrow-up"></i> ${boost}`
: `<i class="fas fa-equals"></i> Probabilidad est谩ndar`;
}
}
}
// Funci贸n para inicializar funcionalidades del marketplace
function initMarketplace() {
// Filtros del marketplace
const filterTags = document.querySelectorAll('.filter-tag');
if (filterTags) {
filterTags.forEach(tag => {
tag.addEventListener('click', () => {
// Eliminar la clase active de todos los filtros
filterTags.forEach(t => t.classList.remove('active'));
// Agregar la clase active al filtro seleccionado
tag.classList.add('active');
// Filtrar productos (simulado)
showNotification({
type: 'info',
title: 'Filtro aplicado',
message: `Mostrando productos: ${tag.textContent}`
});
});
});
}
// Acciones de productos
const productBtns = document.querySelectorAll('.product-card__actions .btn');
if (productBtns) {
productBtns.forEach(btn => {
btn.addEventListener('click', (e) => {
const action = btn.textContent.trim();
const productName = btn.closest('.product-card').querySelector('h4').textContent;
showNotification({
type: 'success',
title: `Acci贸n: ${action}`,
message: `Has seleccionado: ${productName}`
});
});
});
}
// B煤squeda en el marketplace
const searchBtn = document.querySelector('.search-btn');
if (searchBtn) {
searchBtn.addEventListener('click', () => {
const searchInput = document.querySelector('.search-input');
if (searchInput && searchInput.value.trim()) {
showNotification({
type: 'info',
title: 'B煤squeda inteligente',
message: `Buscando: "${searchInput.value}"`
});
} else {
showNotification({
type: 'warning',
title: 'B煤squeda vac铆a',
message: 'Ingresa un t茅rmino para buscar'
});
}
});
}
}
// Funci贸n para inicializar funcionalidades del DAO
function initDAO() {
// Botones de votaci贸n
const voteButtons = document.querySelectorAll('.proposal-actions .btn');
if (voteButtons) {
voteButtons.forEach(btn => {
btn.addEventListener('click', () => {
const isInFavor = btn.textContent.includes('A Favor');
const proposalTitle = btn.closest('.proposal-card').querySelector('h4').textContent;
// Deshabilitar botones de votaci贸n para esa propuesta
const buttons = btn.closest('.proposal-actions').querySelectorAll('.btn');
buttons.forEach(b => {
b.disabled = true;
b.classList.add('btn--disabled');
});
// Actualizar barra de votaci贸n (simulado)
const voteBar = btn.closest('.proposal-card').querySelector(
isInFavor ? '.vote-option--for .vote-fill' : '.vote-option--against .vote-fill'
);
if (voteBar) {
const currentWidth = parseFloat(voteBar.style.width);
voteBar.style.width = (currentWidth + 2) + '%';
// Actualizar porcentaje
const percentageElem = btn.closest('.proposal-card').querySelector(
isInFavor ? '.vote-option--for .vote-percentage' : '.vote-option--against .vote-percentage'
);
if (percentageElem) {
const currentPercentage = parseInt(percentageElem.textContent);
percentageElem.textContent = (currentPercentage + 2) + '%';
// Actualizar porcentaje opuesto
const oppositeElem = btn.closest('.proposal-card').querySelector(
isInFavor ? '.vote-option--against .vote-percentage' : '.vote-option--for .vote-percentage'
);
if (oppositeElem) {
const oppositePercentage = parseInt(oppositeElem.textContent);
oppositeElem.textContent = (oppositePercentage - 2) + '%';
// Actualizar barra opuesta
const oppositeBar = btn.closest('.proposal-card').querySelector(
isInFavor ? '.vote-option--against .vote-fill' : '.vote-option--for .vote-fill'
);
if (oppositeBar) {
const oppositeWidth = parseFloat(oppositeBar.style.width);
oppositeBar.style.width = (oppositeWidth - 2) + '%';
}
}
}
}
// Mostrar notificaci贸n
showNotification({
type: 'success',
title: 'Voto registrado',
message: `Has votado ${isInFavor ? 'a favor' : 'en contra'} de: "${proposalTitle}"`
});
});
});
}
}
// Funci贸n para mostrar notificaciones
function showNotification(options) {
if (!domElements.notificationContainer) return;
const { type, title, message } = options;
// Crear elemento de notificaci贸n
const notification = document.createElement('div');
notification.className = `notification notification--${type}`;
// Iconos seg煤n tipo
let icon;
switch (type) {
case 'success':
icon = 'check-circle';
break;
case 'error':
icon = 'exclamation-circle';
break;
case 'warning':
icon = 'exclamation-triangle';
break;
case 'info':
default:
icon = 'info-circle';
}
// Estructura de la notificaci贸n
notification.innerHTML = `
<div class="notification__icon">
<i class="fas fa-${icon}"></i>
</div>
<div class="notification__content">
<div class="notification__title">${title}</div>
<div class="notification__message">${message}</div>
</div>
`;
// Agregar al contenedor
domElements.notificationContainer.appendChild(notification);
// Eliminar despu茅s de 5 segundos
setTimeout(() => {
notification.style.opacity = '0';
notification.style.transform = 'translateX(100%)';
notification.style.transition = 'all 0.5s ease';
setTimeout(() => {
notification.remove();
}, 500);
}, 5000);
}
// Helpers adicionales
// Formateo de n煤meros para pesos argentinos
function formatCurrency(value) {
return new Intl.NumberFormat('es-AR', {
style: 'currency',
currency: 'ARS',
minimumFractionDigits: 0
}).format(value);
}
// Formateo de n煤meros grandes
function formatNumber(value) {
return new Intl.NumberFormat('es-AR').format(value);
}
// Generar n煤mero aleatorio entre min y max
function getRandomNumber(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}