import { useTransition } from 'react'; import { msg } from '@lingui/core/macro'; import { useLingui } from '@lingui/react'; import { Building2, Loader, TrendingUp, Users } from 'lucide-react'; import { Link } from 'react-router'; import { useNavigation } from 'react-router'; import { useUpdateSearchParams } from '@documenso/lib/client-only/hooks/use-update-search-params'; import type { OrganisationDetailedInsights } from '@documenso/lib/server-only/admin/get-organisation-detailed-insights'; import type { DateRange } from '@documenso/lib/types/search-params'; import type { ExtendedDocumentStatus } from '@documenso/prisma/types/extended-document-status'; import { Button } from '@documenso/ui/primitives/button'; import type { DataTableColumnDef } from '@documenso/ui/primitives/data-table'; import { DataTable } from '@documenso/ui/primitives/data-table'; import { DataTablePagination } from '@documenso/ui/primitives/data-table-pagination'; import { DateRangeFilter } from '~/components/filters/date-range-filter'; import { DocumentStatus } from '~/components/general/document/document-status'; type OrganisationInsightsTableProps = { insights: OrganisationDetailedInsights; page: number; perPage: number; dateRange: DateRange; view: 'teams' | 'users' | 'documents'; }; export const OrganisationInsightsTable = ({ insights, page, perPage, dateRange, view, }: OrganisationInsightsTableProps) => { const { _, i18n } = useLingui(); const [isPending, startTransition] = useTransition(); const navigation = useNavigation(); const updateSearchParams = useUpdateSearchParams(); const isLoading = isPending || navigation.state === 'loading'; const onPaginationChange = (newPage: number, newPerPage: number) => { startTransition(() => { updateSearchParams({ page: newPage, perPage: newPerPage, }); }); }; const handleViewChange = (newView: 'teams' | 'users' | 'documents') => { startTransition(() => { updateSearchParams({ view: newView, page: 1, }); }); }; const teamsColumns = [ { header: _(msg`Team Name`), accessorKey: 'name', cell: ({ row }) => {row.getValue('name')}, size: 240, }, { header: _(msg`Members`), accessorKey: 'memberCount', cell: ({ row }) => Number(row.getValue('memberCount')), size: 120, }, { header: _(msg`Documents`), accessorKey: 'documentCount', cell: ({ row }) => Number(row.getValue('documentCount')), size: 140, }, { header: _(msg`Created`), accessorKey: 'createdAt', cell: ({ row }) => i18n.date(new Date(row.getValue('createdAt'))), size: 160, }, ] satisfies DataTableColumnDef<(typeof insights.teams)[number]>[]; const usersColumns = [ { header: () => {_(msg`Name`)}, accessorKey: 'name', cell: ({ row }) => ( {(row.getValue('name') as string) || (row.getValue('email') as string)} ), size: 220, }, { header: () => {_(msg`Email`)}, accessorKey: 'email', cell: ({ row }) => {row.getValue('email')}, size: 260, }, { header: () => {_(msg`Documents Created`)}, accessorKey: 'documentCount', cell: ({ row }) => Number(row.getValue('documentCount')), size: 180, }, { header: () => {_(msg`Documents Completed`)}, accessorKey: 'signedDocumentCount', cell: ({ row }) => Number(row.getValue('signedDocumentCount')), size: 180, }, { header: () => {_(msg`Joined`)}, accessorKey: 'createdAt', cell: ({ row }) => i18n.date(new Date(row.getValue('createdAt'))), size: 160, }, ] satisfies DataTableColumnDef<(typeof insights.users)[number]>[]; const documentsColumns = [ { header: () => {_(msg`Title`)}, accessorKey: 'title', cell: ({ row }) => ( {row.getValue('title')} ), size: 200, }, { header: () => {_(msg`Status`)}, accessorKey: 'status', cell: ({ row }) => ( ), size: 120, }, { header: () => {_(msg`Team`)}, accessorKey: 'teamName', cell: ({ row }) => ( {row.getValue('teamName')} ), size: 150, }, { header: () => {_(msg`Created`)}, accessorKey: 'createdAt', cell: ({ row }) => i18n.date(new Date(row.getValue('createdAt'))), size: 140, }, { header: () => {_(msg`Completed`)}, accessorKey: 'completedAt', cell: ({ row }) => { const completedAt = row.getValue('completedAt') as Date | null; return completedAt ? i18n.date(new Date(completedAt)) : '-'; }, size: 140, }, ] satisfies DataTableColumnDef<(typeof insights.documents)[number]>[]; const getCurrentData = (): unknown[] => { switch (view) { case 'teams': return insights.teams; case 'users': return insights.users; case 'documents': return insights.documents; default: return []; } }; const getCurrentColumns = (): DataTableColumnDef[] => { switch (view) { case 'teams': return teamsColumns as unknown as DataTableColumnDef[]; case 'users': return usersColumns as unknown as DataTableColumnDef[]; case 'documents': return documentsColumns as unknown as DataTableColumnDef[]; default: return []; } }; return (
{insights.summary && (
)}
columns={getCurrentColumns()} data={getCurrentData()} perPage={perPage} currentPage={page} totalPages={insights.totalPages} onPaginationChange={onPaginationChange} > {(table) => }
{isLoading && (
)}
); }; const SummaryCard = ({ icon: Icon, title, value, subtitle, }: { icon: React.ComponentType<{ className?: string }>; title: string; value: number; subtitle?: string; }) => (

{title}

{value}

{subtitle &&

{subtitle}

}
);