Files
MagoRevisited/static/js/app.js
T
Alby96andClaude Sonnet 4.6 8a9fb5085a Add Mago4 demo ERP with Python FastAPI
Implements a working in-memory ERP demo inspired by Mago4, covering
the core modules: dashboard with KPI widgets, customers, suppliers,
products, sales orders, purchase orders, and warehouse inventory.

- FastAPI backend with Pydantic models and REST API (auto-docs at /docs)
- Jinja2 HTML templates with Mago4-style UI (dark sidebar, blue/orange/
  green/red palette, Material Design icons)
- In-memory fake database seeded with sample customers, suppliers,
  products, and orders — ready to swap for SQLAlchemy + SQL Server
- Workarounds for Python 3.14 + Starlette 1.3 / Jinja2 compatibility
  (cache_size=0, new TemplateResponse(request, name, ctx) signature)
- launch.json for one-click preview; run.bat for manual startup

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 10:17:57 +02:00

121 lines
3.2 KiB
JavaScript

// Utility functions for API calls
async function apiCall(endpoint, method = 'GET', data = null) {
const options = {
method: method,
headers: {
'Content-Type': 'application/json',
}
};
if (data) {
options.body = JSON.stringify(data);
}
try {
const response = await fetch(endpoint, options);
if (!response.ok) {
throw new Error(`API Error: ${response.statusText}`);
}
return await response.json();
} catch (error) {
console.error('API call failed:', error);
showNotification('Errore nella richiesta', 'error');
throw error;
}
}
// Notification system
function showNotification(message, type = 'info') {
const notification = document.createElement('div');
notification.className = `notification notification-${type}`;
notification.textContent = message;
notification.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
padding: 12px 20px;
background-color: ${type === 'error' ? '#D32F2F' : '#1976D2'};
color: white;
border-radius: 4px;
box-shadow: 0 4px 12px rgba(0,0,0,0.2);
z-index: 2000;
animation: slideIn 0.3s ease-in-out;
`;
document.body.appendChild(notification);
setTimeout(() => notification.remove(), 3000);
}
// Format currency
function formatCurrency(value) {
return new Intl.NumberFormat('it-IT', {
style: 'currency',
currency: 'EUR'
}).format(value);
}
// Format date
function formatDate(dateString) {
const date = new Date(dateString);
return date.toLocaleDateString('it-IT');
}
// Initialize page animations
document.addEventListener('DOMContentLoaded', function() {
// Add smooth scrolling
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' });
}
});
});
// Add keyboard shortcuts
document.addEventListener('keydown', function(e) {
// Close modals with Escape
if (e.key === 'Escape') {
document.querySelectorAll('.modal.show').forEach(modal => {
modal.classList.remove('show');
});
}
});
// Initialize tooltips
document.querySelectorAll('[title]').forEach(element => {
element.style.cursor = 'help';
});
});
// Add CSS animation for notifications
const style = document.createElement('style');
style.textContent = `
@keyframes slideIn {
from {
transform: translateX(400px);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
.material-icons {
font-family: 'Material Icons';
font-weight: normal;
font-style: normal;
font-size: 24px;
display: inline-block;
line-height: 1;
text-transform: none;
letter-spacing: normal;
word-wrap: normal;
white-space: nowrap;
direction: ltr;
}
`;
document.head.appendChild(style);