Changeset f45fc82 in Klonkt


Ignore:
Timestamp:
06/15/2026 01:14:02 AM (3 months ago)
Author:
roboburr <roboburr@…>
Branches:
main
Children:
bd7f10d
Parents:
b50a885
Message:

feat: posts/drafts list on the dashboard — drafts findable again

Drafts (status!=published) were nowhere to be found: the timeline only shows
published posts and the dashboard had no posts list. Now a Posts block on the
god/solo and artist dashboard with DRAFTS ON TOP, a draft badge, and
mode-aware Edit/View links.

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

Location:
src
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/routes/admin.js

    rb50a885 rf45fc82  
    1212
    1313const router = express.Router();
     14
     15// Recente posts van één site, CONCEPTEN BOVENAAN, met mode-bewuste edit/view-URLs.
     16// Lost op dat drafts (status != published) nergens terug te vinden waren: de
     17// tijdlijn toont alleen gepubliceerde posts.
     18function sitePosts(siteId, siteSlug, tenancy, limit = 60) {
     19  const base = tenancy === 'hub' ? `/user/${siteSlug}` : '';
     20  return db.prepare(`
     21    SELECT slug, title, status, published_at, created_at, updated_at
     22    FROM posts WHERE site_id = ?
     23    ORDER BY (status != 'published') DESC, COALESCE(updated_at, published_at, created_at) DESC
     24    LIMIT ?
     25  `).all(siteId, limit).map((p) => ({
     26    ...p,
     27    isDraft: p.status !== 'published',
     28    editUrl: `${base}/posts/${p.slug}/edit`,
     29    viewUrl: `${base}/${p.slug}`,
     30  }));
     31}
    1432
    1533router.get('/', requireAuth, (req, res) => {
     
    3553      mySite,
    3654      mine,
     55      posts: sitePosts(mySite.id, mySite.slug, 'hub'), // my-site is hub-only
    3756    });
    3857  }
     
    4160
    4261  // De primaire/owner-site — in solo dé site, in hub de hoofdsite. Geeft de
    43   // "Uiterlijk"-tegel z'n edit-link.
     62  // "Uiterlijk"-tegel z'n edit-link + de posts/concepten-lijst.
    4463  const primarySite = db.prepare(
    45     'SELECT slug, title FROM sites ORDER BY created_at ASC LIMIT 1'
     64    'SELECT id, slug, title FROM sites ORDER BY created_at ASC LIMIT 1'
    4665  ).get() || null;
    4766
     
    7190  `).all() : [];
    7291
     92  // Posts/concepten van de primaire site (in solo = de site; in hub = de
     93  // hoofdsite van de admin). Concepten staan bovenaan zodat ze vindbaar zijn.
     94  const posts = primarySite ? sitePosts(primarySite.id, primarySite.slug, tenancy) : [];
     95
    7396  renderPage(req, res, 'pages/admin', {
    7497    pageTitle: 'Beheer',
     
    78101    stats,
    79102    sites,
     103    posts,
    80104    users,
    81105  });
  • src/views/pages/admin.ejs

    rb50a885 rf45fc82  
    3535  </div>
    3636
     37  <% if (typeof posts !== 'undefined' && posts && posts.length) { %>
     38    <% var _drafts = posts.filter(function(p){ return p.isDraft; }).length; %>
     39    <h2>Posts<% if (_drafts) { %> <span class="pl-draftcount"><%= _drafts %> concept<%= _drafts === 1 ? '' : 'en' %></span><% } %></h2>
     40    <ul class="post-admin-list">
     41      <% posts.forEach(function(p) { %>
     42        <li class="pal-row<%= p.isDraft ? ' is-draft' : '' %>">
     43          <a class="pal-title" href="<%= p.editUrl %>">
     44            <% if (p.isDraft) { %><span class="pal-badge">Concept</span><% } %>
     45            <span class="pal-name"><%= p.title || '(zonder titel)' %></span>
     46          </a>
     47          <span class="pal-actions">
     48            <a class="pal-link" href="<%= p.editUrl %>">Bewerken</a>
     49            <% if (!p.isDraft) { %><a class="pal-link" href="<%= p.viewUrl %>">Bekijk</a><% } %>
     50          </span>
     51        </li>
     52      <% }); %>
     53    </ul>
     54  <% } %>
     55
    3756  <% if (sites && sites.length) { %>
    3857    <h2>Sites</h2>
     
    82101.admin-tagline em { font-style: normal; opacity: 0.7; }
    83102
     103/* Posts/concepten-lijst */
     104.pl-draftcount { font-family: var(--font-ui, system-ui); font-size: 0.8rem; font-weight: 700; color: var(--accent); background: color-mix(in srgb, var(--accent) 14%, transparent); padding: 0.1rem 0.55rem; border-radius: 99px; vertical-align: middle; }
     105.post-admin-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.4rem; }
     106.pal-row { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: 0.7rem 0.9rem; border: 1px solid var(--rule); border-radius: 10px; background: var(--paper-2); transition: border-color 120ms; }
     107.pal-row:hover { border-color: var(--accent); }
     108.pal-row.is-draft { border-left: 3px solid var(--accent); }
     109.pal-title { display: inline-flex; align-items: center; gap: 0.6rem; min-width: 0; color: var(--ink); text-decoration: none; font-weight: 600; }
     110.pal-title:hover { color: var(--accent); }
     111.pal-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
     112.pal-badge { flex-shrink: 0; font-size: 0.68rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--accent); background: color-mix(in srgb, var(--accent) 14%, transparent); padding: 0.1rem 0.5rem; border-radius: 99px; }
     113.pal-actions { display: flex; gap: 0.75rem; flex-shrink: 0; }
     114.pal-link { color: var(--ink-muted); font-size: 0.85rem; text-decoration: none; white-space: nowrap; }
     115.pal-link:hover { color: var(--accent); text-decoration: underline; }
     116
    84117/* Quick-links grid — mobile-first.
    85118   auto-fit + minmax means: as many equal columns as fit, each at least 140px.
  • src/views/pages/my-site.ejs

    rb50a885 rf45fc82  
    1616    <div class="stat-card"><div class="stat-num"><%= mine.published %></div><div class="stat-label">Gepubliceerd</div></div>
    1717  </div>
     18
     19  <% if (typeof posts !== 'undefined' && posts && posts.length) { %>
     20    <% var _drafts = posts.filter(function(p){ return p.isDraft; }).length; %>
     21    <h2 class="ms-posts-title">Posts<% if (_drafts) { %> <span class="pl-draftcount"><%= _drafts %> concept<%= _drafts === 1 ? '' : 'en' %></span><% } %></h2>
     22    <ul class="post-admin-list">
     23      <% posts.forEach(function(p) { %>
     24        <li class="pal-row<%= p.isDraft ? ' is-draft' : '' %>">
     25          <a class="pal-title" href="<%= p.editUrl %>">
     26            <% if (p.isDraft) { %><span class="pal-badge">Concept</span><% } %>
     27            <span class="pal-name"><%= p.title || '(zonder titel)' %></span>
     28          </a>
     29          <span class="pal-actions">
     30            <a class="pal-link" href="<%= p.editUrl %>">Bewerken</a>
     31            <% if (!p.isDraft) { %><a class="pal-link" href="<%= p.viewUrl %>">Bekijk</a><% } %>
     32          </span>
     33        </li>
     34      <% }); %>
     35    </ul>
     36  <% } %>
    1837</div>
    1938
     
    3251.stat-num { font-size: 2rem; font-weight: 700; color: var(--accent); line-height: 1; font-family: var(--font-display, serif); }
    3352.stat-label { color: var(--ink-muted); font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.05em; margin-top: 0.25rem; }
     53
     54/* Posts/concepten-lijst */
     55.ms-posts-title { font-family: var(--font-display, serif); font-size: 1.4rem; margin: 2rem 0 0.75rem; }
     56.pl-draftcount { font-family: var(--font-ui, system-ui); font-size: 0.8rem; font-weight: 700; color: var(--accent); background: color-mix(in srgb, var(--accent) 14%, transparent); padding: 0.1rem 0.55rem; border-radius: 99px; vertical-align: middle; }
     57.post-admin-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.4rem; }
     58.pal-row { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: 0.7rem 0.9rem; border: 1px solid var(--rule); border-radius: 10px; background: var(--paper-2); transition: border-color 120ms; }
     59.pal-row:hover { border-color: var(--accent); }
     60.pal-row.is-draft { border-left: 3px solid var(--accent); }
     61.pal-title { display: inline-flex; align-items: center; gap: 0.6rem; min-width: 0; color: var(--ink); text-decoration: none; font-weight: 600; }
     62.pal-title:hover { color: var(--accent); }
     63.pal-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
     64.pal-badge { flex-shrink: 0; font-size: 0.68rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--accent); background: color-mix(in srgb, var(--accent) 14%, transparent); padding: 0.1rem 0.5rem; border-radius: 99px; }
     65.pal-actions { display: flex; gap: 0.75rem; flex-shrink: 0; }
     66.pal-link { color: var(--ink-muted); font-size: 0.85rem; text-decoration: none; white-space: nowrap; }
     67.pal-link:hover { color: var(--accent); text-decoration: underline; }
    3468</style>
Note: See TracChangeset for help on using the changeset viewer.