feat(admin): dashboard pending-confirmation pill

This commit is contained in:
Julien Herr
2026-05-25 09:12:27 +02:00
parent 1525b36cab
commit f44c6c1eda
2 changed files with 59 additions and 0 deletions
+47
View File
@@ -1292,5 +1292,52 @@ describe("Admin Routes", () => {
expect(reloaded).not.toBeNull(); expect(reloaded).not.toBeNull();
expect(reloaded!.pendingConfirmation).toBe(false); 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: "<p>Click to confirm</p>",
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");
});
}); });
}); });
+12
View File
@@ -401,6 +401,12 @@ const ExpiryBadge = ({ expiresAt }: { expiresAt: number }) => {
); );
}; };
const ConfirmationPill = ({ feedId }: { feedId: string }) => (
<a class="pill pill-confirmation" href={`/admin/feeds/${feedId}/emails`}>
Confirmation pending
</a>
);
// Admin dashboard route // Admin dashboard route
app.get("/", async (c) => { app.get("/", async (c) => {
// Type assertion for environment variables // Type assertion for environment variables
@@ -808,6 +814,9 @@ app.get("/", async (c) => {
</div> </div>
)} )}
</div> </div>
{feed.pendingConfirmation && (
<ConfirmationPill feedId={feed.id} />
)}
</div> </div>
</td> </td>
<td> <td>
@@ -929,6 +938,9 @@ app.get("/", async (c) => {
{feed.expires_at && ( {feed.expires_at && (
<ExpiryBadge expiresAt={feed.expires_at} /> <ExpiryBadge expiresAt={feed.expires_at} />
)} )}
{feed.pendingConfirmation && (
<ConfirmationPill feedId={feed.id} />
)}
{feed.description && ( {feed.description && (
<p class="feed-description"> <p class="feed-description">
<span title={descHover}>{descDisplay}</span> <span title={descHover}>{descDisplay}</span>