From 08d94cf2b2b8f64346bd29cd6db07bd8f1ef75f0 Mon Sep 17 00:00:00 2001 From: Ephraim Atta-Duncan Date: Tue, 17 Sep 2024 16:04:13 +0000 Subject: [PATCH] chore: add initial query --- .../(dashboard)/admin/leaderboard/page.tsx | 25 ++ .../(dashboard)/admin/leaderboard/table.tsx | 263 ++++++++++++++++++ apps/web/src/app/(dashboard)/admin/nav.tsx | 16 +- .../server-only/admin/get-signing-volume.ts | 49 ++++ packages/lib/translations/de/web.js | 2 +- packages/lib/translations/de/web.po | 10 +- packages/lib/translations/en/web.js | 2 +- packages/lib/translations/en/web.po | 10 +- packages/prisma/seed-signing-volume.ts | 124 +++++++++ 9 files changed, 496 insertions(+), 5 deletions(-) create mode 100644 apps/web/src/app/(dashboard)/admin/leaderboard/page.tsx create mode 100644 apps/web/src/app/(dashboard)/admin/leaderboard/table.tsx create mode 100644 packages/lib/server-only/admin/get-signing-volume.ts create mode 100644 packages/prisma/seed-signing-volume.ts diff --git a/apps/web/src/app/(dashboard)/admin/leaderboard/page.tsx b/apps/web/src/app/(dashboard)/admin/leaderboard/page.tsx new file mode 100644 index 000000000..9f10381cb --- /dev/null +++ b/apps/web/src/app/(dashboard)/admin/leaderboard/page.tsx @@ -0,0 +1,25 @@ +import { Trans } from '@lingui/macro'; + +import { setupI18nSSR } from '@documenso/lib/client-only/providers/i18n.server'; +import { getSigningVolume } from '@documenso/lib/server-only/admin/get-signing-volume'; + +import { DataTableDemo as Table } from './table'; + +export default async function Leaderboard() { + setupI18nSSR(); + + const signingVolume = await getSigningVolume(); + + console.log(signingVolume); + + return ( +
+

+ Signing Volume +

+
+ + + + ); +} diff --git a/apps/web/src/app/(dashboard)/admin/leaderboard/table.tsx b/apps/web/src/app/(dashboard)/admin/leaderboard/table.tsx new file mode 100644 index 000000000..ece498bd9 --- /dev/null +++ b/apps/web/src/app/(dashboard)/admin/leaderboard/table.tsx @@ -0,0 +1,263 @@ +'use client'; + +import * as React from 'react'; + +import type { + ColumnDef, + ColumnFiltersState, + SortingState, + VisibilityState, +} from '@tanstack/react-table'; +import { + flexRender, + getCoreRowModel, + getFilteredRowModel, + getPaginationRowModel, + getSortedRowModel, + useReactTable, +} from '@tanstack/react-table'; +import { + ChevronDownIcon as CaretSortIcon, + ChevronDownIcon as DotsHorizontalIcon, +} from 'lucide-react'; + +import { Button } from '@documenso/ui/primitives/button'; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from '@documenso/ui/primitives/dropdown-menu'; +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from '@documenso/ui/primitives/table'; + +const data: Payment[] = [ + { + id: 'm5gr84i9', + amount: 316, + status: 'success', + email: 'ken99@yahoo.com', + }, + { + id: '3u1reuv4', + amount: 242, + status: 'success', + email: 'Abe45@gmail.com', + }, + { + id: 'derv1ws0', + amount: 837, + status: 'processing', + email: 'Monserrat44@gmail.com', + }, + { + id: '5kma53ae', + amount: 874, + status: 'success', + email: 'Silas22@gmail.com', + }, + { + id: 'bhqecj4p', + amount: 721, + status: 'failed', + email: 'carmella@hotmail.com', + }, + { + id: '5kma53ae', + amount: 874, + status: 'success', + email: 'Silas22@gmail.com', + }, + { + id: '5kma53ae', + amount: 874, + status: 'success', + email: 'Silas22@gmail.com', + }, + { + id: '5kma53ae', + amount: 874, + status: 'success', + email: 'Silas22@gmail.com', + }, + { + id: '5kma53ae', + amount: 874, + status: 'success', + email: 'Silas22@gmail.com', + }, +]; + +export type Payment = { + id: string; + amount: number; + status: 'pending' | 'processing' | 'success' | 'failed'; + email: string; +}; + +export const columns: ColumnDef[] = [ + { + accessorKey: 'status', + header: 'Status', + cell: ({ row }) =>
{row.getValue('status')}
, + }, + { + accessorKey: 'email', + header: ({ column }) => { + return ( + + ); + }, + cell: ({ row }) =>
{row.getValue('email')}
, + }, + { + accessorKey: 'amount', + header: () =>
Amount
, + cell: ({ row }) => { + const amount = parseFloat(row.getValue('amount')); + + // Format the amount as a dollar amount + const formatted = new Intl.NumberFormat('en-US', { + style: 'currency', + currency: 'USD', + }).format(amount); + + return
{formatted}
; + }, + }, + { + id: 'actions', + enableHiding: false, + cell: ({ row }) => { + const payment = row.original; + + return ( + + + + + + Actions + navigator.clipboard.writeText(payment.id)}> + Copy payment ID + + + View customer + View payment details + + + ); + }, + }, +]; + +export function DataTableDemo() { + const [sorting, setSorting] = React.useState([]); + const [columnFilters, setColumnFilters] = React.useState([]); + const [columnVisibility, setColumnVisibility] = React.useState({}); + const [rowSelection, setRowSelection] = React.useState({}); + + const table = useReactTable({ + data, + columns, + onSortingChange: setSorting, + onColumnFiltersChange: setColumnFilters, + getCoreRowModel: getCoreRowModel(), + getPaginationRowModel: getPaginationRowModel(), + getSortedRowModel: getSortedRowModel(), + getFilteredRowModel: getFilteredRowModel(), + onColumnVisibilityChange: setColumnVisibility, + onRowSelectionChange: setRowSelection, + state: { + sorting, + columnFilters, + columnVisibility, + rowSelection, + }, + }); + + return ( +
+
+
+ + {table.getHeaderGroups().map((headerGroup) => ( + + {headerGroup.headers.map((header) => { + return ( + + {header.isPlaceholder + ? null + : flexRender(header.column.columnDef.header, header.getContext())} + + ); + })} + + ))} + + + {table.getRowModel().rows?.length ? ( + table.getRowModel().rows.map((row) => ( + + {row.getVisibleCells().map((cell) => ( + + {flexRender(cell.column.columnDef.cell, cell.getContext())} + + ))} + + )) + ) : ( + + + No results. + + + )} + +
+
+
+
+ {table.getFilteredSelectedRowModel().rows.length} of{' '} + {table.getFilteredRowModel().rows.length} row(s) selected. +
+
+ + +
+
+
+ ); +} diff --git a/apps/web/src/app/(dashboard)/admin/nav.tsx b/apps/web/src/app/(dashboard)/admin/nav.tsx index cf0bb81f2..bcae0fc75 100644 --- a/apps/web/src/app/(dashboard)/admin/nav.tsx +++ b/apps/web/src/app/(dashboard)/admin/nav.tsx @@ -6,7 +6,7 @@ import Link from 'next/link'; import { usePathname } from 'next/navigation'; import { Trans } from '@lingui/macro'; -import { BarChart3, FileStack, Settings, Users, Wallet2 } from 'lucide-react'; +import { BarChart3, FileStack, Settings, Trophy, Users, Wallet2 } from 'lucide-react'; import { cn } from '@documenso/ui/lib/utils'; import { Button } from '@documenso/ui/primitives/button'; @@ -80,6 +80,20 @@ export const AdminNav = ({ className, ...props }: AdminNavProps) => { + +