Files
boc/landvex-admin-v2/ui/index.html
T
Bernt 6989a98d75 feat: Passwordless cross-device authentication
- 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
2026-07-07 07:11:50 +00:00

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>