diff --git a/apps/web/src/features/i18n/locales/en-US.json b/apps/web/src/features/i18n/locales/en-US.json index 6a901d12ef..b4cc878dee 100644 --- a/apps/web/src/features/i18n/locales/en-US.json +++ b/apps/web/src/features/i18n/locales/en-US.json @@ -4190,40 +4190,40 @@ "prompt-dismiss": "No thanks", "suspended-title-creator": "Your email digest is suspended (since {{since}})", "suspended-title-community": "This community's email digest is suspended (since {{since}})", - "suspended-reason-complaints": "Too many recipients marked recent issues as spam. Sending is paused to protect every Ecency sender's deliverability.", + "suspended-reason-complaints": "Too many recipients marked recent digests as spam. Sending is paused to protect every Ecency sender's deliverability.", "suspended-reason-bounces": "Too many recent recipients could not be delivered to. Sending is paused to protect every Ecency sender's deliverability.", - "suspended-reason-manual": "Sending is paused by Ecency. No new issues go out until it is lifted.", + "suspended-reason-manual": "Sending is paused by Ecency. No new digests go out until it is lifted.", "suspended-help": "Existing subscribers are kept. Contact Ecency support to have the suspension reviewed.", "send-to-subscribers": "Send to email subscribers", "send-title": "Send to {{list}} email subscribers", "send-loading": "Preparing the preview…", - "send-readers": "{{weekly}} weekly and {{monthly}} monthly readers will get this as their current issue.", + "send-readers": "{{weekly}} weekly and {{monthly}} monthly readers will get this as their current digest.", "send-no-readers": "Nobody is subscribed to this list yet.", - "send-period-taken-some": "The {{cadences}} readers already received this period's issue; they will not get this one.", - "send-period-taken-all": "This period's issue has already gone out to every reader. The next one can be sent in the next period.", - "send-one-per-period": "Readers get at most one issue per period they chose (weekly or monthly). Sending this replaces the automatic digest for the period.", + "send-period-taken-some": "The {{cadences}} readers already received this period's digest; they will not get this one.", + "send-period-taken-all": "This period's digest has already gone out to every reader. The next one can be sent in the next period.", + "send-one-per-period": "Readers get at most one digest per period they chose (weekly or monthly). Sending this replaces the automatic digest for the period.", "send-preview": "Email preview", "send-now": "Send now", "send-done": "Sent to {{count}} readers. Delivery is spread over the next hours.", "send-done-line": "{{cadence}} readers: {{recipients}}", - "send-already-sent": "This period's issue has already gone out. Try again in the next period.", + "send-already-sent": "This period's digest has already gone out. Try again in the next period.", "send-suspended": "Sending is suspended for this list. See the notice on your profile or community page.", "send-post-refused": "This post cannot be sent to the list.", "send-post-not-found": "The post could not be found.", "send-not-allowed": "You cannot send to this list.", "cadence-weekly": "weekly", "cadence-monthly": "monthly", - "sent-issues": "Sent issues", + "sent-issues": "Sent digests", "sent-issue-stats": "{{delivered}} delivered, {{bounced}} bounced", - "send-taken-line": "{{cadence}} readers: the issue for the period starting {{period}} {{what}}", + "send-taken-line": "{{cadence}} readers: the digest for the period starting {{period}} {{what}}", "send-taken-by-digest": "was the automatic digest", "send-taken-by-send": "was sent by you or your team", - "send-see-history": "See sent issues", - "sent-issues-unavailable": "Sent issues could not be loaded right now.", + "send-see-history": "See sent digests", + "sent-issues-unavailable": "Sent digests could not be loaded right now.", "sent-issue-rejected": "{{rejected}} rejected by receivers", "compose-button": "Compose email digest", "compose-title": "Compose an email digest for {{list}}", - "compose-help": "Pick {{min}} to {{max}} recent posts, in the order they should appear, then add a subject and an intro. Readers get it as their current issue.", + "compose-help": "Pick {{min}} to {{max}} recent posts, in the order they should appear, then add a subject and an intro. Readers get it as their current digest.", "compose-loading": "Loading your recent posts…", "compose-candidates-unavailable": "Recent posts could not be loaded right now.", "compose-no-candidates": "No recent posts can be sent yet.", diff --git a/apps/web/src/features/newsletter/sent-issues.tsx b/apps/web/src/features/newsletter/sent-issues.tsx index a18fae6452..b1306bed3a 100644 --- a/apps/web/src/features/newsletter/sent-issues.tsx +++ b/apps/web/src/features/newsletter/sent-issues.tsx @@ -24,7 +24,7 @@ export function SentIssues({ type, target, isSender, - limit = 5, + limit = 3, className }: { type: "creator" | "community"; diff --git a/apps/web/src/specs/features/newsletter/author-send.spec.tsx b/apps/web/src/specs/features/newsletter/author-send.spec.tsx index 5146eaaed2..320a8658b2 100644 --- a/apps/web/src/specs/features/newsletter/author-send.spec.tsx +++ b/apps/web/src/specs/features/newsletter/author-send.spec.tsx @@ -4,7 +4,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import type { ReactElement, ReactNode } from "react"; import { QueryClientProvider } from "@tanstack/react-query"; import { NewsletterRuntimeProvider } from "@/features/newsletter/runtime"; -import { AuthorSendDialog, candidatesKey, communityDigestRoles, ComposeDigestButton, ComposeDigestDialog, sendPreviewKey, SentIssues, useAuthorSendTarget } from "@/features/newsletter"; +import { AuthorSendDialog, candidatesKey, communityDigestRoles, ComposeDigestButton, ComposeDigestDialog, sendPreviewKey, type SentIssue, SentIssues, useAuthorSendTarget } from "@/features/newsletter"; import { useActiveAccount } from "@/core/hooks/use-active-account"; import { cleanupModalContainers, @@ -221,6 +221,18 @@ describe("SentIssues", () => { render(); await waitFor(() => expect(screen.getByText("newsletter.sent-issues-unavailable")).toBeInTheDocument()); }); + + it("shows only the 3 most recent issues, keeping the card compact", async () => { + const issue = (n: number): SentIssue => ({ id: String(n), cadence: "weekly", kind: "digest", period_start: `2026-08-0${n}`, subject: `Issue ${n}`, status: "sent", post_author: null, post_permlink: null, requested_by: null, created_at: `2026-08-0${n}T09:00:00Z`, delivered: n, bounced: 0, rejected: 0 }); + fetchMock.mockReturnValue(json(200, { issues: [issue(4), issue(3), issue(2), issue(1)] })); + render(); + const list = await screen.findByRole("list", { name: "newsletter.sent-issues" }); + expect(list.querySelectorAll("li")).toHaveLength(3); + expect(list).toHaveTextContent("Issue 4"); + expect(list).toHaveTextContent("Issue 3"); + expect(list).toHaveTextContent("Issue 2"); + expect(list).not.toHaveTextContent("Issue 1"); + }); }); describe("ComposeDigestDialog", () => {