255 lines
7.2 KiB
HTML
255 lines
7.2 KiB
HTML
|
|
<!DOCTYPE html>
|
||
|
|
<html lang="sv" data-theme="light">
|
||
|
|
<head>
|
||
|
|
<meta charset="UTF-8">
|
||
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
|
|
<title>AAMOS Admin — Modules</title>
|
||
|
|
<link rel="stylesheet" href="assets/admin.css">
|
||
|
|
<style>
|
||
|
|
.modules-grid {
|
||
|
|
display: grid;
|
||
|
|
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
|
||
|
|
gap: 16px;
|
||
|
|
}
|
||
|
|
.module-card {
|
||
|
|
background: var(--bg-card);
|
||
|
|
border-radius: var(--radius);
|
||
|
|
padding: 20px;
|
||
|
|
box-shadow: var(--shadow);
|
||
|
|
transition: transform 0.2s, box-shadow 0.2s;
|
||
|
|
border: 2px solid transparent;
|
||
|
|
}
|
||
|
|
.module-card:hover {
|
||
|
|
transform: translateY(-2px);
|
||
|
|
box-shadow: var(--shadow-md);
|
||
|
|
}
|
||
|
|
.module-card.enabled {
|
||
|
|
border-color: var(--success);
|
||
|
|
}
|
||
|
|
.module-header {
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
gap: 12px;
|
||
|
|
margin-bottom: 12px;
|
||
|
|
}
|
||
|
|
.module-icon {
|
||
|
|
width: 44px; height: 44px;
|
||
|
|
border-radius: 12px;
|
||
|
|
display: flex; align-items: center; justify-content: center;
|
||
|
|
font-size: 22px;
|
||
|
|
background: var(--bg-input);
|
||
|
|
}
|
||
|
|
.module-title { font-size: 17px; font-weight: 700; }
|
||
|
|
.module-desc { font-size: 13px; color: var(--text-tertiary); margin-bottom: 16px; }
|
||
|
|
|
||
|
|
.module-footer {
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
justify-content: space-between;
|
||
|
|
}
|
||
|
|
.status-badge {
|
||
|
|
font-size: 12px;
|
||
|
|
font-weight: 600;
|
||
|
|
padding: 4px 12px;
|
||
|
|
border-radius: 20px;
|
||
|
|
}
|
||
|
|
.status-running { background: rgba(52,199,89,0.12); color: var(--success); }
|
||
|
|
.status-stopped { background: var(--bg-input); color: var(--text-tertiary); }
|
||
|
|
.status-error { background: rgba(255,59,48,0.12); color: var(--danger); }
|
||
|
|
|
||
|
|
/* Toggle switch */
|
||
|
|
.toggle-switch {
|
||
|
|
position: relative;
|
||
|
|
width: 52px;
|
||
|
|
height: 28px;
|
||
|
|
background: var(--bg-input);
|
||
|
|
border-radius: 14px;
|
||
|
|
cursor: pointer;
|
||
|
|
transition: background 0.3s;
|
||
|
|
border: none;
|
||
|
|
padding: 0;
|
||
|
|
}
|
||
|
|
.toggle-switch.enabled {
|
||
|
|
background: var(--success);
|
||
|
|
}
|
||
|
|
.toggle-switch::after {
|
||
|
|
content: '';
|
||
|
|
position: absolute;
|
||
|
|
top: 2px;
|
||
|
|
left: 2px;
|
||
|
|
width: 24px;
|
||
|
|
height: 24px;
|
||
|
|
background: white;
|
||
|
|
border-radius: 50%;
|
||
|
|
transition: transform 0.3s;
|
||
|
|
box-shadow: 0 1px 3px rgba(0,0,0,0.2);
|
||
|
|
}
|
||
|
|
.toggle-switch.enabled::after {
|
||
|
|
transform: translateX(24px);
|
||
|
|
}
|
||
|
|
|
||
|
|
.service-list {
|
||
|
|
margin-top: 12px;
|
||
|
|
padding-top: 12px;
|
||
|
|
border-top: 1px solid var(--separator);
|
||
|
|
}
|
||
|
|
.service-item {
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
justify-content: space-between;
|
||
|
|
padding: 6px 0;
|
||
|
|
font-size: 13px;
|
||
|
|
}
|
||
|
|
.service-name { color: var(--text-secondary); }
|
||
|
|
.service-status {
|
||
|
|
width: 8px; height: 8px;
|
||
|
|
border-radius: 50%;
|
||
|
|
background: var(--success);
|
||
|
|
}
|
||
|
|
.service-status.down { background: var(--danger); }
|
||
|
|
</style>
|
||
|
|
</head>
|
||
|
|
<body>
|
||
|
|
|
||
|
|
<aside class="sidebar">
|
||
|
|
<div class="sidebar-brand">
|
||
|
|
<div class="brand-icon">
|
||
|
|
<svg viewBox="0 0 24 24"><path d="M12 2L2 7v10l10 5 10-5V7L12 2zm0 2.18L20 8.5v7L12 19.82 4 15.5v-7l8-4.32z"/></svg>
|
||
|
|
</div>
|
||
|
|
<div class="brand-text">
|
||
|
|
<div class="brand-name">AAMOS Admin</div>
|
||
|
|
<div class="brand-sub">Unified v2.0</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<nav class="sidebar-nav">
|
||
|
|
<div class="nav-section-label">Overview</div>
|
||
|
|
<a class="nav-item" href="unified-dashboard.html">
|
||
|
|
<span class="nav-icon">📊</span>
|
||
|
|
Dashboard
|
||
|
|
</a>
|
||
|
|
<a class="nav-item" href="users.html">
|
||
|
|
<span class="nav-icon">👥</span>
|
||
|
|
Users
|
||
|
|
</a>
|
||
|
|
<a class="nav-item active" href="modules.html">
|
||
|
|
<span class="nav-icon">🔧</span>
|
||
|
|
Modules
|
||
|
|
</a>
|
||
|
|
|
||
|
|
<div class="nav-section-label">Systems</div>
|
||
|
|
<a class="nav-item" href="quixzoom.html">
|
||
|
|
<span class="nav-icon">📸</span>
|
||
|
|
quiXzoom
|
||
|
|
</a>
|
||
|
|
<a class="nav-item" href="landvex.html">
|
||
|
|
<span class="nav-icon">🌍</span>
|
||
|
|
LandveX
|
||
|
|
</a>
|
||
|
|
<a class="nav-item" href="economy.html">
|
||
|
|
<span class="nav-icon">💰</span>
|
||
|
|
Economy
|
||
|
|
</a>
|
||
|
|
<a class="nav-item" href="crm.html">
|
||
|
|
<span class="nav-icon">🤝</span>
|
||
|
|
CRM
|
||
|
|
</a>
|
||
|
|
|
||
|
|
<div class="nav-section-label">System</div>
|
||
|
|
<a class="nav-item" href="audit.html">
|
||
|
|
<span class="nav-icon">📋</span>
|
||
|
|
Audit Log
|
||
|
|
</a>
|
||
|
|
<a class="nav-item" href="settings.html">
|
||
|
|
<span class="nav-icon">⚙️</span>
|
||
|
|
Settings
|
||
|
|
</a>
|
||
|
|
</nav>
|
||
|
|
</aside>
|
||
|
|
|
||
|
|
<div class="main">
|
||
|
|
<header class="topbar">
|
||
|
|
<div class="topbar-title">Modules</div>
|
||
|
|
<div class="topbar-actions">
|
||
|
|
<span id="modules-summary" style="color:var(--text-tertiary);font-size:14px;">Loading...</span>
|
||
|
|
</div>
|
||
|
|
</header>
|
||
|
|
|
||
|
|
<section class="page-content active">
|
||
|
|
<div class="modules-grid" id="modules-grid">
|
||
|
|
<div style="grid-column:1/-1;text-align:center;padding:60px;color:var(--text-tertiary)">Loading modules...</div>
|
||
|
|
</div>
|
||
|
|
</section>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<script src="assets/api.js"></script>
|
||
|
|
<script>
|
||
|
|
'use strict';
|
||
|
|
|
||
|
|
const api = createAdminAPI(window.location.origin);
|
||
|
|
let modules = [];
|
||
|
|
|
||
|
|
const moduleIcons = {
|
||
|
|
'academy': '🎓',
|
||
|
|
'finance': '💰',
|
||
|
|
'compliance': '🛡️',
|
||
|
|
'people': '👥',
|
||
|
|
'operations': '⚙️',
|
||
|
|
'commerce': '🛒',
|
||
|
|
'identity': '🔐',
|
||
|
|
'connect': '🔗',
|
||
|
|
'governance': '🏛️',
|
||
|
|
'analytics': '📊'
|
||
|
|
};
|
||
|
|
|
||
|
|
async function loadModules() {
|
||
|
|
try {
|
||
|
|
modules = await api.getModules();
|
||
|
|
renderModules();
|
||
|
|
} catch (err) {
|
||
|
|
document.getElementById('modules-grid').innerHTML =
|
||
|
|
`<div style="grid-column:1/-1;text-align:center;padding:60px;color:var(--danger)">Error: ${err.message}</div>`;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
function renderModules() {
|
||
|
|
const grid = document.getElementById('modules-grid');
|
||
|
|
const enabled = modules.filter(m => m.enabled).length;
|
||
|
|
document.getElementById('modules-summary').textContent = `${enabled}/${modules.length} enabled`;
|
||
|
|
|
||
|
|
grid.innerHTML = modules.map(m => {
|
||
|
|
const icon = moduleIcons[m.id] || '🔧';
|
||
|
|
const statusClass = m.status === 'running' ? 'status-running' : m.status === 'error' ? 'status-error' : 'status-stopped';
|
||
|
|
|
||
|
|
return `
|
||
|
|
<div class="module-card ${m.enabled ? 'enabled' : ''}">
|
||
|
|
<div class="module-header">
|
||
|
|
<div class="module-icon">${icon}</div>
|
||
|
|
<div>
|
||
|
|
<div class="module-title">${m.name}</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<div class="module-desc">${m.description}</div>
|
||
|
|
<div class="module-footer">
|
||
|
|
<span class="status-badge ${statusClass}">${m.status}</span>
|
||
|
|
<button class="toggle-switch ${m.enabled ? 'enabled' : ''}" onclick="toggleModule('${m.id}')" title="${m.enabled ? 'Disable' : 'Enable'}"></button>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
`;
|
||
|
|
}).join('');
|
||
|
|
}
|
||
|
|
|
||
|
|
window.toggleModule = async (id) => {
|
||
|
|
try {
|
||
|
|
await api.toggleModule(id);
|
||
|
|
loadModules();
|
||
|
|
} catch (err) {
|
||
|
|
alert('Error: ' + err.message);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
loadModules();
|
||
|
|
</script>
|
||
|
|
</body>
|
||
|
|
</html>
|