import { useEffect, useMemo, useState, useTransition } from 'react'; import { msg } from '@lingui/core/macro'; import { useLingui } from '@lingui/react'; import { Trans } from '@lingui/react/macro'; import { ChevronDownIcon, ChevronUpIcon, ChevronsUpDown, Loader } from 'lucide-react'; import { Link } from 'react-router'; import { useDebouncedValue } from '@documenso/lib/client-only/hooks/use-debounced-value'; import { useUpdateSearchParams } from '@documenso/lib/client-only/hooks/use-update-search-params'; import type { DateRange } from '@documenso/lib/types/search-params'; 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 { Input } from '@documenso/ui/primitives/input'; export type OrganisationOverview = { id: string; name: string; signingVolume: number; createdAt: Date; customerId: string; subscriptionStatus?: string; isActive?: boolean; teamCount?: number; memberCount?: number; }; type OrganisationOverviewTableProps = { organisations: OrganisationOverview[]; totalPages: number; perPage: number; page: number; sortBy: 'name' | 'createdAt' | 'signingVolume'; sortOrder: 'asc' | 'desc'; dateRange: DateRange; }; export const AdminOrganisationOverviewTable = ({ organisations, totalPages, perPage, page, sortBy, sortOrder, dateRange, }: OrganisationOverviewTableProps) => { const { _, i18n } = useLingui(); const [isPending, startTransition] = useTransition(); const updateSearchParams = useUpdateSearchParams(); const [searchString, setSearchString] = useState(''); const debouncedSearchString = useDebouncedValue(searchString, 1000); const columns = useMemo(() => { return [ { header: () => (
handleColumnSort('name')} > {_(msg`Name`)} {sortBy === 'name' ? ( sortOrder === 'asc' ? ( ) : ( ) ) : ( )}
), accessorKey: 'name', cell: ({ row }) => { return (
{row.getValue('name')}
); }, size: 240, }, { header: () => (
handleColumnSort('signingVolume')} > Document Volume {sortBy === 'signingVolume' ? ( sortOrder === 'asc' ? ( ) : ( ) ) : ( )}
), accessorKey: 'signingVolume', cell: ({ row }) =>
{Number(row.getValue('signingVolume'))}
, size: 160, }, { header: () => { return Teams; }, accessorKey: 'teamCount', cell: ({ row }) =>
{Number(row.original.teamCount) || 0}
, size: 120, }, { header: () => { return Members; }, accessorKey: 'memberCount', cell: ({ row }) =>
{Number(row.original.memberCount) || 0}
, size: 160, }, { header: () => { return (
handleColumnSort('createdAt')} > Created {sortBy === 'createdAt' ? ( sortOrder === 'asc' ? ( ) : ( ) ) : ( )}
); }, accessorKey: 'createdAt', cell: ({ row }) => i18n.date(new Date(row.original.createdAt)), size: 120, }, ] satisfies DataTableColumnDef[]; }, [sortOrder, sortBy, dateRange]); useEffect(() => { startTransition(() => { updateSearchParams({ search: debouncedSearchString, page: 1, perPage, sortBy, sortOrder, }); }); // eslint-disable-next-line react-hooks/exhaustive-deps }, [debouncedSearchString]); const onPaginationChange = (page: number, perPage: number) => { startTransition(() => { updateSearchParams({ page, perPage, }); }); }; const handleChange = (e: React.ChangeEvent) => { setSearchString(e.target.value); }; const handleColumnSort = (column: 'name' | 'createdAt' | 'signingVolume') => { startTransition(() => { updateSearchParams({ search: debouncedSearchString, page, perPage, sortBy: column, sortOrder: sortBy === column && sortOrder === 'asc' ? 'desc' : 'asc', }); }); }; return (
{(table) => } {isPending && (
)}
); };