v1.0.0 - Initial backup

This commit is contained in:
2026-05-16 23:00:37 -05:00
commit bf8b6225a3
114 changed files with 21120 additions and 0 deletions
+200
View File
@@ -0,0 +1,200 @@
/**
* Tom's Java Jive - Admin JavaScript
*/
// Sidebar Toggle
document.addEventListener('DOMContentLoaded', function() {
const sidebarToggle = document.getElementById('sidebarToggle');
const sidebar = document.querySelector('.admin-sidebar');
if (sidebarToggle && sidebar) {
sidebarToggle.addEventListener('click', function() {
sidebar.classList.toggle('open');
});
// Close sidebar when clicking outside on mobile
document.addEventListener('click', function(e) {
if (window.innerWidth <= 1024) {
if (!sidebar.contains(e.target) && !sidebarToggle.contains(e.target)) {
sidebar.classList.remove('open');
}
}
});
}
// Confirm dialogs
document.querySelectorAll('[data-confirm]').forEach(el => {
el.addEventListener('click', function(e) {
if (!confirm(this.dataset.confirm)) {
e.preventDefault();
}
});
});
// Auto-hide alerts
document.querySelectorAll('.alert').forEach(alert => {
setTimeout(() => {
alert.style.opacity = '0';
alert.style.transform = 'translateY(-10px)';
setTimeout(() => alert.remove(), 300);
}, 5000);
});
});
// Toast notifications
const AdminToast = {
container: null,
init() {
if (!this.container) {
this.container = document.createElement('div');
this.container.style.cssText = 'position:fixed;bottom:20px;right:20px;z-index:1000;display:flex;flex-direction:column;gap:8px;';
document.body.appendChild(this.container);
}
},
show(message, type = 'success', duration = 3000) {
this.init();
const colors = {
success: '#10B981',
error: '#EF4444',
warning: '#F59E0B',
info: '#3B82F6'
};
const toast = document.createElement('div');
toast.style.cssText = `
background: white;
padding: 12px 16px;
border-radius: 8px;
box-shadow: 0 10px 15px rgba(0,0,0,0.1);
border-left: 4px solid ${colors[type] || colors.info};
display: flex;
align-items: center;
gap: 10px;
animation: slideIn 0.3s ease;
`;
toast.innerHTML = `
<i class="fas fa-${type === 'success' ? 'check-circle' : type === 'error' ? 'exclamation-circle' : 'info-circle'}" style="color:${colors[type]}"></i>
<span>${message}</span>
`;
this.container.appendChild(toast);
setTimeout(() => {
toast.style.animation = 'slideIn 0.3s ease reverse';
setTimeout(() => toast.remove(), 300);
}, duration);
},
success(msg) { this.show(msg, 'success'); },
error(msg) { this.show(msg, 'error'); },
warning(msg) { this.show(msg, 'warning'); },
info(msg) { this.show(msg, 'info'); }
};
// API helper
async function adminFetch(url, options = {}) {
const defaults = {
headers: {
'Content-Type': 'application/json',
}
};
const response = await fetch(url, { ...defaults, ...options });
const data = await response.json();
if (!response.ok) {
throw new Error(data.error || 'Request failed');
}
return data;
}
// Loading state
function setLoading(button, isLoading) {
if (isLoading) {
button.dataset.originalHtml = button.innerHTML;
button.innerHTML = '<span class="loading"></span> Loading...';
button.disabled = true;
} else {
button.innerHTML = button.dataset.originalHtml || button.innerHTML;
button.disabled = false;
}
}
// Format currency
function formatCurrency(amount) {
return '$' + parseFloat(amount).toFixed(2);
}
// Format date
function formatDate(dateString) {
return new Date(dateString).toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric'
});
}
// Debounce
function debounce(func, wait) {
let timeout;
return function(...args) {
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(this, args), wait);
};
}
// Modal
const Modal = {
open(modalId) {
const modal = document.getElementById(modalId);
if (modal) {
modal.classList.add('active');
document.body.style.overflow = 'hidden';
}
},
close(modalId) {
const modal = document.getElementById(modalId);
if (modal) {
modal.classList.remove('active');
document.body.style.overflow = '';
}
}
};
// Close modals on overlay click
document.addEventListener('click', function(e) {
if (e.target.classList.contains('modal-overlay')) {
e.target.classList.remove('active');
document.body.style.overflow = '';
}
});
// Image preview
function previewImage(input, previewId) {
const preview = document.getElementById(previewId);
if (!preview) return;
if (input.files && input.files[0]) {
const reader = new FileReader();
reader.onload = function(e) {
preview.src = e.target.result;
preview.style.display = 'block';
};
reader.readAsDataURL(input.files[0]);
}
}
// Add slideIn animation
const style = document.createElement('style');
style.textContent = `
@keyframes slideIn {
from { transform: translateX(100%); opacity: 0; }
to { transform: translateX(0); opacity: 1; }
}
`;
document.head.appendChild(style);