BOC v1.0: RS256 auth, Ledger integration, Prometheus metrics, CI/CD, backup
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
// BOC — Business Operations Center
|
||||
// Shared JavaScript utilities
|
||||
|
||||
const API_BASE = '/api/v1';
|
||||
|
||||
function getToken() {
|
||||
return localStorage.getItem('boc_token');
|
||||
}
|
||||
|
||||
function getUser() {
|
||||
const user = localStorage.getItem('boc_user');
|
||||
return user ? JSON.parse(user) : null;
|
||||
}
|
||||
|
||||
function apiRequest(endpoint, options = {}) {
|
||||
const token = getToken();
|
||||
const url = endpoint.startsWith('http') ? endpoint : `${API_BASE}${endpoint}`;
|
||||
|
||||
return fetch(url, {
|
||||
...options,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${token}`,
|
||||
...options.headers
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function formatCurrency(value, currency = 'USD') {
|
||||
if (value === null || value === undefined) return '—';
|
||||
return new Intl.NumberFormat('sv-SE', {
|
||||
style: 'currency',
|
||||
currency,
|
||||
maximumFractionDigits: 0
|
||||
}).format(value);
|
||||
}
|
||||
|
||||
function formatDate(date) {
|
||||
if (!date) return '-';
|
||||
return new Date(date).toLocaleDateString('sv-SE');
|
||||
}
|
||||
|
||||
function formatDateTime(date) {
|
||||
if (!date) return '-';
|
||||
return new Date(date).toLocaleString('sv-SE');
|
||||
}
|
||||
|
||||
function timeAgo(timestamp) {
|
||||
const diff = Date.now() - new Date(timestamp).getTime();
|
||||
const mins = Math.floor(diff / 60000);
|
||||
if (mins < 1) return 'nyss';
|
||||
if (mins < 60) return `${mins}m sedan`;
|
||||
const hours = Math.floor(mins / 60);
|
||||
if (hours < 24) return `${hours}h sedan`;
|
||||
const days = Math.floor(hours / 24);
|
||||
if (days < 30) return `${days}d sedan`;
|
||||
return formatDate(timestamp);
|
||||
}
|
||||
|
||||
function showToast(message, type = 'info') {
|
||||
const toast = document.createElement('div');
|
||||
toast.className = `alert alert-${type}`;
|
||||
toast.style.cssText = 'position:fixed;top:24px;right:24px;z-index:1000;max-width:400px;animation:slideIn 0.3s ease;';
|
||||
toast.textContent = message;
|
||||
document.body.appendChild(toast);
|
||||
setTimeout(() => toast.remove(), 5000);
|
||||
}
|
||||
|
||||
function confirmDelete(message) {
|
||||
return confirm(message || 'Ar du saker pa att du vill ta bort detta?');
|
||||
}
|
||||
|
||||
// Check authentication on page load
|
||||
function requireAuth() {
|
||||
if (!getToken()) {
|
||||
window.location.href = '/';
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Update user email in sidebar
|
||||
function updateUserInfo() {
|
||||
const user = getUser();
|
||||
const el = document.getElementById('user-email');
|
||||
if (el && user) {
|
||||
el.textContent = user.email || 'erik@landvex.com';
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize on page load
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
updateUserInfo();
|
||||
});
|
||||
Reference in New Issue
Block a user