import { Hono } from "hono"; import { Env, FeedConfig, FeedMetadata, EmailData, EmailMetadata, } from "../../types"; import { logger } from "../../lib/logger"; import { Layout, clampText } from "./ui"; import { deleteKeysWithConcurrency } from "./helpers"; import { emailsPageScript } from "../../scripts/generated/emails-page"; type AppEnv = { Bindings: Env }; export const emailsRouter = new Hono(); // ── Shared SVG icons ────────────────────────────────────────────────────────── const CopyIcon = () => ( ); const CheckIcon = () => ( ); type CopyFieldProps = { label: string; value: string; display?: string; }; const CopyField = ({ label, value, display }: CopyFieldProps) => (
{label}
{display ?? value}
); // ── View all emails for a feed ──────────────────────────────────────────────── emailsRouter.get("/feeds/:feedId/emails", async (c) => { const env = c.env; const emailStorage = env.EMAIL_STORAGE; const feedId = c.req.param("feedId"); const message = c.req.query("message"); const count = Number(c.req.query("count") || "0"); const feedConfig = (await emailStorage.get(`feed:${feedId}:config`, { type: "json", })) as FeedConfig | null; const feedMetadata = (await emailStorage.get(`feed:${feedId}:metadata`, { type: "json", })) as FeedMetadata | null; if (!feedConfig || !feedMetadata) { return c.text("Feed not found", 404); } const emailAddress = `${feedId}@${env.DOMAIN}`; const rssUrl = `https://${env.DOMAIN}/rss/${feedId}`; const atomUrl = `https://${env.DOMAIN}/atom/${feedId}`; return c.html(

{feedConfig.title} - Emails

Feed Details

Emails ( {feedMetadata.emails.length})

{message === "bulkDeleted" && (

Deleted {Number.isFinite(count) ? count : 0} email(s).

)} {message === "bulkDeleteNoop" && (

No emails were selected.

)} {feedMetadata.emails.length > 0 ? (
Showing {feedMetadata.emails.length} 0 selected
{feedMetadata.emails.map((email: EmailMetadata) => { const subjectDisplay = clampText(email.subject, 180); const subjectHover = clampText(email.subject, 1000); const sortSubject = subjectHover.toLowerCase(); const sortReceivedAt = String(email.receivedAt); const searchHaystack = clampText( email.subject, 320, ).toLowerCase(); return ( ); })}
Actions
) : (

No emails received yet. Subscribe to newsletters using the email address above.

)}
{/* Config bootstrap — injects dynamic server-side data before the static compiled script */}