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

Thank you for reading my blog.