From 3ba71500bc2d60a00ca81b9439305029670f4d52 Mon Sep 17 00:00:00 2001 From: Adam Mathes Date: Fri, 13 Feb 2026 06:55:21 -0800 Subject: Implement Frontend Feed Items View with tests --- frontend/coverage/src/App.css.html | 2 +- frontend/coverage/src/App.tsx.html | 18 +- .../coverage/src/components/FeedItems.css.html | 262 +++++++++++++++++++ .../coverage/src/components/FeedItems.tsx.html | 283 +++++++++++++++++++++ frontend/coverage/src/components/FeedList.css.html | 2 +- frontend/coverage/src/components/FeedList.tsx.html | 25 +- frontend/coverage/src/components/Login.css.html | 2 +- frontend/coverage/src/components/Login.tsx.html | 2 +- frontend/coverage/src/components/index.html | 48 +++- frontend/coverage/src/index.html | 2 +- 10 files changed, 618 insertions(+), 28 deletions(-) create mode 100644 frontend/coverage/src/components/FeedItems.css.html create mode 100644 frontend/coverage/src/components/FeedItems.tsx.html (limited to 'frontend/coverage/src') diff --git a/frontend/coverage/src/App.css.html b/frontend/coverage/src/App.css.html index 4ba93ef..21cb0dc 100644 --- a/frontend/coverage/src/App.css.html +++ b/frontend/coverage/src/App.css.html @@ -247,7 +247,7 @@ body { + + + + + + \ No newline at end of file diff --git a/frontend/coverage/src/components/FeedItems.tsx.html b/frontend/coverage/src/components/FeedItems.tsx.html new file mode 100644 index 0000000..85c9705 --- /dev/null +++ b/frontend/coverage/src/components/FeedItems.tsx.html @@ -0,0 +1,283 @@ + + + + + + Code coverage report for src/components/FeedItems.tsx + + + + + + + + + +
+
+

All files / src/components FeedItems.tsx

+
+ +
+ 86.36% + Statements + 19/22 +
+ + +
+ 61.11% + Branches + 11/18 +
+ + +
+ 83.33% + Functions + 5/6 +
+ + +
+ 85% + Lines + 17/20 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67  +  +  +  +  +  +3x +3x +3x +3x +  +3x +2x +2x +  +2x +  +  +  +2x +  +1x +  +  +1x +  +  +1x +1x +  +  +  +  +  +  +  +3x +1x +  +1x +  +  +  +  +  +  +  +  +2x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + 
import { useEffect, useState } from 'react';
+import { useParams } from 'react-router-dom';
+import type { Item } from '../types';
+import './FeedItems.css';
+ 
+export default function FeedItems() {
+    const { feedId } = useParams<{ feedId: string }>();
+    const [items, setItems] = useState<Item[]>([]);
+    const [loading, setLoading] = useState(true);
+    const [error, setError] = useState('');
+ 
+    useEffect(() => {
+        setLoading(true);
+        setError('');
+ 
+        const url = feedId
+            ? `/api/stream?feed_id=${feedId}`
+            : '/api/stream'; // Default or "all" view? For now let's assume we need a feedId or handle "all" logic later
+ 
+        fetch(url)
+            .then((res) => {
+                Iif (!res.ok) {
+                    throw new Error('Failed to fetch items');
+                }
+                return res.json();
+            })
+            .then((data) => {
+                setItems(data);
+                setLoading(false);
+            })
+            .catch((err) => {
+                setError(err.message);
+                setLoading(false);
+            });
+    }, [feedId]);
+ 
+    if (loading) return <div className="feed-items-loading">Loading items...</div>;
+    Iif (error) return <div className="feed-items-error">Error: {error}</div>;
+ 
+    return (
+        <div className="feed-items">
+            <h2>Items</h2>
+            {/* TODO: Add Feed Title here if possible, maybe pass from location state or fetch feed details */}
+            {items.length === 0 ? (
+                <p>No items found.</p>
+            ) : (
+                <ul className="item-list">
+                    {items.map((item) => (
+                        <li key={item._id} className={`item ${item.read ? 'read' : 'unread'}`}>
+                            <a href={item.url} target="_blank" rel="noopener noreferrer" className="item-title">
+                                {item.title || '(No Title)'}
+                            </a>
+                            <div className="item-meta">
+                                <span className="item-date">{new Date(item.publish_date).toLocaleDateString()}</span>
+                                {item.feed_title && <span className="item-feed"> - {item.feed_title}</span>}
+                            </div>
+                            {item.description && (
+                                <div className="item-description" dangerouslySetInnerHTML={{ __html: item.description }} />
+                            )}
+                        </li>
+                    ))}
+                </ul>
+            )}
+        </div>
+    );
+}
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/frontend/coverage/src/components/FeedList.css.html b/frontend/coverage/src/components/FeedList.css.html index cd14b1b..f86a2d4 100644 --- a/frontend/coverage/src/components/FeedList.css.html +++ b/frontend/coverage/src/components/FeedList.css.html @@ -211,7 +211,7 @@