"use client"; import { formatDate } from "@/utils"; import * as ScrollArea from "@radix-ui/react-scroll-area"; import { useEffect, useState } from "react"; import { Article } from "@/lib/prisma"; import { useFetcher } from "@remix-run/react"; const Feed = ({ className, variant = "col", icon, title, initialData, }: { className?: string; variant?: "row" | "col"; title: string; icon: keyof typeof ICON_DICT; initialData: Article[]; }) => { const filters = ["latest", "day", "week", "month"] as const; const [content, setContent] = useState>(initialData); const [selectedFilter, setSelectedFilter] = useState<(typeof filters)[number]>("latest"); const [currentPage, setCurrentPage] = useState(0); const fetcher = useFetcher(); const Icon = ICON_DICT[icon]; useEffect(() => { if (currentPage !== 0) { // Fetch data for subsequent pages fetcher.load(`/api/feed?filter=${selectedFilter}&page=${currentPage}`); } }, [selectedFilter, currentPage]); useEffect(() => { if (fetcher.data && currentPage !== 0) { setContent((prevContent) => [...prevContent, ...fetcher.data.data]); } }, [fetcher.data, currentPage]); const handleFilterChange = (filter: (typeof filters)[number]) => { setSelectedFilter(filter); setCurrentPage(0); }; const handleLoadMore = () => { setCurrentPage((prevPage) => prevPage + 1); }; if (fetcher.state === "loading") { return
Loading...
; } if (!fetcher.data) { return
Failed to load
; } return (
{content.map((item, index) => { return (
{formatDate(item.createdAt)}

{item.title}

); })} {(fetcher.data as any)?.next ? ( ) : null}
); }; export default Feed; const PaperIcon = ({ className }: { className?: string }) => { return ( ); }; const TopArrowLodashIcon = ({ className }: { className?: string }) => { return ( ); }; const TrendUpIcon = ({ className }: { className?: string }) => { return ( ); }; const ICON_DICT = { "paper-icon": PaperIcon, "trend-up-icon": TrendUpIcon, "top-arrow-icon": TopArrowLodashIcon, } as const;