"use client" import { formatDate } from "@/utils" import * as ScrollArea from "@radix-ui/react-scroll-area" import { sub } from "date-fns" import { useState, useCallback, useEffect } from "react" const Feed = ({ className, variant = "col", icon, title }: { className?: string variant?: "row" | "col" title: string icon: keyof typeof ICON_DICT }) => { const filters = ["latest", "day", "week", "month"] as const const [dataResponse, setDataResponse] = useState>>(); const [content, setContent] = useState['data']>([]) const [selectedFilter, setSelectedFilter] = useState<(typeof filters)[number]>("latest") const Icon = ICON_DICT[icon] const fetchContent = useCallback( async (overwrite: boolean = false) => { const response = await fetchFeedData({ filter: { timerange: selectedFilter }, next: dataResponse?.next, current: dataResponse?.current, limit: 5 }) setDataResponse(response) setContent((current) => { if (overwrite) { return response.data } return [...current, ...response.data] }) console.log("Fetched data") }, [setContent, dataResponse, selectedFilter] ) const handleFilterChange = (filter: (typeof filters)[number]) => { setSelectedFilter(filter) fetchContent(true) } useEffect(() => { fetchContent() }, []) return (
{content.map((item, index) => { return (
{formatDate(item.date)}

{item.content}

) })} {dataResponse?.next ? : null}
) } const data = Array.from({ length: 20 }, (_, i) => ({ id: i, date: sub(new Date(), { days: i }).toISOString(), content: `Content ${i}` })) // Filter data by timerange and pagination // Randomly sort the data const randomlySortedData = data.sort(() => Math.random() - 0.5) type ApiResponse> = { data: T[], current: number, next?: number | null, amount?: number } async function fetchFeedData({ filter, limit = 5, next = 5, current = 0 }: { filter?: { timerange?: "latest" | "day" | "week" | "month" } next?: number limit?: number current?: number }): Promise> { const data = filter?.timerange ? randomlySortedData.filter(() => Math.random() > 0.5) : randomlySortedData const sliced = data.slice(current, next) const nextPointer = sliced.length >= limit ? next + limit : null return { data: sliced, current: next, next: nextPointer, amount: sliced.length } } 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