feat: master feed card (#15)

* feat: master feed card

* fix: adjust tests
This commit is contained in:
Leon
2025-09-17 18:19:59 +01:00
committed by GitHub
parent 22e8eeac3d
commit 7de80c6d57
9 changed files with 250 additions and 5 deletions

View File

@@ -14,6 +14,7 @@ import { LoadingSpinner } from "@/components/letterfeed/LoadingSpinner"
import { Header } from "@/components/letterfeed/Header"
import { NewsletterList } from "@/components/letterfeed/NewsletterList"
import { EmptyState } from "@/components/letterfeed/EmptyState"
import { MasterFeedCard } from "@/components/letterfeed/MasterFeedCard"
import { NewsletterDialog } from "@/components/letterfeed/NewsletterDialog"
import { SettingsDialog } from "@/components/letterfeed/SettingsDialog"
@@ -68,6 +69,8 @@ function LetterFeedApp() {
onOpenSettings={() => setIsSettingsOpen(true)}
/>
{newsletters.length > 0 && <MasterFeedCard />}
{newsletters.length > 0 ? (
<NewsletterList newsletters={newsletters} onEditNewsletter={openEditDialog} />
) : (

View File

@@ -0,0 +1,39 @@
"use client"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { Rss, ExternalLink } from "lucide-react"
import { getMasterFeedUrl } from "@/lib/api"
export function MasterFeedCard() {
const feedUrl = getMasterFeedUrl()
return (
<Card className="mb-8">
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Rss className="w-5 h-5 text-orange-500" />
Master Feed
</CardTitle>
</CardHeader>
<CardContent className="space-y-4">
<p className="text-sm text-muted-foreground">
This feed contains all entries from all your newsletters in one place.
</p>
<div>
<h4 className="text-sm font-medium text-gray-700 mb-2">RSS Feed URL</h4>
<div className="flex items-center gap-2">
<a
href={feedUrl}
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center gap-1 text-sm text-blue-600 hover:text-blue-800 hover:underline"
>
<ExternalLink className="w-3 h-3" />
{feedUrl}
</a>
</div>
</div>
</CardContent>
</Card>
)
}

View File

@@ -0,0 +1,45 @@
import React from "react"
import { render, screen } from "@testing-library/react"
import "@testing-library/jest-dom"
import { MasterFeedCard } from "../MasterFeedCard"
// Mock the getMasterFeedUrl function
jest.mock("@/lib/api", () => ({
...jest.requireActual("@/lib/api"),
getMasterFeedUrl: jest.fn(() => "http://mock-api/feeds/all"),
}))
// Mock the toast
jest.mock("sonner", () => ({
toast: {
success: jest.fn(),
},
}))
// Mock navigator.clipboard
Object.assign(navigator, {
clipboard: {
writeText: jest.fn(),
},
})
describe("MasterFeedCard", () => {
beforeEach(() => {
jest.clearAllMocks()
})
it("renders the master feed card with the correct URL", () => {
render(<MasterFeedCard />)
expect(screen.getByText("Master Feed")).toBeInTheDocument()
expect(
screen.getByText(
"This feed contains all entries from all your newsletters in one place."
)
).toBeInTheDocument()
const feedLink = screen.getByRole("link")
expect(feedLink).toHaveAttribute("href", "http://mock-api/feeds/all")
expect(feedLink).toHaveTextContent("http://mock-api/feeds/all")
})
})

View File

@@ -208,3 +208,7 @@ export function getFeedUrl(newsletter: Newsletter): string {
const feedIdentifier = newsletter.slug || newsletter.id;
return `${API_BASE_URL}/feeds/${feedIdentifier}`;
}
export function getMasterFeedUrl(): string {
return `${API_BASE_URL}/feeds/all`;
}