- Add /v1/feed API endpoint with handler and tests - Remove health endpoint rate limiting (behind firewall, caused spurious 429s) - Add dashboard feed panel with list, row, empty state, and loading skeleton - Update home page to show feed instead of redirecting to skeptic - Improve API key auth middleware and DTO create/query params - Add OpenAPI conceptual guide (api-intro.md) with semaglutide examples - Add FindMyHealth application scaffolding (vision, architecture, prototypes) - Add FindMyHealth designer/writer and Aphoria founder-CEO agents - Update roadmap with current progress Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
66 lines
1.6 KiB
TypeScript
66 lines
1.6 KiB
TypeScript
"use client";
|
|
|
|
import type { AssertionObject } from "@/lib/api/types";
|
|
import { FeedRow } from "./feed-row";
|
|
import { FeedEmptyState } from "./feed-empty-state";
|
|
import { Button } from "@/components/ui/button";
|
|
|
|
interface FeedListProps {
|
|
assertions: AssertionObject[];
|
|
totalCount: number;
|
|
hasMore: boolean;
|
|
onLoadMore: () => void;
|
|
loading: boolean;
|
|
}
|
|
|
|
export function FeedList({
|
|
assertions,
|
|
totalCount,
|
|
hasMore,
|
|
onLoadMore,
|
|
loading,
|
|
}: FeedListProps) {
|
|
if (assertions.length === 0) {
|
|
return <FeedEmptyState />;
|
|
}
|
|
|
|
return (
|
|
<div className="space-y-4">
|
|
{/* Table header - hidden on mobile */}
|
|
<div className="hidden sm:grid grid-cols-5 gap-4 px-4 py-2 text-xs font-medium text-muted-foreground uppercase tracking-wide border-b border-border">
|
|
<div>Time</div>
|
|
<div>Subject</div>
|
|
<div>Predicate</div>
|
|
<div>Value</div>
|
|
<div>Source</div>
|
|
</div>
|
|
|
|
{/* Rows */}
|
|
<div className="space-y-2">
|
|
{assertions.map((entry) => (
|
|
<FeedRow key={entry.hash} entry={entry} />
|
|
))}
|
|
</div>
|
|
|
|
{/* Load more */}
|
|
{hasMore && (
|
|
<div className="flex justify-center pt-4">
|
|
<Button
|
|
variant="outline"
|
|
size="sm"
|
|
onClick={onLoadMore}
|
|
disabled={loading}
|
|
>
|
|
{loading ? "Loading..." : "Load More"}
|
|
</Button>
|
|
</div>
|
|
)}
|
|
|
|
{/* Summary */}
|
|
<p className="text-xs text-muted-foreground text-center pt-2">
|
|
Showing {assertions.length} of {totalCount} assertions
|
|
</p>
|
|
</div>
|
|
);
|
|
}
|