mirror of
https://github.com/collinbarrett/FilterLists.git
synced 2026-03-11 09:04:27 +00:00
refactor(web): client cache FilterLists data
This commit is contained in:
parent
3fd6756201
commit
e8472d63d8
4 changed files with 83 additions and 35 deletions
|
|
@ -1,19 +1,22 @@
|
|||
import { FilterListTable } from "@/components/filterlist-table";
|
||||
import { columns, FilterList } from "@/components/filterlist-table/columns";
|
||||
|
||||
async function getFilterLists(): Promise<FilterList[]> {
|
||||
const filterLists = await fetch("https://api.filterlists.com/lists", {
|
||||
async function getInitialFilterLists(): Promise<FilterList[]> {
|
||||
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 (
|
||||
<main className="pt-4 p-8 gap-16 sm:p-20 sm:pt-8">
|
||||
<FilterListTable columns={columns} data={filterLists} />
|
||||
<FilterListTable columns={columns} initialData={initialData} />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<FilterList>[];
|
||||
data: FilterList[];
|
||||
initialData: FilterList[];
|
||||
}
|
||||
|
||||
export function FilterListTable({ columns, data }: FilterListTableProps) {
|
||||
export function FilterListTable({
|
||||
columns,
|
||||
initialData,
|
||||
}: FilterListTableProps) {
|
||||
const [data, setData] = useState<FilterList[]>(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) {
|
|||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
<div className="flex items-center justify-between gap-2">
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => table.previousPage()}
|
||||
disabled={!table.getCanPreviousPage()}
|
||||
>
|
||||
Previous
|
||||
</Button>
|
||||
<span className="text-sm">
|
||||
Page {table.getState().pagination.pageIndex + 1} of{" "}
|
||||
{table.getPageCount()}
|
||||
</span>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => table.nextPage()}
|
||||
disabled={!table.getCanNextPage()}
|
||||
>
|
||||
Next
|
||||
</Button>
|
||||
</div>
|
||||
{loading ? (
|
||||
<FilterListTablePaginationSkeleton />
|
||||
) : (
|
||||
<FilterListTablePagination table={table} />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
35
web/src/components/filterlist-table/pagination.tsx
Normal file
35
web/src/components/filterlist-table/pagination.tsx
Normal file
|
|
@ -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<FilterList>;
|
||||
}
|
||||
|
||||
export function FilterListTablePagination({ table }: PaginationProps) {
|
||||
return (
|
||||
<div className="flex items-center justify-between gap-2">
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => table.previousPage()}
|
||||
disabled={!table.getCanPreviousPage()}
|
||||
>
|
||||
Previous
|
||||
</Button>
|
||||
<span className="text-sm">
|
||||
Page {table.getState().pagination.pageIndex + 1} of{" "}
|
||||
{table.getPageCount()}
|
||||
</span>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => table.nextPage()}
|
||||
disabled={!table.getCanNextPage()}
|
||||
>
|
||||
Next
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -23,11 +23,17 @@ export function FilterListTableSkeleton() {
|
|||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div className="flex items-center justify-between gap-2 mt-2">
|
||||
<Skeleton className="h-8 w-20" />
|
||||
<Skeleton className="h-6 w-24" />
|
||||
<Skeleton className="h-8 w-20" />
|
||||
</div>
|
||||
<FilterListTablePaginationSkeleton />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function FilterListTablePaginationSkeleton() {
|
||||
return (
|
||||
<div className="flex items-center justify-between gap-2 mt-2">
|
||||
<Skeleton className="h-8 w-20" />
|
||||
<Skeleton className="h-6 w-24" />
|
||||
<Skeleton className="h-8 w-20" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue