diff --git a/modules/rnotes/components/folk-notes-app.ts b/modules/rnotes/components/folk-notes-app.ts index cee4a1b..66d5555 100644 --- a/modules/rnotes/components/folk-notes-app.ts +++ b/modules/rnotes/components/folk-notes-app.ts @@ -360,17 +360,31 @@ Gear: EUR 400 (10%)

Maya is tracking expenses in rF } private demoCreateNotebook() { - const title = prompt("Notebook name:"); - if (!title?.trim()) return; const now = Date.now(); + const nbId = `demo-nb-${now}`; + const noteId = `demo-note-${now}`; + const newNote: Note = { + id: noteId, title: "Untitled Note", content: "", content_plain: "", + content_format: 'tiptap-json', + type: "NOTE", tags: null, is_pinned: false, + created_at: new Date(now).toISOString(), updated_at: new Date(now).toISOString(), + }; const nb = { - id: `demo-nb-${now}`, title, description: "", - cover_color: "#8b5cf6", note_count: "0", - updated_at: new Date(now).toISOString(), notes: [] as Note[], + id: nbId, title: "Untitled Notebook", description: "", + cover_color: "#8b5cf6", note_count: "1", + updated_at: new Date(now).toISOString(), notes: [newNote], } as any; this.demoNotebooks.push(nb); this.notebooks = this.demoNotebooks.map(({ notes, ...rest }) => rest as Notebook); + this.selectedNotebook = { ...nb }; + this.view = "notebook"; this.render(); + // Auto-open the note for editing + this.selectedNote = newNote; + this.view = "note"; + this.renderNav(); + this.renderMeta(); + this.mountEditor(newNote); } private demoCreateNote() { @@ -726,16 +740,20 @@ Gear: EUR 400 (10%)

Maya is tracking expenses in rF } private async createNotebook() { - const title = prompt("Notebook name:"); - if (!title?.trim()) return; try { const base = this.getApiBase(); - await fetch(`${base}/api/notebooks`, { + const res = await fetch(`${base}/api/notebooks`, { method: "POST", headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ title }), + body: JSON.stringify({ title: "Untitled Notebook" }), }); - await this.loadNotebooks(); + const nb = await res.json(); + if (nb?.id) { + this.view = "notebook"; + await this.loadNotebook(nb.id); + } else { + await this.loadNotebooks(); + } } catch { this.error = "Failed to create notebook"; this.render(); diff --git a/modules/rsocials/components/folk-campaign-manager.ts b/modules/rsocials/components/folk-campaign-manager.ts index c836e98..e321baa 100644 --- a/modules/rsocials/components/folk-campaign-manager.ts +++ b/modules/rsocials/components/folk-campaign-manager.ts @@ -131,7 +131,7 @@ export class FolkCampaignManager extends HTMLElement {

- Open Thread Builder + Open Thread Builder
${phaseHTML} diff --git a/modules/rsocials/components/folk-campaign-planner.ts b/modules/rsocials/components/folk-campaign-planner.ts index d920448..13dd22c 100644 --- a/modules/rsocials/components/folk-campaign-planner.ts +++ b/modules/rsocials/components/folk-campaign-planner.ts @@ -820,7 +820,7 @@ class FolkCampaignPlanner extends HTMLElement { } else if (action === 'open-thread') { const d = node.data as ThreadNodeData; if (d.threadId) { - window.location.href = `/${this.space}/rsocials/thread/${d.threadId}/edit`; + window.location.href = `/${this.space}/rsocials/thread-editor/${d.threadId}/edit`; } } }); @@ -1457,7 +1457,7 @@ class FolkCampaignPlanner extends HTMLElement { if (node?.type === 'thread') { const d = node.data as ThreadNodeData; if (d.threadId) { - window.location.href = `/${this.space}/rsocials/thread/${d.threadId}/edit`; + window.location.href = `/${this.space}/rsocials/thread-editor/${d.threadId}/edit`; } } }); diff --git a/modules/rsocials/components/folk-thread-builder.ts b/modules/rsocials/components/folk-thread-builder.ts index 4a6f28e..441c80e 100644 --- a/modules/rsocials/components/folk-thread-builder.ts +++ b/modules/rsocials/components/folk-thread-builder.ts @@ -274,7 +274,7 @@ export class FolkThreadBuilder extends HTMLElement {
${tweetCards}
- Edit Thread + Edit Thread
@@ -289,7 +289,7 @@ export class FolkThreadBuilder extends HTMLElement {
diff --git a/modules/rsocials/components/folk-thread-gallery.ts b/modules/rsocials/components/folk-thread-gallery.ts index 5682f32..a074066 100644 --- a/modules/rsocials/components/folk-thread-gallery.ts +++ b/modules/rsocials/components/folk-thread-gallery.ts @@ -96,7 +96,7 @@ export class FolkThreadGallery extends HTMLElement { const cardsHTML = threads.length === 0 ? `

No threads yet. Create your first thread!

- Create Thread + Create Thread
` : `
${threads.map(t => { @@ -164,7 +164,7 @@ export class FolkThreadGallery extends HTMLElement { diff --git a/modules/rsocials/mod.ts b/modules/rsocials/mod.ts index 25a30b3..eb994dd 100644 --- a/modules/rsocials/mod.ts +++ b/modules/rsocials/mod.ts @@ -467,7 +467,7 @@ routes.get("/thread/:id", async (c) => { })); }); -routes.get("/thread/:id/edit", async (c) => { +routes.get("/thread-editor/:id/edit", async (c) => { const space = c.req.param("space") || "demo"; const dataSpace = (c.get("effectiveSpace" as any) as string) || space; const id = c.req.param("id"); @@ -490,11 +490,11 @@ routes.get("/thread/:id/edit", async (c) => { })); }); -routes.get("/thread", (c) => { +routes.get("/thread-editor", (c) => { const space = c.req.param("space") || "demo"; const dataSpace = (c.get("effectiveSpace" as any) as string) || space; return c.html(renderShell({ - title: `Thread Builder — rSocials | rSpace`, + title: `Thread Editor — rSocials | rSpace`, moduleId: "rsocials", spaceSlug: space, modules: getModuleInfoList(), @@ -522,8 +522,16 @@ routes.get("/threads", (c) => { routes.get("/campaigns", (c) => { const space = c.req.param("space") || "demo"; - const dataSpace = (c.get("effectiveSpace" as any) as string) || space; - return c.redirect(`/${space}/rsocials/campaign`); + return c.html(renderShell({ + title: `Campaigns — rSocials | rSpace`, + moduleId: "rsocials", + spaceSlug: space, + modules: getModuleInfoList(), + theme: "dark", + body: ``, + styles: ``, + scripts: ``, + })); }); // ── Demo feed rendering (server-rendered, no web component needed) ── @@ -615,20 +623,55 @@ routes.get("/landing", (c) => { })); }); -// ── Default: campaign planner canvas ── +// ── Default: rSocials hub with navigation ── routes.get("/", (c) => { const space = c.req.param("space") || "demo"; - const dataSpace = (c.get("effectiveSpace" as any) as string) || space; + const base = `/${escapeHtml(space)}/rsocials`; return c.html(renderShell({ - title: `${space} — rSocials | rSpace`, + title: `rSocials — ${space} | rSpace`, moduleId: "rsocials", spaceSlug: space, modules: getModuleInfoList(), - body: ``, - scripts: ``, - styles: ``, theme: "dark", + styles: ``, + body: ``, })); }); @@ -667,19 +710,7 @@ export const socialsModule: RSpaceModule = { ], subPageInfos: [ { - path: "thread", - title: "Thread Builder", - icon: "🧵", - tagline: "rSocials Tool", - description: "Compose, preview, and schedule tweet threads with a live card-by-card preview. Save drafts, generate share images, and publish when ready.", - features: [ - { icon: "✍️", title: "Live Preview", text: "See your thread as tweet cards in real time as you type, with character counts and thread numbering." }, - { icon: "💾", title: "Save & Edit Drafts", text: "Save thread drafts to your space, revisit and refine them before publishing." }, - { icon: "🖼️", title: "Share Images", text: "Auto-generate a branded share image of your thread for cross-posting." }, - ], - }, - { - path: "campaign", + path: "campaigns", title: "Campaign Manager", icon: "📢", tagline: "rSocials Tool", @@ -697,5 +728,17 @@ export const socialsModule: RSpaceModule = { tagline: "rSocials Tool", description: "Browse all saved thread drafts in your community. Find inspiration, remix threads, or pick up where you left off.", }, + { + path: "thread-editor", + title: "Thread Editor", + icon: "🧵", + tagline: "rSocials Tool", + description: "Compose, preview, and schedule tweet threads with a live card-by-card preview. Save drafts, generate share images, and publish when ready.", + features: [ + { icon: "✍️", title: "Live Preview", text: "See your thread as tweet cards in real time as you type, with character counts and thread numbering." }, + { icon: "💾", title: "Save & Edit Drafts", text: "Save thread drafts to your space, revisit and refine them before publishing." }, + { icon: "🖼️", title: "Share Images", text: "Auto-generate a branded share image of your thread for cross-posting." }, + ], + }, ], };