WIP: dashboard sharing UI (pre-merge)
This commit is contained in:
parent
247d56263a
commit
f0735ae18c
|
|
@ -10,7 +10,8 @@
|
||||||
<div class="app-shell">
|
<div class="app-shell">
|
||||||
<aside class="sidebar">
|
<aside class="sidebar">
|
||||||
<h2>NOTXCS</h2>
|
<h2>NOTXCS</h2>
|
||||||
<div class="user-info">Signed in as <strong id="username-display"></strong></div>
|
<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.html" 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>
|
<button class="secondary" id="logout-btn" style="margin-bottom: 16px;">Log out</button>
|
||||||
|
|
||||||
<ul class="place-list" id="place-list"></ul>
|
<ul class="place-list" id="place-list"></ul>
|
||||||
|
|
@ -76,6 +77,20 @@
|
||||||
<div id="access-groups-empty" class="empty-state hidden">No access groups yet for this place.</div>
|
<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>
|
<ul class="acl-list" id="access-groups-list"></ul>
|
||||||
</div>
|
</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>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,15 @@
|
||||||
let currentPlaceId = null;
|
let currentPlaceId = null;
|
||||||
let places = [];
|
let places = [];
|
||||||
let accessGroups = [];
|
let accessGroups = [];
|
||||||
|
let currentUser = null;
|
||||||
|
let currentPlaceAccessLevel = null;
|
||||||
|
|
||||||
|
const ROLE_LABELS = {
|
||||||
|
1: 'User',
|
||||||
|
2: 'Elevated',
|
||||||
|
3: 'Admin',
|
||||||
|
4: 'Superadmin'
|
||||||
|
};
|
||||||
|
|
||||||
async function api(path, options = {}) {
|
async function api(path, options = {}) {
|
||||||
const res = await fetch(path, {
|
const res = await fetch(path, {
|
||||||
|
|
@ -21,7 +30,10 @@ async function init() {
|
||||||
window.location.href = '/login.html';
|
window.location.href = '/login.html';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
currentUser = me.user;
|
||||||
document.getElementById('username-display').textContent = me.user.username;
|
document.getElementById('username-display').textContent = me.user.username;
|
||||||
|
document.getElementById('role-badge').textContent = ROLE_LABELS[me.user.role] || 'User';
|
||||||
|
document.getElementById('admin-link').classList.toggle('hidden', me.user.role < 3);
|
||||||
|
|
||||||
await loadPlaces();
|
await loadPlaces();
|
||||||
}
|
}
|
||||||
|
|
@ -52,12 +64,21 @@ async function selectPlace(placeId) {
|
||||||
const data = await api(`/dashboard/places/${encodeURIComponent(placeId)}`);
|
const data = await api(`/dashboard/places/${encodeURIComponent(placeId)}`);
|
||||||
if (!data.success) return;
|
if (!data.success) return;
|
||||||
|
|
||||||
|
currentPlaceAccessLevel = data.accessLevel;
|
||||||
|
|
||||||
document.getElementById('no-place').classList.add('hidden');
|
document.getElementById('no-place').classList.add('hidden');
|
||||||
document.getElementById('place-view').classList.remove('hidden');
|
document.getElementById('place-view').classList.remove('hidden');
|
||||||
document.getElementById('place-title').textContent = placeId;
|
document.getElementById('place-title').textContent = placeId;
|
||||||
|
|
||||||
|
const canManageOwnership = currentPlaceAccessLevel === 'owner' || currentPlaceAccessLevel === 'bypass';
|
||||||
|
document.getElementById('delete-place-btn').classList.toggle('hidden', !canManageOwnership);
|
||||||
|
document.getElementById('shared-access-card').classList.toggle('hidden', !canManageOwnership);
|
||||||
|
|
||||||
renderReaders(data.accessPoints || []);
|
renderReaders(data.accessPoints || []);
|
||||||
await loadAccessGroups();
|
await loadAccessGroups();
|
||||||
|
if (canManageOwnership) {
|
||||||
|
await loadSharedAccess();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderReaders(accessPoints) {
|
function renderReaders(accessPoints) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue