GiorgioBergamin's picture
Necesito dise帽ar una ladpage para un producto Saas llamado potbi, corresponde a una aplicaci贸n de gesti贸n de restuarantes, donde tiene modulo de operaciones, pos, y modulo de gestion financiera
071bafa verified
// Potbi Landing Page JavaScript
document.addEventListener('DOMContentLoaded', function() {
// Initialize Feather icons
if (typeof feather !== 'undefined') {
feather.replace();
}
// Demo tabs functionality
initDemoTabs();
// Counter animation
initCounters();
// Smooth scroll for anchor links
initSmoothScroll();
// Intersection Observer for animations
initScrollAnimations();
// Navbar scroll effect
initNavbarScroll();
});
// Demo Tabs
function initDemoTabs() {
const tabs = document.querySelectorAll('.demo-tab');
const contents = document.querySelectorAll('.demo-content');
tabs.forEach(tab => {
tab.addEventListener('click', () => {
const targetId = tab.dataset.tab;
// Update tabs
tabs.forEach(t => {
t.classList.remove('active');
t.classList.add('bg-slate-800/30', 'border-slate-800');
t.classList.remove('bg-slate-800/50', 'border-slate-700');
});
tab.classList.add('active');
tab.classList.remove('bg-slate-800/30', 'border-slate-800');
tab.classList.add('bg-slate-800/50', 'border-slate-700');
// Update contents
contents.forEach(content => {
content.classList.add('hidden');
content.classList.remove('active');
});
const targetContent = document.getElementById(`demo-${targetId}`);
if (targetContent) {
targetContent.classList.remove('hidden');
// Small delay to allow display:block to apply before opacity transition
setTimeout(() => {
targetContent.classList.add('active');
}, 10);
}
// Re-render icons
if (typeof feather !== 'undefined') {
feather.replace();
}
});
});
}
// Counter Animation
function initCounters() {
const counters = document.querySelectorAll('[data-count]');
const observerOptions = {
threshold: 0.5,
rootMargin: '0px'
};
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const counter = entry.target;
const target = parseFloat(counter.dataset.count);
const isDecimal = target % 1 !== 0;
const duration = 2000;
const startTime = performance.now();
function updateCounter(currentTime) {
const elapsed = currentTime - startTime;
const progress = Math.min(elapsed / duration, 1);
// Easing function
const easeOutQuart = 1 - Math.pow(1 - progress, 4);
const current = target * easeOutQuart;
if (isDecimal) {
counter.textContent = current.toFixed(1);
} else {
counter.textContent = Math.floor(current).toLocaleString();
}
if (progress < 1) {
requestAnimationFrame(updateCounter);
} else {
if (isDecimal) {
counter.textContent = target.toFixed(1);
} else {
counter.textContent = target.toLocaleString();
}
}
}
requestAnimationFrame(updateCounter);
observer.unobserve(counter);
}
});
}, observerOptions);
counters.forEach(counter => observer.observe(counter));
}
// Smooth Scroll
function initSmoothScroll() {
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function(e) {
const href = this.getAttribute('href');
if (href === '#') return;
const target = document.querySelector(href);
if (target) {
e.preventDefault();
const offsetTop = target.offsetTop - 80; // Account for fixed header
window.scrollTo({
top: offsetTop,
behavior: 'smooth'
});
}
});
});
}
// Scroll Animations
function initScrollAnimations() {
const animatedElements = document.querySelectorAll('.animate-on-scroll');
const observerOptions = {
threshold: 0.1,
rootMargin: '0px 0px -50px 0px'
};
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('animate-in');
observer.unobserve(entry.target);
}
});
}, observerOptions);
animatedElements.forEach(el => observer.observe(el));
}
// Navbar Scroll Effect
function initNavbarScroll() {
const navbar = document.querySelector('potbi-navbar');
if (!navbar) return;
let lastScroll = 0;
let ticking = false;
function updateNavbar() {
const currentScroll = window.pageYOffset;
if (currentScroll > 100) {
navbar.classList.add('scrolled');
} else {
navbar.classList.remove('scrolled');
}
lastScroll = currentScroll;
ticking = false;
}
window.addEventListener('scroll', () => {
if (!ticking) {
requestAnimationFrame(updateNavbar);
ticking = true;
}
}, { passive: true });
}
// Utility: Debounce function
function debounce(func, wait) {
let timeout;
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
}
// Utility: Throttle function
function throttle(func, limit) {
let inThrottle;
return function(...args) {
if (!inThrottle) {
func.apply(this, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
};
}
// Form validation helper
function validateEmail(email) {
const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return re.test(String(email).toLowerCase());
}
// Mobile menu toggle (for components)
function toggleMobileMenu() {
const menu = document.getElementById('mobile-menu');
if (menu) {
menu.classList.toggle('hidden');
menu.classList.toggle('mobile-menu-enter');
}
}
// Export functions for global access
window.Potbi = {
toggleMobileMenu,
validateEmail,
debounce,
throttle
};