'use client'; import * as React from 'react'; import { AlertTriangle, ChevronDown, CheckCircle2, Filter, Ban, MoreHorizontal, Search, ArrowUpDown, } from 'lucide-react'; import { flexRender, getCoreRowModel, getSortedRowModel, useReactTable, type ColumnDef, type SortingState, } from '@tanstack/react-table'; 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 SegmentedControl from '@/components/ui/segmented-control'; import * as StatusBadge from '@/components/ui/status-badge'; import * as Table from '@/components/ui/table'; type PaymentData = { id: string; paymentPreference: { name: string; company: string; logo: string; }; employee: { name: string; position: string; avatar: string; color: 'yellow' | 'blue' | 'sky' | 'purple' | 'red' | 'gray'; }; cardNumber: string; monthlySalary: number; status: 'Paid' | 'Pending' | 'Unpaid'; }; const data: PaymentData[] = [ { id: '1', paymentPreference: { name: 'Visa', company: 'Visa Inc.', logo: 'https://alignui.com/images/banking-and-finance/visa.svg', }, employee: { name: 'Nuray Aksoy', position: 'Product Manager', avatar: 'https://alignui.com/images/avatar/illustration/nuray.png', color: 'red', }, cardNumber: '**** **** **** 1234', monthlySalary: 5550.63, status: 'Paid', }, { id: '2', paymentPreference: { name: 'PayPal', company: 'PayPal Holdings, Inc.', logo: 'https://alignui.com/images/banking-and-finance/paypal.svg', }, employee: { name: 'James Brown', position: 'Marketing Manager', avatar: 'https://alignui.com/images/avatar/illustration/james.png', color: 'gray', }, cardNumber: '**** **** **** 2345', monthlySalary: 4420.35, status: 'Paid', }, { id: '3', paymentPreference: { name: 'Mastercard', company: 'Mastercard Inc.', logo: 'https://alignui.com/images/banking-and-finance/mastercard.svg', }, employee: { name: 'Sophia Williams', position: 'HR Assistant', avatar: 'https://alignui.com/images/avatar/illustration/sophia.png', color: 'yellow', }, cardNumber: '**** **** **** 3456', monthlySalary: 2730.12, status: 'Pending', }, { id: '4', paymentPreference: { name: 'Stripe', company: 'Stripe Inc.', logo: 'https://alignui.com/images/banking-and-finance/stripe.svg', }, employee: { name: 'Emma Wright', position: 'Front-end Developer', avatar: 'https://alignui.com/images/avatar/illustration/emma.png', color: 'sky', }, cardNumber: '**** **** **** 4567', monthlySalary: 3814.22, status: 'Paid', }, { id: '5', paymentPreference: { name: 'Western Union', company: 'Wester Union Inc.', logo: 'https://alignui.com/images/banking-and-finance/western-union.svg', }, employee: { name: 'Matthew Johnson', position: 'Data Software Engineer', avatar: 'https://alignui.com/images/avatar/illustration/matthew.png', color: 'purple', }, cardNumber: '**** **** **** 6780', monthlySalary: 4251.53, status: 'Unpaid', }, { id: '6', paymentPreference: { name: 'Wise', company: 'Wise Group Ltd.', logo: 'https://alignui.com/images/banking-and-finance/wise.svg', }, employee: { name: 'Arthur Taylor', position: 'Entrepreneur', avatar: 'https://alignui.com/images/avatar/illustration/arthur.png', color: 'blue', }, cardNumber: '**** **** **** 5676', monthlySalary: 6441.52, status: 'Pending', }, ]; const getStatusBadge = (status: 'Paid' | 'Pending' | 'Unpaid') => { const statusMap = { Paid: { status: 'completed' as const, icon: CheckCircle2, }, Pending: { status: 'pending' as const, icon: AlertTriangle, }, Unpaid: { status: 'disabled' as const, icon: Ban, }, } satisfies Record< string, { status: 'disabled' | 'completed' | 'pending' | 'failed'; icon: React.ComponentType<{ className?: string }>; } >; const config = statusMap[status]; return ( {status} ); }; export default function EmployeePaymentsTable() { 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) => item.status.toLowerCase() === filter); }, [filter]); const columns: ColumnDef[] = [ { id: 'select', header: ({ table }) => ( table.toggleAllPageRowsSelected(!!value)} aria-label='Select all' /> ), cell: ({ row }) => ( row.toggleSelected(!!value)} aria-label='Select row' /> ), }, { id: 'paymentPreference', accessorKey: 'paymentPreference.name', header: ({ column }) => ( column.toggleSorting(column.getIsSorted() === 'asc')} > Payment Preference ), cell: ({ row }) => ( {row.original.paymentPreference.name} {row.original.paymentPreference.company} ), }, { id: 'employee', accessorKey: 'employee.name', header: ({ column }) => ( column.toggleSorting(column.getIsSorted() === 'asc')} > Employee Name ), cell: ({ row }) => ( {row.original.employee.name} {row.original.employee.position} ), }, { id: 'cardNumber', accessorKey: 'cardNumber', header: ({ column }) => ( column.toggleSorting(column.getIsSorted() === 'asc')} > Card Number ), cell: ({ row }) => ( {row.original.cardNumber} ), }, { id: 'monthlySalary', accessorKey: 'monthlySalary', header: ({ column }) => ( column.toggleSorting(column.getIsSorted() === 'asc')} > Monthly Salary ), cell: ({ row }) => ( $ {row.original.monthlySalary.toLocaleString('en-US', { minimumFractionDigits: 2, })} ), }, { id: 'status', accessorKey: 'status', header: ({ column }) => ( column.toggleSorting(column.getIsSorted() === 'asc')} > Status ), cell: ({ row }) => getStatusBadge(row.original.status), }, { id: 'actions', cell: () => ( ), }, ]; const table = useReactTable({ data: filteredData, columns, onSortingChange: setSorting, getCoreRowModel: getCoreRowModel(), getSortedRowModel: getSortedRowModel(), onRowSelectionChange: setRowSelection, state: { sorting, rowSelection, }, }); return ( All Paid Unpaid ⌘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 && } ))} ); }