2024-05-29
In this blog we will be displaying the user details in a table for the user and admin to see. We will continue from the Accept Invitation blog .
Blog post by MF Mabala
Displaying user details in a shadcn DataTable
We have done a lot in our previous blog and we will be continuing from the blog and we will add a data-table to display the invitation details for the user. To understand what we will be doing please visit my previous blog on : https://madinku.dev/post/accepting-an-invitation-with-a-graphql-mutation
Also familiarize yourself with the shadcn data-table on the link: https://ui.shadcn.com/docs/components/data-table. We will be adding the data-table in the invitation.tsx. At the moment the file looks like this.
import { useInvitationQuery } from '@gen/graphql';
export function useInvitation() {
const { loading, data, refetch } = useInvitationQuery({
variables: {
id: '',
},
});
return {
data,
loading,
refetch,
};
}
If you go to the link I showed above you will have a better understand of what I will be doing. Let us start by adding the columns that will be displayed on the table.
import { useInvitationQuery } from '@gen/graphql';
import {
ColumnDef,
ColumnFiltersState,
SortingState,
VisibilityState,
getCoreRowModel,
getFacetedRowModel,
getFacetedUniqueValues,
getFilteredRowModel,
getPaginationRowModel,
getSortedRowModel,
useReactTable,
} from '@tanstack/react-table';
const columns: ColumnDef<AcceptInvitation>[] = [
{
id: 'select',
enableSorting: false,
enableHiding: false,
},
{
accessorKey: 'email',
header: ({ column }) => <DataTableColumnHeader column={column} title="Email" />,
enableSorting: true,
enableHiding: false,
},
{
accessorKey: 'firstName',
header: ({ column }) => <DataTableColumnHeader column={column} title="First name" />,
enableSorting: true,
enableHiding: false,
},
{
accessorKey: 'lastName',
header: ({ column }) => <DataTableColumnHeader column={column} title="Last name" />,
enableSorting: true,
enableHiding: false,
},
{
accessorKey: 'role',
header: ({ column }) => <DataTableColumnHeader column={column} title="Role" />,
},
{
accessorKey: 'status',
header: ({ column }) => <DataTableColumnHeader column={column} title="Status" />,
enableHiding: false,
},
];
export const acceptInvitationSchema = z.object({
id: z.string(),
firstName: z.string().optional().nullable(),
lastName: z.string().optional().nullable(),
status: z.nativeEnum(InvitationStatus),
email: z.string().email(),
});
export type AcceptInvitation = z.infer<typeof acceptInvitationSchema>;
export function useInvitation() {
const { loading, data, refetch } = useInvitationQuery({
variables: {
id: '',
},
});
return {
data,
loading,
refetch,
};
}
After you add the columns you would like to show on your table you have to add functionality to your table. You can add a feature for sorting, you can add column filters and visibilities. Below Are all the things I want to add.
import { useInvitationQuery } from '@gen/graphql';
import {
ColumnDef,
ColumnFiltersState,
SortingState,
VisibilityState,
getCoreRowModel,
getFacetedRowModel,
getFacetedUniqueValues,
getFilteredRowModel,
getPaginationRowModel,
getSortedRowModel,
useReactTable,
} from '@tanstack/react-table';
import { DataTableColumnHeader } from '~/components/ui';
import { DataTableRowActions } from '~/users/components';
const columns: ColumnDef<AcceptInvitation>[] = [
{
id: 'select',
enableSorting: false,
enableHiding: false,
},
{
accessorKey: 'email',
header: ({ column }) => <DataTableColumnHeader column={column} title="Email" />,
enableSorting: true,
enableHiding: false,
},
{
accessorKey: 'firstName',
header: ({ column }) => <DataTableColumnHeader column={column} title="First name" />,
enableSorting: true,
enableHiding: false,
},
{
accessorKey: 'lastName',
header: ({ column }) => <DataTableColumnHeader column={column} title="Last name" />,
enableSorting: true,
enableHiding: false,
},
{
accessorKey: 'role',
header: ({ column }) => <DataTableColumnHeader column={column} title="Role" />,
},
{
accessorKey: 'status',
header: ({ column }) => <DataTableColumnHeader column={column} title="Status" />,
enableHiding: false,
},
];
export const acceptInvitationSchema = z.object({
id: z.string(),
firstName: z.string().optional().nullable(),
lastName: z.string().optional().nullable(),
status: z.nativeEnum(InvitationStatus),
email: z.string().email(),
});
export type AcceptInvitation = z.infer<typeof acceptInvitationSchema>;
export function useInvitation() {
const [rowSelection, setRowSelection] = useState({});
const [columnVisibility, setColumnVisibility] =
useState<VisibilityState>({});
const [columnFilters, setColumnFilters] =
useState<ColumnFiltersState>([]);
const [sorting, setSorting] = useState<SortingState>([]);
const { loading, data, refetch } = useInvitationQuery({
variables: {
id: '',
},
});
const table = useReactTable({
data: data?.invitation || [],
columns,
state: {
sorting,
columnVisibility,
rowSelection,
columnFilters,
},
enableRowSelection: true,
onRowSelectionChange: setRowSelection,
onSortingChange: setSorting,
onColumnFiltersChange: setColumnFilters,
onColumnVisibilityChange: setColumnVisibility,
getCoreRowModel: getCoreRowModel(),
getFilteredRowModel: getFilteredRowModel(),
getPaginationRowModel: getPaginationRowModel(),
getSortedRowModel: getSortedRowModel(),
getFacetedRowModel: getFacetedRowModel(),
getFacetedUniqueValues: getFacetedUniqueValues(),
});
return {
table,
columns,
data,
loading,
refetch,
};
}
Please make sure you have the correct imports . For your table to be visible you have to return the table and columns . Now that we have our table we have to add it to our page that is rendered .
import { AcceptInvite} from '~/users/components';
import { useInvitation } from '~/users/hooks';
export function InvitationPage() {
const { data, loading, data, columns} = useInvitation();
console.log({ invitation, loading });
return (
<div>
{ Loading? !data:<Loader> <AcceptInvite type={'Member'} {...data.?invitation} }
</div>
<DataTable table={table} columns={columns} />
);
}
The table should look something like