From bd2508211760edbc1bad1d515587d08fd2ec99c9 Mon Sep 17 00:00:00 2001 From: Adam Mathes Date: Fri, 13 Feb 2026 06:58:30 -0800 Subject: Implement Item Interactions (read/star) with tests --- frontend/src/components/FeedItem.tsx | 89 ++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 frontend/src/components/FeedItem.tsx (limited to 'frontend/src/components/FeedItem.tsx') diff --git a/frontend/src/components/FeedItem.tsx b/frontend/src/components/FeedItem.tsx new file mode 100644 index 0000000..aa0cea8 --- /dev/null +++ b/frontend/src/components/FeedItem.tsx @@ -0,0 +1,89 @@ +import { useState } from 'react'; +import type { Item } from '../types'; +import './FeedItem.css'; + +interface FeedItemProps { + item: Item; +} + +export default function FeedItem({ item: initialItem }: FeedItemProps) { + const [item, setItem] = useState(initialItem); + const [loading, setLoading] = useState(false); + + const toggleRead = () => { + updateItem({ ...item, read: !item.read }); + }; + + const toggleStar = () => { + updateItem({ ...item, starred: !item.starred }); + }; + + const updateItem = (newItem: Item) => { + setLoading(true); + // Optimistic update + const previousItem = item; + setItem(newItem); + + fetch(`/api/item/${newItem._id}`, { + method: 'PUT', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + _id: newItem._id, + read: newItem.read, + starred: newItem.starred, + }), + }) + .then((res) => { + if (!res.ok) { + throw new Error('Failed to update item'); + } + return res.json(); + }) + .then(() => { + // Confirm with server response if needed, but for now we trust the optimistic update + // or we could setItem(updated) if the server returns the full object + setLoading(false); + }) + .catch((err) => { + console.error('Error updating item:', err); + // Revert on error + setItem(previousItem); + setLoading(false); + }); + }; + + return ( +
  • +
    + + {item.title || '(No Title)'} + +
    + + +
    +
    +
    + {new Date(item.publish_date).toLocaleDateString()} + {item.feed_title && - {item.feed_title}} +
    + {item.description && ( +
    + )} +
  • + ); +} -- cgit v1.2.3