chore: minor changes

This commit is contained in:
Ephraim Atta-Duncan
2025-08-14 10:17:45 +00:00
parent 28f1948a5e
commit 020c0497ba
11 changed files with 187 additions and 141 deletions

View File

@ -3,6 +3,7 @@ import { useEffect, useMemo, useState, useTransition } from 'react';
import { msg } from '@lingui/core/macro';
import { useLingui } from '@lingui/react';
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';
@ -16,7 +17,7 @@ export type OrganisationOverview = {
name: string;
signingVolume: number;
createdAt: Date;
planId: string;
customerId: string;
subscriptionStatus?: string;
isActive?: boolean;
teamCount?: number;
@ -71,16 +72,16 @@ export const AdminOrganisationOverviewTable = ({
cell: ({ row }) => {
return (
<div>
<a
<Link
className="text-primary underline"
href={`/admin/organisation-insights/${row.original.id}`}
to={`/admin/organisation-insights/${row.original.id}`}
>
{row.getValue('name')}
</a>
</Link>
</div>
);
},
size: 200,
size: 240,
},
{
header: () => (
@ -88,7 +89,7 @@ export const AdminOrganisationOverviewTable = ({
className="flex cursor-pointer items-center"
onClick={() => handleColumnSort('signingVolume')}
>
{_(msg`Document Volume`)}
<span className="whitespace-nowrap">{_(msg`Document Volume`)}</span>
{sortBy === 'signingVolume' ? (
sortOrder === 'asc' ? (
<ChevronUpIcon className="ml-2 h-4 w-4" />
@ -102,26 +103,7 @@ export const AdminOrganisationOverviewTable = ({
),
accessorKey: 'signingVolume',
cell: ({ row }) => <div>{Number(row.getValue('signingVolume'))}</div>,
size: 120,
},
{
header: () => {
return <div>{_(msg`Status`)}</div>;
},
accessorKey: 'subscriptionStatus',
cell: ({ row }) => {
const status = row.original.subscriptionStatus;
return (
<div
className={`inline-flex items-center rounded-full px-2 py-1 text-xs font-medium ${
status ? 'bg-green-100 text-green-800' : 'bg-gray-100 text-gray-800'
}`}
>
{status || 'Free'}
</div>
);
},
size: 100,
size: 160,
},
{
header: () => {
@ -129,7 +111,7 @@ export const AdminOrganisationOverviewTable = ({
},
accessorKey: 'teamCount',
cell: ({ row }) => <div>{Number(row.original.teamCount) || 0}</div>,
size: 80,
size: 120,
},
{
header: () => {
@ -137,7 +119,7 @@ export const AdminOrganisationOverviewTable = ({
},
accessorKey: 'memberCount',
cell: ({ row }) => <div>{Number(row.original.memberCount) || 0}</div>,
size: 80,
size: 160,
},
{
header: () => {
@ -146,7 +128,7 @@ export const AdminOrganisationOverviewTable = ({
className="flex cursor-pointer items-center"
onClick={() => handleColumnSort('createdAt')}
>
{_(msg`Created`)}
<span className="whitespace-nowrap">{_(msg`Created`)}</span>
{sortBy === 'createdAt' ? (
sortOrder === 'asc' ? (
<ChevronUpIcon className="ml-2 h-4 w-4" />
@ -160,7 +142,7 @@ export const AdminOrganisationOverviewTable = ({
);
},
accessorKey: 'createdAt',
cell: ({ row }) => i18n.date(row.original.createdAt),
cell: ({ row }) => i18n.date(new Date(row.original.createdAt)),
size: 120,
},
] satisfies DataTableColumnDef<OrganisationOverview>[];

View File

@ -93,7 +93,8 @@ export const AdminOrganisationsTable = ({
),
},
{
header: t`Status`,
id: 'role',
header: t`Role`,
cell: ({ row }) => (
<Badge variant="neutral">
{row.original.owner.id === memberUserId ? t`Owner` : t`Member`}
@ -101,6 +102,7 @@ export const AdminOrganisationsTable = ({
),
},
{
id: 'billingStatus',
header: t`Status`,
cell: ({ row }) => {
const subscription = row.original.subscription;
@ -111,7 +113,7 @@ export const AdminOrganisationsTable = ({
isPaid ? 'bg-green-100 text-green-800' : 'bg-gray-100 text-gray-800'
}`}
>
{isPaid ? 'Paid' : 'Free'}
{isPaid ? t`Paid` : t`Free`}
</div>
);
},
@ -184,7 +186,7 @@ export const AdminOrganisationsTable = ({
onPaginationChange={onPaginationChange}
columnVisibility={{
owner: showOwnerColumn,
status: memberUserId !== undefined,
role: memberUserId !== undefined,
}}
error={{
enable: isLoadingError,

View File

@ -6,18 +6,21 @@ import { Archive, Building2, Loader, TrendingUp, Users } from 'lucide-react';
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: string;
dateRange: DateRange;
view: 'teams' | 'users' | 'documents';
};
@ -54,82 +57,104 @@ export const OrganisationInsightsTable = ({
{
header: _(msg`Team Name`),
accessorKey: 'name',
cell: ({ row }) => row.getValue('name'),
cell: ({ row }) => <span className="block max-w-full truncate">{row.getValue('name')}</span>,
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(row.getValue('createdAt')),
cell: ({ row }) => i18n.date(new Date(row.getValue('createdAt'))),
size: 160,
},
] satisfies DataTableColumnDef<(typeof insights.teams)[number]>[];
const usersColumns = [
{
header: _(msg`Name`),
header: () => <span className="whitespace-nowrap">{_(msg`Name`)}</span>,
accessorKey: 'name',
cell: ({ row }) => row.getValue('name') || row.getValue('email'),
cell: ({ row }) => (
<span className="block max-w-full truncate">
{(row.getValue('name') as string) || (row.getValue('email') as string)}
</span>
),
size: 220,
},
{
header: _(msg`Email`),
header: () => <span className="whitespace-nowrap">{_(msg`Email`)}</span>,
accessorKey: 'email',
cell: ({ row }) => row.getValue('email'),
cell: ({ row }) => <span className="block max-w-full truncate">{row.getValue('email')}</span>,
size: 260,
},
{
header: _(msg`Documents Created`),
header: () => <span className="whitespace-nowrap">{_(msg`Documents Created`)}</span>,
accessorKey: 'documentCount',
cell: ({ row }) => Number(row.getValue('documentCount')),
size: 180,
},
{
header: _(msg`Documents Signed`),
header: () => <span className="whitespace-nowrap">{_(msg`Documents Signed`)}</span>,
accessorKey: 'signedDocumentCount',
cell: ({ row }) => Number(row.getValue('signedDocumentCount')),
size: 180,
},
{
header: _(msg`Joined`),
header: () => <span className="whitespace-nowrap">{_(msg`Joined`)}</span>,
accessorKey: 'createdAt',
cell: ({ row }) => i18n.date(row.getValue('createdAt')),
cell: ({ row }) => i18n.date(new Date(row.getValue('createdAt'))),
size: 160,
},
] satisfies DataTableColumnDef<(typeof insights.users)[number]>[];
const documentsColumns = [
{
header: _(msg`Title`),
header: () => <span className="whitespace-nowrap">{_(msg`Title`)}</span>,
accessorKey: 'title',
cell: ({ row }) => row.getValue('title'),
cell: ({ row }) => <span className="block max-w-full truncate">{row.getValue('title')}</span>,
size: 240,
},
{
header: _(msg`Status`),
header: () => <span className="whitespace-nowrap">{_(msg`Status`)}</span>,
accessorKey: 'status',
cell: ({ row }) => row.getValue('status'),
cell: ({ row }) => (
<DocumentStatus status={row.getValue('status') as ExtendedDocumentStatus} />
),
size: 140,
},
{
header: _(msg`Team`),
header: () => <span className="whitespace-nowrap">{_(msg`Team`)}</span>,
accessorKey: 'teamName',
cell: ({ row }) => row.getValue('teamName'),
cell: ({ row }) => (
<span className="block max-w-full truncate">{row.getValue('teamName')}</span>
),
size: 180,
},
{
header: _(msg`Created`),
header: () => <span className="whitespace-nowrap">{_(msg`Created`)}</span>,
accessorKey: 'createdAt',
cell: ({ row }) => i18n.date(row.getValue('createdAt')),
cell: ({ row }) => i18n.date(new Date(row.getValue('createdAt'))),
size: 160,
},
{
header: _(msg`Completed`),
header: () => <span className="whitespace-nowrap">{_(msg`Completed`)}</span>,
accessorKey: 'completedAt',
cell: ({ row }) => {
const completedAt = row.getValue('completedAt') as Date | null;
return completedAt ? i18n.date(completedAt) : '-';
return completedAt ? i18n.date(new Date(completedAt)) : '-';
},
size: 160,
},
] satisfies DataTableColumnDef<(typeof insights.documents)[number]>[];