Files
gerbeur/src/pages/index/HotFeed.tsx

59 lines
1.6 KiB
TypeScript

import { useMemo } from "react";
import { t } from "@lingui/core/macro"
import { Trans } from "@lingui/react/macro";
import { DumpCard } from "../../components/DumpCard.tsx";
import { ErrorCard } from "../../components/ErrorCard.tsx";
import { hotScore } from "../../utils/hotScore.ts";
import type { MainFeedProps } from "./types.ts";
export function HotFeed(
{
dumps,
loading,
error,
hasMore,
loadingMore,
sentinelRef,
voteCounts,
myVotes,
user,
castVote,
removeVote,
}: MainFeedProps,
) {
const sorted = useMemo(
() => [...dumps].sort((a, b) => hotScore(b) - hotScore(a)),
[dumps],
);
if (loading) return <p className="index-status"><Trans>Loading</Trans></p>;
if (error) return <ErrorCard title={t`Failed to load`} message={error} />;
if (sorted.length === 0) {
return <p className="index-status"><Trans>No dumps yet. Be the first!</Trans></p>;
}
return (
<>
<ul className="dump-feed">
{sorted.map((dump) => (
<DumpCard
key={dump.id}
dump={dump}
voteCount={voteCounts[dump.id] ?? dump.voteCount}
voted={myVotes.has(dump.id)}
canVote={!!user}
castVote={castVote}
removeVote={removeVote}
isOwner={user?.id === dump.userId}
/>
))}
</ul>
<div ref={sentinelRef} />
{loadingMore && <p className="feed-loading-more"><Trans>Loading more</Trans></p>}
{!hasMore && sorted.length > 0 && (
<p className="feed-end"><Trans>You've reached the end.</Trans></p>
)}
</>
);
}