From 7956e9fa6772ab57a0794fb7cba7e9d9c0bd7878 Mon Sep 17 00:00:00 2001 From: Mohamed Bassem Date: Sat, 28 Dec 2024 12:30:24 +0000 Subject: feat: Implement the all highlights page. Fixes #620 --- .../dashboard/highlights/AllHighlights.tsx | 98 ++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 apps/web/components/dashboard/highlights/AllHighlights.tsx (limited to 'apps/web/components/dashboard/highlights/AllHighlights.tsx') diff --git a/apps/web/components/dashboard/highlights/AllHighlights.tsx b/apps/web/components/dashboard/highlights/AllHighlights.tsx new file mode 100644 index 00000000..27dda6ff --- /dev/null +++ b/apps/web/components/dashboard/highlights/AllHighlights.tsx @@ -0,0 +1,98 @@ +"use client"; + +import { useEffect } from "react"; +import Link from "next/link"; +import { ActionButton } from "@/components/ui/action-button"; +import useRelativeTime from "@/lib/hooks/relative-time"; +import { api } from "@/lib/trpc"; +import { Separator } from "@radix-ui/react-dropdown-menu"; +import dayjs from "dayjs"; +import relativeTime from "dayjs/plugin/relativeTime"; +import { Dot, LinkIcon } from "lucide-react"; +import { useTranslation } from "react-i18next"; +import { useInView } from "react-intersection-observer"; + +import { + ZGetAllHighlightsResponse, + ZHighlight, +} from "@hoarder/shared/types/highlights"; + +import HighlightCard from "./HighlightCard"; + +dayjs.extend(relativeTime); + +function Highlight({ highlight }: { highlight: ZHighlight }) { + const { fromNow, localCreatedAt } = useRelativeTime(highlight.createdAt); + const { t } = useTranslation(); + return ( +
+ + + {fromNow} + + + + {t("common.source")} + + +
+ ); +} + +export default function AllHighlights({ + highlights: initialHighlights, +}: { + highlights: ZGetAllHighlightsResponse; +}) { + const { data, fetchNextPage, hasNextPage, isFetchingNextPage } = + api.highlights.getAll.useInfiniteQuery( + {}, + { + initialData: () => ({ + pages: [initialHighlights], + pageParams: [null], + }), + initialCursor: null, + getNextPageParam: (lastPage) => lastPage.nextCursor, + }, + ); + + const { ref: loadMoreRef, inView: loadMoreButtonInView } = useInView(); + useEffect(() => { + if (loadMoreButtonInView && hasNextPage && !isFetchingNextPage) { + fetchNextPage(); + } + }, [loadMoreButtonInView]); + + return ( +
+ {data?.pages + .flatMap((p) => p.highlights) + .map((h) => ( + <> + + + + ))} + {hasNextPage && ( +
+ fetchNextPage()} + variant="ghost" + > + Load More + +
+ )} +
+ ); +} -- cgit v1.2.3-70-g09d2