Initial commit - Fire alarm management application
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
108
app/static/css/style.css
Normal file
108
app/static/css/style.css
Normal file
@@ -0,0 +1,108 @@
|
||||
/* Fire Alarm Management App Styles */
|
||||
|
||||
body {
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.card {
|
||||
box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
|
||||
border: none;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
background-color: #fff;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.125);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.table th {
|
||||
font-weight: 600;
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
|
||||
.progress {
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
|
||||
.btn-group-sm > .btn {
|
||||
padding: 0.25rem 0.5rem;
|
||||
}
|
||||
|
||||
/* Dashboard cards */
|
||||
.card.bg-primary,
|
||||
.card.bg-success,
|
||||
.card.bg-info,
|
||||
.card.bg-warning {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.card.bg-primary .card-title,
|
||||
.card.bg-success .card-title,
|
||||
.card.bg-info .card-title {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
/* Form improvements */
|
||||
.form-control:focus,
|
||||
.form-select:focus {
|
||||
border-color: #0d6efd;
|
||||
box-shadow: 0 0 0 0.2rem rgba(13, 110, 253, 0.25);
|
||||
}
|
||||
|
||||
/* Table hover effect */
|
||||
.table-hover tbody tr:hover {
|
||||
background-color: rgba(13, 110, 253, 0.05);
|
||||
}
|
||||
|
||||
/* Badge styles */
|
||||
.badge {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* Responsive tables */
|
||||
@media (max-width: 768px) {
|
||||
.table-responsive {
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* Chart containers */
|
||||
canvas {
|
||||
max-height: 300px;
|
||||
}
|
||||
|
||||
/* Breadcrumb */
|
||||
.breadcrumb {
|
||||
background: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* Modal improvements */
|
||||
.modal-header {
|
||||
border-bottom: 1px solid #dee2e6;
|
||||
}
|
||||
|
||||
.modal-footer {
|
||||
border-top: 1px solid #dee2e6;
|
||||
}
|
||||
|
||||
/* Phase cards in schedule */
|
||||
.card.border-success {
|
||||
border-width: 2px !important;
|
||||
}
|
||||
|
||||
/* Filter row */
|
||||
.row.mb-4 .form-control,
|
||||
.row.mb-4 .form-select {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
/* Loading spinner */
|
||||
.spinner-border {
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
}
|
||||
110
app/static/js/app.js
Normal file
110
app/static/js/app.js
Normal file
@@ -0,0 +1,110 @@
|
||||
// Fire Alarm Management App - Common JavaScript
|
||||
|
||||
// Format currency
|
||||
function formatCurrency(value) {
|
||||
return '$' + (value || 0).toLocaleString('en-US', {
|
||||
minimumFractionDigits: 0,
|
||||
maximumFractionDigits: 0
|
||||
});
|
||||
}
|
||||
|
||||
// Format date
|
||||
function formatDate(dateStr) {
|
||||
if (!dateStr) return '-';
|
||||
const date = new Date(dateStr);
|
||||
return date.toLocaleDateString('en-US', {
|
||||
year: 'numeric',
|
||||
month: 'short',
|
||||
day: 'numeric'
|
||||
});
|
||||
}
|
||||
|
||||
// Get progress bar class based on completion percentage
|
||||
function getProgressClass(completion) {
|
||||
if (completion >= 100) return 'bg-success';
|
||||
if (completion > 50) return 'bg-info';
|
||||
if (completion > 0) return 'bg-warning';
|
||||
return 'bg-secondary';
|
||||
}
|
||||
|
||||
// Show toast notification
|
||||
function showToast(message, type = 'success') {
|
||||
const toastContainer = document.getElementById('toastContainer') || createToastContainer();
|
||||
|
||||
const toast = document.createElement('div');
|
||||
toast.className = `toast align-items-center text-white bg-${type} border-0`;
|
||||
toast.setAttribute('role', 'alert');
|
||||
toast.innerHTML = `
|
||||
<div class="d-flex">
|
||||
<div class="toast-body">${message}</div>
|
||||
<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast"></button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
toastContainer.appendChild(toast);
|
||||
const bsToast = new bootstrap.Toast(toast);
|
||||
bsToast.show();
|
||||
|
||||
toast.addEventListener('hidden.bs.toast', () => toast.remove());
|
||||
}
|
||||
|
||||
function createToastContainer() {
|
||||
const container = document.createElement('div');
|
||||
container.id = 'toastContainer';
|
||||
container.className = 'toast-container position-fixed bottom-0 end-0 p-3';
|
||||
document.body.appendChild(container);
|
||||
return container;
|
||||
}
|
||||
|
||||
// Confirm dialog
|
||||
function confirmAction(message) {
|
||||
return new Promise((resolve) => {
|
||||
resolve(confirm(message));
|
||||
});
|
||||
}
|
||||
|
||||
// API helper functions
|
||||
async function apiGet(url) {
|
||||
const response = await fetch(url);
|
||||
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
|
||||
return response.json();
|
||||
}
|
||||
|
||||
async function apiPost(url, data) {
|
||||
const response = await fetch(url, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(data)
|
||||
});
|
||||
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
|
||||
return response.json();
|
||||
}
|
||||
|
||||
async function apiPut(url, data) {
|
||||
const response = await fetch(url, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(data)
|
||||
});
|
||||
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
|
||||
return response.json();
|
||||
}
|
||||
|
||||
async function apiDelete(url) {
|
||||
const response = await fetch(url, { method: 'DELETE' });
|
||||
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Debounce function for search inputs
|
||||
function debounce(func, wait) {
|
||||
let timeout;
|
||||
return function executedFunction(...args) {
|
||||
const later = () => {
|
||||
clearTimeout(timeout);
|
||||
func(...args);
|
||||
};
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(later, wait);
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user