notXCS/public/dashboard/index.html

243 lines
9.3 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dashboard - NOTXCS</title>
<link rel="stylesheet" href="/css/style.css">
</head>
<body>
<div class="app-shell">
<aside class="sidebar">
<h2>NOTXCS</h2>
<div class="user-info">Signed in as <strong id="username-display"></strong> <span id="role-badge" class="badge type-badge"></span></div>
<a id="admin-link" class="hidden" href="/admin" style="display:block;margin-bottom:12px;color:var(--accent);font-size:13px;">Manage users</a>
<button class="secondary" id="logout-btn" style="margin-bottom: 16px;">Log out</button>
<ul class="place-list" id="place-list"></ul>
<div class="card" style="margin-top: 16px;">
<h3 style="margin-top:0;font-size:14px;">Add place</h3>
<form id="add-place-form">
<label for="place-name">Name <span style="color:var(--muted);font-weight:normal;">(optional)</span></label>
<input type="text" id="place-name">
<div id="add-place-custom-fields" class="hidden">
<label for="place-id">Place ID <span style="color:var(--muted);font-weight:normal;">(leave blank to auto-generate)</span></label>
<input type="text" id="place-id">
<label for="place-api-key">API Key <span style="color:var(--muted);font-weight:normal;">(leave blank to auto-generate)</span></label>
<input type="text" id="place-api-key">
</div>
<button type="submit" class="primary">Add place</button>
</form>
</div>
</aside>
<main class="main">
<div id="no-place" class="empty-state">
Select or create a place from the sidebar to manage its readers.
</div>
<div id="place-view" class="hidden">
<div class="main-header">
<h1 id="place-title"></h1>
<button class="secondary" id="download-kit-btn">Download kit</button>
<button class="danger" id="delete-place-btn">Delete place</button>
</div>
<div class="card">
<h3>Name</h3>
<form id="set-place-name-form" class="inline-form">
<div class="field-group">
<label for="place-name-custom">Place name <span style="color:var(--muted);font-weight:normal;">(leave blank to show the place ID instead)</span></label>
<input type="text" id="place-name-custom">
</div>
<button type="submit" class="primary">Save</button>
</form>
</div>
<div class="card">
<h3>API Key</h3>
<div class="inline-form">
<div class="field-group">
<label for="place-id-display">Place ID</label>
<input type="text" id="place-id-display" readonly>
</div>
<div class="field-group">
<label for="place-api-key-display">Current key</label>
<input type="password" id="place-api-key-display" readonly>
</div>
<button type="button" class="secondary" id="toggle-api-key-btn">Show</button>
<button type="button" class="secondary" id="copy-api-key-btn">Copy</button>
<button type="button" class="secondary" id="regenerate-api-key-btn">Regenerate</button>
</div>
<form id="set-api-key-form" class="inline-form hidden" style="margin-top:8px;">
<div class="field-group">
<label for="place-api-key-custom">Set custom key <span style="color:var(--muted);font-weight:normal;">(leave blank to auto-generate)</span></label>
<input type="text" id="place-api-key-custom">
</div>
<button type="submit" class="primary">Save</button>
</form>
</div>
<div class="card">
<div class="card-header">
<h3>Readers</h3>
<form id="add-reader-form" class="inline-form card-header-form">
<div class="field-group">
<input type="text" id="reader-name" placeholder="Reader name" required>
</div>
<button type="submit" class="primary">Add reader</button>
</form>
</div>
<div id="readers-empty" class="empty-state hidden">No readers yet for this place.</div>
<div class="readers-grid" id="readers-grid"></div>
</div>
<div class="card">
<h3>Add access group</h3>
<p style="margin-top:-8px;color:var(--muted);font-size:13px;">Access groups (e.g. "Staff") bundle multiple users/cards/rank rules so they can be assigned to multiple readers at once.</p>
<form id="add-access-group-form" class="inline-form">
<div class="field-group">
<label for="access-group-name">Name</label>
<input type="text" id="access-group-name" required>
</div>
<button type="submit" class="primary">Add group</button>
</form>
</div>
<div class="card">
<h3>Access groups</h3>
<div id="access-groups-empty" class="empty-state hidden">No access groups yet for this place.</div>
<ul class="acl-list" id="access-groups-list"></ul>
</div>
<div class="card" id="shared-access-card">
<h3>Shared access</h3>
<p style="margin-top:-8px;color:var(--muted);font-size:13px;">Grant other users access to manage this place's settings, readers and access groups.</p>
<form id="add-shared-access-form" class="inline-form">
<div class="field-group">
<label for="shared-access-username">Username</label>
<input type="text" id="shared-access-username" required>
</div>
<button type="submit" class="primary">Grant access</button>
</form>
<div id="shared-access-empty" class="empty-state hidden">No other users have been granted access to this place.</div>
<ul class="acl-list" id="shared-access-list"></ul>
</div>
</div>
</main>
</div>
<div id="acl-modal" class="modal-overlay hidden">
<div class="modal">
<div class="modal-header">
<h2>Allowed persons &amp; credentials — <span id="acl-reader-name"></span></h2>
<button class="secondary" id="acl-close-btn">Close</button>
</div>
<div class="card">
<h3>Add entry</h3>
<form id="add-acl-form" class="inline-form">
<div class="field-group">
<label for="acl-type">Type</label>
<select id="acl-type">
<option value="0">User ID</option>
<option value="1">Card number</option>
<option value="2">Group exact rank</option>
<option value="3">Group minimum rank</option>
<option value="4">Allow all</option>
<option value="5">Access group</option>
</select>
</div>
<div class="field-group" id="acl-data-group">
<label for="acl-data">User ID</label>
<input type="text" id="acl-data">
</div>
<div class="field-group hidden" id="acl-group-id-group">
<label for="acl-group-id">Group ID</label>
<input type="text" id="acl-group-id">
</div>
<div class="field-group hidden" id="acl-group-rank-group">
<label for="acl-group-rank">Rank</label>
<input type="number" id="acl-group-rank" min="0">
</div>
<div class="field-group hidden" id="acl-access-group-group">
<label for="acl-access-group">Access group</label>
<select id="acl-access-group"></select>
</div>
<button type="submit" class="primary">Add entry</button>
</form>
</div>
<div class="card">
<h3>Entries</h3>
<div id="acl-empty" class="empty-state hidden">No entries yet. Access will be denied for everyone until an entry is added.</div>
<ul class="acl-list" id="acl-list"></ul>
</div>
</div>
</div>
<div id="logs-modal" class="modal-overlay hidden">
<div class="modal">
<div class="modal-header">
<h2>Scan logs — <span id="logs-reader-name"></span></h2>
<button class="secondary" id="logs-close-btn">Close</button>
</div>
<div class="card">
<h3>Recent scans</h3>
<div id="logs-empty" class="empty-state hidden">No scans have been recorded for this reader yet.</div>
<ul class="acl-list" id="logs-list"></ul>
</div>
</div>
</div>
<div id="group-modal" class="modal-overlay hidden">
<div class="modal">
<div class="modal-header">
<h2>Access group members — <span id="group-name"></span></h2>
<button class="secondary" id="group-close-btn">Close</button>
</div>
<div class="card">
<h3>Add member</h3>
<form id="add-group-member-form" class="inline-form">
<div class="field-group">
<label for="group-member-type">Type</label>
<select id="group-member-type">
<option value="0">User ID</option>
<option value="1">Card number</option>
<option value="2">Group exact rank</option>
<option value="3">Group minimum rank</option>
<option value="4">Allow all</option>
</select>
</div>
<div class="field-group" id="group-member-data-group">
<label for="group-member-data">User ID</label>
<input type="text" id="group-member-data">
</div>
<div class="field-group hidden" id="group-member-group-id-group">
<label for="group-member-group-id">Group ID</label>
<input type="text" id="group-member-group-id">
</div>
<div class="field-group hidden" id="group-member-group-rank-group">
<label for="group-member-group-rank">Rank</label>
<input type="number" id="group-member-group-rank" min="0">
</div>
<button type="submit" class="primary">Add member</button>
</form>
</div>
<div class="card">
<h3>Members</h3>
<div id="group-members-empty" class="empty-state hidden">No members yet. This group grants no access until members are added.</div>
<ul class="acl-list" id="group-members-list"></ul>
</div>
</div>
</div>
<script src="/js/dashboard.js"></script>
</body>
</html>