mirror of
https://github.com/khoaliber/LetterFeed.git
synced 2026-03-02 21:19:13 +00:00
feat: master feed card (#15)
* feat: master feed card * fix: adjust tests
This commit is contained in:
@@ -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} />
|
||||
) : (
|
||||
|
||||
39
frontend/src/components/letterfeed/MasterFeedCard.tsx
Normal file
39
frontend/src/components/letterfeed/MasterFeedCard.tsx
Normal 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>
|
||||
)
|
||||
}
|
||||
@@ -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")
|
||||
})
|
||||
})
|
||||
@@ -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`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user