Initial commit
This commit is contained in:
commit
983cee0320
322 changed files with 57174 additions and 0 deletions
187
backup/first -fina app/app/static/js/script.js
Executable file
187
backup/first -fina app/app/static/js/script.js
Executable file
|
|
@ -0,0 +1,187 @@
|
|||
// PWA Service Worker Registration
|
||||
if ('serviceWorker' in navigator) {
|
||||
window.addEventListener('load', () => {
|
||||
navigator.serviceWorker.register('/static/js/service-worker.js')
|
||||
.then(registration => {
|
||||
console.log('[PWA] Service Worker registered successfully:', registration.scope);
|
||||
|
||||
// Check for updates
|
||||
registration.addEventListener('updatefound', () => {
|
||||
const newWorker = registration.installing;
|
||||
newWorker.addEventListener('statechange', () => {
|
||||
if (newWorker.state === 'installed' && navigator.serviceWorker.controller) {
|
||||
console.log('[PWA] New version available! Refresh to update.');
|
||||
// Optionally show a notification to the user
|
||||
if (confirm('A new version of FINA is available. Reload to update?')) {
|
||||
newWorker.postMessage({ type: 'SKIP_WAITING' });
|
||||
window.location.reload();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
console.log('[PWA] Service Worker registration failed:', error);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// PWA Install Prompt
|
||||
let deferredPrompt;
|
||||
const installPrompt = document.getElementById('pwa-install-prompt');
|
||||
const installBtn = document.getElementById('pwa-install-btn');
|
||||
const dismissBtn = document.getElementById('pwa-dismiss-btn');
|
||||
|
||||
// Check if already installed (standalone mode)
|
||||
const isInstalled = () => {
|
||||
return window.matchMedia('(display-mode: standalone)').matches ||
|
||||
window.navigator.standalone === true ||
|
||||
document.referrer.includes('android-app://');
|
||||
};
|
||||
|
||||
// Detect iOS
|
||||
const isIOS = () => {
|
||||
return /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
|
||||
};
|
||||
|
||||
// Show iOS install instructions
|
||||
function showIOSInstallPrompt() {
|
||||
if (installPrompt) {
|
||||
const promptText = installPrompt.querySelector('.pwa-prompt-text p');
|
||||
if (promptText && isIOS() && !window.navigator.standalone) {
|
||||
promptText.textContent = 'Tap Share button and then "Add to Home Screen"';
|
||||
installBtn.style.display = 'none'; // Hide install button on iOS
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('beforeinstallprompt', (e) => {
|
||||
// Prevent the default mini-infobar
|
||||
e.preventDefault();
|
||||
// Store the event for later use
|
||||
deferredPrompt = e;
|
||||
|
||||
// Don't show if already installed
|
||||
if (isInstalled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Show custom install prompt if not dismissed
|
||||
const dismissed = localStorage.getItem('pwa-install-dismissed');
|
||||
const dismissedUntil = parseInt(dismissed || '0');
|
||||
|
||||
if (Date.now() > dismissedUntil && installPrompt) {
|
||||
installPrompt.style.display = 'block';
|
||||
}
|
||||
});
|
||||
|
||||
// Handle iOS separately
|
||||
if (isIOS() && !isInstalled()) {
|
||||
const dismissed = localStorage.getItem('pwa-install-dismissed');
|
||||
const dismissedUntil = parseInt(dismissed || '0');
|
||||
|
||||
if (Date.now() > dismissedUntil && installPrompt) {
|
||||
setTimeout(() => {
|
||||
installPrompt.style.display = 'block';
|
||||
showIOSInstallPrompt();
|
||||
}, 2000); // Show after 2 seconds
|
||||
}
|
||||
}
|
||||
|
||||
if (installBtn) {
|
||||
installBtn.addEventListener('click', async () => {
|
||||
if (!deferredPrompt) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Show the install prompt
|
||||
deferredPrompt.prompt();
|
||||
|
||||
// Wait for the user's response
|
||||
const { outcome } = await deferredPrompt.userChoice;
|
||||
console.log(`[PWA] User response: ${outcome}`);
|
||||
|
||||
// Clear the saved prompt since it can't be used again
|
||||
deferredPrompt = null;
|
||||
|
||||
// Hide the prompt
|
||||
installPrompt.style.display = 'none';
|
||||
});
|
||||
}
|
||||
|
||||
if (dismissBtn) {
|
||||
dismissBtn.addEventListener('click', () => {
|
||||
installPrompt.style.display = 'none';
|
||||
// Remember dismissal for 7 days
|
||||
localStorage.setItem('pwa-install-dismissed', Date.now() + (7 * 24 * 60 * 60 * 1000));
|
||||
});
|
||||
}
|
||||
|
||||
// Check if app is installed
|
||||
window.addEventListener('appinstalled', () => {
|
||||
console.log('[PWA] App installed successfully');
|
||||
if (installPrompt) {
|
||||
installPrompt.style.display = 'none';
|
||||
}
|
||||
localStorage.removeItem('pwa-install-dismissed');
|
||||
});
|
||||
|
||||
// Online/Offline status
|
||||
window.addEventListener('online', () => {
|
||||
console.log('[PWA] Back online');
|
||||
// Show notification or update UI
|
||||
showToast('Connection restored', 'success');
|
||||
});
|
||||
|
||||
window.addEventListener('offline', () => {
|
||||
console.log('[PWA] Gone offline');
|
||||
showToast('You are offline. Some features may be limited.', 'info');
|
||||
});
|
||||
|
||||
// Toast notification function
|
||||
function showToast(message, type = 'info') {
|
||||
const toast = document.createElement('div');
|
||||
toast.className = `alert alert-${type} glass-card`;
|
||||
toast.textContent = message;
|
||||
document.body.appendChild(toast);
|
||||
|
||||
setTimeout(() => {
|
||||
toast.classList.add('hiding');
|
||||
setTimeout(() => toast.remove(), 300);
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
// Language menu toggle
|
||||
function toggleLanguageMenu() {
|
||||
const menu = document.getElementById('language-menu');
|
||||
menu.classList.toggle('show');
|
||||
}
|
||||
|
||||
// Close language menu when clicking outside
|
||||
document.addEventListener('click', function(event) {
|
||||
const switcher = document.querySelector('.language-switcher');
|
||||
const menu = document.getElementById('language-menu');
|
||||
|
||||
if (menu && switcher && !switcher.contains(event.target)) {
|
||||
menu.classList.remove('show');
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
console.log('Finance Tracker loaded');
|
||||
|
||||
// Auto-hide flash messages after 2 seconds
|
||||
const alerts = document.querySelectorAll('.alert');
|
||||
|
||||
alerts.forEach(function(alert) {
|
||||
// Add hiding animation after 2 seconds
|
||||
setTimeout(function() {
|
||||
alert.classList.add('hiding');
|
||||
|
||||
// Remove from DOM after animation completes
|
||||
setTimeout(function() {
|
||||
alert.remove();
|
||||
}, 300); // Wait for animation to finish
|
||||
}, 2000); // Show for 2 seconds
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue