Advertisement
Guest User

Untitled

a guest
Jan 18th, 2024
177
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. 'use client';
  2.  
  3. import React from "react";
  4. import {
  5.   Table,
  6.   TableHeader,
  7.   TableColumn,
  8.   TableBody,
  9.   TableRow,
  10.   TableCell,
  11.   Input,
  12.   Button,
  13.   DropdownTrigger,
  14.   Dropdown,
  15.   DropdownMenu,
  16.   DropdownItem,
  17.   Chip,
  18.   User,
  19.   Pagination,
  20.   Selection,
  21.   ChipProps,
  22.   SortDescriptor
  23. } from "@nextui-org/react";
  24. import {PlusIcon} from "./PlusIcon";
  25. import {VerticalDotsIcon} from "./VerticalDotsIcon";
  26. import {ChevronDownIcon} from "./ChevronDownIcon";
  27. import {SearchIcon} from "./SearchIcon";
  28. import {columns, Rule, statusOptions} from "../../lib/definitions";
  29. import {capitalize} from "./utils";
  30. import { Key } from "@react-types/shared";
  31.  
  32. const statusColorMap: Record<string, ChipProps["color"]> = {
  33.   active: "success",
  34.   paused: "danger",
  35.   vacation: "warning",
  36. };
  37.  
  38. const INITIAL_VISIBLE_COLUMNS = ["all"];
  39.  
  40. export default function RulesTable({rules}: {rules: Rule[];}) {
  41.   const [filterValue, setFilterValue] = React.useState("");
  42.   const [selectedKeys, setSelectedKeys] = React.useState<Selection>(new Set([]));
  43.   const [visibleColumns, setVisibleColumns] = React.useState<Selection>(new Set(INITIAL_VISIBLE_COLUMNS));
  44.   const [statusFilter, setStatusFilter] = React.useState<Selection>("all");
  45.   const [rowsPerPage, setRowsPerPage] = React.useState(5);
  46.   const [sortDescriptor, setSortDescriptor] = React.useState<SortDescriptor>({
  47.     column: "name",
  48.     direction: "ascending",
  49.   });
  50.  
  51.   const [page, setPage] = React.useState(1);
  52.  
  53.   const hasSearchFilter = Boolean(filterValue);
  54.  
  55.   const headerColumns = React.useMemo(() => {
  56.     if (visibleColumns === "all") return columns;
  57.  
  58.     return columns.filter((column: { uid: Key; }) => Array.from(visibleColumns).includes(column.uid));
  59.   }, [visibleColumns]);
  60.  
  61.   const filteredItems = React.useMemo(() => {
  62.     //let filteredUsers = [...users];
  63.     let filteredRules = [...rules];
  64.  
  65.     if (hasSearchFilter) {
  66.       filteredRules = filteredRules.filter((rule) =>
  67.         rule.name.toLowerCase().includes(filterValue.toLowerCase()),
  68.       );
  69.     }
  70.     if (statusFilter !== "all" && Array.from(statusFilter).length !== statusOptions.length) {
  71.       filteredRules = filteredRules.filter((rule) =>
  72.         Array.from(statusFilter).includes(rule.status),
  73.       );
  74.     }
  75.  
  76.     return filteredRules;
  77.   }, [rules, hasSearchFilter, statusFilter, filterValue]);
  78.  
  79.   const pages = Math.ceil(filteredItems.length / rowsPerPage);
  80.  
  81.   const items = React.useMemo(() => {
  82.     const start = (page - 1) * rowsPerPage;
  83.     const end = start + rowsPerPage;
  84.  
  85.     return filteredItems.slice(start, end);
  86.   }, [page, filteredItems, rowsPerPage]);
  87.  
  88.   const sortedItems = React.useMemo(() => {
  89.     return [...items].sort((a: Rule, b: Rule) => {
  90.       const first = a[sortDescriptor.column as keyof Rule] as string;
  91.       const second = b[sortDescriptor.column as keyof Rule] as string;
  92.       const cmp = first < second ? -1 : first > second ? 1 : 0;
  93.       return sortDescriptor.direction === "descending" ? -cmp : cmp;
  94.     });
  95.   }, [sortDescriptor, items]);
  96.  
  97.   const renderCell = React.useCallback((rule: Rule, columnKey: React.Key) => {
  98.     const cellValue = rule[columnKey as keyof Rule];
  99.     console.log(rule)
  100.     return cellValue;
  101.   }, []);
  102.  
  103.   const onNextPage = React.useCallback(() => {
  104.     if (page < pages) {
  105.       setPage(page + 1);
  106.     }
  107.   }, [page, pages]);
  108.  
  109.   const onPreviousPage = React.useCallback(() => {
  110.     if (page > 1) {
  111.       setPage(page - 1);
  112.     }
  113.   }, [page]);
  114.  
  115.   const onRowsPerPageChange = React.useCallback((e: React.ChangeEvent<HTMLSelectElement>) => {
  116.     setRowsPerPage(Number(e.target.value));
  117.     setPage(1);
  118.   }, []);
  119.  
  120.   const onSearchChange = React.useCallback((value?: string) => {
  121.     if (value) {
  122.       setFilterValue(value);
  123.       setPage(1);
  124.     } else {
  125.       setFilterValue("");
  126.     }
  127.   }, []);
  128.  
  129.   const onClear = React.useCallback(()=>{
  130.     setFilterValue("")
  131.     setPage(1)
  132.   },[])
  133.  
  134.   const topContent = React.useMemo(() => {
  135.     return (
  136.       <div className="flex flex-col gap-4">
  137.         <div className="flex justify-between gap-3 items-end">
  138.           <Input
  139.             isClearable
  140.             className="w-full sm:max-w-[44%]"
  141.             placeholder="Search by name..."
  142.             startContent={<SearchIcon />}
  143.             value={filterValue}
  144.             onClear={() => onClear()}
  145.             onValueChange={onSearchChange}
  146.           />
  147.           <div className="flex gap-3">
  148.             <Dropdown>
  149.               <DropdownTrigger className="hidden sm:flex">
  150.                 <Button endContent={<ChevronDownIcon className="text-small" />} variant="flat">
  151.                   Status
  152.                 </Button>
  153.               </DropdownTrigger>
  154.               <DropdownMenu
  155.                 disallowEmptySelection
  156.                 aria-label="Table Columns"
  157.                 closeOnSelect={false}
  158.                 selectedKeys={statusFilter}
  159.                 selectionMode="multiple"
  160.                 onSelectionChange={setStatusFilter}
  161.               >
  162.                 {statusOptions.map((status) => (
  163.                   <DropdownItem key={status.uid} className="capitalize">
  164.                     {capitalize(status.name)}
  165.                   </DropdownItem>
  166.                 ))}
  167.               </DropdownMenu>
  168.             </Dropdown>
  169.             <Dropdown>
  170.               <DropdownTrigger className="hidden sm:flex">
  171.                 <Button endContent={<ChevronDownIcon className="text-small" />} variant="flat">
  172.                   Columns
  173.                 </Button>
  174.               </DropdownTrigger>
  175.               <DropdownMenu
  176.                 disallowEmptySelection
  177.                 aria-label="Table Columns"
  178.                 closeOnSelect={false}
  179.                 selectedKeys={visibleColumns}
  180.                 selectionMode="multiple"
  181.                 onSelectionChange={setVisibleColumns}
  182.               >
  183.                 {columns.map((column) => (
  184.                   <DropdownItem key={column.uid} className="capitalize">
  185.                     {capitalize(column.name)}
  186.                   </DropdownItem>
  187.                 ))}
  188.               </DropdownMenu>
  189.             </Dropdown>
  190.           </div>
  191.         </div>
  192.         <div className="flex justify-between items-center">
  193.           <span className="text-default-400 text-small">Total {rules.length} rules</span>
  194.           <label className="flex items-center text-default-400 text-small">
  195.             Rows per page:
  196.             <select
  197.               className="bg-transparent outline-none text-default-400 text-small"
  198.               onChange={onRowsPerPageChange}
  199.             >
  200.               <option value="5">5</option>
  201.               <option value="10">10</option>
  202.               <option value="15">15</option>
  203.               <option value="15">25</option>
  204.               <option value="15">40</option>
  205.               <option value="15">60</option>
  206.             </select>
  207.           </label>
  208.         </div>
  209.       </div>
  210.     );
  211.   }, [filterValue, onSearchChange, statusFilter, visibleColumns, rules.length, onRowsPerPageChange, onClear]);
  212.  
  213.   const bottomContent = React.useMemo(() => {
  214.     return (
  215.       <div className="py-2 px-2 flex justify-between items-center">
  216.         <Pagination
  217.           isCompact
  218.           showControls
  219.           showShadow
  220.           color="primary"
  221.           page={page}
  222.           total={pages}
  223.           onChange={setPage}
  224.         />
  225.         <div className="hidden sm:flex w-[30%] justify-end gap-2">
  226.           <Button isDisabled={pages === 1} size="sm" variant="flat" onPress={onPreviousPage}>
  227.             Previous
  228.           </Button>
  229.           <Button isDisabled={pages === 1} size="sm" variant="flat" onPress={onNextPage}>
  230.             Next
  231.           </Button>
  232.         </div>
  233.       </div>
  234.     );
  235.   }, [page, pages, onPreviousPage, onNextPage]);
  236.  
  237.   console.log(sortedItems)
  238.   return (
  239.     <Table
  240.       aria-label="Example table with custom cells, pagination and sorting"
  241.       isHeaderSticky
  242.       bottomContent={bottomContent}
  243.       bottomContentPlacement="outside"
  244.       classNames={{
  245.         wrapper: "max-h-[382px]",
  246.       }}
  247.       selectedKeys={selectedKeys}
  248.       selectionMode="multiple"
  249.       sortDescriptor={sortDescriptor}
  250.       topContent={topContent}
  251.       topContentPlacement="outside"
  252.       onSelectionChange={setSelectedKeys}
  253.       onSortChange={setSortDescriptor}
  254.     >
  255.       <TableHeader columns={headerColumns}>
  256.         {(column) => (
  257.           <TableColumn
  258.             key={column.uid}
  259.             align={column.uid === "actions" ? "center" : "start"}
  260.             allowsSorting={column.sortable}
  261.           >
  262.             {column.name}
  263.           </TableColumn>
  264.         )}
  265.       </TableHeader>
  266.       <TableBody emptyContent={"No users found"} items={sortedItems}>
  267.         {(item) => (
  268.           <TableRow key={item.id}>
  269.             {(columnKey) => <TableCell>{renderCell(item, columnKey)}</TableCell>}
  270.           </TableRow>
  271.         )}
  272.       </TableBody>
  273.     </Table>
  274.   );
  275. }
  276.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement