import React, {SVGProps} from "react"; import { Table, TableHeader, TableColumn, TableBody, TableRow, TableCell, Input, Button, DropdownTrigger, Dropdown, DropdownMenu, DropdownItem, Chip, User, Pagination, Selection, ChipProps, SortDescriptor, } from "@heroui/react"; export type IconSvgProps = SVGProps & { size?: number; }; export function capitalize(s: string) { return s ? s.charAt(0).toUpperCase() + s.slice(1).toLowerCase() : ""; } export const PlusIcon = ({size = 24, width, height, ...props}: IconSvgProps) => { return ( ); }; export const VerticalDotsIcon = ({size = 24, width, height, ...props}: IconSvgProps) => { return ( ); }; export const SearchIcon = (props: IconSvgProps) => { return ( ); }; export const ChevronDownIcon = ({strokeWidth = 1.5, ...otherProps}: IconSvgProps) => { return ( ); }; export const columns = [ {name: "ID", uid: "id", sortable: true}, {name: "NAME", uid: "name", sortable: true}, {name: "AGE", uid: "age", sortable: true}, {name: "ROLE", uid: "role", sortable: true}, {name: "TEAM", uid: "team"}, {name: "EMAIL", uid: "email"}, {name: "STATUS", uid: "status", sortable: true}, {name: "ACTIONS", uid: "actions"}, ]; export const statusOptions = [ {name: "Active", uid: "active"}, {name: "Paused", uid: "paused"}, {name: "Vacation", uid: "vacation"}, ]; export const users = [ { id: 1, name: "Tony Reichert", role: "CEO", team: "Management", status: "active", age: "29", avatar: "https://i.pravatar.cc/150?u=a042581f4e29026024d", email: "tony.reichert@example.com", }, { id: 2, name: "Zoey Lang", role: "Tech Lead", team: "Development", status: "paused", age: "25", avatar: "https://i.pravatar.cc/150?u=a042581f4e29026704d", email: "zoey.lang@example.com", }, { id: 3, name: "Jane Fisher", role: "Sr. Dev", team: "Development", status: "active", age: "22", avatar: "https://i.pravatar.cc/150?u=a04258114e29026702d", email: "jane.fisher@example.com", }, { id: 4, name: "William Howard", role: "C.M.", team: "Marketing", status: "vacation", age: "28", avatar: "https://i.pravatar.cc/150?u=a048581f4e29026701d", email: "william.howard@example.com", }, { id: 5, name: "Kristen Copper", role: "S. Manager", team: "Sales", status: "active", age: "24", avatar: "https://i.pravatar.cc/150?u=a092581d4ef9026700d", email: "kristen.cooper@example.com", }, { id: 6, name: "Brian Kim", role: "P. Manager", team: "Management", age: "29", avatar: "https://i.pravatar.cc/150?u=a042581f4e29026024d", email: "brian.kim@example.com", status: "Active", }, { id: 7, name: "Michael Hunt", role: "Designer", team: "Design", status: "paused", age: "27", avatar: "https://i.pravatar.cc/150?u=a042581f4e29027007d", email: "michael.hunt@example.com", }, { id: 8, name: "Samantha Brooks", role: "HR Manager", team: "HR", status: "active", age: "31", avatar: "https://i.pravatar.cc/150?u=a042581f4e27027008d", email: "samantha.brooks@example.com", }, { id: 9, name: "Frank Harrison", role: "F. Manager", team: "Finance", status: "vacation", age: "33", avatar: "https://i.pravatar.cc/150?img=4", email: "frank.harrison@example.com", }, { id: 10, name: "Emma Adams", role: "Ops Manager", team: "Operations", status: "active", age: "35", avatar: "https://i.pravatar.cc/150?img=5", email: "emma.adams@example.com", }, { id: 11, name: "Brandon Stevens", role: "Jr. Dev", team: "Development", status: "active", age: "22", avatar: "https://i.pravatar.cc/150?img=8", email: "brandon.stevens@example.com", }, { id: 12, name: "Megan Richards", role: "P. Manager", team: "Product", status: "paused", age: "28", avatar: "https://i.pravatar.cc/150?img=10", email: "megan.richards@example.com", }, { id: 13, name: "Oliver Scott", role: "S. Manager", team: "Security", status: "active", age: "37", avatar: "https://i.pravatar.cc/150?img=12", email: "oliver.scott@example.com", }, { id: 14, name: "Grace Allen", role: "M. Specialist", team: "Marketing", status: "active", age: "30", avatar: "https://i.pravatar.cc/150?img=16", email: "grace.allen@example.com", }, { id: 15, name: "Noah Carter", role: "IT Specialist", team: "I. Technology", status: "paused", age: "31", avatar: "https://i.pravatar.cc/150?img=15", email: "noah.carter@example.com", }, { id: 16, name: "Ava Perez", role: "Manager", team: "Sales", status: "active", age: "29", avatar: "https://i.pravatar.cc/150?img=20", email: "ava.perez@example.com", }, { id: 17, name: "Liam Johnson", role: "Data Analyst", team: "Analysis", status: "active", age: "28", avatar: "https://i.pravatar.cc/150?img=33", email: "liam.johnson@example.com", }, { id: 18, name: "Sophia Taylor", role: "QA Analyst", team: "Testing", status: "active", age: "27", avatar: "https://i.pravatar.cc/150?img=29", email: "sophia.taylor@example.com", }, { id: 19, name: "Lucas Harris", role: "Administrator", team: "Information Technology", status: "paused", age: "32", avatar: "https://i.pravatar.cc/150?img=50", email: "lucas.harris@example.com", }, { id: 20, name: "Mia Robinson", role: "Coordinator", team: "Operations", status: "active", age: "26", avatar: "https://i.pravatar.cc/150?img=45", email: "mia.robinson@example.com", }, ]; const statusColorMap: Record = { active: "success", paused: "danger", vacation: "warning", }; const INITIAL_VISIBLE_COLUMNS = ["name", "role", "status", "actions"]; type User = (typeof users)[0]; export default function App() { const [filterValue, setFilterValue] = React.useState(""); const [selectedKeys, setSelectedKeys] = React.useState(new Set([])); const [visibleColumns, setVisibleColumns] = React.useState( new Set(INITIAL_VISIBLE_COLUMNS), ); const [statusFilter, setStatusFilter] = React.useState("all"); const [rowsPerPage, setRowsPerPage] = React.useState(5); const [sortDescriptor, setSortDescriptor] = React.useState({ column: "age", direction: "ascending", }); const [page, setPage] = React.useState(1); const hasSearchFilter = Boolean(filterValue); const headerColumns = React.useMemo(() => { if (visibleColumns === "all") return columns; return columns.filter((column) => Array.from(visibleColumns).includes(column.uid)); }, [visibleColumns]); const filteredItems = React.useMemo(() => { let filteredUsers = [...users]; if (hasSearchFilter) { filteredUsers = filteredUsers.filter((user) => user.name.toLowerCase().includes(filterValue.toLowerCase()), ); } if (statusFilter !== "all" && Array.from(statusFilter).length !== statusOptions.length) { filteredUsers = filteredUsers.filter((user) => Array.from(statusFilter).includes(user.status), ); } return filteredUsers; }, [users, filterValue, statusFilter]); const pages = Math.ceil(filteredItems.length / rowsPerPage) || 1; const items = React.useMemo(() => { const start = (page - 1) * rowsPerPage; const end = start + rowsPerPage; return filteredItems.slice(start, end); }, [page, filteredItems, rowsPerPage]); const sortedItems = React.useMemo(() => { return [...items].sort((a: User, b: User) => { const first = a[sortDescriptor.column as keyof User] as number; const second = b[sortDescriptor.column as keyof User] as number; const cmp = first < second ? -1 : first > second ? 1 : 0; return sortDescriptor.direction === "descending" ? -cmp : cmp; }); }, [sortDescriptor, items]); const renderCell = React.useCallback((user: User, columnKey: React.Key) => { const cellValue = user[columnKey as keyof User]; switch (columnKey) { case "name": return ( {user.email} ); case "role": return (

{cellValue}

{user.team}

); case "status": return ( {cellValue} ); case "actions": return (
View Edit Delete
); default: return cellValue; } }, []); const onNextPage = React.useCallback(() => { if (page < pages) { setPage(page + 1); } }, [page, pages]); const onPreviousPage = React.useCallback(() => { if (page > 1) { setPage(page - 1); } }, [page]); const onRowsPerPageChange = React.useCallback((e: React.ChangeEvent) => { setRowsPerPage(Number(e.target.value)); setPage(1); }, []); const onSearchChange = React.useCallback((value?: string) => { if (value) { setFilterValue(value); setPage(1); } else { setFilterValue(""); } }, []); const onClear = React.useCallback(() => { setFilterValue(""); setPage(1); }, []); const topContent = React.useMemo(() => { return (
} value={filterValue} onClear={() => onClear()} onValueChange={onSearchChange} />
{statusOptions.map((status) => ( {capitalize(status.name)} ))} {columns.map((column) => ( {capitalize(column.name)} ))}
Total {users.length} users
); }, [ filterValue, statusFilter, visibleColumns, onSearchChange, onRowsPerPageChange, users.length, hasSearchFilter, ]); const bottomContent = React.useMemo(() => { return (
{selectedKeys === "all" ? "All items selected" : `${selectedKeys.size} of ${filteredItems.length} selected`}
); }, [selectedKeys, items.length, page, pages, hasSearchFilter]); return ( {(column) => ( {column.name} )} {(item) => ( {(columnKey) => {renderCell(item, columnKey)}} )}
); }