Changeset 8afbdd6 in Klonkt for src/views/shell.ejs


Ignore:
Timestamp:
06/14/2026 06:07:51 PM (3 months ago)
Author:
roboburr <roboburr@…>
Branches:
main
Children:
c869272
Parents:
b94c08e
Message:

feat: viewer role + artists directory + Klonkt Hub Beta rebrand

Viewer role (replaces the separate view-mode/readonly toggle):

  • 'kijker' is now a real role (VALID_ROLES) selectable in Admin. May view EVERYTHING including Admin, but cannot modify anything.
  • isViewer(user) (= role kijker or legacy readonly flag) is the source; requireGod/requireSiteManager(BySlug) let a viewer through (viewing), the global guard 403s every write. Existing readonly accounts are migrated on each role change (readonly=0).
  • Write leaks via GET patched: /prutter/new (INSERT) blocks for viewers, /prutter/:id skips markAsRead (UPDATE); WS upgrade rejects viewers (the HTTP guard doesn't cover WebSockets).
  • Clean "Viewer mode" page (viewer-blocked) instead of raw 403 text; styled sticky banner; account page shows read-only UI instead of an upload button that silently 403s. canMutate hides write buttons.

Scalability (>50 artists):

  • Hub home shows max 24 (most active first) + "All N artists ->".
  • New searchable, paginated /artiesten directory (hub only).
  • 'user' + 'artiesten' reserved as slugs.

Rebrand PrutFolio v1 -> Klonkt Hub Beta (footer, PWA manifest, account/
admin texts, default page title, startup, README; internal package +
PWA id 'prutfolio' remain for stability).

Co-Authored-By: Claude <noreply@…>

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/views/shell.ejs

    rb94c08e r8afbdd6  
    239239<body class="<%= bodyClass || 'on-home' %> has-bottom-tab" data-feed-view="<%= _e(safeSite.feed_view_default || 'timeline') %>" data-grid-cols="3" data-site-base="<%= _e((typeof siteUrlBase !== 'undefined' && siteUrlBase) ? siteUrlBase : '') %>">
    240240
    241 <% if (user && user.readonly) { %>
    242   <div style="position:sticky;top:0;z-index:50;background:#e8b04b;color:#1a1a1a;text-align:center;font-size:0.85rem;font-weight:600;padding:0.4rem 1rem;">
    243     👁️ Demo — alleen-lezen: je kunt alles bekijken, maar niets wijzigen.
     241<% if (typeof isViewer !== 'undefined' && isViewer) { %>
     242  <div class="viewer-banner" role="status">
     243    <span class="viewer-banner-ico" aria-hidden="true">👁️</span>
     244    <span class="viewer-banner-text"><strong>Kijker-modus</strong> — je kunt alles bekijken, maar niets wijzigen.</span>
    244245  </div>
     246  <style>
     247    .viewer-banner {
     248      position: sticky; top: 0; z-index: 60;
     249      display: flex; align-items: center; justify-content: center; gap: 0.5rem;
     250      padding: 0.5rem 1rem;
     251      background: linear-gradient(90deg,
     252        color-mix(in srgb, var(--accent) 88%, #000) 0%,
     253        var(--accent) 100%);
     254      color: #fff;
     255      font-size: 0.85rem; line-height: 1.3;
     256      box-shadow: 0 1px 6px color-mix(in srgb, var(--accent) 45%, transparent);
     257    }
     258    .viewer-banner-ico { font-size: 1rem; }
     259    .viewer-banner-text strong { font-weight: 700; }
     260  </style>
    245261<% } %>
    246262
Note: See TracChangeset for help on using the changeset viewer.