import { useUpdateSearchParams } from '@documenso/lib/client-only/hooks/use-update-search-params'; import type { TDocumentAuditLog } from '@documenso/lib/types/document-audit-logs'; import { ZUrlSearchParamsSchema } from '@documenso/lib/types/search-params'; import { formatDocumentAuditLogAction } from '@documenso/lib/utils/document-audit-logs'; import { trpc } from '@documenso/trpc/react'; import { CopyTextButton } from '@documenso/ui/components/common/copy-text-button'; 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 { Dialog, DialogContent, DialogHeader, DialogTitle } from '@documenso/ui/primitives/dialog'; import { Skeleton } from '@documenso/ui/primitives/skeleton'; import { TableCell } from '@documenso/ui/primitives/table'; import { useToast } from '@documenso/ui/primitives/use-toast'; import { msg } from '@lingui/core/macro'; import { useLingui } from '@lingui/react'; import { Trans } from '@lingui/react/macro'; import type { DateTimeFormatOptions } from 'luxon'; import { DateTime } from 'luxon'; import { useMemo, useState } from 'react'; import { useSearchParams } from 'react-router'; import { UAParser } from 'ua-parser-js'; export type AdminDocumentLogsTableProps = { envelopeId: string; }; const dateFormat: DateTimeFormatOptions = { ...DateTime.DATETIME_SHORT, hourCycle: 'h12', }; export const AdminDocumentLogsTable = ({ envelopeId }: AdminDocumentLogsTableProps) => { const { _, i18n } = useLingui(); const { toast } = useToast(); const [searchParams] = useSearchParams(); const updateSearchParams = useUpdateSearchParams(); const [selectedAuditLog, setSelectedAuditLog] = useState(null); const parsedSearchParams = ZUrlSearchParamsSchema.parse(Object.fromEntries(searchParams ?? [])); const { data, isLoading, isLoadingError } = trpc.admin.document.findAuditLogs.useQuery( { envelopeId, page: parsedSearchParams.page, perPage: parsedSearchParams.perPage, }, { placeholderData: (previousData) => previousData, }, ); const onPaginationChange = (page: number, perPage: number) => { updateSearchParams({ page, perPage, }); }; const results = data ?? { data: [], perPage: 10, currentPage: 1, totalPages: 1, }; const columns = useMemo(() => { const parser = new UAParser(); return [ { header: _(msg`Time`), accessorKey: 'createdAt', cell: ({ row }) => i18n.date(row.original.createdAt, dateFormat), }, { header: _(msg`User`), accessorKey: 'name', cell: ({ row }) => row.original.name || row.original.email ? (
{row.original.name && (

{row.original.name}

)} {row.original.email && (

{row.original.email}

)}
) : (

N/A

), }, { header: _(msg`Action`), accessorKey: 'type', cell: ({ row }) => {formatDocumentAuditLogAction(i18n, row.original).description}, }, { header: _(msg`IP Address`), accessorKey: 'ipAddress', }, { header: _(msg`Browser`), cell: ({ row }) => { if (!row.original.userAgent) { return 'N/A'; } parser.setUA(row.original.userAgent); const result = parser.getResult(); return result.browser.name ?? 'N/A'; }, }, { header: '', id: 'actions', cell: ({ row }) => ( ), }, ] satisfies DataTableColumnDef<(typeof results)['data'][number]>[]; }, []); return ( <>
), }} > {(table) => }
setSelectedAuditLog(null)}> Audit Log Details {selectedAuditLog && (
toast({ title: _(msg`Copied to clipboard`) })} />
                {JSON.stringify(selectedAuditLog, null, 2)}
              
)}
); };