feat: band NC folder config, fix watcher event filter, add light/dark theme

- Add PATCH /bands/{id} endpoint for admins to update nc_folder_path
- Add band NC scan folder UI panel with inline edit
- Fix watcher: use activity type field (not human-readable subject) for upload detection
- Reorder watcher filters: audio extension check first, then band path, then type
- Add dark/light theme toggle using GitHub Primer-inspired CSS custom properties
- All inline styles migrated to CSS variables for theme-awareness

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Steffen Schuhmann
2026-03-29 00:29:58 +01:00
parent 5536bf4394
commit fbac62a0ea
13 changed files with 419 additions and 211 deletions

View File

@@ -47,29 +47,29 @@ export function InvitePage() {
}
return (
<div style={{ background: "#080A0E", minHeight: "100vh", display: "flex", alignItems: "center", justifyContent: "center", color: "#E2E6F0" }}>
<div style={{ background: "#0E1118", border: "1px solid #1C2235", borderRadius: 12, padding: 40, maxWidth: 420, width: "100%", textAlign: "center" }}>
<h1 style={{ color: "#F0A840", fontFamily: "monospace", marginBottom: 8, fontSize: 22 }}> RehearsalHub</h1>
<p style={{ color: "#5A6480", fontSize: 13, marginBottom: 28 }}>Band invite</p>
<div style={{ background: "var(--bg)", minHeight: "100vh", display: "flex", alignItems: "center", justifyContent: "center", color: "var(--text)" }}>
<div style={{ background: "var(--bg-subtle)", border: "1px solid var(--border)", borderRadius: 12, padding: 40, maxWidth: 420, width: "100%", textAlign: "center" }}>
<h1 style={{ color: "var(--accent)", fontFamily: "monospace", marginBottom: 8, fontSize: 22 }}> RehearsalHub</h1>
<p style={{ color: "var(--text-muted)", fontSize: 13, marginBottom: 28 }}>Band invite</p>
{error && (
<div style={{ background: "#1A0810", border: "1px solid #E85878", borderRadius: 6, padding: "12px 16px", color: "#E85878", fontSize: 13, marginBottom: 20 }}>
<div style={{ background: "var(--danger-bg)", border: "1px solid var(--danger)", borderRadius: 6, padding: "12px 16px", color: "var(--danger)", fontSize: 13, marginBottom: 20 }}>
{error}
</div>
)}
{done && (
<div style={{ color: "#38C9A8", fontSize: 14 }}>
<div style={{ color: "var(--teal)", fontSize: 14 }}>
Joined! Redirecting
</div>
)}
{!done && invite && (
<>
<p style={{ color: "#E2E6F0", fontSize: 15, marginBottom: 6 }}>
You've been invited to join a band as <strong style={{ color: "#F0A840" }}>{invite.role}</strong>.
<p style={{ color: "var(--text)", fontSize: 15, marginBottom: 6 }}>
You've been invited to join a band as <strong style={{ color: "var(--accent)" }}>{invite.role}</strong>.
</p>
<p style={{ color: "#5A6480", fontSize: 12, marginBottom: 28 }}>
<p style={{ color: "var(--text-muted)", fontSize: 12, marginBottom: 28 }}>
Expires {new Date(invite.expires_at).toLocaleDateString()}
{invite.used_at && " · Already used"}
</p>
@@ -78,16 +78,16 @@ export function InvitePage() {
<button
onClick={accept}
disabled={accepting || !!invite.used_at}
style={{ width: "100%", background: "#F0A840", border: "none", borderRadius: 8, color: "#080A0E", cursor: "pointer", padding: "12px 0", fontWeight: 700, fontSize: 15 }}
style={{ width: "100%", background: "var(--accent)", border: "none", borderRadius: 8, color: "var(--accent-fg)", cursor: "pointer", padding: "12px 0", fontWeight: 700, fontSize: 15 }}
>
{accepting ? "Joining…" : "Accept Invite"}
</button>
) : (
<div>
<p style={{ color: "#5A6480", fontSize: 13, marginBottom: 16 }}>Log in or register to accept this invite.</p>
<p style={{ color: "var(--text-muted)", fontSize: 13, marginBottom: 16 }}>Log in or register to accept this invite.</p>
<button
onClick={goLogin}
style={{ width: "100%", background: "#F0A840", border: "none", borderRadius: 8, color: "#080A0E", cursor: "pointer", padding: "12px 0", fontWeight: 700, fontSize: 15 }}
style={{ width: "100%", background: "var(--accent)", border: "none", borderRadius: 8, color: "var(--accent-fg)", cursor: "pointer", padding: "12px 0", fontWeight: 700, fontSize: 15 }}
>
Log in / Register
</button>
@@ -97,7 +97,7 @@ export function InvitePage() {
)}
{!done && !invite && !error && (
<p style={{ color: "#5A6480" }}>Loading invite</p>
<p style={{ color: "var(--text-muted)" }}>Loading invite</p>
)}
</div>
</div>