diff --git a/client/src/pages/home.tsx b/client/src/pages/home.tsx index c0845f9..ad3e53c 100644 --- a/client/src/pages/home.tsx +++ b/client/src/pages/home.tsx @@ -22,12 +22,9 @@ import { Rss, Bell, BellOff, + BellRing, } from "lucide-react"; -import { - useNewsletters, - useNewsletterSearch, - type NewslettersResponse, -} from "@/lib/newsletter-data"; +import { useNewsletters, useNewsletterSearch, type NewslettersResponse } from "@/lib/newsletter-data"; import { useToast } from "@/hooks/use-toast"; import { apiRequest } from "@/lib/queryClient"; import { queryClient } from "@/lib/queryClient"; @@ -39,6 +36,7 @@ const ITEMS_PER_PAGE = 20; export default function Home() { const [searchQuery, setSearchQuery] = useState(""); const [isImporting, setIsImporting] = useState(false); + const [isSendingTestNotification, setIsSendingTestNotification] = useState(false); const [page, setPage] = useState(1); const [isSubscribed, setIsSubscribed] = useState(false); const [allItems, setAllItems] = useState([]); @@ -65,9 +63,8 @@ export default function Home() { const isCurrentFetching = searchQuery ? isSearchFetching : isFetching; // Check if there are more pages to load - const hasMorePages = currentData - ? currentData.page * currentData.limit < currentData.total - : false; + const hasMorePages = currentData ? + (currentData.page * currentData.limit < currentData.total) : false; // Merge newsletter items when data changes useEffect(() => { @@ -78,16 +75,12 @@ export default function Home() { setAllItems(currentData.newsletters); } else { // Merge items, ensuring we don't have duplicates - setAllItems((prevItems) => { + setAllItems(prevItems => { // Create a set of IDs from new items for faster lookups - const newItemIds = new Set( - currentData.newsletters.map((item) => item.id), - ); + const newItemIds = new Set(currentData.newsletters.map(item => item.id)); // Filter out any previous items that would be duplicated - const filteredPrevItems = prevItems.filter( - (item) => !newItemIds.has(item.id), - ); + const filteredPrevItems = prevItems.filter(item => !newItemIds.has(item.id)); // Combine previous (non-duplicate) items with new items return [...filteredPrevItems, ...currentData.newsletters]; @@ -104,15 +97,16 @@ export default function Home() { const handleImport = async () => { try { setIsImporting(true); - const response = await apiRequest("POST", "/api/newsletters/import"); + await apiRequest("POST", "/api/newsletters/import"); + await queryClient.invalidateQueries({ queryKey: ["/api/newsletters"] }); toast({ title: "Success", - description: response.message, + description: "Newsletters imported successfully", }); - } catch (error: any) { + } catch (error) { toast({ title: "Error", - description: error.message || "Failed to import newsletters", + description: "Failed to import newsletters", variant: "destructive", }); } finally { @@ -120,22 +114,6 @@ export default function Home() { } }; - const handleTestNotification = async () => { - try { - const response = await apiRequest("POST", "/api/notifications/test"); - toast({ - title: "Notifications Sent", - description: `${response.message} (${response.totalSubscribers} subscribers)`, - }); - } catch (error: any) { - toast({ - title: "Error", - description: error.message || "Failed to send test notifications", - variant: "destructive", - }); - } - }; - const handleShare = async (newsletter: Newsletter) => { if (navigator.share) { try { @@ -158,6 +136,25 @@ export default function Home() { } }; + const handleSendTestNotification = async () => { + try { + setIsSendingTestNotification(true); + const response = await apiRequest("POST", "/api/notifications/test"); + toast({ + title: "Test Notifications Sent", + description: `Results: ${response.succeeded} succeeded, ${response.failed} failed out of ${response.total} subscriptions`, + }); + } catch (error: any) { + toast({ + title: "Error", + description: error.message || "Failed to send test notifications", + variant: "destructive", + }); + } finally { + setIsSendingTestNotification(false); + } + }; + const handleSubscribe = async () => { try { if (!("serviceWorker" in navigator) || !("Notification" in window)) { @@ -213,21 +210,13 @@ export default function Home() { } }; - const handleObserver = useCallback( - (entries: IntersectionObserverEntry[]) => { - const target = entries[0]; - if ( - target.isIntersecting && - !isCurrentLoading && - !isCurrentFetching && - hasMorePages - ) { - console.log("Loading more newsletters. Current page:", page); - setPage((prev) => prev + 1); - } - }, - [isCurrentLoading, isCurrentFetching, hasMorePages, page], - ); + const handleObserver = useCallback((entries: IntersectionObserverEntry[]) => { + const target = entries[0]; + if (target.isIntersecting && !isCurrentLoading && !isCurrentFetching && hasMorePages) { + console.log("Loading more newsletters. Current page:", page); + setPage((prev) => prev + 1); + } + }, [isCurrentLoading, isCurrentFetching, hasMorePages, page]); useEffect(() => { const currentLoader = loader.current; @@ -275,25 +264,29 @@ export default function Home() { /> {isDevelopment && ( - - )} - {isDevelopment && ( - + <> + + + )}