import { QueryClient, QueryClientProvider, useInfiniteQuery } from "@tanstack/react-query";
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
EmptyState,
Timeline,
type TimelineItem,
} from "@godxjp/ui/data-display";
import { SkeletonTable } from "@godxjp/ui/feedback";
import { Flex, PageContainer } from "@godxjp/ui/layout";
import { InfiniteQueryState, flattenItemPages } from "@godxjp/ui/query";
/**
* InfiniteQueryState · useInfiniteQuery widget: flattens pages, renders the
* skeleton/empty/error states, and a built-in load-more footer. Use
* flattenItemPages for `{ items }` pages. Composed from real @godxjp/ui +
* @tanstack/react-query.
*/
const queryClient = new QueryClient();
type Activity = { id: string; text: string; actor: string; time: string };
const feed: Activity[] = [
{ id: "a1", text: "請求書 INV-0312 を承認", actor: "経理 田中", time: "10:24" },
{ id: "a2", text: "仕訳 #2024-0312 を作成", actor: "システム", time: "10:20" },
{ id: "a3", text: "請求書 INV-0312 を発行", actor: "営業 グエン", time: "09:50" },
{ id: "a4", text: "受注 ORD-0455 を登録", actor: "営業 グエン", time: "09:30" },
{ id: "a5", text: "取引先 BTY-0012 を更新", actor: "管理 佐藤", time: "09:10" },
];
const PAGE = 3;
function Block() {
const query = useInfiniteQuery({
queryKey: ["activity-feed"],
queryFn: async ({ pageParam }) => {
const start = pageParam;
return {
items: feed.slice(start, start + PAGE),
nextCursor: start + PAGE < feed.length ? start + PAGE : null,
};
},
initialPageParam: 0,
getNextPageParam: (last) => last.nextCursor,
});
return (
query={query}
skeleton={}
flatten={flattenItemPages}
isEmpty={(items) => items.length === 0}
empty={}
>
{(items) => (
((a, i) => ({
title: a.text,
location: a.actor,
time: a.time,
current: i === 0,
}))}
/>
)}
);
}
export default function Demo() {
return (
アクティビティ
Click 「もっと見る」 to append the next page.
);
}