6989a98d75
- Arkitektur: docs/auth/passwordless-architecture.md - Backend: iom/quixzoom-auth-service/ (FastAPI + Redis) - Webb: quixzoom-market-pages/se/login/ (QR-kod + polling) - App: iom/quixzoom-app/src/features/auth/ (push + deep links) Flöde: QR-kod → app-godkännande → webb-inloggad
106 lines
3.7 KiB
HTML
106 lines
3.7 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="sv">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>LandveX Admin — Ekonomi</title>
|
|
<style>
|
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
body { font-family: -apple-system, system-ui, sans-serif; background: #f5f5f5; }
|
|
.header { background: #1a1a2e; color: #fff; padding: 20px; }
|
|
.header h1 { font-size: 20px; }
|
|
.header p { opacity: 0.7; font-size: 14px; margin-top: 4px; }
|
|
.container { max-width: 1200px; margin: 0 auto; padding: 20px; }
|
|
.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 20px; }
|
|
.card { background: #fff; padding: 24px; border-radius: 12px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
|
|
.card h2 { font-size: 14px; text-transform: uppercase; color: #666; margin-bottom: 8px; }
|
|
.card .value { font-size: 32px; font-weight: 600; }
|
|
.card .sub { color: #999; font-size: 14px; margin-top: 4px; }
|
|
.status { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 6px; }
|
|
.status.online { background: #28a745; }
|
|
.status.offline { background: #dc3545; }
|
|
.services { margin-top: 20px; }
|
|
.service { display: flex; justify-content: space-between; padding: 12px 0; border-bottom: 1px solid #eee; }
|
|
.nav { background: #16213e; padding: 0 20px; display: flex; gap: 4px; }
|
|
.nav a { color: rgba(255,255,255,0.7); text-decoration: none; padding: 12px 16px; font-size: 14px; }
|
|
.nav a.active { color: #fff; background: rgba(255,255,255,0.1); }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="header">
|
|
<h1>LandveX Admin</h1>
|
|
<p>Ekonomi — Realtid från aamos-ledger och ouroboros-finance</p>
|
|
</div>
|
|
|
|
<div class="nav">
|
|
<a href="index.html" class="active">Ekonomi</a>
|
|
<a href="intelligence.html">Intelligence</a>
|
|
<a href="#">CRM</a>
|
|
<a href="#">Support</a>
|
|
</div>
|
|
|
|
<div class="container">
|
|
<div class="grid">
|
|
<div class="card">
|
|
<h2>Bank Balance</h2>
|
|
<div class="value" id="balance">$26,400</div>
|
|
<div class="sub">~276K SEK • Uppdaterad nu</div>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<h2>Monthly Burn</h2>
|
|
<div class="value">$6,000</div>
|
|
<div class="sub">~60K SEK/mån</div>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<h2>Runway</h2>
|
|
<div class="value">4.4 mån</div>
|
|
<div class="sub">Vid nuvarande burn</div>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<h2>Systemstatus</h2>
|
|
<div class="sub">
|
|
<span class="status online"></span>Ledger (3250)<br>
|
|
<span class="status online"></span>Ouroboros (3202)
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card services" style="margin-top: 20px;">
|
|
<h2>Kopplade Tjänster</h2>
|
|
<div id="services">
|
|
<div class="service"><span>Laddar...</span></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
async function loadData() {
|
|
try {
|
|
const res = await fetch('/api/finance/overview');
|
|
const data = await res.json();
|
|
|
|
const servicesDiv = document.getElementById('services');
|
|
servicesDiv.innerHTML = `
|
|
<div class="service">
|
|
<span>aamos-ledger</span>
|
|
<span>${data.services.ledger.url} • v${data.services.ledger.version}</span>
|
|
</div>
|
|
<div class="service">
|
|
<span>ouroboros-finance</span>
|
|
<span>${data.services.ouroboros.url} • v${data.services.ouroboros.version}</span>
|
|
</div>
|
|
`;
|
|
} catch (e) {
|
|
console.error('Fel:', e);
|
|
}
|
|
}
|
|
|
|
loadData();
|
|
setInterval(loadData, 30000); // Uppdatera var 30e sekund
|
|
</script>
|
|
</body>
|
|
</html>
|