File size: 4,960 Bytes
6a561a0 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | document.addEventListener('DOMContentLoaded', function() {
initThemeToggle();
feather.replace();
initTooltips();
loadMockData();
initMobileMenu();
initSmoothScrolling();
});
function initThemeToggle() {
const themeToggle = document.createElement('button');
themeToggle.className = 'metro-btn flex items-center space-x-2';
themeToggle.innerHTML = `
<i data-feather="moon" class="w-4 h-4"></i>
<span class="hidden md:inline">Toggle Theme</span>
`;
themeToggle.addEventListener('click', function() {
document.documentElement.classList.toggle('dark');
const icon = themeToggle.querySelector('i');
if (document.documentElement.classList.contains('dark')) {
icon.setAttribute('data-feather', 'sun');
} else {
icon.setAttribute('data-feather', 'moon');
}
feather.replace();
});
}
function initTooltips() {
const tooltipElements = document.querySelectorAll('[data-tooltip]');
tooltipElements.forEach(element => {
element.addEventListener('mouseenter', function(e) {
const tooltipText = this.getAttribute('data-tooltip');
const tooltip = document.createElement('div');
tooltip.className = 'fixed z-50 px-3 py-2 text-sm bg-gray-900 text-white rounded-lg shadow-lg';
tooltip.textContent = tooltipText;
document.body.appendChild(tooltip);
const rect = this.getBoundingClientRect();
tooltip.style.left = `${rect.left + rect.width / 2 - tooltip.offsetWidth / 2}px`;
tooltip.style.top = `${rect.top - tooltip.offsetHeight - 10}px`;
this._tooltip = tooltip;
});
element.addEventListener('mouseleave', function() {
if (this._tooltip) {
this._tooltip.remove();
delete this._tooltip;
}
});
});
}
function loadMockData() {
console.log('Loading mock data for MetroPulse dashboard...');
setTimeout(() => {
const stats = {
users: '12,847',
revenue: '$84,520',
sessions: '3,245',
responseTime: '124ms'
};
document.querySelectorAll('.stat-value').forEach((el, index) => {
const values = Object.values(stats);
if (index < values.length) {
el.textContent = values[index];
}
});
}, 1000);
}
function initMobileMenu() {
const mobileMenuBtn = document.querySelector('[data-mobile-menu-toggle]');
const mobileMenu = document.querySelector('[data-mobile-menu]');
if (mobileMenuBtn && mobileMenu) {
mobileMenuBtn.addEventListener('click', function() {
mobileMenu.classList.toggle('hidden');
this.setAttribute('aria-expanded',
mobileMenu.classList.contains('hidden') ? 'false' : 'true'
);
});
document.addEventListener('click', function(e) {
if (!mobileMenu.contains(e.target) && !mobileMenuBtn.contains(e.target)) {
mobileMenu.classList.add('hidden');
mobileMenuBtn.setAttribute('aria-expanded', 'false');
}
});
}
}
function initSmoothScrolling() {
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
const targetId = this.getAttribute('href');
if (targetId === '#') return;
const targetElement = document.querySelector(targetId);
if (targetElement) {
window.scrollTo({
top: targetElement.offsetTop - 80,
behavior: 'smooth'
});
}
});
});
}
function showNotification(message, type = 'info') {
const notification = document.createElement('div');
const colors = {
info: 'bg-primary-600',
success: 'bg-green-600',
warning: 'bg-yellow-600',
error: 'bg-red-600'
};
notification.className = `fixed top-4 right-4 z-50 px-6 py-4 rounded-lg text-white shadow-lg transform translate-x-full opacity-0 transition-all duration-300 ${colors[type]}`;
notification.textContent = message;
document.body.appendChild(notification);
setTimeout(() => {
notification.classList.remove('translate-x-full', 'opacity-0');
notification.classList.add('translate-x-0', 'opacity-100');
}, 10);
setTimeout(() => {
notification.classList.remove('translate-x-0', 'opacity-100');
notification.classList.add('translate-x-full', 'opacity-0');
setTimeout(() => {
notification.remove();
}, 300);
}, 5000);
}
window.MetroPulse = {
showNotification,
initThemeToggle,
loadMockData
}; |