diff --git a/pos/app/(main)/checkout/layout.tsx b/pos/app/(main)/checkout/layout.tsx index bf74da5a12..e525319dcf 100644 --- a/pos/app/(main)/checkout/layout.tsx +++ b/pos/app/(main)/checkout/layout.tsx @@ -10,7 +10,7 @@ const Layout = ({ children }: { children: React.ReactNode }) => { const mode = useAtomValue(modeAtom) return ( <> - {["main", "coffee-shop"].includes(mode) &&
{children}
} + {["main", "coffee-shop", "restaurant"].includes(mode) &&
{children}
} {mode === "kiosk" && {children}} ) diff --git a/pos/app/(main)/checkout/page.tsx b/pos/app/(main)/checkout/page.tsx index 6e5347afae..8e30df57c0 100644 --- a/pos/app/(main)/checkout/page.tsx +++ b/pos/app/(main)/checkout/page.tsx @@ -11,7 +11,7 @@ const Checkout = () => { const mode = useAtomValue(modeAtom) return ( <> - {["main", "coffee-shop"].includes(mode) &&
} + {["main", "coffee-shop", "restaurant"].includes(mode) &&
} {mode === "kiosk" && } ) diff --git a/pos/app/(main)/main.tsx b/pos/app/(main)/main.tsx index 87b58470c2..df8c142683 100644 --- a/pos/app/(main)/main.tsx +++ b/pos/app/(main)/main.tsx @@ -1,15 +1,5 @@ -import CheckoutConfig from "@/modules/auth/checkoutConfig" -import BuyAction from "@/modules/checkout/components/buyAction/buyAction.main" -import Cart from "@/modules/checkout/components/cart/cart.main" -import TotalAmount from "@/modules/checkout/components/totalAmount/totalAmount.main" -import Customer from "@/modules/customer" -import ChooseType from "@/modules/orders/components/chooseType/chooseType.main" -import OrderDetail from "@/modules/orders/OrderDetail" -import Products from "@/modules/products" -import BarcodeResult from "@/modules/products/barcodeResult.market" -import Search from "@/modules/products/components/search/search.main" -import ProductCategories from "@/modules/products/productCategories.main" -import Slots from "@/modules/slots" +import CheckoutMain from "@/modules/checkout/main" +import ProductsContainer from "@/modules/products/productsContainer" import { cn } from "@/lib/utils" import BarcodeListener from "@/components/barcodeListener" @@ -21,32 +11,10 @@ const MainIndexPage = () => {
-
- -
- -
-
-
- - - -
+
- - -
- -
- -
- - - -
-
-
+
diff --git a/pos/app/(main)/page.tsx b/pos/app/(main)/page.tsx index 5e268358ed..b3e820ebf3 100644 --- a/pos/app/(main)/page.tsx +++ b/pos/app/(main)/page.tsx @@ -7,6 +7,7 @@ import { useAtomValue } from "jotai" const Market = dynamic(() => import("./market")) const Main = dynamic(() => import("./main")) const Kiosk = dynamic(() => import("./kiosk")) +const Restaurant = dynamic(() => import("./restaurant")) export default function IndexPage() { const mode = useAtomValue(modeAtom) @@ -14,6 +15,7 @@ export default function IndexPage() { <> {mode === "market" && } {["main", "coffee-shop"].includes(mode) &&
} + {mode === "restaurant" && } {mode === "kiosk" && } ) diff --git a/pos/app/(main)/restaurant.tsx b/pos/app/(main)/restaurant.tsx new file mode 100644 index 0000000000..fced75ee80 --- /dev/null +++ b/pos/app/(main)/restaurant.tsx @@ -0,0 +1,30 @@ +import CheckoutMain from "@/modules/checkout/main" +import ProductsContainer from "@/modules/products/productsContainer" +import Slots from "@/modules/slots" +import SelectTab from "@/modules/slots/components/SelectTab" +import { selectedTabAtom } from "@/store" +import { useAtomValue } from "jotai" + +import { cn } from "@/lib/utils" +import Header from "@/components/header/header.main" + +const Restaurant = () => { + const selectedTab = useAtomValue(selectedTabAtom) + return ( + <> +
+
+
+ {selectedTab === "plan" && } + {selectedTab === "products" && } + +
+
+ +
+
+ + ) +} + +export default Restaurant diff --git a/pos/components/header/headerLayout.tsx b/pos/components/header/headerLayout.tsx index c9e83557dc..a1802f1019 100644 --- a/pos/components/header/headerLayout.tsx +++ b/pos/components/header/headerLayout.tsx @@ -21,12 +21,7 @@ const HeaderLayout = (props: { }) => { const mode = useAtomValue(modeAtom) - return ( - <> - {["coffee-shop", "main"].includes(mode) &&
} - {mode === "market" && } - - ) + return <>{mode === "market" ? :
} } export default HeaderLayout diff --git a/pos/components/header/logo.tsx b/pos/components/header/logo.tsx index ab37ee021c..816345b50c 100644 --- a/pos/components/header/logo.tsx +++ b/pos/components/header/logo.tsx @@ -1,7 +1,7 @@ "use client" import { usePathname, useRouter } from "next/navigation" -import { activeCategoryAtom } from "@/store" +import { activeCategoryAtom, slotFilterAtom } from "@/store" import { configAtom } from "@/store/config.store" import { setInitialAtom } from "@/store/order.store" import { useAtomValue, useSetAtom } from "jotai" @@ -13,6 +13,7 @@ const Logo = () => { const router = useRouter() const setInitialState = useSetAtom(setInitialAtom) const setCategory = useSetAtom(activeCategoryAtom) + const setSlotFilter = useSetAtom(slotFilterAtom) const config = useAtomValue(configAtom) const { logo } = config?.uiOptions || {} @@ -20,10 +21,11 @@ const Logo = () => { const reset = () => { setInitialState() setCategory("") + setSlotFilter(null) } return ( -
+
(pathname === "/" ? reset() : router.push("/"))} diff --git a/pos/components/ui/context-menu.tsx b/pos/components/ui/context-menu.tsx new file mode 100644 index 0000000000..38040f846b --- /dev/null +++ b/pos/components/ui/context-menu.tsx @@ -0,0 +1,200 @@ +"use client" + +import * as React from "react" +import * as ContextMenuPrimitive from "@radix-ui/react-context-menu" +import { Check, ChevronRight, Circle } from "lucide-react" + +import { cn } from "@/lib/utils" + +const ContextMenu = ContextMenuPrimitive.Root + +const ContextMenuTrigger = ContextMenuPrimitive.Trigger + +const ContextMenuGroup = ContextMenuPrimitive.Group + +const ContextMenuPortal = ContextMenuPrimitive.Portal + +const ContextMenuSub = ContextMenuPrimitive.Sub + +const ContextMenuRadioGroup = ContextMenuPrimitive.RadioGroup + +const ContextMenuSubTrigger = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean + } +>(({ className, inset, children, ...props }, ref) => ( + + {children} + + +)) +ContextMenuSubTrigger.displayName = ContextMenuPrimitive.SubTrigger.displayName + +const ContextMenuSubContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +ContextMenuSubContent.displayName = ContextMenuPrimitive.SubContent.displayName + +const ContextMenuContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + + + +)) +ContextMenuContent.displayName = ContextMenuPrimitive.Content.displayName + +const ContextMenuItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean + } +>(({ className, inset, ...props }, ref) => ( + +)) +ContextMenuItem.displayName = ContextMenuPrimitive.Item.displayName + +const ContextMenuCheckboxItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, checked, ...props }, ref) => ( + + + + + + + {children} + +)) +ContextMenuCheckboxItem.displayName = + ContextMenuPrimitive.CheckboxItem.displayName + +const ContextMenuRadioItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + + + + + + {children} + +)) +ContextMenuRadioItem.displayName = ContextMenuPrimitive.RadioItem.displayName + +const ContextMenuLabel = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean + } +>(({ className, inset, ...props }, ref) => ( + +)) +ContextMenuLabel.displayName = ContextMenuPrimitive.Label.displayName + +const ContextMenuSeparator = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +ContextMenuSeparator.displayName = ContextMenuPrimitive.Separator.displayName + +const ContextMenuShortcut = ({ + className, + ...props +}: React.HTMLAttributes) => { + return ( + + ) +} +ContextMenuShortcut.displayName = "ContextMenuShortcut" + +export { + ContextMenu, + ContextMenuTrigger, + ContextMenuContent, + ContextMenuItem, + ContextMenuCheckboxItem, + ContextMenuRadioItem, + ContextMenuLabel, + ContextMenuSeparator, + ContextMenuShortcut, + ContextMenuGroup, + ContextMenuPortal, + ContextMenuSub, + ContextMenuSubContent, + ContextMenuSubTrigger, + ContextMenuRadioGroup, +} diff --git a/pos/modules/checkout/main.tsx b/pos/modules/checkout/main.tsx new file mode 100644 index 0000000000..6804250065 --- /dev/null +++ b/pos/modules/checkout/main.tsx @@ -0,0 +1,27 @@ +import CheckoutConfig from "@/modules/auth/checkoutConfig" +import BuyAction from "@/modules/checkout/components/buyAction/buyAction.main" +import Cart from "@/modules/checkout/components/cart/cart.main" +import TotalAmount from "@/modules/checkout/components/totalAmount/totalAmount.main" +import Customer from "@/modules/customer" +import ChooseType from "@/modules/orders/components/chooseType/chooseType.main" +import OrderDetail from "@/modules/orders/OrderDetail" + +const CheckoutMain = () => { + return ( + + +
+ +
+ +
+ + + +
+
+
+ ) +} + +export default CheckoutMain diff --git a/pos/modules/orders/ActiveOrders.main.tsx b/pos/modules/orders/ActiveOrders.main.tsx index 06ac38e2a1..814daf0145 100644 --- a/pos/modules/orders/ActiveOrders.main.tsx +++ b/pos/modules/orders/ActiveOrders.main.tsx @@ -1,5 +1,6 @@ import { useEffect } from "react" -import { activeOrderIdAtom, slotCodeAtom } from "@/store/order.store" +import { slotFilterAtom } from "@/store" +import { activeOrderIdAtom } from "@/store/order.store" import { useAtom, useAtomValue } from "jotai" import { ORDER_STATUSES } from "@/lib/constants" @@ -16,7 +17,7 @@ import useFullOrders from "./hooks/useFullOrders" const ActiveOrders = () => { const { ALL, COMPLETE } = ORDER_STATUSES const [_id, setActiveOrderId] = useAtom(activeOrderIdAtom) - const slotCode = useAtomValue(slotCodeAtom) + const slotCode = useAtomValue(slotFilterAtom) const { fullOrders, subToOrderStatuses, totalCount, handleLoadMore } = useFullOrders({ @@ -25,7 +26,7 @@ const ActiveOrders = () => { sortField: "createdAt", isPaid: false, statuses: ALL.filter((a) => a !== COMPLETE), - slotCode: _id ? undefined : slotCode, + slotCode: slotCode, }, query: queries.activeOrders, onCompleted(orders) { diff --git a/pos/modules/products/index.tsx b/pos/modules/products/index.tsx index e6ef33e6dc..7d3f9e9ab5 100644 --- a/pos/modules/products/index.tsx +++ b/pos/modules/products/index.tsx @@ -14,7 +14,7 @@ const Products = () => { return ( <> {mode === "market" && } - {mode === "main" &&
} + {["main", "restaurant"].includes(mode) &&
} {mode === "coffee-shop" && } ) diff --git a/pos/modules/products/productsContainer.tsx b/pos/modules/products/productsContainer.tsx new file mode 100644 index 0000000000..887c873ea4 --- /dev/null +++ b/pos/modules/products/productsContainer.tsx @@ -0,0 +1,29 @@ +import { modeAtom } from "@/store" +import { useAtomValue } from "jotai" + +import Products from "." +import Slots from "../slots/slots.main" +import BarcodeResult from "./barcodeResult.market" +import Search from "./components/search/search.main" +import ProductCategories from "./productCategories.main" + +const ProductsContainer = () => { + const mode = useAtomValue(modeAtom) + return ( + <> +
+ +
+ +
+
+
+ {mode !== "restaurant" && } + + +
+ + ) +} + +export default ProductsContainer diff --git a/pos/modules/settings/ChooseTheme.tsx b/pos/modules/settings/ChooseTheme.tsx index ccb788943a..5ffec18c11 100644 --- a/pos/modules/settings/ChooseTheme.tsx +++ b/pos/modules/settings/ChooseTheme.tsx @@ -30,9 +30,8 @@ const ChooseTheme = () => { Үндсэн Дэлгүүр Кофе шоп - Kiosk - Waiting Screen - Kitchen Screen + Ресторан + Киоск diff --git a/pos/modules/slots/components/SelectTab.tsx b/pos/modules/slots/components/SelectTab.tsx new file mode 100644 index 0000000000..e6b82eb85b --- /dev/null +++ b/pos/modules/slots/components/SelectTab.tsx @@ -0,0 +1,28 @@ +import { selectedTabAtom } from "@/store" +import { slotCodeAtom } from "@/store/order.store" +import { useAtom, useAtomValue } from "jotai" + +import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs" + +const SelectTab = () => { + const [selectedTab, setSelectedTab] = useAtom(selectedTabAtom) + const slot = useAtomValue(slotCodeAtom) + return ( + setSelectedTab(val as any)} + > + + + Ширээ {slot ? ` (${slot})` : ""} + + + Бараа + + + + ) +} + +export default SelectTab diff --git a/pos/modules/slots/components/Slot.tsx b/pos/modules/slots/components/Slot.tsx index 19eee47e24..87e095cf99 100644 --- a/pos/modules/slots/components/Slot.tsx +++ b/pos/modules/slots/components/Slot.tsx @@ -1,83 +1,112 @@ -import { RadioGroupItem } from "@radix-ui/react-radio-group" -import { cva } from "class-variance-authority" +import { memo } from "react" +import { selectedTabAtom } from "@/store" +import { slotCodeAtom } from "@/store/order.store" import { motion } from "framer-motion" -import { Check } from "lucide-react" +import { useSetAtom } from "jotai" +import { CheckCircle2, Circle, XCircleIcon } from "lucide-react" import { ISlot } from "@/types/slots.type" -import { Button } from "@/components/ui/button" -import { - HoverCard, - HoverCardContent, - HoverCardTrigger, -} from "@/components/ui/hover-card" +import { cn } from "@/lib/utils" +import { ContextMenuTrigger } from "@/components/ui/context-menu" import { Label } from "@/components/ui/label" -const className = cva("h-10 w-10 text-base font-bold px-0 relative ", { - variants: { - status: { - serving: "bg-blue-300 hover:bg-blue-200", - available: "bg-green-300 hover:bg-green-200", - reserved: "bg-orange-200 hover:bg-orange-200", - }, - }, - defaultVariants: { - status: "available", - }, -}) +import SlotActions from "./slotActions" const MotionLabel = motion(Label) -const Slot = ({ - code, - name, - status, - active, - isPreDates, -}: ISlot & { - status?: "serving" | "available" | "reserved" - active: boolean -}) => { +const statusIcons = { + serving: CheckCircle2, + available: Circle, + reserved: XCircleIcon, +} + +const Slot = ( + props: ISlot & { + status?: "serving" | "available" | "reserved" + active: boolean + } +) => { + const { active, code, name, option, status } = props + + const { + rotateAngle, + width, + height, + top, + left, + color, + zIndex, + borderRadius, + isShape, + } = option || {} + + const Icon = statusIcons[status || "available"] + const style = { + width, + height, + top, + left, + transform: `rotate(${rotateAngle}deg)`, + backgroundColor: color, + zIndex, + borderRadius, + } + const setActiveSlot = useSetAtom(slotCodeAtom) + const setSelectedTab = useSetAtom(selectedTabAtom) + + if (isShape) + return ( +
+ ) + + const handleChoose = () => { + setActiveSlot(code) + setSelectedTab("products") + } + return ( - - - - - {isPreDates && ( - - {isPreDates.toString()} - - )} - + + +
+ + {name || code} +
+ +
+
) } -export default Slot +export default memo(Slot) diff --git a/pos/modules/slots/components/createSlot.tsx b/pos/modules/slots/components/createSlot.tsx new file mode 100644 index 0000000000..742a9090ac --- /dev/null +++ b/pos/modules/slots/components/createSlot.tsx @@ -0,0 +1,29 @@ +import { selectedTabAtom } from "@/store" +import { + activeOrderIdAtom, + setInitialAtom, + slotCodeAtom, +} from "@/store/order.store" +import { useAtomValue, useSetAtom } from "jotai" + +import { ContextMenuItem } from "@/components/ui/context-menu" + +const CreateSlot = ({ code }: { code: string }) => { + const activeOrderId = useAtomValue(activeOrderIdAtom) + const setInitial = useSetAtom(setInitialAtom) + const setSlot = useSetAtom(slotCodeAtom) + const setSelectedTab = useSetAtom(selectedTabAtom) + const handleCreate = () => { + setInitial() + setSlot(code) + setSelectedTab("products") + } + + return ( + + Шинэ захиалга үүсгэх + + ) +} + +export default CreateSlot diff --git a/pos/modules/slots/components/preDates.tsx b/pos/modules/slots/components/preDates.tsx new file mode 100644 index 0000000000..f1af324e12 --- /dev/null +++ b/pos/modules/slots/components/preDates.tsx @@ -0,0 +1,39 @@ +import { selectedTabAtom } from "@/store" +import { activeOrderIdAtom } from "@/store/order.store" +import { format } from "date-fns" +import { useSetAtom } from "jotai" +import { CalendarDaysIcon } from "lucide-react" + +import { ISlot } from "@/types/slots.type" +import { + ContextMenuItem, + ContextMenuSeparator, +} from "@/components/ui/context-menu" +import { DropdownMenuLabel } from "@/components/ui/dropdown-menu" + +const PreDates = ({ isPreDates }: { isPreDates: ISlot["isPreDates"] }) => { + const setActiveOrder = useSetAtom(activeOrderIdAtom) + const setSelectedTab = useSetAtom(selectedTabAtom) + if (!isPreDates?.length) return null + return ( + <> + + Урьдчилсан захиалгууд + {isPreDates.map((preDate) => ( + { + setActiveOrder(preDate._id) + setSelectedTab("products") + }} + > + + {format(new Date(preDate.dueDate), "yyyy/MM/dd HH:mm")} + + ))} + + ) +} + +export default PreDates diff --git a/pos/modules/slots/components/slot.main.tsx b/pos/modules/slots/components/slot.main.tsx new file mode 100644 index 0000000000..661da4a1de --- /dev/null +++ b/pos/modules/slots/components/slot.main.tsx @@ -0,0 +1,74 @@ +import { RadioGroupItem } from "@radix-ui/react-radio-group" +import { cva } from "class-variance-authority" +import { motion } from "framer-motion" +import { Check } from "lucide-react" + +import { ISlot } from "@/types/slots.type" +import { Button } from "@/components/ui/button" +import { ContextMenuTrigger } from "@/components/ui/context-menu" +import { Label } from "@/components/ui/label" + +import SlotActions from "./slotActions" + +const className = cva("h-10 w-10 text-base font-bold px-0 relative ", { + variants: { + status: { + serving: "bg-blue-300 hover:bg-blue-200", + available: "bg-green-300 hover:bg-green-200", + reserved: "bg-orange-200 hover:bg-orange-200", + }, + }, + defaultVariants: { + status: "available", + }, +}) + +const MotionLabel = motion(Label) + +const Slot = ( + props: ISlot & { + status?: "serving" | "available" | "reserved" + active: boolean + } +) => { + const { code, name, status, active } = props + + return ( + + + + + + ) +} + +export default Slot diff --git a/pos/modules/slots/components/slotActions.tsx b/pos/modules/slots/components/slotActions.tsx new file mode 100644 index 0000000000..2e52d42fc0 --- /dev/null +++ b/pos/modules/slots/components/slotActions.tsx @@ -0,0 +1,73 @@ +import { memo } from "react" +import { selectedTabAtom, slotFilterAtom } from "@/store" +import { slotCodeAtom } from "@/store/order.store" +import { useSetAtom } from "jotai" +import { CheckCircle2, Circle, ListFilterIcon, XCircleIcon } from "lucide-react" + +import { ISlot } from "@/types/slots.type" +import { + ContextMenu, + ContextMenuContent, + ContextMenuItem, + ContextMenuSeparator, +} from "@/components/ui/context-menu" + +import CreateSlot from "./createSlot" +import PreDates from "./preDates" + +const statusIcons = { + serving: CheckCircle2, + available: Circle, + reserved: XCircleIcon, +} + +const SlotActions = ({ + code, + name, + isPreDates, + status, + children, +}: ISlot & { + status?: "serving" | "available" | "reserved" + active: boolean + children: React.ReactNode +}) => { + const setActiveSlot = useSetAtom(slotCodeAtom) + const setSelectedTab = useSetAtom(selectedTabAtom) + const setFilterSlots = useSetAtom(slotFilterAtom) + const Icon = statusIcons[status || "available"] + const handleChoose = () => { + setActiveSlot(code) + setSelectedTab("products") + } + return ( + + {children} + +
+
+ {name} ({code}) +
+
+ + {status} +
+
+ + + Сонгох + + setFilterSlots(code)} + > + + Захиалгууд + + +
+
+ ) +} + +export default memo(SlotActions) diff --git a/pos/modules/slots/graphql/queries.ts b/pos/modules/slots/graphql/queries.ts index 325cf56ff4..95853680bc 100644 --- a/pos/modules/slots/graphql/queries.ts +++ b/pos/modules/slots/graphql/queries.ts @@ -1,11 +1,17 @@ -const slots = ` - query poscSlots { - poscSlots{ +import { gql } from "@apollo/client" + +const slots = gql` + query PoscSlots { + poscSlots { _id code name + option status - isPreDates + isPreDates { + dueDate + _id + } } } ` diff --git a/pos/modules/slots/hooks/useSlots.tsx b/pos/modules/slots/hooks/useSlots.tsx index d5278d9cb3..0b03ccb300 100644 --- a/pos/modules/slots/hooks/useSlots.tsx +++ b/pos/modules/slots/hooks/useSlots.tsx @@ -1,9 +1,9 @@ -import { gql, useQuery } from "@apollo/client" +import { useQuery } from "@apollo/client" import { queries } from "../graphql" const useSlots = () => { - const { data, loading } = useQuery(gql(queries.slots)) + const { data, loading } = useQuery(queries.slots) const { poscSlots: slots } = data || {} return { slots, loading } } diff --git a/pos/modules/slots/index.tsx b/pos/modules/slots/index.tsx index 437894b022..a1c1212bdb 100644 --- a/pos/modules/slots/index.tsx +++ b/pos/modules/slots/index.tsx @@ -1,43 +1,40 @@ +import { slotFilterAtom } from "@/store" import { slotCodeAtom } from "@/store/order.store" -import { useAtom } from "jotai" +import { useAtom, useSetAtom } from "jotai" import { ISlot } from "@/types/slots.type" -import { LoaderIcon } from "@/components/ui/loader" -import { RadioGroup } from "@/components/ui/radio-group" -import { ScrollArea } from "@/components/ui/scroll-area" -import Slot from "./components/Slot" +import Slot from "./components/slot" import useSlots from "./hooks/useSlots" const Slots = () => { const { slots, loading } = useSlots() const [activeSlot, setActiveSlot] = useAtom(slotCodeAtom) - - if (!loading && !slots.length) return null - + const setSlotFilter = useSetAtom(slotFilterAtom) return ( - - setActiveSlot(value)} +
+
- {loading ? ( - - ) : ( - <> - {(slots || []).map((slot: ISlot) => ( - - ))} - - )} - - +
{ + setActiveSlot(null) + setSlotFilter(null) + }} + /> + {(slots || []).map((slot: ISlot) => ( + + ))} +
+
) } -// productsConfigs + export default Slots diff --git a/pos/modules/slots/slots.main.tsx b/pos/modules/slots/slots.main.tsx new file mode 100644 index 0000000000..712104aed6 --- /dev/null +++ b/pos/modules/slots/slots.main.tsx @@ -0,0 +1,47 @@ +import { slotFilterAtom } from "@/store" +import { slotCodeAtom } from "@/store/order.store" +import { useAtom, useSetAtom } from "jotai" + +import { ISlot } from "@/types/slots.type" +import { LoaderIcon } from "@/components/ui/loader" +import { RadioGroup } from "@/components/ui/radio-group" +import { ScrollArea } from "@/components/ui/scroll-area" + +import Slot from "./components/slot.main" +import useSlots from "./hooks/useSlots" + +const Slots = () => { + const { slots, loading } = useSlots() + const [activeSlot, setActiveSlot] = useAtom(slotCodeAtom) + const setSlotFilter = useSetAtom(slotFilterAtom) + + if (!loading && !slots.length) return null + + return ( + + { + setActiveSlot(value) + setSlotFilter(value) + }} + > + {loading ? ( + + ) : ( + <> + {(slots || []).map((slot: ISlot) => ( + + ))} + + )} + + + ) +} +export default Slots diff --git a/pos/package.json b/pos/package.json index 3cc62f8b7d..77a6df83c1 100644 --- a/pos/package.json +++ b/pos/package.json @@ -20,6 +20,7 @@ "@radix-ui/react-aspect-ratio": "^1.0.3", "@radix-ui/react-checkbox": "^1.0.4", "@radix-ui/react-collapsible": "^1.0.3", + "@radix-ui/react-context-menu": "^2.1.5", "@radix-ui/react-dialog": "^1.0.4", "@radix-ui/react-dropdown-menu": "^2.0.5", "@radix-ui/react-hover-card": "^1.0.7", diff --git a/pos/public/js/env.js b/pos/public/js/env.js index 8e605ef564..5162560bf4 100644 --- a/pos/public/js/env.js +++ b/pos/public/js/env.js @@ -1,6 +1,6 @@ window.env = { - NEXT_PUBLIC_MAIN_API_DOMAIN: "https://staging.erxes.io/gateway", - NEXT_PUBLIC_MAIN_SUBS_DOMAIN: "wss://staging.erxes.io/gateway/graphql", + NEXT_PUBLIC_MAIN_API_DOMAIN: "http://localhost:4000", + NEXT_PUBLIC_MAIN_SUBS_DOMAIN: "ws://localhost:4000/graphql", NEXT_PUBLIC_SERVER_API_DOMAIN: "http://localhost:4000", - NEXT_PUBLIC_SERVER_DOMAIN: "http://localhost:3000", + NEXT_PUBLIC_SERVER_DOMAIN: "http://localhost:4000", } diff --git a/pos/store/index.tsx b/pos/store/index.tsx index e693303205..f1022cb4bc 100644 --- a/pos/store/index.tsx +++ b/pos/store/index.tsx @@ -27,6 +27,10 @@ export const reportDateAtom = atom(null) export const productCountAtom = atom(0) +export const selectedTabAtom = atom<"plan" | "products">("plan") + +export const slotFilterAtom = atom(null) + // dialog export const kioskModalView = atom("") diff --git a/pos/store/order.store.ts b/pos/store/order.store.ts index e2ae000e16..915bfa7251 100644 --- a/pos/store/order.store.ts +++ b/pos/store/order.store.ts @@ -15,6 +15,7 @@ import { import { customerSearchAtom } from "." import { cartAtom, orderItemInput, totalAmountAtom } from "./cart.store" import { allowTypesAtom } from "./config.store" +import { selectedTabAtom } from "." import { paymentSheetAtom } from "./ui.store" // order @@ -89,6 +90,7 @@ export const setInitialAtom = atom( set(dueDateAtom, undefined) set(isPreAtom, undefined) set(buttonTypeAtom, null) + set(selectedTabAtom, "plan") } ) diff --git a/pos/types/config.types.ts b/pos/types/config.types.ts index b1822ce166..c76da5b02f 100644 --- a/pos/types/config.types.ts +++ b/pos/types/config.types.ts @@ -87,4 +87,4 @@ export interface ICurrentUser { } } -export type modeT = "market" | "main" | "kiosk" | "coffee-shop" +export type modeT = "market" | "main" | "kiosk" | "coffee-shop" | "restaurant" diff --git a/pos/types/slots.type.ts b/pos/types/slots.type.ts index 1c42f6dcb6..edcd25438a 100644 --- a/pos/types/slots.type.ts +++ b/pos/types/slots.type.ts @@ -2,5 +2,16 @@ export interface ISlot { _id: string code: string name: string - isPreDates: string | null + isPreDates: { dueDate: string; _id: string }[] + option: { + width: number + height: number + top: number + left: number + rotateAngle: number + borderRadius: number + color: string + zIndex: string + isShape: boolean + } } diff --git a/pos/yarn.lock b/pos/yarn.lock index a9af070261..58ee67b1c5 100644 --- a/pos/yarn.lock +++ b/pos/yarn.lock @@ -587,6 +587,19 @@ dependencies: "@babel/runtime" "^7.13.10" +"@radix-ui/react-context-menu@^2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@radix-ui/react-context-menu/-/react-context-menu-2.1.5.tgz#1bdbd72761439f9166f75dc4598f276265785c83" + integrity sha512-R5XaDj06Xul1KGb+WP8qiOh7tKJNz2durpLBXAGZjSVtctcRFCuEvy2gtMwRJGePwQQE5nV77gs4FwRi8T+r2g== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/primitive" "1.0.1" + "@radix-ui/react-context" "1.0.1" + "@radix-ui/react-menu" "2.0.6" + "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-use-callback-ref" "1.0.1" + "@radix-ui/react-use-controllable-state" "1.0.1" + "@radix-ui/react-context@1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@radix-ui/react-context/-/react-context-1.0.0.tgz#f38e30c5859a9fb5e9aa9a9da452ee3ed9e0aee0" @@ -734,6 +747,16 @@ "@radix-ui/react-primitive" "1.0.3" "@radix-ui/react-use-callback-ref" "1.0.1" +"@radix-ui/react-focus-scope@1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.4.tgz#2ac45fce8c5bb33eb18419cdc1905ef4f1906525" + integrity sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-compose-refs" "1.0.1" + "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-use-callback-ref" "1.0.1" + "@radix-ui/react-hover-card@^1.0.7": version "1.0.7" resolved "https://registry.yarnpkg.com/@radix-ui/react-hover-card/-/react-hover-card-1.0.7.tgz#684bca2504432566357e7157e087051aa3577948" @@ -799,6 +822,31 @@ aria-hidden "^1.1.1" react-remove-scroll "2.5.5" +"@radix-ui/react-menu@2.0.6": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@radix-ui/react-menu/-/react-menu-2.0.6.tgz#2c9e093c1a5d5daa87304b2a2f884e32288ae79e" + integrity sha512-BVkFLS+bUC8HcImkRKPSiVumA1VPOOEC5WBMiT+QAVsPzW1FJzI9KnqgGxVDPBcql5xXrHkD3JOVoXWEXD8SYA== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/primitive" "1.0.1" + "@radix-ui/react-collection" "1.0.3" + "@radix-ui/react-compose-refs" "1.0.1" + "@radix-ui/react-context" "1.0.1" + "@radix-ui/react-direction" "1.0.1" + "@radix-ui/react-dismissable-layer" "1.0.5" + "@radix-ui/react-focus-guards" "1.0.1" + "@radix-ui/react-focus-scope" "1.0.4" + "@radix-ui/react-id" "1.0.1" + "@radix-ui/react-popper" "1.1.3" + "@radix-ui/react-portal" "1.0.4" + "@radix-ui/react-presence" "1.0.1" + "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-roving-focus" "1.0.4" + "@radix-ui/react-slot" "1.0.2" + "@radix-ui/react-use-callback-ref" "1.0.1" + aria-hidden "^1.1.1" + react-remove-scroll "2.5.5" + "@radix-ui/react-navigation-menu@^1.1.3": version "1.1.3" resolved "https://registry.yarnpkg.com/@radix-ui/react-navigation-menu/-/react-navigation-menu-1.1.3.tgz#4b0f078226971b56b0fe2a9e4dde3cc2abfa731f"