fix(frontend): surface upload errors, push ban/lock, route guards (WS8)
H11: UploadSheet now honors the modal contract — role=dialog/aria-modal + accessible name, a focus-trap/Escape/focus-restore $effect mirroring ContextSheet, and inert + pointer-events-none when closed so its controls leave the tab order and AT tree. H12: a layout-level $effect toasts each upload-queue item the first time it transitions to 'error', so a banned/locked/over-quota guest is actually told why their photo didn't post instead of the composer silently closing. M10: api.ts now redirects to /join after clearAuth() on a 401 (guarded against loops on the auth screens), so a 401 no longer strands the user on a dead page. M11: ban and event-lock are pushed to guests. A new uploadsLocked store is seeded from /me/context (now exposes uploads_locked) and kept live by event-closed/opened SSE; the feed shows a banner and the FAB is disabled when locked. A user-banned SSE event force-logs-out the targeted user. M19: feed and export pages track a distinct loadError and render an "Erneut versuchen" retry card instead of collapsing a fetch failure into "empty" / "not released". Light-mode empty-state text bumped to gray-500 for contrast. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -55,6 +55,9 @@ pub struct MeContextDto {
|
||||
pub privacy_note: String,
|
||||
pub quota_enabled: bool,
|
||||
pub storage_quota_enabled: bool,
|
||||
/// Whether uploads are currently locked for the event, so the client can show
|
||||
/// a banner + disable the upload affordance on load (not just via SSE).
|
||||
pub uploads_locked: bool,
|
||||
}
|
||||
|
||||
pub async fn get_context(
|
||||
@@ -68,6 +71,10 @@ pub async fn get_context(
|
||||
let privacy_note = config::get_str(&state.pool, "privacy_note", "").await;
|
||||
let quota_enabled = config::get_bool(&state.pool, "quota_enabled", true).await;
|
||||
let storage_quota_enabled = config::get_bool(&state.pool, "storage_quota_enabled", true).await;
|
||||
let uploads_locked = crate::models::event::Event::find_by_slug(&state.pool, &state.config.event_slug)
|
||||
.await?
|
||||
.map(|e| e.uploads_locked_at.is_some())
|
||||
.unwrap_or(false);
|
||||
|
||||
Ok(Json(MeContextDto {
|
||||
user_id: user.id,
|
||||
@@ -76,5 +83,6 @@ pub async fn get_context(
|
||||
privacy_note,
|
||||
quota_enabled,
|
||||
storage_quota_enabled,
|
||||
uploads_locked,
|
||||
}))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user