q12xo172i: Render post cards in the signed-in home feed

This commit is contained in:
2026-10-19 14:01:17 -06:00
parent 20af24b25d
commit 18e0386a99
9 changed files with 581 additions and 1 deletions
+69
View File
@@ -0,0 +1,69 @@
import type { Ref } from "react";
import type { CardPost } from "@/lib/feed-model";
import { PostCard } from "./PostCard";
export type FeedStatus = "loading" | "ready" | "error";
export interface FeedViewProps {
posts: CardPost[];
status: FeedStatus;
loadingMore: boolean;
loadMoreFailed: boolean;
newCount: number;
onRetry: () => void;
onShowNew: () => void;
sentinelRef?: Ref<HTMLDivElement>;
now?: number;
}
function Spinner() {
return <span className="spinner" role="status" aria-label="Loading" />;
}
export function FeedView(p: FeedViewProps) {
if (p.status === "loading") {
return (
<section className="feed">
<div className="feed-center">
<Spinner />
</div>
</section>
);
}
if (p.status === "error") {
return (
<section className="feed">
<div className="feed-message" role="alert">
<p>The feed did not load.</p>
<button type="button" onClick={p.onRetry}>Try again</button>
</div>
</section>
);
}
return (
<section className="feed">
{p.newCount > 0 ? (
<button type="button" className="new-posts" onClick={p.onShowNew}>
{p.newCount === 1 ? "1 new post" : `${p.newCount} new posts`}
</button>
) : null}
{p.posts.length === 0 ? (
<p className="feed-message">No posts yet.</p>
) : (
p.posts.map((post) => <PostCard key={post.key} post={post} now={p.now} />)
)}
{p.loadMoreFailed ? (
<div className="feed-message" role="alert">
<p>The feed did not load.</p>
<button type="button" onClick={p.onRetry}>Try again</button>
</div>
) : null}
{p.loadingMore ? (
<div className="feed-center">
<Spinner />
</div>
) : null}
<div ref={p.sentinelRef} className="sentinel" aria-hidden="true" />
</section>
);
}