Spaces:
Running
Running
| // SoberanIA Argentina - Sistema Fintech Cooperativo | |
| // JavaScript Application Logic | |
| class SoberaniaApp { | |
| constructor() { | |
| this.currentUser = null; | |
| this.products = [ | |
| {id: 1, nombre: "Mate artesanal de calabaza", precio: 15500, vendedor: "Cooperativa San Telmo", categoria: "Artesanías", descripcion: "Mate tradicional hecho a mano", icono: "🧉"}, | |
| {id: 2, nombre: "Dulce de leche artesanal 1kg", precio: 8900, vendedor: "Granja El Ombú", categoria: "Alimentación", descripcion: "Dulce de leche casero", icono: "🍯"}, | |
| {id: 3, nombre: "Empanadas salteñas x12", precio: 12000, vendedor: "Doña Rosa", categoria: "Alimentación", descripcion: "Empanadas tradicionales", icono: "🥟"}, | |
| {id: 4, nombre: "Remera Argentina algodón", precio: 18500, vendedor: "Textil Cooperativo", categoria: "Indumentaria", descripcion: "Remera 100% algodón", icono: "👕"}, | |
| {id: 5, nombre: "Miel de abeja orgánica 500g", precio: 6500, vendedor: "Apícola Los Andes", categoria: "Alimentación", descripcion: "Miel pura de montaña", icono: "🍯"}, | |
| {id: 6, nombre: "Poncho de vicuña", precio: 45000, vendedor: "Tejedores del Norte", categoria: "Artesanías", descripcion: "Poncho tradicional", icono: "🧥"}, | |
| ]; | |
| this.exchangeRate = 1.05; // PESO-D to ARS | |
| this.userBalance = 125750; | |
| this.isLoggedIn = false; | |
| this.init(); | |
| } | |
| init() { | |
| this.setupEventListeners(); | |
| this.renderProducts(); | |
| this.startCounters(); | |
| this.initCharts(); | |
| this.startCountdown(); | |
| this.setupConversor(); | |
| this.setupCreditCalculator(); | |
| this.checkLoginStatus(); | |
| } | |
| setupEventListeners() { | |
| // Navigation | |
| document.querySelectorAll('.nav__item').forEach(item => { | |
| item.addEventListener('click', (e) => { | |
| const section = e.target.dataset.section; | |
| this.showSection(section); | |
| }); | |
| }); | |
| // Authentication | |
| document.getElementById('register-btn').addEventListener('click', () => this.showModal('register-modal')); | |
| document.getElementById('login-btn').addEventListener('click', () => this.showModal('login-modal')); | |
| document.getElementById('logout-btn').addEventListener('click', () => this.logout()); | |
| document.getElementById('cuenta-login-btn').addEventListener('click', () => this.showModal('login-modal')); | |
| // Modal controls | |
| document.querySelectorAll('.modal-close').forEach(close => { | |
| close.addEventListener('click', (e) => { | |
| const modal = e.target.closest('.modal'); | |
| this.hideModal(modal.id); | |
| }); | |
| }); | |
| // Click outside modal to close | |
| document.querySelectorAll('.modal').forEach(modal => { | |
| modal.addEventListener('click', (e) => { | |
| if (e.target === modal) { | |
| this.hideModal(modal.id); | |
| } | |
| }); | |
| }); | |
| // Forms | |
| document.getElementById('register-form').addEventListener('submit', (e) => this.handleRegister(e)); | |
| document.getElementById('login-form').addEventListener('submit', (e) => this.handleLogin(e)); | |
| document.getElementById('product-form').addEventListener('submit', (e) => this.handleProductSubmit(e)); | |
| // Marketplace | |
| document.getElementById('sell-product-btn').addEventListener('click', () => { | |
| if (this.isLoggedIn) { | |
| this.showModal('product-modal'); | |
| } else { | |
| alert('Debes iniciar sesión para publicar productos'); | |
| this.showModal('login-modal'); | |
| } | |
| }); | |
| document.getElementById('product-search').addEventListener('input', (e) => this.filterProducts(e.target.value)); | |
| document.querySelectorAll('.filter-btn').forEach(btn => { | |
| btn.addEventListener('click', (e) => this.filterByCategory(e.target.dataset.category)); | |
| }); | |
| // Fintech | |
| document.getElementById('convert-btn').addEventListener('click', () => this.convertCurrency()); | |
| document.getElementById('convert-amount').addEventListener('input', () => this.updateConversion()); | |
| document.getElementById('convert-from').addEventListener('change', () => this.updateConversion()); | |
| document.getElementById('add-funds-btn').addEventListener('click', () => this.addFunds()); | |
| document.getElementById('transfer-btn').addEventListener('click', () => this.transfer()); | |
| document.getElementById('simulate-investment-btn').addEventListener('click', () => this.simulateInvestment()); | |
| document.getElementById('request-credit-btn').addEventListener('click', () => this.requestCredit()); | |
| // Credit calculator | |
| document.getElementById('credit-amount').addEventListener('input', () => this.updateCreditCalculation()); | |
| document.getElementById('credit-term').addEventListener('change', () => this.updateCreditCalculation()); | |
| // Sorteos | |
| document.getElementById('participate-btn').addEventListener('click', () => this.participateInSorteo()); | |
| } | |
| showSection(sectionId) { | |
| // Hide all sections | |
| document.querySelectorAll('.section').forEach(section => { | |
| section.classList.remove('active'); | |
| }); | |
| // Show target section | |
| document.getElementById(sectionId).classList.add('active'); | |
| // Update navigation | |
| document.querySelectorAll('.nav__item').forEach(item => { | |
| item.classList.remove('active'); | |
| }); | |
| document.querySelector(`[data-section="${sectionId}"]`).classList.add('active'); | |
| // Special handling for account section | |
| if (sectionId === 'cuenta') { | |
| this.updateAccountSection(); | |
| } | |
| } | |
| updateAccountSection() { | |
| const content = document.getElementById('cuenta-content'); | |
| if (this.isLoggedIn) { | |
| content.innerHTML = ` | |
| <div class="account-dashboard"> | |
| <div class="account-info"> | |
| <h3>Información de la Cuenta</h3> | |
| <div class="account-details"> | |
| <p><strong>Nombre:</strong> ${this.currentUser.nombre}</p> | |
| <p><strong>Email:</strong> ${this.currentUser.email}</p> | |
| <p><strong>Provincia:</strong> ${this.currentUser.provincia}</p> | |
| <p><strong>Tipo de cuenta:</strong> ${this.currentUser.jubilado ? 'Jubilado (prioritario)' : 'General'}</p> | |
| </div> | |
| </div> | |
| <div class="account-stats"> | |
| <h3>Mis Estadísticas</h3> | |
| <div class="stats-grid"> | |
| <div class="stat-item"> | |
| <strong>Saldo PESO-D:</strong> $${this.userBalance.toLocaleString()} | |
| </div> | |
| <div class="stat-item"> | |
| <strong>Sorteos participados:</strong> 12 | |
| </div> | |
| <div class="stat-item"> | |
| <strong>Productos publicados:</strong> 3 | |
| </div> | |
| <div class="stat-item"> | |
| <strong>Impacto social:</strong> +$2,500 redistribuidos | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| `; | |
| } else { | |
| content.innerHTML = ` | |
| <div class="login-required"> | |
| <h3>Acceso Requerido</h3> | |
| <p>Ingresa a tu cuenta para ver esta sección</p> | |
| <button class="btn btn--primary" id="cuenta-login-btn">Ingresar</button> | |
| </div> | |
| `; | |
| document.getElementById('cuenta-login-btn').addEventListener('click', () => this.showModal('login-modal')); | |
| } | |
| } | |
| showModal(modalId) { | |
| document.getElementById(modalId).classList.add('active'); | |
| document.body.style.overflow = 'hidden'; | |
| } | |
| hideModal(modalId) { | |
| document.getElementById(modalId).classList.remove('active'); | |
| document.body.style.overflow = 'auto'; | |
| } | |
| handleRegister(e) { | |
| e.preventDefault(); | |
| const formData = { | |
| nombre: document.getElementById('register-name').value, | |
| email: document.getElementById('register-email').value, | |
| dni: document.getElementById('register-dni').value, | |
| provincia: document.getElementById('register-provincia').value, | |
| password: document.getElementById('register-password').value, | |
| jubilado: document.getElementById('register-jubilado').checked, | |
| terms: document.getElementById('register-terms').checked | |
| }; | |
| // Validation | |
| if (!formData.terms) { | |
| alert('Debes aceptar los términos y condiciones'); | |
| return; | |
| } | |
| if (formData.dni.length < 7 || formData.dni.length > 8) { | |
| alert('El DNI debe tener 7 u 8 dígitos'); | |
| return; | |
| } | |
| // Simulate registration | |
| this.currentUser = formData; | |
| this.isLoggedIn = true; | |
| this.updateAuthUI(); | |
| this.hideModal('register-modal'); | |
| alert(`¡Bienvenido/a ${formData.nombre}! Tu cuenta ha sido creada exitosamente.${formData.jubilado ? ' Como jubilado/a, tendrás prioridad en los sorteos.' : ''}`); | |
| // Reset form | |
| document.getElementById('register-form').reset(); | |
| } | |
| handleLogin(e) { | |
| e.preventDefault(); | |
| const email = document.getElementById('login-email').value; | |
| const password = document.getElementById('login-password').value; | |
| // Simulate login validation | |
| if (email && password) { | |
| // Mock user data | |
| this.currentUser = { | |
| nombre: 'Usuario Demo', | |
| email: email, | |
| provincia: 'Buenos Aires', | |
| jubilado: false | |
| }; | |
| this.isLoggedIn = true; | |
| this.updateAuthUI(); | |
| this.hideModal('login-modal'); | |
| alert(`¡Bienvenido/a de vuelta!`); | |
| // Reset form | |
| document.getElementById('login-form').reset(); | |
| } else { | |
| alert('Por favor completa todos los campos'); | |
| } | |
| } | |
| logout() { | |
| this.currentUser = null; | |
| this.isLoggedIn = false; | |
| this.updateAuthUI(); | |
| this.showSection('dashboard'); | |
| alert('Has cerrado sesión exitosamente'); | |
| } | |
| updateAuthUI() { | |
| const userInfo = document.getElementById('user-info'); | |
| const authButtons = document.getElementById('auth-buttons'); | |
| const userWelcome = document.getElementById('user-welcome'); | |
| if (this.isLoggedIn) { | |
| userInfo.style.display = 'flex'; | |
| authButtons.style.display = 'none'; | |
| userWelcome.textContent = `Hola, ${this.currentUser.nombre}`; | |
| // Update participation status | |
| const participationStatus = document.getElementById('participation-status'); | |
| if (participationStatus) { | |
| participationStatus.innerHTML = ` | |
| <p>✅ Participas automáticamente en todos los sorteos</p> | |
| <p>Probabilidad: ${this.currentUser.jubilado ? '3x (Jubilado prioritario)' : '1x (General)'}</p> | |
| `; | |
| } | |
| } else { | |
| userInfo.style.display = 'none'; | |
| authButtons.style.display = 'flex'; | |
| // Update participation status | |
| const participationStatus = document.getElementById('participation-status'); | |
| if (participationStatus) { | |
| participationStatus.innerHTML = ` | |
| <p>Registrate para participar automáticamente en todos los sorteos</p> | |
| `; | |
| } | |
| } | |
| } | |
| checkLoginStatus() { | |
| // Check if user was logged in (simplified - in real app would check localStorage/session) | |
| this.updateAuthUI(); | |
| } | |
| renderProducts() { | |
| const grid = document.getElementById('products-grid'); | |
| grid.innerHTML = ''; | |
| this.products.forEach(product => { | |
| const productCard = document.createElement('div'); | |
| productCard.className = 'product-card'; | |
| productCard.innerHTML = ` | |
| <div class="product-image">${product.icono}</div> | |
| <div class="product-info"> | |
| <div class="product-name">${product.nombre}</div> | |
| <div class="product-price">$${product.precio.toLocaleString()}</div> | |
| <div class="product-seller">Vendido por: ${product.vendedor}</div> | |
| <div class="product-category">${product.categoria}</div> | |
| </div> | |
| `; | |
| grid.appendChild(productCard); | |
| }); | |
| } | |
| filterProducts(searchTerm) { | |
| const filteredProducts = this.products.filter(product => | |
| product.nombre.toLowerCase().includes(searchTerm.toLowerCase()) || | |
| product.vendedor.toLowerCase().includes(searchTerm.toLowerCase()) | |
| ); | |
| this.renderFilteredProducts(filteredProducts); | |
| } | |
| filterByCategory(category) { | |
| // Update active filter button | |
| document.querySelectorAll('.filter-btn').forEach(btn => { | |
| btn.classList.remove('active'); | |
| }); | |
| document.querySelector(`[data-category="${category}"]`).classList.add('active'); | |
| const filteredProducts = category === 'all' | |
| ? this.products | |
| : this.products.filter(product => product.categoria === category); | |
| this.renderFilteredProducts(filteredProducts); | |
| } | |
| renderFilteredProducts(products) { | |
| const grid = document.getElementById('products-grid'); | |
| grid.innerHTML = ''; | |
| products.forEach(product => { | |
| const productCard = document.createElement('div'); | |
| productCard.className = 'product-card'; | |
| productCard.innerHTML = ` | |
| <div class="product-image">${product.icono}</div> | |
| <div class="product-info"> | |
| <div class="product-name">${product.nombre}</div> | |
| <div class="product-price">$${product.precio.toLocaleString()}</div> | |
| <div class="product-seller">Vendido por: ${product.vendedor}</div> | |
| <div class="product-category">${product.categoria}</div> | |
| </div> | |
| `; | |
| grid.appendChild(productCard); | |
| }); | |
| if (products.length === 0) { | |
| grid.innerHTML = '<p style="text-align: center; color: var(--color-text-secondary);">No se encontraron productos</p>'; | |
| } | |
| } | |
| handleProductSubmit(e) { | |
| e.preventDefault(); | |
| if (!this.isLoggedIn) { | |
| alert('Debes iniciar sesión para publicar productos'); | |
| return; | |
| } | |
| const productData = { | |
| id: this.products.length + 1, | |
| nombre: document.getElementById('product-name').value, | |
| precio: parseInt(document.getElementById('product-price').value), | |
| categoria: document.getElementById('product-category').value, | |
| descripcion: document.getElementById('product-description').value, | |
| vendedor: this.currentUser.nombre, | |
| icono: this.getProductIcon(document.getElementById('product-category').value) | |
| }; | |
| this.products.unshift(productData); | |
| this.renderProducts(); | |
| this.hideModal('product-modal'); | |
| alert('¡Producto publicado exitosamente en el marketplace cooperativo!'); | |
| // Reset form | |
| document.getElementById('product-form').reset(); | |
| } | |
| getProductIcon(category) { | |
| const icons = { | |
| 'Alimentación': '🍽️', | |
| 'Artesanías': '🎨', | |
| 'Indumentaria': '👕', | |
| 'Tecnología': '📱', | |
| 'Servicios': '🛠️' | |
| }; | |
| return icons[category] || '📦'; | |
| } | |
| startCounters() { | |
| this.animateCounter('usuarios-counter', 1247500, 2000); | |
| this.animateCounter('redistribuido-counter', 45320780000, 3000, '$'); | |
| this.animateCounter('pesod-counter', 32654892300, 2500, '$'); | |
| } | |
| animateCounter(elementId, target, duration, prefix = '') { | |
| const element = document.getElementById(elementId); | |
| const start = 0; | |
| const range = target - start; | |
| const startTime = performance.now(); | |
| const animate = (currentTime) => { | |
| const elapsed = currentTime - startTime; | |
| const progress = Math.min(elapsed / duration, 1); | |
| const easeOutCubic = 1 - Math.pow(1 - progress, 3); | |
| const current = start + (range * easeOutCubic); | |
| element.textContent = prefix + Math.floor(current).toLocaleString(); | |
| if (progress < 1) { | |
| requestAnimationFrame(animate); | |
| } | |
| }; | |
| requestAnimationFrame(animate); | |
| } | |
| initCharts() { | |
| this.createUsersChart(); | |
| this.createRedistributionChart(); | |
| } | |
| createUsersChart() { | |
| const ctx = document.getElementById('users-chart'); | |
| if (!ctx) return; | |
| new Chart(ctx, { | |
| type: 'line', | |
| data: { | |
| labels: ['Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun'], | |
| datasets: [{ | |
| label: 'Usuarios Registrados', | |
| data: [850000, 920000, 1050000, 1150000, 1200000, 1247500], | |
| borderColor: '#0033A0', | |
| backgroundColor: 'rgba(0, 51, 160, 0.1)', | |
| tension: 0.4, | |
| fill: true | |
| }] | |
| }, | |
| options: { | |
| responsive: true, | |
| maintainAspectRatio: false, | |
| plugins: { | |
| legend: { | |
| display: false | |
| } | |
| }, | |
| scales: { | |
| y: { | |
| beginAtZero: false, | |
| ticks: { | |
| callback: function(value) { | |
| return (value / 1000000).toFixed(1) + 'M'; | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }); | |
| } | |
| createRedistributionChart() { | |
| const ctx = document.getElementById('redistribution-chart'); | |
| if (!ctx) return; | |
| new Chart(ctx, { | |
| type: 'bar', | |
| data: { | |
| labels: ['Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun'], | |
| datasets: [{ | |
| label: 'Monto Redistribuido (Millones)', | |
| data: [5200, 6800, 8500, 9200, 10800, 12500], | |
| backgroundColor: ['#1FB8CD', '#FFC185', '#B4413C', '#ECEBD5', '#5D878F', '#DB4545'] | |
| }] | |
| }, | |
| options: { | |
| responsive: true, | |
| maintainAspectRatio: false, | |
| plugins: { | |
| legend: { | |
| display: false | |
| } | |
| }, | |
| scales: { | |
| y: { | |
| beginAtZero: true, | |
| ticks: { | |
| callback: function(value) { | |
| return '$' + value + 'M'; | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }); | |
| } | |
| startCountdown() { | |
| const updateCountdown = () => { | |
| // Simulate countdown (3 days, 14 hours) | |
| const now = new Date(); | |
| const targetDate = new Date(now.getTime() + (3 * 24 * 60 * 60 * 1000) + (14 * 60 * 60 * 1000)); | |
| const diff = targetDate - now; | |
| const days = Math.floor(diff / (1000 * 60 * 60 * 24)); | |
| const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); | |
| const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60)); | |
| const countdownText = `${days} días ${hours} horas ${minutes} min`; | |
| document.getElementById('countdown').textContent = countdownText; | |
| document.getElementById('sorteo-countdown').textContent = countdownText; | |
| }; | |
| updateCountdown(); | |
| setInterval(updateCountdown, 60000); // Update every minute | |
| } | |
| setupConversor() { | |
| this.updateConversion(); | |
| } | |
| updateConversion() { | |
| const amount = parseFloat(document.getElementById('convert-amount').value) || 0; | |
| const fromCurrency = document.getElementById('convert-from').value; | |
| const resultElement = document.getElementById('conversion-result'); | |
| let result = 0; | |
| if (fromCurrency === 'PESOD') { | |
| result = amount * this.exchangeRate; | |
| } else { | |
| result = amount / this.exchangeRate; | |
| } | |
| resultElement.textContent = '$' + result.toFixed(2); | |
| } | |
| convertCurrency() { | |
| const amount = parseFloat(document.getElementById('convert-amount').value); | |
| if (!amount || amount <= 0) { | |
| alert('Por favor ingresa un monto válido'); | |
| return; | |
| } | |
| const fromCurrency = document.getElementById('convert-from').value; | |
| const action = fromCurrency === 'PESOD' ? 'convertido a Pesos ARS' : 'convertido a PESO-D'; | |
| alert(`Conversión exitosa: $${amount.toLocaleString()} ${action}`); | |
| } | |
| addFunds() { | |
| const amount = prompt('¿Cuánto deseas cargar a tu wallet?'); | |
| if (amount && !isNaN(amount) && parseFloat(amount) > 0) { | |
| this.userBalance += parseFloat(amount); | |
| document.getElementById('wallet-balance').textContent = '$' + this.userBalance.toLocaleString(); | |
| alert(`Se han cargado $${parseFloat(amount).toLocaleString()} a tu wallet`); | |
| } | |
| } | |
| transfer() { | |
| const amount = prompt('¿Cuánto deseas transferir?'); | |
| const recipient = prompt('¿A quién deseas transferir? (Email o DNI)'); | |
| if (amount && recipient && !isNaN(amount) && parseFloat(amount) > 0) { | |
| if (parseFloat(amount) <= this.userBalance) { | |
| this.userBalance -= parseFloat(amount); | |
| document.getElementById('wallet-balance').textContent = '$' + this.userBalance.toLocaleString(); | |
| alert(`Transferencia exitosa: $${parseFloat(amount).toLocaleString()} enviados a ${recipient}`); | |
| } else { | |
| alert('Saldo insuficiente'); | |
| } | |
| } | |
| } | |
| simulateInvestment() { | |
| alert('Funcionalidad de simulación de inversiones disponible próximamente. Se conectará con el sistema de bonos soberanos argentinos.'); | |
| } | |
| setupCreditCalculator() { | |
| this.updateCreditCalculation(); | |
| } | |
| updateCreditCalculation() { | |
| const amount = parseFloat(document.getElementById('credit-amount').value) || 0; | |
| const term = parseInt(document.getElementById('credit-term').value) || 6; | |
| // Simple interest calculation (12% annual rate) | |
| const monthlyRate = 0.01; // 1% monthly | |
| const monthlyPayment = amount > 0 ? (amount * monthlyRate * Math.pow(1 + monthlyRate, term)) / (Math.pow(1 + monthlyRate, term) - 1) : 0; | |
| const totalInterest = (monthlyPayment * term) - amount; | |
| document.getElementById('monthly-payment').textContent = '$' + monthlyPayment.toFixed(0); | |
| document.getElementById('total-interest').textContent = '$' + totalInterest.toFixed(0); | |
| } | |
| requestCredit() { | |
| const amount = document.getElementById('credit-amount').value; | |
| const term = document.getElementById('credit-term').value; | |
| if (!this.isLoggedIn) { | |
| alert('Debes iniciar sesión para solicitar un crédito'); | |
| this.showModal('login-modal'); | |
| return; | |
| } | |
| if (!amount || amount <= 0) { | |
| alert('Por favor ingresa un monto válido'); | |
| return; | |
| } | |
| alert(`Solicitud de crédito P2P enviada:\nMonto: $${parseFloat(amount).toLocaleString()}\nPlazo: ${term} meses\n\nRecibirás una respuesta en 24-48 horas.`); | |
| } | |
| participateInSorteo() { | |
| if (!this.isLoggedIn) { | |
| alert('Debes registrarte para participar en los sorteos'); | |
| this.showModal('register-modal'); | |
| return; | |
| } | |
| alert(`¡Ya participas automáticamente en todos los sorteos!\n\nTu probabilidad: ${this.currentUser.jubilado ? '3x (Prioritario para jubilados)' : '1x (Usuario general)'}\n\nPróximo sorteo: 3 días 14 horas`); | |
| } | |
| } | |
| // Initialize the application when DOM is loaded | |
| document.addEventListener('DOMContentLoaded', () => { | |
| new SoberaniaApp(); | |
| // Add some visual enhancements | |
| addVisualEnhancements(); | |
| }); | |
| function addVisualEnhancements() { | |
| // Add hover effects to cards | |
| const cards = document.querySelectorAll('.metric-card, .product-card, .fintech-card'); | |
| cards.forEach(card => { | |
| card.addEventListener('mouseenter', function() { | |
| this.style.transform = 'translateY(-2px)'; | |
| }); | |
| card.addEventListener('mouseleave', function() { | |
| this.style.transform = 'translateY(0)'; | |
| }); | |
| }); | |
| // Add loading states to buttons | |
| const buttons = document.querySelectorAll('.btn'); | |
| buttons.forEach(button => { | |
| button.addEventListener('click', function(e) { | |
| if (this.classList.contains('btn--primary')) { | |
| const originalText = this.textContent; | |
| this.textContent = 'Procesando...'; | |
| this.disabled = true; | |
| setTimeout(() => { | |
| this.textContent = originalText; | |
| this.disabled = false; | |
| }, 1000); | |
| } | |
| }); | |
| }); | |
| // Add smooth scrolling for better UX | |
| document.querySelectorAll('a[href^="#"]').forEach(anchor => { | |
| anchor.addEventListener('click', function (e) { | |
| e.preventDefault(); | |
| const target = document.querySelector(this.getAttribute('href')); | |
| if (target) { | |
| target.scrollIntoView({ | |
| behavior: 'smooth', | |
| block: 'start' | |
| }); | |
| } | |
| }); | |
| }); | |
| // Add form validation feedback | |
| const inputs = document.querySelectorAll('.form-control'); | |
| inputs.forEach(input => { | |
| input.addEventListener('blur', function() { | |
| if (this.required && !this.value) { | |
| this.style.borderColor = 'var(--color-error)'; | |
| } else { | |
| this.style.borderColor = 'var(--color-border)'; | |
| } | |
| }); | |
| input.addEventListener('input', function() { | |
| this.style.borderColor = 'var(--color-border)'; | |
| }); | |
| }); | |
| // Add progressive enhancement for accessibility | |
| const focusableElements = document.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'); | |
| let currentFocus = 0; | |
| document.addEventListener('keydown', function(e) { | |
| if (e.key === 'Tab') { | |
| // Enhanced tab navigation | |
| if (e.shiftKey) { | |
| currentFocus--; | |
| if (currentFocus < 0) currentFocus = focusableElements.length - 1; | |
| } else { | |
| currentFocus++; | |
| if (currentFocus >= focusableElements.length) currentFocus = 0; | |
| } | |
| } | |
| // ESC key closes modals | |
| if (e.key === 'Escape') { | |
| const activeModal = document.querySelector('.modal.active'); | |
| if (activeModal) { | |
| activeModal.classList.remove('active'); | |
| document.body.style.overflow = 'auto'; | |
| } | |
| } | |
| }); | |
| // Add real-time validation for specific fields | |
| const dniInput = document.getElementById('register-dni'); | |
| if (dniInput) { | |
| dniInput.addEventListener('input', function() { | |
| this.value = this.value.replace(/\D/g, ''); // Only numbers | |
| if (this.value.length > 8) { | |
| this.value = this.value.slice(0, 8); | |
| } | |
| }); | |
| } | |
| // Add tooltips for complex features | |
| const tooltipTriggers = document.querySelectorAll('[data-tooltip]'); | |
| tooltipTriggers.forEach(trigger => { | |
| trigger.addEventListener('mouseenter', function() { | |
| const tooltip = document.createElement('div'); | |
| tooltip.className = 'tooltip'; | |
| tooltip.textContent = this.dataset.tooltip; | |
| tooltip.style.position = 'absolute'; | |
| tooltip.style.background = 'var(--color-text)'; | |
| tooltip.style.color = 'var(--color-surface)'; | |
| tooltip.style.padding = 'var(--space-8)'; | |
| tooltip.style.borderRadius = 'var(--radius-sm)'; | |
| tooltip.style.fontSize = 'var(--font-size-sm)'; | |
| tooltip.style.zIndex = '9999'; | |
| tooltip.style.maxWidth = '200px'; | |
| document.body.appendChild(tooltip); | |
| const rect = this.getBoundingClientRect(); | |
| tooltip.style.left = rect.left + 'px'; | |
| tooltip.style.top = (rect.bottom + 5) + 'px'; | |
| this.tooltip = tooltip; | |
| }); | |
| trigger.addEventListener('mouseleave', function() { | |
| if (this.tooltip) { | |
| this.tooltip.remove(); | |
| this.tooltip = null; | |
| } | |
| }); | |
| }); | |
| // Add notification system | |
| window.showNotification = function(message, type = 'info') { | |
| const notification = document.createElement('div'); | |
| notification.className = `notification notification--${type}`; | |
| notification.innerHTML = ` | |
| <span>${message}</span> | |
| <button onclick="this.parentElement.remove()">×</button> | |
| `; | |
| notification.style.cssText = ` | |
| position: fixed; | |
| top: 20px; | |
| right: 20px; | |
| background: var(--color-surface); | |
| border: 1px solid var(--color-border); | |
| border-radius: var(--radius-base); | |
| padding: var(--space-16); | |
| box-shadow: var(--shadow-lg); | |
| z-index: 10000; | |
| max-width: 300px; | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| gap: var(--space-12); | |
| `; | |
| document.body.appendChild(notification); | |
| setTimeout(() => { | |
| notification.remove(); | |
| }, 5000); | |
| }; | |
| console.log('🇦🇷 SoberanIA Argentina - Sistema Fintech Cooperativo inicializado correctamente'); | |
| console.log('💫 Transformando la economía argentina a través de la cooperación'); | |
| } |