From be5128053f59efc73ef09531f79e23e00de13103 Mon Sep 17 00:00:00 2001 From: PxlLoewe <72106766+PxlLoewe@users.noreply.github.com> Date: Thu, 6 Feb 2025 00:18:44 +0100 Subject: [PATCH] data table --- apps/dispatch/tsconfig.json | 8 +-- apps/hub/app/_components/PaginatedTable.tsx | 27 ++++++++ apps/hub/app/_components/Table.tsx | 75 +++++++++++++++++++++ apps/hub/app/page.tsx | 33 ++++++--- apps/hub/package.json | 1 + package-lock.json | 32 +++++++++ 6 files changed, 161 insertions(+), 15 deletions(-) create mode 100644 apps/hub/app/_components/PaginatedTable.tsx create mode 100644 apps/hub/app/_components/Table.tsx diff --git a/apps/dispatch/tsconfig.json b/apps/dispatch/tsconfig.json index 7aef0569..a09ecff3 100644 --- a/apps/dispatch/tsconfig.json +++ b/apps/dispatch/tsconfig.json @@ -12,9 +12,9 @@ "**/*.tsx", "next-env.d.ts", "next.config.js", - ".next/types/**/*.ts" + ".next/types/**/*.ts", + "../hub/app/_components/PaginatedTable.tsx", + "../hub/app/_components/Table.tsx" ], - "exclude": [ - "node_modules" - ] + "exclude": ["node_modules"] } diff --git a/apps/hub/app/_components/PaginatedTable.tsx b/apps/hub/app/_components/PaginatedTable.tsx new file mode 100644 index 00000000..18b81113 --- /dev/null +++ b/apps/hub/app/_components/PaginatedTable.tsx @@ -0,0 +1,27 @@ +import SortableTable, { SortableTableProps } from './Table'; + +interface PaginatedTableProps + extends Omit, 'data'> { + prismaGetter: ( + fnProps: { + cursor: number; + take: number; + } & any + ) => Promise; +} + +export async function PaginatedTable({ + prismaGetter, + ...restProps +}: PaginatedTableProps) { + const data = await prismaGetter({ + cursor: 0, + take: 10, + }); + + return ( +
+ +
+ ); +} diff --git a/apps/hub/app/_components/Table.tsx b/apps/hub/app/_components/Table.tsx new file mode 100644 index 00000000..56781285 --- /dev/null +++ b/apps/hub/app/_components/Table.tsx @@ -0,0 +1,75 @@ +'use client'; +import { useState } from 'react'; +import { + useReactTable, + getCoreRowModel, + getSortedRowModel, + ColumnDef, + SortingState, + flexRender, +} from '@tanstack/react-table'; +import { ChevronDown, ChevronUp } from 'lucide-react'; // Icons for sorting + +export interface SortableTableProps { + data: TData[]; + columns: ColumnDef[]; +} + +export default function SortableTable({ + data, + columns, +}: SortableTableProps) { + const [sorting, setSorting] = useState([]); + + const table = useReactTable({ + data, + columns, + getCoreRowModel: getCoreRowModel(), + getSortedRowModel: getSortedRowModel(), + onSortingChange: setSorting, + state: { sorting }, + }); + + return ( +
+ + + {table.getHeaderGroups().map((headerGroup) => ( + + {headerGroup.headers.map((header) => ( + + ))} + + ))} + + + {table.getRowModel().rows.map((row) => ( + + {row.getVisibleCells().map((cell) => ( + + ))} + + ))} + +
+
+ {flexRender( + header.column.columnDef.header, + header.getContext() + )} + {header.column.getIsSorted() === 'asc' && ( + + )} + {header.column.getIsSorted() === 'desc' && ( + + )} +
+
+ {flexRender(cell.column.columnDef.cell, cell.getContext())} +
+
+ ); +} diff --git a/apps/hub/app/page.tsx b/apps/hub/app/page.tsx index 5ebfaa09..fec363b5 100644 --- a/apps/hub/app/page.tsx +++ b/apps/hub/app/page.tsx @@ -1,22 +1,33 @@ -'use client'; - -import { useSession } from 'next-auth/react'; import Link from 'next/link'; -import { useEffect } from 'react'; +import { PrismaClient } from '@repo/db'; +import { PaginatedTable } from '../app/_components/PaginatedTable'; + +export default async function Home() { + const prisma = new PrismaClient(); -export default function Home() { - const { data: session, update } = useSession(); - useEffect(() => { - update(); - }, []); return (

Hub

- {!session &&

Not signed in

} - {session?.user?.firstname &&

Hi, {session?.user?.firstname}

} +
); } diff --git a/apps/hub/package.json b/apps/hub/package.json index fb81eb92..7119a2d9 100644 --- a/apps/hub/package.json +++ b/apps/hub/package.json @@ -12,6 +12,7 @@ "@hookform/resolvers": "^3.10.0", "@next-auth/prisma-adapter": "^1.0.7", "@repo/ui": "*", + "@tanstack/react-table": "^8.20.6", "bcryptjs": "^2.4.3", "clsx": "^2.1.1", "lodash": "^4.17.21", diff --git a/package-lock.json b/package-lock.json index e6dfeaad..8de936db 100644 --- a/package-lock.json +++ b/package-lock.json @@ -108,6 +108,7 @@ "@hookform/resolvers": "^3.10.0", "@next-auth/prisma-adapter": "^1.0.7", "@repo/ui": "*", + "@tanstack/react-table": "^8.20.6", "bcryptjs": "^2.4.3", "clsx": "^2.1.1", "lodash": "^4.17.21", @@ -1474,6 +1475,37 @@ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.0.3.tgz", "integrity": "sha512-ImmZF0Lon5RrQpsEAKGxRvHwCvMgSC4XVlFRqmbzTEDb/3wvin9zfEZrMwgsa3yqBbPqahYcVI6lulM2S7IZAA==" }, + "node_modules/@tanstack/react-table": { + "version": "8.20.6", + "resolved": "https://registry.npmjs.org/@tanstack/react-table/-/react-table-8.20.6.tgz", + "integrity": "sha512-w0jluT718MrOKthRcr2xsjqzx+oEM7B7s/XXyfs19ll++hlId3fjTm+B2zrR3ijpANpkzBAr15j1XGVOMxpggQ==", + "dependencies": { + "@tanstack/table-core": "8.20.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, + "node_modules/@tanstack/table-core": { + "version": "8.20.5", + "resolved": "https://registry.npmjs.org/@tanstack/table-core/-/table-core-8.20.5.tgz", + "integrity": "sha512-P9dF7XbibHph2PFRz8gfBKEXEY/HJPOhym8CHmjF8y3q5mWpKx9xtZapXQUWCgkqvsK0R46Azuz+VaxD4Xl+Tg==", + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, "node_modules/@tootallnate/quickjs-emscripten": { "version": "0.23.0", "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz",