merge(dev): rsocials centered status toggles
CI/CD / deploy (push) Successful in 3m0s Details

This commit is contained in:
Jeff Emmett 2026-04-18 11:46:10 -04:00
commit c3ee221cbd
2 changed files with 12 additions and 27 deletions

View File

@ -22,7 +22,7 @@ interface DraftPostCard {
threadId?: string;
}
type StatusFilter = 'all' | 'draft' | 'scheduled' | 'published';
type StatusFilter = 'draft' | 'scheduled' | 'published';
const STATUS_STORAGE_KEY = 'rsocials:gallery:status-filter';
export class FolkThreadGallery extends HTMLElement {
@ -32,7 +32,7 @@ export class FolkThreadGallery extends HTMLElement {
private _offlineUnsub: (() => void) | null = null;
private _subscribedDocIds: string[] = [];
private _isDemoFallback = false;
private _statusFilter: StatusFilter = 'all';
private _statusFilter: StatusFilter = 'draft';
static get observedAttributes() { return ['space']; }
@ -42,7 +42,7 @@ export class FolkThreadGallery extends HTMLElement {
// Restore last status filter
try {
const saved = localStorage.getItem(STATUS_STORAGE_KEY);
if (saved === 'draft' || saved === 'scheduled' || saved === 'published' || saved === 'all') {
if (saved === 'draft' || saved === 'scheduled' || saved === 'published') {
this._statusFilter = saved;
}
} catch { /* ignore */ }
@ -162,7 +162,7 @@ export class FolkThreadGallery extends HTMLElement {
// Filter + sort posts by status + recency
const filteredPosts = this._allPosts
.filter(p => filter === 'all' || p.status === filter)
.filter(p => p.status === filter)
.sort((a, b) => {
const aT = a.scheduledAt ? new Date(a.scheduledAt).getTime() : 0;
const bT = b.scheduledAt ? new Date(b.scheduledAt).getTime() : 0;
@ -171,7 +171,6 @@ export class FolkThreadGallery extends HTMLElement {
// Status counts for chip badges
const counts = {
all: this._allPosts.length,
draft: this._allPosts.filter(p => p.status === 'draft').length,
scheduled: this._allPosts.filter(p => p.status === 'scheduled').length,
published: this._allPosts.filter(p => p.status === 'published').length,
@ -183,15 +182,13 @@ export class FolkThreadGallery extends HTMLElement {
</button>`;
const filterBar = `<div class="filter-bar" role="toolbar" aria-label="Filter posts by status">
${chip('all', 'All')}
${chip('draft', 'Drafts')}
${chip('scheduled', 'Scheduled')}
${chip('published', 'Published')}
</div>`;
// Threads are shown only when status is "all" or "published" — they don't have draft state in this schema.
const showThreads = filter === 'all' || filter === 'published';
const threadsVisible = showThreads ? threads : [];
// Threads render alongside published posts (they have no draft state).
const threadsVisible = filter === 'published' ? threads : [];
const threadCardsHTML = filteredPosts.length === 0 && threadsVisible.length === 0
? `<div class="empty">
@ -287,7 +284,8 @@ export class FolkThreadGallery extends HTMLElement {
.badge--published { background: rgba(34,197,94,0.15); color: #22c55e; }
.badge--campaign { background: rgba(99,102,241,0.15); color: #a5b4fc; }
.filter-bar {
display: flex; gap: 0.4rem; flex-wrap: wrap; margin-bottom: 1.25rem;
display: flex; gap: 0.5rem; flex-wrap: wrap; margin-bottom: 1.5rem;
justify-content: center;
}
.chip {
display: inline-flex; align-items: center; gap: 0.4rem;

View File

@ -3026,7 +3026,7 @@ routes.get("/threads", (c) => {
theme: "dark",
body: `<folk-thread-gallery space="${escapeHtml(space)}"></folk-thread-gallery>`,
styles: `<link rel="stylesheet" href="/modules/rsocials/socials.css">`,
scripts: `<script type="module" src="/modules/rsocials/folk-thread-gallery.js?v=2"></script>`,
scripts: `<script type="module" src="/modules/rsocials/folk-thread-gallery.js?v=3"></script>`,
}));
});
@ -3173,28 +3173,15 @@ routes.get("/landing", (c) => {
routes.get("/", (c) => {
const space = c.req.param("space") || "demo";
const host = c.req.header("host")?.split(":")[0] || "";
const isSubdomain = (host.endsWith(".rspace.online") && host !== "rspace.online" && !host.startsWith("www.")) || host.endsWith(".rsocials.online");
const base = isSubdomain ? "/rsocials" : `/${escapeHtml(space)}/rsocials`;
return c.html(renderShell({
title: `rSocials — ${space} | rSpace`,
moduleId: "rsocials",
spaceSlug: space,
modules: getModuleInfoList(),
theme: "dark",
styles: `<link rel="stylesheet" href="/modules/rsocials/socials.css">
<style>
.rs-subnav{max-width:900px;margin:1.25rem auto 0;padding:0 1rem;display:flex;gap:.5rem;flex-wrap:wrap;align-items:center;justify-content:flex-end}
.rs-subnav a{font-size:.8rem;padding:.45rem .9rem;border-radius:8px;border:1px solid var(--rs-input-border,#334155);background:var(--rs-bg-surface,#1e293b);color:var(--rs-text-secondary,#94a3b8);text-decoration:none;display:inline-flex;gap:.4rem;align-items:center}
.rs-subnav a:hover{border-color:#14b8a6;color:#5eead4}
</style>`,
body: `<nav class="rs-subnav" aria-label="rSocials sections">
<a href="${base}/campaigns">📢 Campaigns</a>
<a href="${base}/campaign-flow">🧩 Campaign Canvas</a>
<a href="${base}/newsletter">📧 Newsletter</a>
</nav>
<folk-thread-gallery space="${escapeHtml(space)}"></folk-thread-gallery>`,
scripts: `<script type="module" src="/modules/rsocials/folk-thread-gallery.js?v=2"></script>`,
styles: `<link rel="stylesheet" href="/modules/rsocials/socials.css">`,
body: `<folk-thread-gallery space="${escapeHtml(space)}"></folk-thread-gallery>`,
scripts: `<script type="module" src="/modules/rsocials/folk-thread-gallery.js?v=3"></script>`,
}));
});