'use client'; import { AlignCommandIcon as IconCmd } from '@/components/misc/alignui-icons'; import * as React from 'react'; import { ChevronDown, Filter, MoreHorizontal, Search, ArrowUpDown, } from 'lucide-react'; import { flexRender, getCoreRowModel, getSortedRowModel, useReactTable, type ColumnDef, type SortingState, } from '@tanstack/react-table'; import * as AvatarGroup from '@/components/ui/avatar-group'; import * as Avatar from '@/components/ui/avatar'; import * as Button from '@/components/ui/button'; import * as Checkbox from '@/components/ui/checkbox'; import * as Input from '@/components/ui/input'; import * as Kbd from '@/components/ui/kbd'; import * as ProgressBar from '@/components/ui/progress-bar'; import * as SegmentedControl from '@/components/ui/segmented-control'; import * as Table from '@/components/ui/table'; type Data = { id: string; company: { name: string; category: string; logo: string; }; description: string; teamMembers: { avatars: string[]; count?: number; }; deadline: string; progress: number; }; const data: Data[] = [ { id: '1', company: { name: 'Spotify', category: 'Music & Podcast', logo: 'https://alignui.com/images/major-brands/spotify.svg', }, description: 'Spotify mobile app UX enhancements and rebranding project.', teamMembers: { avatars: [ 'https://alignui.com/images/avatar/illustration/james.png', 'https://alignui.com/images/avatar/illustration/sophia.png', 'https://alignui.com/images/avatar/illustration/arthur.png', 'https://alignui.com/images/avatar/illustration/emma.png', ], count: 9, }, deadline: '29/09/2023', progress: 100, }, { id: '2', company: { name: 'Opensea', category: 'NFT Marketplace', logo: 'https://alignui.com/images/major-brands/opensea.svg', }, description: 'Mobile & Desktop App Design', teamMembers: { avatars: [ 'https://alignui.com/images/avatar/illustration/james.png', 'https://alignui.com/images/avatar/illustration/sophia.png', 'https://alignui.com/images/avatar/illustration/arthur.png', 'https://alignui.com/images/avatar/illustration/emma.png', ], count: 4, }, deadline: '02/11/2023', progress: 60, }, { id: '3', company: { name: 'Zoom', category: 'Video Conferencing', logo: 'https://alignui.com/images/major-brands/zoom.svg', }, description: 'Integration of advanced security features.', teamMembers: { avatars: [ 'https://alignui.com/images/avatar/illustration/james.png', 'https://alignui.com/images/avatar/illustration/sophia.png', 'https://alignui.com/images/avatar/illustration/arthur.png', 'https://alignui.com/images/avatar/illustration/emma.png', ], count: 3, }, deadline: '20/11/2023', progress: 45, }, { id: '4', company: { name: 'Notion', category: 'Note-Taking and Organization', logo: 'https://alignui.com/images/major-brands/notion.svg', }, description: 'Redesign of user interface and addition of new features.', teamMembers: { avatars: [ 'https://alignui.com/images/avatar/illustration/james.png', 'https://alignui.com/images/avatar/illustration/sophia.png', 'https://alignui.com/images/avatar/illustration/arthur.png', 'https://alignui.com/images/avatar/illustration/emma.png', ], count: 1, }, deadline: '05/01/2024', progress: 30, }, { id: '5', company: { name: 'Skype', category: 'Video & Voice Communication', logo: 'https://alignui.com/images/major-brands/skype.svg', }, description: 'Migration to a new infrastructure for improved performance.', teamMembers: { avatars: [ 'https://alignui.com/images/avatar/illustration/james.png', 'https://alignui.com/images/avatar/illustration/sophia.png', 'https://alignui.com/images/avatar/illustration/arthur.png', 'https://alignui.com/images/avatar/illustration/emma.png', ], count: 6, }, deadline: '20/03/2024', progress: 10, }, { id: '6', company: { name: 'Slack', category: 'Team Collaboration', logo: 'https://alignui.com/images/major-brands/slack.svg', }, description: 'Integration with third-party productivity tools.', teamMembers: { avatars: [ 'https://alignui.com/images/avatar/illustration/james.png', 'https://alignui.com/images/avatar/illustration/sophia.png', 'https://alignui.com/images/avatar/illustration/arthur.png', 'https://alignui.com/images/avatar/illustration/emma.png', ], count: 2, }, deadline: '15/06/2024', progress: 5, }, ]; const columns: ColumnDef[] = [ { id: 'select', header: ({ table }) => ( table.toggleAllPageRowsSelected(!!value)} aria-label='Select all' /> ), cell: () => ( row.toggleSelected(!!value)} aria-label='Select row' /> ), }, { id: 'company', accessorKey: 'company.name', header: ({ column }) => ( column.toggleSorting(column.getIsSorted() === 'asc')} > Company Name ), cell: () => (
{row.original.company.name} {row.original.company.category}
), }, { id: 'description', accessorKey: 'description', header: ({ column }) => ( column.toggleSorting(column.getIsSorted() === 'asc')} > Description ), cell: () => ( {row.original.description} ), }, { id: 'teamMembers', accessorKey: 'teamMembers', header: ({ column }) => ( column.toggleSorting(column.getIsSorted() === 'asc')} > Team Members ), cell: ({ row }) => ( {row.original.teamMembers.avatars.map((avatar, index) => ( ))} {row.original.teamMembers.count && ( +{row.original.teamMembers.count} )} ), }, { id: 'deadline', accessorKey: 'deadline', header: ({ column }) => ( column.toggleSorting(column.getIsSorted() === 'asc')} > Deadline ), cell: ({ row }) => ( {row.original.deadline} ), }, { id: 'progress', accessorKey: 'progress', header: ({ column }) => ( column.toggleSorting(column.getIsSorted() === 'asc')} > Progress ), cell: ({ row }) => (
{row.original.progress}%
), }, { id: 'actions', enableHiding: false, cell: () => ( ), }, ]; export default function TaskProgressTable() { const [sorting, setSorting] = React.useState([]); const [filter, setFilter] = React.useState('all'); const [rowSelection, setRowSelection] = React.useState({}); const filteredData = React.useMemo(() => { if (filter === 'all') return data; return data.filter((item) => { if (filter === 'active') return item.progress > 0 && item.progress < 100; if (filter === 'completed') return item.progress === 100; return true; }); }, [filter]); const table = useReactTable({ data: filteredData, columns, onSortingChange: setSorting, getCoreRowModel: getCoreRowModel(), getSortedRowModel: getSortedRowModel(), onRowSelectionChange: setRowSelection, state: { sorting, rowSelection, }, }); return (
All Ongoing Completed
1
Filter Sort by
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => { const customClass = header.id === 'select' ? 'pr-0' : ''; return ( {header.isPlaceholder ? null : flexRender( header.column.columnDef.header, header.getContext(), )} ); })} ))} {table.getRowModel().rows?.length > 0 && table.getRowModel().rows.map((row, i, arr) => ( {row.getVisibleCells().map((cell) => { const customCellClass = cell.column.id === 'select' ? 'pr-0' : ''; return ( {flexRender( cell.column.columnDef.cell, cell.getContext(), )} ); })} {i < arr.length - 1 && } ))}
); }