From 907c9e7a480da85ccca3a2c8469f58ad881ceddd Mon Sep 17 00:00:00 2001 From: Ravindu Hasanka Date: Wed, 17 Jul 2024 02:10:20 +0530 Subject: [PATCH 1/4] feat:table started --- src/App.tsx | 10 + .../FoodList/ChevronDownIcon.tsx | 24 ++ src/pages/BranchManager/FoodList/PlusIcon.tsx | 26 ++ .../BranchManager/FoodList/SearchIcon.tsx | 30 ++ .../FoodList/VerticalDotsIcon.tsx | 20 ++ src/pages/BranchManager/FoodList/data.tsx | 222 ++++++++++++ src/pages/BranchManager/FoodList/index.tsx | 329 ++++++++++++++++++ src/pages/BranchManager/FoodList/types.tsx | 5 + src/pages/BranchManager/FoodList/utils.tsx | 4 + 9 files changed, 670 insertions(+) create mode 100644 src/pages/BranchManager/FoodList/ChevronDownIcon.tsx create mode 100644 src/pages/BranchManager/FoodList/PlusIcon.tsx create mode 100644 src/pages/BranchManager/FoodList/SearchIcon.tsx create mode 100644 src/pages/BranchManager/FoodList/VerticalDotsIcon.tsx create mode 100644 src/pages/BranchManager/FoodList/data.tsx create mode 100644 src/pages/BranchManager/FoodList/index.tsx create mode 100644 src/pages/BranchManager/FoodList/types.tsx create mode 100644 src/pages/BranchManager/FoodList/utils.tsx diff --git a/src/App.tsx b/src/App.tsx index 017cf00..d31c3ac 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -16,6 +16,7 @@ import UserLayout from '@layouts/UserLayout'; import Foods from '@pages/BranchManager/Foods'; import FoodItem from '@pages/FoodItem'; import AllFoodItems from '@pages/AllFoodItems'; +import FoodList from '@pages/BranchManager/FoodList'; import { Gallery } from '@components/Gallery/Gallery'; const routes = createRoutesFromElements( @@ -90,6 +91,15 @@ const routes = createRoutesFromElements( } /> + + + + + } + /> , ); diff --git a/src/pages/BranchManager/FoodList/ChevronDownIcon.tsx b/src/pages/BranchManager/FoodList/ChevronDownIcon.tsx new file mode 100644 index 0000000..3307e0c --- /dev/null +++ b/src/pages/BranchManager/FoodList/ChevronDownIcon.tsx @@ -0,0 +1,24 @@ +import React from "react"; +import {IconSvgProps} from "./types"; + +export const ChevronDownIcon = ({strokeWidth = 1.5, ...otherProps}: IconSvgProps) => ( + +); diff --git a/src/pages/BranchManager/FoodList/PlusIcon.tsx b/src/pages/BranchManager/FoodList/PlusIcon.tsx new file mode 100644 index 0000000..c1c355e --- /dev/null +++ b/src/pages/BranchManager/FoodList/PlusIcon.tsx @@ -0,0 +1,26 @@ +import React from "react"; +import {IconSvgProps} from "./types"; + +export const PlusIcon = ({size = 24, width, height, ...props}: IconSvgProps) => ( + +); diff --git a/src/pages/BranchManager/FoodList/SearchIcon.tsx b/src/pages/BranchManager/FoodList/SearchIcon.tsx new file mode 100644 index 0000000..4cf8459 --- /dev/null +++ b/src/pages/BranchManager/FoodList/SearchIcon.tsx @@ -0,0 +1,30 @@ +import React from "react"; +import {IconSvgProps} from "./types"; + +export const SearchIcon = (props: IconSvgProps) => ( + +); diff --git a/src/pages/BranchManager/FoodList/VerticalDotsIcon.tsx b/src/pages/BranchManager/FoodList/VerticalDotsIcon.tsx new file mode 100644 index 0000000..ae1a6f8 --- /dev/null +++ b/src/pages/BranchManager/FoodList/VerticalDotsIcon.tsx @@ -0,0 +1,20 @@ +import React from "react"; +import {IconSvgProps} from "./types"; + +export const VerticalDotsIcon = ({size = 24, width, height, ...props}: IconSvgProps) => ( + +); diff --git a/src/pages/BranchManager/FoodList/data.tsx b/src/pages/BranchManager/FoodList/data.tsx new file mode 100644 index 0000000..4042cf3 --- /dev/null +++ b/src/pages/BranchManager/FoodList/data.tsx @@ -0,0 +1,222 @@ +import React from "react"; +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"}, +]; + +const statusOptions = [ + {name: "Active", uid: "active"}, + {name: "Paused", uid: "paused"}, + {name: "Vacation", uid: "vacation"}, +]; + +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", + }, +]; + +export {columns, users, statusOptions}; diff --git a/src/pages/BranchManager/FoodList/index.tsx b/src/pages/BranchManager/FoodList/index.tsx new file mode 100644 index 0000000..7ad3966 --- /dev/null +++ b/src/pages/BranchManager/FoodList/index.tsx @@ -0,0 +1,329 @@ +import React from "react"; +import { + Table, + TableHeader, + TableColumn, + TableBody, + TableRow, + TableCell, + Input, + Button, + DropdownTrigger, + Dropdown, + DropdownMenu, + DropdownItem, + Chip, + User, + Pagination, + Selection, + ChipProps, + SortDescriptor +} from "@nextui-org/react"; +import {PlusIcon} from "./PlusIcon"; +import {VerticalDotsIcon} from "./VerticalDotsIcon"; +import {ChevronDownIcon} from "./ChevronDownIcon"; +import {SearchIcon} from "./SearchIcon"; +import {columns, users, statusOptions} from "./data"; +import {capitalize} from "./utils"; + +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 FoodList() { + 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); + + 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)}} + + )} + +
+ ); +} diff --git a/src/pages/BranchManager/FoodList/types.tsx b/src/pages/BranchManager/FoodList/types.tsx new file mode 100644 index 0000000..3ad9927 --- /dev/null +++ b/src/pages/BranchManager/FoodList/types.tsx @@ -0,0 +1,5 @@ +import {SVGProps} from "react"; + +export type IconSvgProps = SVGProps & { + size?: number; +}; \ No newline at end of file diff --git a/src/pages/BranchManager/FoodList/utils.tsx b/src/pages/BranchManager/FoodList/utils.tsx new file mode 100644 index 0000000..e8b7ccc --- /dev/null +++ b/src/pages/BranchManager/FoodList/utils.tsx @@ -0,0 +1,4 @@ +import React from "react"; +export function capitalize(str: string) { + return str.charAt(0).toUpperCase() + str.slice(1); +} From 59bdc325bfd1a94e6b94404d66d9ecae46263df8 Mon Sep 17 00:00:00 2001 From: Ravindu Hasanka Date: Wed, 17 Jul 2024 03:41:27 +0530 Subject: [PATCH 2/4] Feat: Table updated --- src/pages/BranchManager/FoodList/index.tsx | 986 ++++++++++++++------- 1 file changed, 690 insertions(+), 296 deletions(-) diff --git a/src/pages/BranchManager/FoodList/index.tsx b/src/pages/BranchManager/FoodList/index.tsx index 7ad3966..433f9b7 100644 --- a/src/pages/BranchManager/FoodList/index.tsx +++ b/src/pages/BranchManager/FoodList/index.tsx @@ -1,329 +1,723 @@ import React from "react"; import { - Table, - TableHeader, - TableColumn, - TableBody, - TableRow, - TableCell, - Input, - Button, - DropdownTrigger, - Dropdown, - DropdownMenu, - DropdownItem, - Chip, - User, - Pagination, - Selection, - ChipProps, - SortDescriptor + Table, + TableHeader, + TableColumn, + TableBody, + TableRow, + TableCell, + Input, + Button, + DropdownTrigger, + Dropdown, + DropdownMenu, + DropdownItem, + Chip, + Pagination, + Selection, + ChipProps, + SortDescriptor } from "@nextui-org/react"; -import {PlusIcon} from "./PlusIcon"; -import {VerticalDotsIcon} from "./VerticalDotsIcon"; -import {ChevronDownIcon} from "./ChevronDownIcon"; -import {SearchIcon} from "./SearchIcon"; -import {columns, users, statusOptions} from "./data"; -import {capitalize} from "./utils"; +import { PlusIcon } from "./PlusIcon"; +import { VerticalDotsIcon } from "./VerticalDotsIcon"; +import { ChevronDownIcon } from "./ChevronDownIcon"; +import { SearchIcon } from "./SearchIcon"; +import { capitalize } from "./utils"; const statusColorMap: Record = { - active: "success", - paused: "danger", - vacation: "warning", + active: "success", + paused: "danger", + vacation: "warning", }; -const INITIAL_VISIBLE_COLUMNS = ["name", "role", "status", "actions"]; +const INITIAL_VISIBLE_COLUMNS = ["foodId", "name", "price", "availability", "cafeId", "category", "discountStatus", "discountId", "features", "actions"]; -type User = typeof users[0]; +type Food = { + id: number; + foodId: string; + name: string; + price: number; + availability: string; + cafeId: string; + category: string; + discountStatus: string; + discountId: string; + features: { feature: string; amount: string }[]; +}; + +const foods: Food[] = [ + { + id: 1, + foodId: 'F001', + name: 'Pizza', + price: 12.99, + availability: 'Available', + cafeId: 'C001', + category: 'Fast Food', + discountStatus: 'Active', + discountId: 'D001', + features: [ + { feature: 'Cheese', amount: 'Extra' }, + { feature: 'Size', amount: 'Large' }, + ], + }, + { + id: 2, + foodId: 'F002', + name: 'Burger', + price: 8.99, + availability: 'Available', + cafeId: 'C002', + category: 'Fast Food', + discountStatus: 'Paused', + discountId: 'D002', + features: [ + { feature: 'Sauce', amount: 'Regular' }, + { feature: 'Size', amount: 'Medium' }, + ], + }, + { + id: 3, + foodId: 'F003', + name: 'Salad', + price: 6.49, + availability: 'Available', + cafeId: 'C003', + category: 'Healthy', + discountStatus: 'Vacation', + discountId: 'D003', + features: [ + { feature: 'Greens', amount: 'Fresh' }, + { feature: 'Dressing', amount: 'Light' }, + ], + }, + { + id: 4, + foodId: 'F004', + name: 'Pasta', + price: 10.99, + availability: 'Available', + cafeId: 'C002', + category: 'Italian', + discountStatus: 'Active', + discountId: 'D004', + features: [ + { feature: 'Sauce', amount: 'Tomato' }, + { feature: 'Cheese', amount: 'Parmesan' }, + ], + }, + { + id: 5, + foodId: 'F005', + name: 'Sandwich', + price: 5.99, + availability: 'Available', + cafeId: 'C001', + category: 'Snack', + discountStatus: 'Active', + discountId: 'D005', + features: [ + { feature: 'Bread', amount: 'Whole Wheat' }, + { feature: 'Fillings', amount: 'Ham, Cheese, Lettuce' }, + ], + }, + { + id: 6, + foodId: 'F006', + name: 'Sushi', + price: 14.99, + availability: 'Available', + cafeId: 'C003', + category: 'Japanese', + discountStatus: 'Active', + discountId: 'D006', + features: [ + { feature: 'Fish', amount: 'Salmon' }, + { feature: 'Rice', amount: 'Sushi Rice' }, + ], + }, + { + id: 7, + foodId: 'F007', + name: 'Steak', + price: 19.99, + availability: 'Available', + cafeId: 'C002', + category: 'Grill', + discountStatus: 'Active', + discountId: 'D007', + features: [ + { feature: 'Cut', amount: 'Ribeye' }, + { feature: 'Cook', amount: 'Medium Rare' }, + ], + }, + { + id: 8, + foodId: 'F008', + name: 'Curry', + price: 11.49, + availability: 'Available', + cafeId: 'C001', + category: 'Indian', + discountStatus: 'Paused', + discountId: 'D008', + features: [ + { feature: 'Spice Level', amount: 'Medium' }, + { feature: 'Type', amount: 'Vegetarian' }, + ], + }, + { + id: 9, + foodId: 'F009', + name: 'Fish and Chips', + price: 9.99, + availability: 'Available', + cafeId: 'C002', + category: 'British', + discountStatus: 'Active', + discountId: 'D009', + features: [ + { feature: 'Fish', amount: 'Cod' }, + { feature: 'Side', amount: 'Chips' }, + ], + }, + { + id: 10, + foodId: 'F010', + name: 'Tacos', + price: 7.99, + availability: 'Available', + cafeId: 'C003', + category: 'Mexican', + discountStatus: 'Active', + discountId: 'D010', + features: [ + { feature: 'Meat', amount: 'Beef' }, + { feature: 'Tortilla', amount: 'Corn' }, + ], + }, + { + id: 11, + foodId: 'F011', + name: 'Ramen', + price: 10.49, + availability: 'Available', + cafeId: 'C001', + category: 'Japanese', + discountStatus: 'Active', + discountId: 'D011', + features: [ + { feature: 'Broth', amount: 'Tonkotsu' }, + { feature: 'Toppings', amount: 'Egg, Pork, Bamboo Shoots' }, + ], + }, + { + id: 12, + foodId: 'F012', + name: 'Pho', + price: 8.99, + availability: 'Available', + cafeId: 'C002', + category: 'Vietnamese', + discountStatus: 'Active', + discountId: 'D012', + features: [ + { feature: 'Noodles', amount: 'Rice Noodles' }, + { feature: 'Broth', amount: 'Beef' }, + ], + }, + { + id: 13, + foodId: 'F013', + name: 'Lasagna', + price: 12.99, + availability: 'Available', + cafeId: 'C001', + category: 'Italian', + discountStatus: 'Active', + discountId: 'D013', + features: [ + { feature: 'Layers', amount: 'Cheese, Meat, Pasta' }, + { feature: 'Sauce', amount: 'Tomato' }, + ], + }, + { + id: 14, + foodId: 'F014', + name: 'Chicken Wings', + price: 9.49, + availability: 'Available', + cafeId: 'C003', + category: 'Appetizer', + discountStatus: 'Paused', + discountId: 'D014', + features: [ + { feature: 'Flavor', amount: 'Buffalo' }, + { feature: 'Side', amount: 'Blue Cheese Dressing' }, + ], + }, + { + id: 15, + foodId: 'F015', + name: 'Fish Tacos', + price: 8.99, + availability: 'Available', + cafeId: 'C002', + category: 'Mexican', + discountStatus: 'Active', + discountId: 'D015', + features: [ + { feature: 'Fish', amount: 'Mahi Mahi' }, + { feature: 'Tortilla', amount: 'Flour' }, + ], + }, + { + id: 16, + foodId: 'F016', + name: 'Caesar Salad', + price: 7.49, + availability: 'Available', + cafeId: 'C001', + category: 'Salad', + discountStatus: 'Active', + discountId: 'D016', + features: [ + { feature: 'Greens', amount: 'Romaine Lettuce' }, + { feature: 'Dressing', amount: 'Caesar' }, + ], + }, + { + id: 17, + foodId: 'F017', + name: 'Pad Thai', + price: 11.99, + availability: 'Available', + cafeId: 'C003', + category: 'Thai', + discountStatus: 'Active', + discountId: 'D017', + features: [ + { feature: 'Noodles', amount: 'Rice Noodles' }, + { feature: 'Protein', amount: 'Shrimp' }, + ], + }, + { + id: 18, + foodId: 'F018', + name: 'Hamburger', + price: 6.99, + availability: 'Available', + cafeId: 'C002', + category: 'Fast Food', + discountStatus: 'Paused', + discountId: 'D018', + features: [ + { feature: 'Condiments', amount: 'Ketchup, Mustard' }, + { feature: 'Extras', amount: 'Pickles, Onion' }, + ], + }, + { + id: 19, + foodId: 'F019', + name: 'Ceviche', + price: 13.99, + availability: 'Available', + cafeId: 'C001', + category: 'Seafood', + discountStatus: 'Active', + discountId: 'D019', + features: [ + { feature: 'Fish', amount: 'Snapper' }, + { feature: 'Citrus', amount: 'Lime' }, + ], + }, + { + id: 20, + foodId: 'F020', + name: 'Fajitas', + price: 14.49, + availability: 'Available', + cafeId: 'C003', + category: 'Mexican', + discountStatus: 'Active', + discountId: 'D020', + features: [ + { feature: 'Meat', amount: 'Chicken' }, + { feature: 'Toppings', amount: 'Peppers, Onions' }, + ], + }, + { + id: 21, + foodId: 'F021', + name: 'Pulled Pork Sandwich', + price: 9.99, + availability: 'Available', + cafeId: 'C002', + category: 'Sandwich', + discountStatus: 'Active', + discountId: 'D021', + features: [ + { feature: 'Meat', amount: 'Pulled Pork' }, + { feature: 'Sauce', amount: 'BBQ' }, + ], + }, + { + id: 22, + foodId: 'F022', + name: 'Ravioli', + price: 11.99, + availability: 'Available', + cafeId: 'C001', + category: 'Italian', + discountStatus: 'Active', + discountId: 'D022', + features: [ + { feature: 'Filling', amount: 'Cheese' }, + { feature: 'Sauce', amount: 'Tomato Cream' }, + ], + }, + { + id: 23, + foodId: 'F023', + name: 'Sashimi', + price: 16.99, + availability: 'Available', + cafeId: 'C003', + category: 'Japanese', + discountStatus: 'Active', + discountId: 'D023', + features: [ + { feature: 'Fish', amount: 'Tuna, Salmon' }, + { feature: 'Presentation', amount: 'Raw' }, + ], + }, + { + id: 24, + foodId: 'F024', + name: 'Gyro', + price: 7.99, + availability: 'Available', + cafeId: 'C002', + category: 'Greek', + discountStatus: 'Active', + discountId: 'D024', + features: [ + { feature: 'Meat', amount: 'Lamb, Beef' }, + { feature: 'Wrap', amount: 'Pita Bread' }, + ], + }, + { + id: 25, + foodId: 'F025', + name: 'Philly Cheesesteak', + price: 12.49, + availability: 'Available', + cafeId: 'C001', + category: 'Sandwich', + discountStatus: 'Active', + discountId: 'D025', + features: [ + { feature: 'Meat', amount: 'Beef' }, + { feature: 'Cheese', amount: 'Provolone' }, + ], + }, + { + id: 26, + foodId: 'F026', + name: 'Maki Roll', + price: 9.99, + availability: 'Available', + cafeId: 'C003', + category: 'Japanese', + discountStatus: 'Active', + discountId: 'D026', + features: [ + { feature: 'Ingredients', amount: 'Cucumber, Avocado' }, + { feature: 'Fish', amount: 'Tuna, Salmon' }, + ], + }, + { + id: 27, + foodId: 'F027', + name: 'Pierogi', + price: 10.99, + availability: 'Available', + cafeId: 'C002', + category: 'Polish', + discountStatus: 'Active', + discountId: 'D027', + features: [ + { feature: 'Filling', amount: 'Potato, Cheese' }, + { feature: 'Side', amount: 'Sour Cream' }, + ], + }, + { + id: 28, + foodId: 'F028', + name: 'Chicken Parmesan', + price: 13.99, + availability: 'Available', + cafeId: 'C001', + category: 'Italian', + discountStatus: 'Active', + discountId: 'D028', + features: [ + { feature: 'Meat', amount: 'Chicken' }, + { feature: 'Cheese', amount: 'Parmesan' }, + ], + }, + { + id: 29, + foodId: 'F029', + name: 'Falafel Wrap', + price: 8.49, + availability: 'Available', + cafeId: 'C003', + category: 'Middle Eastern', + discountStatus: 'Active', + discountId: 'D029', + features: [ + { feature: 'Falafel', amount: 'Chickpea' }, + { feature: 'Wrap', amount: 'Pita Bread' }, + ], + }, + { + id: 30, + foodId: 'F030', + name: 'Chili Con Carne', + price: 10.49, + availability: 'Available', + cafeId: 'C002', + category: 'Mexican', + discountStatus: 'Active', + discountId: 'D030', + features: [ + { feature: 'Meat', amount: 'Beef' }, + { feature: 'Beans', amount: 'Kidney Beans' }, + ], + }, + // Add more food items as needed +]; +const columns = [ + { name: 'Name', uid: 'name' }, + { name: 'Price', uid: 'price' }, + { name: 'Availability', uid: 'availability' }, + { name: 'Cafe ID', uid: 'cafeId' }, + { name: 'Category', uid: 'category' }, + { name: 'Discount Status', uid: 'discountStatus' }, + { name: 'Discount ID', uid: 'discountId' }, + { name: 'Features', uid: 'features' }, + { name: 'Actions', uid: 'actions' }, +]; export default function FoodList() { - 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 [filterValue, setFilterValue] = React.useState(''); + const [visibleColumns, setVisibleColumns] = React.useState(new Set(INITIAL_VISIBLE_COLUMNS)); + const [rowsPerPage, setRowsPerPage] = React.useState(5); + const [sortDescriptor, setSortDescriptor] = React.useState({ + column: 'price', + direction: 'ascending', + }); + const [page, setPage] = React.useState(1); + const hasSearchFilter = Boolean(filterValue); - const [page, setPage] = React.useState(1); + const headerColumns = React.useMemo(() => { + if (visibleColumns === 'all') return columns; - const hasSearchFilter = Boolean(filterValue); + return columns.filter((column) => Array.from(visibleColumns).includes(column.uid)); + }, [visibleColumns]); - const headerColumns = React.useMemo(() => { - if (visibleColumns === "all") return columns; + const filteredItems = React.useMemo(() => { + let filteredFoods = [...foods]; - return columns.filter((column) => Array.from(visibleColumns).includes(column.uid)); - }, [visibleColumns]); + if (hasSearchFilter) { + filteredFoods = filteredFoods.filter((food) => + food.name.toLowerCase().includes(filterValue.toLowerCase()), + ); + } - const filteredItems = React.useMemo(() => { - let filteredUsers = [...users]; + return filteredFoods; + }, [foods, filterValue]); - 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), - ); - } + const pages = Math.ceil(filteredItems.length / rowsPerPage); - return filteredUsers; - }, [users, filterValue, statusFilter]); + const items = React.useMemo(() => { + const start = (page - 1) * rowsPerPage; + const end = start + rowsPerPage; - const pages = Math.ceil(filteredItems.length / rowsPerPage); + return filteredItems.slice(start, end); + }, [page, filteredItems, rowsPerPage]); - const items = React.useMemo(() => { - const start = (page - 1) * rowsPerPage; - const end = start + rowsPerPage; + const sortedItems = React.useMemo(() => { + return [...items].sort((a, b) => { + const first = a[sortDescriptor.column as keyof typeof a] as number; + const second = b[sortDescriptor.column as keyof typeof b] as number; + const cmp = first < second ? -1 : first > second ? 1 : 0; - return filteredItems.slice(start, end); - }, [page, filteredItems, rowsPerPage]); + return sortDescriptor.direction === 'descending' ? -cmp : cmp; + }); + }, [sortDescriptor, items]); - 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; + const renderCell = React.useCallback((food, columnKey) => { + const cellValue = food[columnKey as keyof typeof food]; - return sortDescriptor.direction === "descending" ? -cmp : cmp; - }); - }, [sortDescriptor, items]); + switch (columnKey) { + case 'name': + return cellValue; + case 'price': + return `$${cellValue}`; + case 'features': + return (cellValue as { feature: string; amount: string }[]) + .map((f) => `${f.feature}: ${f.amount}`) + .join(', '); + case 'actions': + return ( +
+ + + + + + View + Edit + Delete + + +
+ ); + default: + return String(cellValue); + } + }, []); - const renderCell = React.useCallback((user: User, columnKey: React.Key) => { - const cellValue = user[columnKey as keyof User]; + const onNextPage = React.useCallback(() => { + if (page < pages) { + setPage(page + 1); + } + }, [page, pages]); - 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 onPreviousPage = React.useCallback(() => { + if (page > 1) { + setPage(page - 1); + } + }, [page]); - const onNextPage = React.useCallback(() => { - if (page < pages) { - setPage(page + 1); - } - }, [page, pages]); + const onRowsPerPageChange = React.useCallback((e) => { + setRowsPerPage(Number(e.target.value)); + setPage(1); + }, []); - const onPreviousPage = React.useCallback(() => { - if (page > 1) { - setPage(page - 1); - } - }, [page]); + const onSearchChange = React.useCallback((value) => { + if (value) { + setFilterValue(value); + setPage(1); + } else { + setFilterValue(''); + } + }, []); - const onRowsPerPageChange = React.useCallback((e: React.ChangeEvent) => { - setRowsPerPage(Number(e.target.value)); - setPage(1); - }, []); + const onClear = React.useCallback(() => { + setFilterValue(''); + setPage(1); + }, []); - const onSearchChange = React.useCallback((value?: string) => { - if (value) { - setFilterValue(value); - setPage(1); - } else { - setFilterValue(""); - } - }, []); + const topContent = React.useMemo(() => { + return ( +
+
+ } + value={filterValue} + onClear={() => onClear()} + onValueChange={onSearchChange} + /> + +
+
+ Total {foods.length} foods + +
+
+ ); + }, [filterValue, onSearchChange, onRowsPerPageChange, foods.length]); - const onClear = React.useCallback(()=>{ - setFilterValue("") - setPage(1) - },[]) + const bottomContent = React.useMemo(() => { + return ( +
- 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, - ]); +
+ + + +
+
+ ); + }, [page, pages]); - const bottomContent = React.useMemo(() => { return ( -
- - {selectedKeys === "all" - ? "All items selected" - : `${selectedKeys.size} of ${filteredItems.length} selected`} - - -
- - -
-
+ + + {(column) => ( + + {column.name} + + )} + + + {(item) => ( + + {(columnKey) => ( + + {renderCell(item, columnKey)} + + )} + + )} + +
); - }, [selectedKeys, items.length, page, pages, hasSearchFilter]); - - return ( - - - {(column) => ( - - {column.name} - - )} - - - {(item) => ( - - {(columnKey) => {renderCell(item, columnKey)}} - - )} - -
- ); -} +} \ No newline at end of file From 14bfd947a676b0f1e808a2db197eb499dfdf10b0 Mon Sep 17 00:00:00 2001 From: Ravindu Hasanka Date: Wed, 17 Jul 2024 22:12:27 +0530 Subject: [PATCH 3/4] feat: the discount page done --- src/App.tsx | 10 + .../BranchManager/FoodList/DiscountList.tsx | 451 ++++++++++++++++++ src/pages/BranchManager/FoodList/index.tsx | 21 +- 3 files changed, 472 insertions(+), 10 deletions(-) create mode 100644 src/pages/BranchManager/FoodList/DiscountList.tsx diff --git a/src/App.tsx b/src/App.tsx index d31c3ac..5c29d93 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -18,6 +18,7 @@ import FoodItem from '@pages/FoodItem'; import AllFoodItems from '@pages/AllFoodItems'; import FoodList from '@pages/BranchManager/FoodList'; import { Gallery } from '@components/Gallery/Gallery'; +import DiscountList from './pages/BranchManager/FoodList/DiscountList'; const routes = createRoutesFromElements( @@ -100,6 +101,15 @@ const routes = createRoutesFromElements( } /> + + + + + } + /> , ); diff --git a/src/pages/BranchManager/FoodList/DiscountList.tsx b/src/pages/BranchManager/FoodList/DiscountList.tsx new file mode 100644 index 0000000..7f4bcba --- /dev/null +++ b/src/pages/BranchManager/FoodList/DiscountList.tsx @@ -0,0 +1,451 @@ +import React from "react"; +import { + Table, + TableHeader, + TableColumn, + TableBody, + TableRow, + TableCell, + Input, + Button, + DropdownTrigger, + Dropdown, + DropdownMenu, + DropdownItem, + Chip, + User, + Pagination, + Selection, + ChipProps, + SortDescriptor +} from "@nextui-org/react"; +import { PlusIcon } from "./PlusIcon"; +import { VerticalDotsIcon } from "./VerticalDotsIcon"; +import { ChevronDownIcon } from "./ChevronDownIcon"; +import { SearchIcon } from "./SearchIcon"; +// Import discountData instead of users +// import { discountData } from "./data"; // assuming you have the data in data.js +import { capitalize } from "./utils"; + +// Define columns for Discount data +const columns = [ + { name: "Discount Name", uid: "Name" }, + { name: "Description", uid: "Description" }, + { name: "Discount Type", uid: "DiscountType" }, + { name: "Start Date", uid: "StartDate" }, + { name: "End Date", uid: "EndDate" }, + { name: "Menu Item Type", uid: "MenuItemType" }, + { name: "Discount Amount", uid: "DiscountAmount" }, + { name: "Offer Details", uid: "OfferDetails" }, + { name: "Actions", uid: "actions" }, +]; + +const discountData = [ + { + DiscountId: 1, + Name: "Morning Saver", + Description: "Get 20% off on all breakfast items.", + DiscountType: "Percentage", + StartDate: "2024-07-01", + EndDate: "2024-07-31", + CafeId: 101, + IsActive: true, + MenuItemType: "Breakfast", + MenuItemId: 1, + DiscountAmount: 20, + OfferDetails: "Valid from 7 AM to 10 AM." + }, + { + DiscountId: 2, + Name: "Lunch Combo", + Description: "Flat $5 off on lunch combo.", + DiscountType: "Flat", + StartDate: "2024-07-01", + EndDate: "2024-07-31", + CafeId: 102, + IsActive: true, + MenuItemType: "Lunch", + MenuItemId: 2, + DiscountAmount: 5, + OfferDetails: "Valid from 12 PM to 3 PM." + }, + { + DiscountId: 3, + Name: "Happy Hour", + Description: "Get 30% off on all drinks.", + DiscountType: "Percentage", + StartDate: "2024-07-01", + EndDate: "2024-07-31", + CafeId: 103, + IsActive: true, + MenuItemType: "Drinks", + MenuItemId: 3, + DiscountAmount: 30, + OfferDetails: "Valid from 4 PM to 6 PM." + }, + { + DiscountId: 4, + Name: "Dinner Delight", + Description: "Flat $10 off on dinner orders above $50.", + DiscountType: "Flat", + StartDate: "2024-07-01", + EndDate: "2024-07-31", + CafeId: 104, + IsActive: true, + MenuItemType: "Dinner", + MenuItemId: 4, + DiscountAmount: 10, + OfferDetails: "Valid for orders above $50." + }, + { + DiscountId: 5, + Name: "Weekend Special", + Description: "Get 25% off on all items during weekends.", + DiscountType: "Percentage", + StartDate: "2024-07-01", + EndDate: "2024-07-31", + CafeId: 105, + IsActive: true, + MenuItemType: "All", + MenuItemId: 5, + DiscountAmount: 25, + OfferDetails: "Valid on Saturdays and Sundays." + }, + { + DiscountId: 6, + Name: "Student Discount", + Description: "Get 15% off on showing student ID.", + DiscountType: "Percentage", + StartDate: "2024-07-01", + EndDate: "2024-07-31", + CafeId: 106, + IsActive: true, + MenuItemType: "All", + MenuItemId: 6, + DiscountAmount: 15, + OfferDetails: "Valid for students with ID." + }, + { + DiscountId: 7, + Name: "Happy Monday", + Description: "Get 10% off on all items on Mondays.", + DiscountType: "Percentage", + StartDate: "2024-07-01", + EndDate: "2024-07-31", + CafeId: 107, + IsActive: true, + MenuItemType: "All", + MenuItemId: 7, + DiscountAmount: 10, + OfferDetails: "Valid all day on Mondays." + }, + { + DiscountId: 8, + Name: "Coffee Lovers", + Description: "Buy one get one free on all coffees.", + DiscountType: "BOGO", + StartDate: "2024-07-01", + EndDate: "2024-07-31", + CafeId: 108, + IsActive: true, + MenuItemType: "Drinks", + MenuItemId: 8, + DiscountAmount: 50, + OfferDetails: "Valid all day." + }, + { + DiscountId: 9, + Name: "Family Feast", + Description: "Get 20% off on family meals.", + DiscountType: "Percentage", + StartDate: "2024-07-01", + EndDate: "2024-07-31", + CafeId: 109, + IsActive: true, + MenuItemType: "Dinner", + MenuItemId: 9, + DiscountAmount: 20, + OfferDetails: "Valid for family meals only." + }, + { + DiscountId: 10, + Name: "Birthday Bash", + Description: "Get a free dessert on your birthday.", + DiscountType: "Free Item", + StartDate: "2024-07-01", + EndDate: "2024-07-31", + CafeId: 110, + IsActive: true, + MenuItemType: "Dessert", + MenuItemId: 10, + DiscountAmount: 100, + OfferDetails: "Valid on your birthday only." + }, + { + DiscountId: 11, + Name: "Late Night Snack", + Description: "Flat $5 off on orders after 9 PM.", + DiscountType: "Flat", + StartDate: "2024-07-01", + EndDate: "2024-07-31", + CafeId: 111, + IsActive: true, + MenuItemType: "All", + MenuItemId: 11, + DiscountAmount: 5, + OfferDetails: "Valid after 9 PM." + }, + { + DiscountId: 12, + Name: "Tea Time", + Description: "Get 20% off on all teas.", + DiscountType: "Percentage", + StartDate: "2024-07-01", + EndDate: "2024-07-31", + CafeId: 112, + IsActive: true, + MenuItemType: "Drinks", + MenuItemId: 12, + DiscountAmount: 20, + OfferDetails: "Valid from 3 PM to 5 PM." + }, +]; + + +const INITIAL_VISIBLE_COLUMNS = ["Name", "Description", "DiscountType", "StartDate", "EndDate", "MenuItemType", "DiscountAmount", "actions"]; + +type Discount = typeof discountData[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 [rowsPerPage, setRowsPerPage] = React.useState(5); + const [sortDescriptor, setSortDescriptor] = React.useState({ + column: "DiscountAmount", + direction: "ascending", + }); + const [page, setPage] = React.useState(1); + + const pages = Math.ceil(discountData.length / rowsPerPage); + + const hasSearchFilter = Boolean(filterValue); + + const headerColumns = React.useMemo(() => { + if (visibleColumns === "all") return columns; + + return columns.filter((column) => Array.from(visibleColumns).includes(column.uid)) as { name: string; uid: string; sortable: boolean }[]; + }, [visibleColumns]); + + const filteredItems = React.useMemo(() => { + let filteredDiscounts = [...discountData]; // Use discountData + + if (hasSearchFilter) { + filteredDiscounts = filteredDiscounts.filter((discount) => + discount.Name.toLowerCase().includes(filterValue.toLowerCase()), + ); + } + + return filteredDiscounts; + }, [discountData, filterValue]); + + 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: Discount, b: Discount) => { + const first = a[sortDescriptor.column as keyof Discount] as string | number; + const second = b[sortDescriptor.column as keyof Discount] as string | number; + const cmp = first < second ? -1 : first > second ? 1 : 0; + + return sortDescriptor.direction === "descending" ? -cmp : cmp; + }); + }, [sortDescriptor, items]); + + const renderCell = React.useCallback((discount: Discount, columnKey: React.Key) => { + const cellValue = discount[columnKey as keyof Discount]; + + switch (columnKey) { + case "Name": + return cellValue; + case "Description": + return cellValue; + case "DiscountType": + return cellValue; + case "StartDate": + return cellValue; + case "EndDate": + return cellValue; + case "MenuItemType": + return cellValue; + case "DiscountAmount": + return `${cellValue}%`; + case "OfferDetails": + return cellValue; + case "actions": + return ( +
+ + + + + + View + Edit + Delete + + +
+ ); + default: + return cellValue; + } + }, []); + + 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 topContent = React.useMemo(() => { + return ( +
+
+ } + value={filterValue} + variant="bordered" + onClear={() => setFilterValue("")} + onValueChange={onSearchChange} + /> + +
+
+ Total {discountData.length} discounts {/* Updated text */} + +
+
+ ); + }, [ + filterValue, + onSearchChange, + onRowsPerPageChange, + discountData.length, // Updated reference + hasSearchFilter, + ]); + + const bottomContent = React.useMemo(() => { + return ( +
+ + {/* + {selectedKeys === "all" + ? "All items selected" + : `${selectedKeys.size} of ${items.length} selected`} + */} +
+ + ); + }, [selectedKeys, items.length, page, pages, hasSearchFilter]); + + const classNames = React.useMemo( + () => ({ + wrapper: ["max-h-[382px]", "max-w-3xl"], + th: ["bg-transparent", "text-default-500", "border-b", "border-divider"], + td: [ + // changing the rows border radius + // first + "group-data-[first=true]:first:before:rounded-none", + "group-data-[first=true]:last:before:rounded-none", + // middle + "group-data-[middle=true]:before:rounded-none", + // last + "group-data-[last=true]:first:before:rounded-none", + "group-data-[last=true]:last:before:rounded-none", + ], + }), + [], + ); + + return ( + + + {(column) => ( + + {column.name} + + )} + + + {(item) => ( + + {(columnKey) => ( + {renderCell(item, columnKey)} + )} + + )} + +
+ ); +} \ No newline at end of file diff --git a/src/pages/BranchManager/FoodList/index.tsx b/src/pages/BranchManager/FoodList/index.tsx index 433f9b7..942a8c6 100644 --- a/src/pages/BranchManager/FoodList/index.tsx +++ b/src/pages/BranchManager/FoodList/index.tsx @@ -522,7 +522,7 @@ export default function FoodList() { const hasSearchFilter = Boolean(filterValue); const headerColumns = React.useMemo(() => { - if (visibleColumns === 'all') return columns; + // if (visibleColumns === 'all') return columns; return columns.filter((column) => Array.from(visibleColumns).includes(column.uid)); }, [visibleColumns]); @@ -558,7 +558,7 @@ export default function FoodList() { }); }, [sortDescriptor, items]); - const renderCell = React.useCallback((food, columnKey) => { + const renderCell = React.useCallback((food:any, columnKey:any) => { const cellValue = food[columnKey as keyof typeof food]; switch (columnKey) { @@ -604,12 +604,12 @@ export default function FoodList() { } }, [page]); - const onRowsPerPageChange = React.useCallback((e) => { + const onRowsPerPageChange = React.useCallback((e:any) => { setRowsPerPage(Number(e.target.value)); setPage(1); }, []); - const onSearchChange = React.useCallback((value) => { + const onSearchChange = React.useCallback((value:any) => { if (value) { setFilterValue(value); setPage(1); @@ -626,6 +626,7 @@ export default function FoodList() { const topContent = React.useMemo(() => { return (
+

Food List

onClear()} onValueChange={onSearchChange} /> -
@@ -662,13 +663,13 @@ export default function FoodList() { return (
-
+
- + {(column) => ( Date: Wed, 17 Jul 2024 22:15:11 +0530 Subject: [PATCH 4/4] enh: title added --- src/pages/BranchManager/FoodList/DiscountList.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pages/BranchManager/FoodList/DiscountList.tsx b/src/pages/BranchManager/FoodList/DiscountList.tsx index 7f4bcba..464fa92 100644 --- a/src/pages/BranchManager/FoodList/DiscountList.tsx +++ b/src/pages/BranchManager/FoodList/DiscountList.tsx @@ -325,6 +325,7 @@ export default function App() { const topContent = React.useMemo(() => { return (
+

Discount List