source: Klonkt/src/views/pages/circle-feed.ejs@ efdde37

main
Last change on this file since efdde37 was 0091cb7, checked in by roboburr <roboburr@…>, 3 months ago

Circles v1 — steps 4+5: Admin UI + /cirkel feed

  • Mode 'Circles' in Admin > Settings (radio + section).
  • Admin > Circle (admin-circle): add sources/list/status, per source Refresh (syncOne) + Delete (cleans up orphaned cache), and a visibility toggle (sites.allow_circle, opt-out for surfacing).
  • /cirkel feed: cached remote_posts as static cards (source/avatar, title, summary, cover, link to source). Only when tenancy=circle.
  • allow_circle column (ensureColumn) + CircleFederation respects it.
  • Output escaped everywhere + URL-scheme guards (http/https) against XSS import.

v1 functionally complete (publish + pull + UI + feed). Remaining: hardening/review.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@…>

  • Property mode set to 100644
File size: 3.5 KB
Line 
1<div class="container circle-page">
2 <header class="circle-head">
3 <h1>Cirkel</h1>
4 <p class="circle-sub">Wat er speelt bij de Klonkt-sites in jouw cirkel.</p>
5 </header>
6
7 <% if (!posts.length) { %>
8 <p class="circle-empty">Nog niets in je cirkel. Voeg sites toe via
9 <a href="/admin/circle">Beheer &rsaquo; Cirkel</a> en ververs ze.</p>
10 <% } else { %>
11 <div class="circle-grid">
12 <% posts.forEach(function(p){ %>
13 <article class="circle-card">
14 <% if (p.image) { %>
15 <a class="cc-cover" <% if (p.url) { %>href="<%= p.url %>" target="_blank" rel="noopener"<% } %>>
16 <img loading="lazy" src="<%= p.image %>" alt="">
17 </a>
18 <% } %>
19 <div class="cc-body">
20 <div class="cc-src">
21 <% if (p.actorAvatar) { %><img class="cc-avatar" src="<%= p.actorAvatar %>" alt=""><% } %>
22 <% if (p.actorUrl) { %>
23 <a href="<%= p.actorUrl %>" target="_blank" rel="noopener"><%= p.actorName %></a>
24 <% } else { %><span><%= p.actorName %></span><% } %>
25 </div>
26 <h2 class="cc-title">
27 <% if (p.url) { %><a href="<%= p.url %>" target="_blank" rel="noopener"><%= p.title %></a>
28 <% } else { %><%= p.title %><% } %>
29 </h2>
30 <% if (p.summary) { %><p class="cc-summary"><%= p.summary %></p><% } %>
31 <div class="cc-foot">
32 <% if (p.published) { %><span class="cc-date"><%= p.published.slice(0,10) %></span><% } %>
33 <% if (p.url) { %><a class="cc-link" href="<%= p.url %>" target="_blank" rel="noopener">Lees bij de bron &rarr;</a><% } %>
34 </div>
35 </div>
36 </article>
37 <% }); %>
38 </div>
39 <% } %>
40</div>
41
42<style>
43.circle-page { max-width: 1000px; margin: 2.5rem auto; padding: 0 1rem; }
44.circle-head h1 { font-family: var(--font-display, serif); font-size: 2rem; margin: 0 0 .25rem; }
45.circle-sub { color: var(--ink-muted); margin: 0 0 2rem; }
46.circle-empty { color: var(--ink-muted); }
47.circle-empty a { color: var(--accent); }
48.circle-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 1.1rem; }
49.circle-card { display: flex; flex-direction: column; border: 1px solid var(--rule); border-radius: 12px; overflow: hidden; background: var(--paper-2); }
50.cc-cover { display: block; aspect-ratio: 16/9; overflow: hidden; }
51.cc-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
52.cc-body { padding: .9rem 1rem 1rem; display: flex; flex-direction: column; gap: .5rem; }
53.cc-src { display: flex; align-items: center; gap: .45rem; font-size: .8rem; color: var(--ink-muted); }
54.cc-src a { color: var(--ink-muted); text-decoration: none; }
55.cc-src a:hover { color: var(--accent); }
56.cc-avatar { width: 22px; height: 22px; border-radius: 50%; object-fit: cover; }
57.cc-title { font-family: var(--font-display, serif); font-size: 1.15rem; margin: 0; line-height: 1.25; }
58.cc-title a { color: var(--ink); text-decoration: none; }
59.cc-title a:hover { color: var(--accent); }
60.cc-summary { margin: 0; font-size: .9rem; color: var(--ink-soft, var(--ink-muted)); line-height: 1.5;
61 display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
62.cc-foot { display: flex; justify-content: space-between; align-items: center; gap: .5rem; margin-top: auto; padding-top: .35rem; font-size: .78rem; }
63.cc-date { color: var(--ink-muted); }
64.cc-link { color: var(--accent); text-decoration: none; white-space: nowrap; }
65</style>
Note: See TracBrowser for help on using the repository browser.