From f44c6c1edae9fc50052b7d957b68934a7bede081 Mon Sep 17 00:00:00 2001 From: Julien Herr Date: Mon, 25 May 2026 09:12:27 +0200 Subject: [PATCH] feat(admin): dashboard pending-confirmation pill --- src/routes/admin.test.ts | 47 ++++++++++++++++++++++++++++++++++++++++ src/routes/admin.tsx | 12 ++++++++++ 2 files changed, 59 insertions(+) diff --git a/src/routes/admin.test.ts b/src/routes/admin.test.ts index de2da6a..1a08584 100644 --- a/src/routes/admin.test.ts +++ b/src/routes/admin.test.ts @@ -1292,5 +1292,52 @@ describe("Admin Routes", () => { expect(reloaded).not.toBeNull(); expect(reloaded!.pendingConfirmation).toBe(false); }); + + it("dashboard list view shows pill-confirmation for feeds with pendingConfirmation", async () => { + const authCookie = await loginAndGetCookie(); + const repo = FeedRepository.from(mockEnv as unknown as Env); + + // Create feed aggregate with a confirmation email + const feedId = FeedId.generate(); + const mailboxId = MailboxId.unchecked("confirm.dash.04"); + const feed = Feed.create( + feedId, + { + title: "Dashboard Confirm Feed", + language: "en", + allowedSenders: [], + blockedSenders: [], + }, + { mailboxId }, + ); + await repo.save(feed); + + const emailKey = repo.newEmailKey(feedId); + await repo.putEmail(emailKey, { + subject: "Confirm your subscription", + from: "newsletter@example.com", + content: "

Click to confirm

", + receivedAt: Date.now(), + headers: {}, + }); + + feed.ingest( + { + key: emailKey, + subject: "Confirm your subscription", + receivedAt: Date.now(), + confirmation: { links: ["https://x/confirm"] }, + }, + { maxBytes: 1_000_000 }, + ); + await repo.saveMetadata(feed); + + const res = await request("/admin?view=list", { + headers: { Cookie: authCookie }, + }); + expect(res.status).toBe(200); + const body = await res.text(); + expect(body).toContain("pill-confirmation"); + }); }); }); diff --git a/src/routes/admin.tsx b/src/routes/admin.tsx index 43ac8a0..3c5dd5b 100644 --- a/src/routes/admin.tsx +++ b/src/routes/admin.tsx @@ -401,6 +401,12 @@ const ExpiryBadge = ({ expiresAt }: { expiresAt: number }) => { ); }; +const ConfirmationPill = ({ feedId }: { feedId: string }) => ( + + Confirmation pending + +); + // Admin dashboard route app.get("/", async (c) => { // Type assertion for environment variables @@ -808,6 +814,9 @@ app.get("/", async (c) => { )} + {feed.pendingConfirmation && ( + + )} @@ -929,6 +938,9 @@ app.get("/", async (c) => { {feed.expires_at && ( )} + {feed.pendingConfirmation && ( + + )} {feed.description && (

{descDisplay}