users-columns.tsx 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. import { ColumnDef } from '@tanstack/react-table'
  2. import { cn } from '@/lib/utils'
  3. import { Badge } from '@/components/ui/badge'
  4. import { Checkbox } from '@/components/ui/checkbox'
  5. import LongText from '@/components/long-text'
  6. import { callTypes, userTypes } from '../data/data'
  7. import { User } from '../data/schema'
  8. import { DataTableColumnHeader } from './data-table-column-header'
  9. import { DataTableRowActions } from './data-table-row-actions'
  10. export const columns: ColumnDef<User>[] = [
  11. {
  12. id: 'select',
  13. header: ({ table }) => (
  14. <Checkbox
  15. checked={
  16. table.getIsAllPageRowsSelected() ||
  17. (table.getIsSomePageRowsSelected() && 'indeterminate')
  18. }
  19. onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}
  20. aria-label='Select all'
  21. className='translate-y-[2px]'
  22. />
  23. ),
  24. meta: {
  25. className: cn(
  26. 'sticky md:table-cell start-0 z-10 rounded-tl',
  27. 'bg-background group-hover/row:bg-muted group-data-[state=selected]/row:bg-muted'
  28. ),
  29. },
  30. cell: ({ row }) => (
  31. <Checkbox
  32. checked={row.getIsSelected()}
  33. onCheckedChange={(value) => row.toggleSelected(!!value)}
  34. aria-label='Select row'
  35. className='translate-y-[2px]'
  36. />
  37. ),
  38. enableSorting: false,
  39. enableHiding: false,
  40. },
  41. {
  42. accessorKey: 'username',
  43. header: ({ column }) => (
  44. <DataTableColumnHeader column={column} title='Username' />
  45. ),
  46. cell: ({ row }) => (
  47. <LongText className='max-w-36'>{row.getValue('username')}</LongText>
  48. ),
  49. meta: {
  50. className: cn(
  51. 'drop-shadow-[0_1px_2px_rgb(0_0_0_/_0.1)] dark:drop-shadow-[0_1px_2px_rgb(255_255_255_/_0.1)] lg:drop-shadow-none',
  52. 'bg-background group-hover/row:bg-muted group-data-[state=selected]/row:bg-muted',
  53. 'sticky start-6 md:table-cell'
  54. ),
  55. },
  56. enableHiding: false,
  57. },
  58. {
  59. id: 'fullName',
  60. header: ({ column }) => (
  61. <DataTableColumnHeader column={column} title='Name' />
  62. ),
  63. cell: ({ row }) => {
  64. const { firstName, lastName } = row.original
  65. const fullName = `${firstName} ${lastName}`
  66. return <LongText className='max-w-36'>{fullName}</LongText>
  67. },
  68. meta: { className: 'w-36' },
  69. },
  70. {
  71. accessorKey: 'email',
  72. header: ({ column }) => (
  73. <DataTableColumnHeader column={column} title='Email' />
  74. ),
  75. cell: ({ row }) => (
  76. <div className='w-fit text-nowrap'>{row.getValue('email')}</div>
  77. ),
  78. },
  79. {
  80. accessorKey: 'phoneNumber',
  81. header: ({ column }) => (
  82. <DataTableColumnHeader column={column} title='Phone Number' />
  83. ),
  84. cell: ({ row }) => <div>{row.getValue('phoneNumber')}</div>,
  85. enableSorting: false,
  86. },
  87. {
  88. accessorKey: 'status',
  89. header: ({ column }) => (
  90. <DataTableColumnHeader column={column} title='Status' />
  91. ),
  92. cell: ({ row }) => {
  93. const { status } = row.original
  94. const badgeColor = callTypes.get(status)
  95. return (
  96. <div className='flex space-x-2'>
  97. <Badge variant='outline' className={cn('capitalize', badgeColor)}>
  98. {row.getValue('status')}
  99. </Badge>
  100. </div>
  101. )
  102. },
  103. filterFn: (row, id, value) => {
  104. return value.includes(row.getValue(id))
  105. },
  106. enableHiding: false,
  107. enableSorting: false,
  108. },
  109. {
  110. accessorKey: 'role',
  111. header: ({ column }) => (
  112. <DataTableColumnHeader column={column} title='Role' />
  113. ),
  114. cell: ({ row }) => {
  115. const { role } = row.original
  116. const userType = userTypes.find(({ value }) => value === role)
  117. if (!userType) {
  118. return null
  119. }
  120. return (
  121. <div className='flex items-center gap-x-2'>
  122. {userType.icon && (
  123. <userType.icon size={16} className='text-muted-foreground' />
  124. )}
  125. <span className='text-sm capitalize'>{row.getValue('role')}</span>
  126. </div>
  127. )
  128. },
  129. filterFn: (row, id, value) => {
  130. return value.includes(row.getValue(id))
  131. },
  132. enableSorting: false,
  133. enableHiding: false,
  134. },
  135. {
  136. id: 'actions',
  137. cell: DataTableRowActions,
  138. },
  139. ]