diff --git a/web/src/app/page.tsx b/web/src/app/page.tsx index 842b7c882..721129fa6 100644 --- a/web/src/app/page.tsx +++ b/web/src/app/page.tsx @@ -1,19 +1,22 @@ import { FilterListTable } from "@/components/filterlist-table"; import { columns, FilterList } from "@/components/filterlist-table/columns"; -async function getFilterLists(): Promise { - const filterLists = await fetch("https://api.filterlists.com/lists", { +async function getInitialFilterLists(): Promise { + const response = await fetch("https://api.filterlists.com/lists", { next: { revalidate: 86400 }, }); - return await filterLists.json(); + const lists = await response.json(); + + // TODO: add pagination support to API + return lists.slice(0, 20); } export default async function Home() { - const filterLists = await getFilterLists(); + const initialData = await getInitialFilterLists(); return (
- +
); } diff --git a/web/src/components/filterlist-table/index.tsx b/web/src/components/filterlist-table/index.tsx index 2b9bc12fa..a06591251 100644 --- a/web/src/components/filterlist-table/index.tsx +++ b/web/src/components/filterlist-table/index.tsx @@ -16,15 +16,36 @@ import { TableHeader, TableRow, } from "@/components/ui/table"; -import { Button } from "@/components/ui/button"; import { FilterList } from "./columns"; +import { useEffect, useState } from "react"; +import { FilterListTablePagination } from "./pagination"; +import { FilterListTablePaginationSkeleton } from "./skeleton"; interface FilterListTableProps { columns: ColumnDef[]; - data: FilterList[]; + initialData: FilterList[]; } -export function FilterListTable({ columns, data }: FilterListTableProps) { +export function FilterListTable({ + columns, + initialData, +}: FilterListTableProps) { + const [data, setData] = useState(initialData); + const [loading, setLoading] = useState(true); + + useEffect(() => { + async function fetchAll() { + try { + const response = await fetch("https://api.filterlists.com/lists"); + const lists = await response.json(); + setData(lists); + } finally { + setLoading(false); + } + } + fetchAll(); + }, [initialData.length]); + const table = useReactTable({ data, columns, @@ -61,28 +82,11 @@ export function FilterListTable({ columns, data }: FilterListTableProps) { ))} -
- - - Page {table.getState().pagination.pageIndex + 1} of{" "} - {table.getPageCount()} - - -
+ {loading ? ( + + ) : ( + + )} ); } diff --git a/web/src/components/filterlist-table/pagination.tsx b/web/src/components/filterlist-table/pagination.tsx new file mode 100644 index 000000000..b8e70aa25 --- /dev/null +++ b/web/src/components/filterlist-table/pagination.tsx @@ -0,0 +1,35 @@ +import * as React from "react"; +import { Button } from "@/components/ui/button"; +import { Table } from "@tanstack/react-table"; +import { FilterList } from "./columns"; + +interface PaginationProps { + table: Table; +} + +export function FilterListTablePagination({ table }: PaginationProps) { + return ( +
+ + + Page {table.getState().pagination.pageIndex + 1} of{" "} + {table.getPageCount()} + + +
+ ); +} diff --git a/web/src/components/filterlist-table/skeleton.tsx b/web/src/components/filterlist-table/skeleton.tsx index 0e8677b02..90f473715 100644 --- a/web/src/components/filterlist-table/skeleton.tsx +++ b/web/src/components/filterlist-table/skeleton.tsx @@ -23,11 +23,17 @@ export function FilterListTableSkeleton() { -
- - - -
+ + + ); +} + +export function FilterListTablePaginationSkeleton() { + return ( +
+ + +
); }