unify single user and multi user behaviour
This commit is contained in:
@@ -12,8 +12,9 @@ const { title = 'BincioActivity', description = 'Your personal activity stats',
|
||||
const editUrl = import.meta.env.PUBLIC_EDIT_URL ?? '';
|
||||
const baseUrl = import.meta.env.BASE_URL ?? '/';
|
||||
|
||||
// Detect whether this instance is private (multi-user, requires login to view).
|
||||
// Read root index.json at build time to detect instance configuration.
|
||||
let instancePrivate = false;
|
||||
let singleHandle: string | null = null; // set when there is exactly one shard
|
||||
try {
|
||||
const candidates = [
|
||||
process.env.BINCIO_DATA_DIR,
|
||||
@@ -24,6 +25,9 @@ try {
|
||||
if (dataDir) {
|
||||
const root = JSON.parse(readFileSync(join(dataDir, 'index.json'), 'utf-8'));
|
||||
instancePrivate = root?.instance?.private === true;
|
||||
const shards: Array<{ handle?: string }> = root?.shards ?? [];
|
||||
const handles = shards.map(s => s.handle).filter(Boolean);
|
||||
if (handles.length === 1) singleHandle = handles[0] as string;
|
||||
}
|
||||
} catch { /* non-fatal */ }
|
||||
---
|
||||
@@ -137,13 +141,29 @@ try {
|
||||
<a href={baseUrl} class="font-bold text-white tracking-tight hover:text-[--accent] transition-colors">
|
||||
Bincio<span class="text-[--accent]">Activity</span>
|
||||
</a>
|
||||
<a href={baseUrl} class="text-sm text-zinc-400 hover:text-white transition-colors">Feed</a>
|
||||
<a href={`${baseUrl}stats/`} class="text-sm text-zinc-400 hover:text-white transition-colors">Stats</a>
|
||||
<a href={`${baseUrl}athlete/`} class="text-sm text-zinc-400 hover:text-white transition-colors">Athlete</a>
|
||||
<a href={`${baseUrl}record/`} class="text-sm text-zinc-400 hover:text-white transition-colors">Record</a>
|
||||
<!-- Feed tab: only shown for multi-user (more than one shard) -->
|
||||
{!singleHandle && (
|
||||
<a href={baseUrl} class="text-sm text-zinc-400 hover:text-white transition-colors">Feed</a>
|
||||
)}
|
||||
<!-- Single-user: static handle link. Multi-user: populated by user-widget script. -->
|
||||
{singleHandle
|
||||
? <a href={`${baseUrl}u/${singleHandle}/`} class="text-sm text-zinc-400 hover:text-white transition-colors">@{singleHandle}</a>
|
||||
: <a id="nav-me" href="#" style="display:none" class="text-sm text-[--accent] hover:text-white transition-colors"></a>
|
||||
}
|
||||
<!-- Per-user nav links — updated by user-widget script in multi-user mode -->
|
||||
<a id="nav-stats" href={singleHandle ? `${baseUrl}u/${singleHandle}/stats/` : `${baseUrl}stats/`} data-user-path="stats/" class="text-sm text-zinc-400 hover:text-white transition-colors">Stats</a>
|
||||
<a id="nav-athlete" href={singleHandle ? `${baseUrl}u/${singleHandle}/athlete/` : `${baseUrl}athlete/`} data-user-path="athlete/" class="text-sm text-zinc-400 hover:text-white transition-colors">Athlete</a>
|
||||
<a id="nav-record" href={singleHandle ? `${baseUrl}u/${singleHandle}/record/` : `${baseUrl}record/`} data-user-path="record/" class="text-sm text-zinc-400 hover:text-white transition-colors">Record</a>
|
||||
<a href={`${baseUrl}convert/`} class="text-sm text-zinc-400 hover:text-white transition-colors">Convert</a>
|
||||
|
||||
<div class="ml-auto flex items-center gap-1">
|
||||
<!-- Logout button — hidden until logged in -->
|
||||
<button
|
||||
id="nav-logout"
|
||||
style="display:none"
|
||||
class="text-xs text-zinc-500 hover:text-white transition-colors px-2 h-8"
|
||||
aria-label="Log out"
|
||||
>Log out</button>
|
||||
{editUrl && (
|
||||
<button
|
||||
id="upload-btn"
|
||||
@@ -283,6 +303,41 @@ try {
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- User widget: only needed for multi-user (single-user nav links are static) -->
|
||||
{!singleHandle && (
|
||||
<script define:vars={{ baseUrl }}>
|
||||
(async () => {
|
||||
try {
|
||||
const r = await fetch('/api/me', { credentials: 'include' });
|
||||
if (!r.ok) return;
|
||||
const user = await r.json();
|
||||
|
||||
// Show @handle link → /u/{handle}/
|
||||
const meEl = document.getElementById('nav-me');
|
||||
if (meEl) {
|
||||
meEl.textContent = '@' + user.handle;
|
||||
meEl.href = baseUrl + 'u/' + user.handle + '/';
|
||||
meEl.style.display = '';
|
||||
}
|
||||
|
||||
// Update per-user nav links to point to /u/{handle}/{page}/
|
||||
document.querySelectorAll('[data-user-path]').forEach(el => {
|
||||
el.href = baseUrl + 'u/' + user.handle + '/' + el.getAttribute('data-user-path');
|
||||
});
|
||||
|
||||
// Show logout button
|
||||
const logoutEl = document.getElementById('nav-logout');
|
||||
if (logoutEl) logoutEl.style.display = '';
|
||||
} catch (_) {}
|
||||
})();
|
||||
|
||||
document.getElementById('nav-logout')?.addEventListener('click', async () => {
|
||||
try { await fetch('/api/auth/logout', { method: 'POST', credentials: 'include' }); } catch (_) {}
|
||||
window.location.href = baseUrl + 'login/';
|
||||
});
|
||||
</script>
|
||||
)}
|
||||
|
||||
{editUrl && (
|
||||
<script define:vars={{ editUrl, baseUrl }}>
|
||||
const modal = document.getElementById('upload-modal');
|
||||
|
||||
Reference in New Issue
Block a user