The DailyNews component library is divided into two layers. Page-level smart components live inDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/miikorz/DailyNews/llms.txt
Use this file to discover all available pages before exploring further.
src/components/ — they own data-fetching logic, call custom hooks, and compose the full page layout. Reusable UI primitives live in src/ui/ — they are stateless or lightly stateful, accept explicit props, and can be dropped into any page without side effects. Both layers are written in TypeScript and styled exclusively with Tailwind CSS utility classes.
NewsHome
NewsHome is the landing page component rendered at the / route. It displays a hero section with the application tagline and then mounts <NewsList /> inside an unordered list element so screen readers and assistive tools can traverse the feed as a semantic list.
Props: none — NewsHome is a leaf route component with no external props.
NewsList
NewsList is the core feed component. On mount it calls getAllFeeds() from useFeedManagement to populate the feed. Each item renders as a clickable card that opens the article in a new tab. Edit and delete action buttons appear on hover. Deleting a feed first opens a <Modal> for confirmation. The search bar at the top is powered by <NewsSearch>, which drives searchFeedsByTitle via a 500 ms debounce.
Props: none — all data is fetched internally via useFeedManagement.
Behaviour summary:
| Interaction | Result |
|---|---|
| Click feed card | Opens feed.link in a new tab |
| Click edit icon | Navigates to /new/:id |
| Click delete icon | Opens delete confirmation <Modal> |
| Confirm delete | Calls deleteFeed(id), removes item from state |
| Type in search box | Calls searchFeedsByTitle after 500 ms debounce |
When the
feeds array is empty and loading is false, NewsList renders a “No feeds found, try another search” message. While loading is true it renders a “Loading…” placeholder instead.NewsSearch
NewsSearch is a controlled text input that debounces user keystrokes before triggering a search. It holds an internal searchValue state, passes it through useDebounce with a 500 ms delay, and fires the onSearch callback only after the debounced value settles — preventing an API request on every keystroke.
Props:
Callback invoked with the debounced search string. Receives
null on first render (before the user types anything).NewsDetail
NewsDetail serves double duty as both the create (/add) and edit (/new/:id) form for a feed item. It reads the optional :id route param via useParams; when an id is present it fetches the existing feed with getFeedById on mount. On submit it validates that title and link are non-empty, then either calls updateFeed directly (edit mode) or opens a confirmation <Modal> before calling createFeed (create mode). After a successful creation, useFeedManagement navigates back to / after a 1-second delay.
Props: none — routing context supplies the id param.
Form fields:
| Field | Required | Notes |
|---|---|---|
| Title | ✅ | Validated on submit |
| Description | ❌ | Free-text textarea |
| Link | ✅ | Validated on submit |
| Newsletter | ❌ | Name of the source newsletter |
| Author | ❌ | Author’s name |
| Portrait image | ❌ | Full image URL; previewed live in the right panel |
NotFound
NotFound is the 404 catch-all rendered for any route that doesn’t match the defined paths. It displays a large “404” heading, a descriptive message, and a “Go Home” link button that navigates back to /.
Props: none.
Header
Header is the persistent site header rendered outside the <Routes> block in main.tsx, so it appears on every page. It displays the <LogoIcon> SVG alongside the “Daily News” brand name. Clicking either the icon or the text navigates to / via useNavigate.
Props: none.
MultiTool
MultiTool is a fixed floating action button docked to the bottom-right corner of every page. On hover it expands to reveal two action buttons: one to navigate to /add (create a new feed) and one to toggle dark mode. The dark-mode button switches between a <MoonIcon> and a <SunIcon> to reflect the current mode. Mode state is managed with a local dark boolean that mirrors document.body.classList.
Props: none.
Button IDs (used in tests):
id | Action |
|---|---|
add-button | Navigates to /add |
dark-mode-button | Toggles dark class on document.body |
Modal
Modal is a generic confirmation dialog. When isOpen is true it renders a centred overlay with a title, a message, and a “Confirm” button. Clicking “Confirm” calls both onSubmit and onClose so the caller never has to close the modal manually after confirmation. When isOpen is false the component returns null and is removed from the DOM entirely.
Props:
Controls whether the modal is visible.
Called when the user clicks the ✕ close button or after confirmation.
Called when the user clicks “Confirm”.
Heading text rendered in the modal.
Body text describing the action to be confirmed.
Toast
Toast is the notification display component rendered at the app root in main.tsx, outside the router. It reads the toasts array from ToastContext and renders each notification as a fixed banner at the top of the viewport. Notifications slide in with a CSS fadeIn animation and fade out automatically after 2.5 seconds (the context auto-removes them from state after 3 seconds).
Props: none — driven entirely by ToastContext.
Toast types and colours:
ToastType | Background |
|---|---|
SUCCESS | bg-green-300 |
ERROR | bg-red-300 |
INFO | bg-rose-500 |