From f0735ae18c43879ef6c7c48f00db426ce8390630 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 2 Jul 2026 15:11:58 +0000
Subject: [PATCH] WIP: dashboard sharing UI (pre-merge)
---
public/dashboard.html | 17 ++++++++++++++++-
public/js/dashboard.js | 21 +++++++++++++++++++++
2 files changed, 37 insertions(+), 1 deletion(-)
diff --git a/public/dashboard.html b/public/dashboard.html
index 51c430e..c67b2e6 100644
--- a/public/dashboard.html
+++ b/public/dashboard.html
@@ -10,7 +10,8 @@
+
+
+
Shared access
+
Grant other users access to manage this place's settings, readers and access groups.
+
+
No other users have been granted access to this place.
+
+
diff --git a/public/js/dashboard.js b/public/js/dashboard.js
index 93fa45d..ed838a4 100644
--- a/public/js/dashboard.js
+++ b/public/js/dashboard.js
@@ -1,6 +1,15 @@
let currentPlaceId = null;
let places = [];
let accessGroups = [];
+let currentUser = null;
+let currentPlaceAccessLevel = null;
+
+const ROLE_LABELS = {
+ 1: 'User',
+ 2: 'Elevated',
+ 3: 'Admin',
+ 4: 'Superadmin'
+};
async function api(path, options = {}) {
const res = await fetch(path, {
@@ -21,7 +30,10 @@ async function init() {
window.location.href = '/login.html';
return;
}
+ currentUser = me.user;
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();
}
@@ -52,12 +64,21 @@ async function selectPlace(placeId) {
const data = await api(`/dashboard/places/${encodeURIComponent(placeId)}`);
if (!data.success) return;
+ currentPlaceAccessLevel = data.accessLevel;
+
document.getElementById('no-place').classList.add('hidden');
document.getElementById('place-view').classList.remove('hidden');
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 || []);
await loadAccessGroups();
+ if (canManageOwnership) {
+ await loadSharedAccess();
+ }
}
function renderReaders(accessPoints) {