sme-pos-package 1.0.7 → 1.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (318) hide show
  1. package/dist/index.d.mts +37 -2
  2. package/dist/index.mjs +17 -104
  3. package/dist/index.mjs.map +1 -1
  4. package/dist/tailwind.preset.d.mts +27 -0
  5. package/dist/tailwind.preset.mjs +2 -0
  6. package/dist/tailwind.preset.mjs.map +1 -0
  7. package/package.json +18 -30
  8. package/public/assets/images/bank-logos.png +0 -0
  9. package/public/assets/images/banner1.png +0 -0
  10. package/public/assets/images/banner2.png +0 -0
  11. package/public/assets/images/banner3.png +0 -0
  12. package/public/assets/images/banner4.png +0 -0
  13. package/public/assets/images/cashier.svg +9 -0
  14. package/public/assets/images/empty-cart.png +0 -0
  15. package/public/assets/images/empty-table-state.png +0 -0
  16. package/public/assets/images/layout-display/left-layout.png +0 -0
  17. package/public/assets/images/layout-display/right-layout.png +0 -0
  18. package/public/assets/images/modal-illustration.png +0 -0
  19. package/public/assets/images/order-empty-state.png +0 -0
  20. package/public/assets/images/order.png +0 -0
  21. package/public/assets/images/payment-success-label.png +0 -0
  22. package/public/assets/images/table-empty.png +0 -0
  23. package/public/assets/images/take-away.png +0 -0
  24. package/public/assets/lottie/loading.json +1 -0
  25. package/public/assets/lottie/soft_pos.json +1 -0
  26. package/public/assets/lottie/success.json +1 -0
  27. package/public/config.json +27 -0
  28. package/public/env.json +17 -0
  29. package/src/animations/success.json +9730 -0
  30. package/src/assets/icons/breadcrumbs-icon.tsx +85 -0
  31. package/src/assets/icons/cart-icon.tsx +14 -0
  32. package/src/assets/icons/common.tsx +270 -0
  33. package/src/assets/icons/customer-view-icon.tsx +20 -0
  34. package/src/assets/icons/dining-table.tsx +34 -0
  35. package/src/assets/icons/edit-line-icon.tsx +18 -0
  36. package/src/assets/icons/emenu-icon.tsx +39 -0
  37. package/src/assets/icons/file-close-line-icon.tsx +18 -0
  38. package/src/assets/icons/helper-icon.tsx +84 -0
  39. package/src/assets/icons/home-gear-line-icon.tsx +18 -0
  40. package/src/assets/icons/kanban-icon.tsx +16 -0
  41. package/src/assets/icons/loading-icon.tsx +45 -0
  42. package/src/assets/icons/logout-box-line-icon.tsx +18 -0
  43. package/src/assets/icons/order-icon.tsx +92 -0
  44. package/src/assets/icons/payment-icon.tsx +429 -0
  45. package/src/assets/icons/pincode.tsx +196 -0
  46. package/src/assets/icons/pos-connect-icon.tsx +67 -0
  47. package/src/assets/icons/pos-device-icon.tsx +52 -0
  48. package/src/assets/icons/pos-icon.tsx +75 -0
  49. package/src/assets/icons/printer-line-icon.tsx +18 -0
  50. package/src/assets/icons/star-icon.tsx +174 -0
  51. package/src/assets/icons/table-icon.tsx +77 -0
  52. package/src/assets/icons/user-add-line-icon.tsx +33 -0
  53. package/src/assets/icons/user-icon.tsx +65 -0
  54. package/src/components/common/button-action.tsx +46 -0
  55. package/src/components/common/button-icon.tsx +23 -0
  56. package/src/components/common/dropdown/index.tsx +79 -0
  57. package/src/components/common/empty-state.tsx +60 -0
  58. package/src/components/common/header/index.tsx +89 -0
  59. package/src/components/common/header/tabs.tsx +119 -0
  60. package/src/components/common/image.tsx +20 -0
  61. package/src/components/common/input/index.tsx +55 -0
  62. package/src/components/common/input/radio-group.tsx +75 -0
  63. package/src/components/common/input/text-area.tsx +28 -0
  64. package/src/components/common/modal/delete-confirm-modal-container.tsx +65 -0
  65. package/src/components/common/modal/index.ts +2 -0
  66. package/src/components/common/modal/modal-direction.tsx +125 -0
  67. package/src/components/common/modal/modal-header.tsx +37 -0
  68. package/src/components/common/modal/modal-wrapper.tsx +56 -0
  69. package/src/components/common/modal/modal-zoom.tsx +61 -0
  70. package/src/components/common/pagination.tsx +95 -0
  71. package/src/components/common/refresh-button.tsx +28 -0
  72. package/src/components/common/search-bar.tsx +27 -0
  73. package/src/components/common/search.tsx +59 -0
  74. package/src/components/common/skeleton.tsx +7 -0
  75. package/src/components/common/tabs-layout.tsx +98 -0
  76. package/src/components/common/use-check-session.tsx +19 -0
  77. package/src/components/customer-management/add-customer/add-customer-drawer.tsx +286 -0
  78. package/src/components/customer-management/add-customer/address-select.tsx +51 -0
  79. package/src/components/customer-management/choose-customer-drawer.tsx +177 -0
  80. package/src/components/customer-management/customer-info-drawer.tsx +166 -0
  81. package/src/components/customer-management/customer-no-data.tsx +18 -0
  82. package/src/components/emenu/emenu-qr-code.tsx +59 -0
  83. package/src/components/emenu/menu-link.tsx +67 -0
  84. package/src/components/index.ts +8 -0
  85. package/src/components/kanban-template/kitchen-template.tsx +60 -0
  86. package/src/components/kanban-template/pos-order-template.tsx +77 -0
  87. package/src/components/kanban-template/pos-template.tsx +170 -0
  88. package/src/components/kitchen-management/change-status-confirm-modal.tsx +61 -0
  89. package/src/components/kitchen-management/index.ts +1 -0
  90. package/src/components/kitchen-management/kitchen-order/index.tsx +153 -0
  91. package/src/components/kitchen-management/kitchen-order/line.tsx +78 -0
  92. package/src/components/kitchen-management/kitchen-order/state.tsx +52 -0
  93. package/src/components/kitchen-management/kitchen-status.tsx +69 -0
  94. package/src/components/kitchen-management/orders-kitchen-management.tsx +113 -0
  95. package/src/components/order-management/index.tsx +128 -0
  96. package/src/components/order-management/order-actions.tsx +46 -0
  97. package/src/components/order-management/order-detail/header.tsx +37 -0
  98. package/src/components/order-management/order-detail/index.ts +3 -0
  99. package/src/components/order-management/order-detail/information.tsx +96 -0
  100. package/src/components/order-management/order-detail/order-detail.tsx +84 -0
  101. package/src/components/order-management/order-detail/order-line.tsx +56 -0
  102. package/src/components/order-management/order-detail/summary.tsx +221 -0
  103. package/src/components/order-management/order-header.tsx +113 -0
  104. package/src/components/order-management/order-pagination.tsx +49 -0
  105. package/src/components/order-management/order-status.tsx +58 -0
  106. package/src/components/order-management/order-table.tsx +179 -0
  107. package/src/components/order-management/order-tabs.tsx +48 -0
  108. package/src/components/pos-management/add-product-from-barcode/index.tsx +97 -0
  109. package/src/components/pos-management/cart-content/action-line.tsx +81 -0
  110. package/src/components/pos-management/cart-content/cancel-order-line-modal.tsx +41 -0
  111. package/src/components/pos-management/cart-content/cart-item.tsx +173 -0
  112. package/src/components/pos-management/cart-content/cart-items.tsx +130 -0
  113. package/src/components/pos-management/cart-content/draft-orders/draft-order-line.tsx +67 -0
  114. package/src/components/pos-management/cart-content/draft-orders/index.tsx +40 -0
  115. package/src/components/pos-management/cart-content/edit-cart-modal.tsx +11 -0
  116. package/src/components/pos-management/cart-content/index.tsx +260 -0
  117. package/src/components/pos-management/cart-content/no-select-order.tsx +26 -0
  118. package/src/components/pos-management/cart-content/order-info/customer-info.tsx +53 -0
  119. package/src/components/pos-management/cart-content/order-info/index.tsx +109 -0
  120. package/src/components/pos-management/cart-content/order-total.tsx +36 -0
  121. package/src/components/pos-management/cart-content/orders-line.tsx +72 -0
  122. package/src/components/pos-management/menu-content/category-tab.tsx +38 -0
  123. package/src/components/pos-management/menu-content/create-order-modal.tsx +65 -0
  124. package/src/components/pos-management/menu-content/product-content.tsx +93 -0
  125. package/src/components/pos-management/menu-content/product-detail/info.tsx +28 -0
  126. package/src/components/pos-management/menu-content/product-detail/modal.tsx +148 -0
  127. package/src/components/pos-management/menu-content/product-detail/option.tsx +87 -0
  128. package/src/components/pos-management/menu-content/product-detail/quantity-control.tsx +155 -0
  129. package/src/components/pos-management/menu-content/product-detail/sale-keypad.tsx +100 -0
  130. package/src/components/pos-management/menu-content/product-item.tsx +65 -0
  131. package/src/components/pos-management/order-helper/cancel-order-confirm.tsx +43 -0
  132. package/src/components/pos-management/order-helper/history-call.tsx +105 -0
  133. package/src/components/pos-management/order-helper/order-helper-modal.tsx +116 -0
  134. package/src/components/pos-management/payment-content/bill/actions.tsx +46 -0
  135. package/src/components/pos-management/payment-content/bill/content.tsx +207 -0
  136. package/src/components/pos-management/payment-content/bill/index.tsx +18 -0
  137. package/src/components/pos-management/payment-content/card-payment/index.tsx +124 -0
  138. package/src/components/pos-management/payment-content/card-payment/pos-payment/pos-connect.tsx +183 -0
  139. package/src/components/pos-management/payment-content/card-payment/pos-payment/qr-connect.tsx +185 -0
  140. package/src/components/pos-management/payment-content/card-payment/waiting-for-payment-pos-modal.tsx +37 -0
  141. package/src/components/pos-management/payment-content/cash-payment/index.tsx +216 -0
  142. package/src/components/pos-management/payment-content/index.tsx +70 -0
  143. package/src/components/pos-management/payment-content/payment-info.tsx +67 -0
  144. package/src/components/pos-management/payment-content/payment-layout.tsx +16 -0
  145. package/src/components/pos-management/payment-content/payment-method-cards.tsx +99 -0
  146. package/src/components/pos-management/payment-content/qr-payment/index.tsx +118 -0
  147. package/src/components/pos-management/payment-content/qr-payment/qr_code.js +29 -0
  148. package/src/components/pos-management/payment-content/qr-payment/vietqr.js +436 -0
  149. package/src/components/pos-management/payment-content/session-close-modal.tsx +35 -0
  150. package/src/components/pos-management/payment-content/soft-pos-payment/index.tsx +48 -0
  151. package/src/components/pos-management/pos-helpers/back-confirm.tsx +45 -0
  152. package/src/components/pos-management/pos-helpers/index.tsx +135 -0
  153. package/src/components/pos-management/pos-helpers/layout-display-modal.tsx +99 -0
  154. package/src/components/pos-management/search.tsx +48 -0
  155. package/src/components/pos-management/table-content/filtered-tables.tsx +59 -0
  156. package/src/components/pos-management/table-content/floor-tabs.tsx +65 -0
  157. package/src/components/pos-management/table-content/index.tsx +76 -0
  158. package/src/components/pos-management/table-content/table-item.tsx +127 -0
  159. package/src/components/pos-management/table-content/tables.tsx +96 -0
  160. package/src/components/restaurant-management/add-floor-modal.tsx +133 -0
  161. package/src/components/restaurant-management/add-table-modal.tsx +198 -0
  162. package/src/components/restaurant-management/delete-floor-confirm-modal.tsx +42 -0
  163. package/src/components/restaurant-management/delete-table-confirm-modal.tsx +51 -0
  164. package/src/components/restaurant-management/header.tsx +22 -0
  165. package/src/components/restaurant-management/index.tsx +54 -0
  166. package/src/components/restaurant-management/left-side.tsx +51 -0
  167. package/src/components/restaurant-management/right-side.tsx +179 -0
  168. package/src/components/restaurant-management/table-empty.tsx +43 -0
  169. package/src/components/session-management/close-session-modal/actions.tsx +45 -0
  170. package/src/components/session-management/close-session-modal/close-session-confirm.tsx +157 -0
  171. package/src/components/session-management/close-session-modal/close-session-ticket.tsx +218 -0
  172. package/src/components/session-management/close-session-modal/container.tsx +25 -0
  173. package/src/components/session-management/close-session-modal/draft-orders-confirm.tsx +53 -0
  174. package/src/components/session-management/close-session-modal/draft-orders-summary.tsx +82 -0
  175. package/src/components/session-management/close-session-modal/draft-orders.tsx +34 -0
  176. package/src/components/session-management/close-session-modal/index.tsx +35 -0
  177. package/src/components/session-management/close-session-modal/order/index.ts +1 -0
  178. package/src/components/session-management/close-session-modal/order/order-line.tsx +64 -0
  179. package/src/components/session-management/close-session-modal/order/orders-in-draft.tsx +31 -0
  180. package/src/components/session-management/close-session-modal/session-summary.tsx +165 -0
  181. package/src/components/session-management/index.ts +1 -0
  182. package/src/components/session-management/open-shift/index.tsx +172 -0
  183. package/src/components/table-management/index.tsx +0 -0
  184. package/src/constants/api/index.ts +1 -0
  185. package/src/constants/headers.constant.tsx +24 -0
  186. package/src/constants/index.ts +1 -0
  187. package/src/constants/language.store.ts +21 -0
  188. package/src/constants/methods.constant.ts +10 -0
  189. package/src/constants/order-state.ts +8 -0
  190. package/src/constants/payment-color.constant.ts +26 -0
  191. package/src/constants/query.constant.ts +14 -0
  192. package/src/constants/routes.constants.ts +23 -0
  193. package/src/constants/template-name.constant.ts +9 -0
  194. package/src/hooks/bill/use-get-bill-information.ts +49 -0
  195. package/src/hooks/bill/use-print-bill.tsx +0 -0
  196. package/src/hooks/common/load-env-config.ts +98 -0
  197. package/src/hooks/common/use-back.ts +13 -0
  198. package/src/hooks/common/use-broadcast.ts +22 -0
  199. package/src/hooks/common/use-click-outside.ts +58 -0
  200. package/src/hooks/common/use-get-base64-photo.ts +71 -0
  201. package/src/hooks/common/use-get-query.ts +25 -0
  202. package/src/hooks/common/use-pos.ts +21 -0
  203. package/src/hooks/common/use-query-params.ts +89 -0
  204. package/src/hooks/common/use-speech.ts +36 -0
  205. package/src/hooks/customer/use-customer-provider.ts +247 -0
  206. package/src/hooks/floor/use-floor-provider.ts +172 -0
  207. package/src/hooks/kitchen/use-kitchen-provider.ts +80 -0
  208. package/src/hooks/order/use-get-point-reward.ts +50 -0
  209. package/src/hooks/order/use-loop-fetch-order.ts +30 -0
  210. package/src/hooks/order/use-order-items.ts +61 -0
  211. package/src/hooks/order/use-orders.ts +76 -0
  212. package/src/hooks/payment/use-payment-provider.ts +221 -0
  213. package/src/hooks/product/use-product-provider.ts +87 -0
  214. package/src/hooks/session/use-check-session.tsx +19 -0
  215. package/src/hooks/session/use-session-provider.ts +79 -0
  216. package/src/hooks/table/use-pos-table-provider.ts +193 -0
  217. package/src/index.css +5 -0
  218. package/src/index.ts +10 -0
  219. package/src/layouts/common.tsx +15 -0
  220. package/src/layouts/index.ts +4 -0
  221. package/src/layouts/pos-layout.tsx +33 -0
  222. package/src/layouts/pos-order-layout.tsx +43 -0
  223. package/src/layouts/sale-layout.tsx +25 -0
  224. package/src/locales/en.json +394 -0
  225. package/src/locales/vi.json +400 -0
  226. package/src/pages/index.ts +4 -0
  227. package/src/pages/login/index.tsx +128 -0
  228. package/src/pages/pincode/index.tsx +198 -0
  229. package/src/pages/pos/kitchen-management/layout.tsx +18 -0
  230. package/src/pages/pos/management-floor/index.tsx +7 -0
  231. package/src/pages/pos/management-order/index.tsx +7 -0
  232. package/src/pages/pos/management-order/order-detail/index.tsx +7 -0
  233. package/src/pages/pos/management-table/index.tsx +0 -0
  234. package/src/pages/pos/payment-success/index.tsx +75 -0
  235. package/src/provider/app-provider.tsx +56 -0
  236. package/src/provider/fallback/custom-error.tsx +26 -0
  237. package/src/provider/main-provider.tsx +41 -0
  238. package/src/provider/meta-provider.tsx +72 -0
  239. package/src/provider/modal-provider.tsx +48 -0
  240. package/src/provider/notification-provider.tsx +64 -0
  241. package/src/provider/pos-provider/close-session-provider/index.tsx +207 -0
  242. package/src/provider/pos-provider/customer-provider/index.tsx +30 -0
  243. package/src/provider/pos-provider/floor-provider/index.tsx +39 -0
  244. package/src/provider/pos-provider/index.ts +6 -0
  245. package/src/provider/pos-provider/kitchen-provider/index.tsx +30 -0
  246. package/src/provider/pos-provider/order-detail-provider/index.tsx +233 -0
  247. package/src/provider/pos-provider/order-provider/index.tsx +803 -0
  248. package/src/provider/pos-provider/payment-provider/index.tsx +30 -0
  249. package/src/provider/pos-provider/product-provider/index.tsx +30 -0
  250. package/src/provider/pos-provider/sale-provider/index.tsx +168 -0
  251. package/src/provider/pos-provider/session-provider/index.tsx +30 -0
  252. package/src/provider/pos-provider/socket-provider/index.tsx +118 -0
  253. package/src/provider/pos-provider/table-provider/index.tsx +30 -0
  254. package/src/provider/public-provider.tsx +104 -0
  255. package/src/provider/use-session-provider.ts +79 -0
  256. package/src/router/app-router.tsx +38 -0
  257. package/src/router/index.tsx +26 -0
  258. package/src/router/pos-route.tsx +75 -0
  259. package/src/router/protected-route.tsx +16 -0
  260. package/src/router/public-route.tsx +11 -0
  261. package/src/store/header/index.ts +21 -0
  262. package/src/store/session/index.ts +25 -0
  263. package/src/store/states/cart.state.ts +135 -0
  264. package/src/store/states/close-session.state.ts +20 -0
  265. package/src/store/states/customer.state.ts +19 -0
  266. package/src/store/states/payment.state.ts +14 -0
  267. package/src/styles/base.css +212 -0
  268. package/src/styles/common.css +65 -0
  269. package/src/styles/lib/tailwind.css +0 -0
  270. package/src/styles/lib/tailwind.theme.css +34 -0
  271. package/src/styles/loading.css +72 -0
  272. package/src/styles/main.css +5 -0
  273. package/src/styles/refreshing-content.css +55 -0
  274. package/src/styles/text.css +44 -0
  275. package/src/types/account.ts +61 -0
  276. package/src/types/branch.ts +6 -0
  277. package/src/types/category.ts +13 -0
  278. package/src/types/common.ts +4 -0
  279. package/src/types/customer.ts +52 -0
  280. package/src/types/dashboard.ts +18 -0
  281. package/src/types/edc.ts +37 -0
  282. package/src/types/export-e-invoice.ts +17 -0
  283. package/src/types/filter.d.ts +12 -0
  284. package/src/types/floor/floor.ts +16 -0
  285. package/src/types/floor.d.ts +36 -0
  286. package/src/types/index.ts +127 -0
  287. package/src/types/invoice.ts +32 -0
  288. package/src/types/modal.ts +15 -0
  289. package/src/types/notification.ts +12 -0
  290. package/src/types/order.ts +182 -0
  291. package/src/types/payment.ts +44 -0
  292. package/src/types/product/product.ts +47 -0
  293. package/src/types/product.ts +137 -0
  294. package/src/types/provider-info.d.ts +14 -0
  295. package/src/types/qr.d.ts +25 -0
  296. package/src/types/report.d.ts +43 -0
  297. package/src/types/sale.d.ts +68 -0
  298. package/src/types/search.d.ts +7 -0
  299. package/src/types/session.d.ts +30 -0
  300. package/src/types/shop-qr.d.ts +89 -0
  301. package/src/types/staff.d.ts +35 -0
  302. package/src/types/store.d.ts +25 -0
  303. package/src/types/table.d.ts +57 -0
  304. package/src/utils/close-session-ticket.tsx +129 -0
  305. package/src/utils/functions.ts +299 -0
  306. package/src/utils/i18n.ts +25 -0
  307. package/src/utils/pos/bill.ts +156 -0
  308. package/src/utils/pos/convert-order.ts +58 -0
  309. package/src/utils/pos/helpers.ts +48 -0
  310. package/src/utils/pos/session.ts +44 -0
  311. package/src/utils/storages/index.ts +1 -0
  312. package/src/utils/storages/local-storage.ts +72 -0
  313. package/tailwind.preset.ts +25 -0
  314. package/tsconfig.json +30 -0
  315. package/tsup.config.ts +30 -0
  316. package/dist/index.d.ts +0 -58
  317. package/dist/index.js +0 -145
  318. package/dist/index.js.map +0 -1
@@ -0,0 +1,135 @@
1
+ import { IcBackPos, IcLayout } from "@assets/icons/helper-icon";
2
+ import LogoutBoxLineIcon from "@assets/icons/logout-box-line-icon";
3
+ import PrinterLineIcon from "@assets/icons/printer-line-icon";
4
+ import ModalZoom from "@components/common/modal/modal-zoom";
5
+ import CloseSessionModal from "@components/session-management/close-session-modal";
6
+ import { QUERY_KEYS } from "@constants/query.constant";
7
+ import { useQueryParams } from "@hooks/common/use-query-params";
8
+ import { useCloseSession } from "@provider/pos-provider/close-session-provider";
9
+ import { useSessionStore } from "@store/session";
10
+ import { useState } from "react";
11
+ import { toast } from "react-toastify";
12
+ import { BackConfirm } from "./back-confirm";
13
+ import LayoutDisplayModal from "./layout-display-modal";
14
+
15
+ type TProps = {
16
+ isOpen: boolean;
17
+ onClose: () => void;
18
+ };
19
+
20
+ enum PosHelper {
21
+ SETTING_PRINT = "setting-print",
22
+ LAYOUT_DISPLAY = "layout-display",
23
+ CLOSE_SESSION = "close-session",
24
+ BACK_POS = "back-pos",
25
+ }
26
+
27
+ const OPTIONS = [
28
+ {
29
+ id: 1,
30
+ label: "Bố cục hiển thị",
31
+ value: PosHelper.LAYOUT_DISPLAY,
32
+ icon: IcLayout,
33
+ },
34
+ {
35
+ id: 2,
36
+ label: "Cài đặt máy in",
37
+ value: PosHelper.SETTING_PRINT,
38
+ icon: PrinterLineIcon,
39
+ },
40
+ {
41
+ id: 3,
42
+ label: "Trở về điểm bán",
43
+ value: PosHelper.BACK_POS,
44
+ icon: IcBackPos,
45
+ },
46
+ {
47
+ id: 4,
48
+ label: "Đóng ca",
49
+ value: PosHelper.CLOSE_SESSION,
50
+ icon: LogoutBoxLineIcon,
51
+ },
52
+ ];
53
+
54
+ export const PosHelperModal = ({ isOpen, onClose }: TProps) => {
55
+ const { setStep, step } = useSessionStore();
56
+ const { updateQuery } = useQueryParams();
57
+
58
+ const { getDataCloseSessionQuery, draftInPaidOrders } = useCloseSession();
59
+
60
+ const [showWarning, setShowWarning] = useState(false);
61
+ const [showLayoutDisplay, setShowLayoutDisplay] = useState(false);
62
+
63
+ const onShowComingSoon = () => toast.info("Đang phát triển");
64
+
65
+ const handleCloseSession = async () => {
66
+ updateQuery(QUERY_KEYS.OPEN, QUERY_KEYS.CLOSE_SESSION);
67
+ await getDataCloseSessionQuery.refetch();
68
+ if (draftInPaidOrders.length > 0) setStep(1);
69
+ else setStep(3);
70
+ };
71
+
72
+ const onShowLayoutDisplay = () => {
73
+ setShowLayoutDisplay(true);
74
+ onClose();
75
+ };
76
+
77
+ const handleOptionClick = (value: PosHelper) => {
78
+ switch (value) {
79
+ case PosHelper.BACK_POS:
80
+ setShowWarning(true);
81
+ break;
82
+ case PosHelper.SETTING_PRINT:
83
+ onShowComingSoon();
84
+ break;
85
+ case PosHelper.LAYOUT_DISPLAY:
86
+ onShowLayoutDisplay();
87
+ break;
88
+ case PosHelper.CLOSE_SESSION:
89
+ handleCloseSession();
90
+ onClose();
91
+ break;
92
+ default:
93
+ break;
94
+ }
95
+ };
96
+
97
+ return (
98
+ <>
99
+ <ModalZoom
100
+ isOpen={isOpen}
101
+ onClose={onClose}
102
+ className="border-[0.5px] border-stroke-disabled p-2 bg-neutral-100-96 rounded-xl"
103
+ modalClassName="w-[70%]"
104
+ >
105
+ <div className="grid grid-cols-2 gap-2">
106
+ {OPTIONS.map((option) => (
107
+ <button
108
+ key={option.id}
109
+ onClick={() => {
110
+ handleOptionClick(option.value);
111
+ }}
112
+ className="flex flex-col items-center gap-4 w-full h-[189px] rounded-2xl bg-white justify-center text-colored-primary"
113
+ >
114
+ <option.icon />
115
+ <span className="text-text-primary text-2xl font-semibold leading-8 tracking-[-0.24px]">
116
+ {option.label}
117
+ </span>
118
+ </button>
119
+ ))}
120
+ </div>
121
+ </ModalZoom>
122
+
123
+ <BackConfirm isOpen={showWarning} onClose={() => setShowWarning(false)} />
124
+
125
+ {showLayoutDisplay && (
126
+ <LayoutDisplayModal
127
+ isOpen={showLayoutDisplay}
128
+ onClose={() => setShowLayoutDisplay(false)}
129
+ />
130
+ )}
131
+
132
+ {step > 0 && <CloseSessionModal />}
133
+ </>
134
+ );
135
+ };
@@ -0,0 +1,99 @@
1
+ import Image from "@components/common/image";
2
+ import ModalZoom from "@components/common/modal/modal-zoom";
3
+ import useHeaderStore from "@store/header";
4
+ import { cn } from "@utils/functions";
5
+ import { localStorageUtils } from "@utils/storages";
6
+ import { useState } from "react";
7
+
8
+ type TProps = {
9
+ isOpen: boolean;
10
+ onClose: () => void;
11
+ };
12
+
13
+ const LAYOUT_OPTIONS = [
14
+ {
15
+ value: "left",
16
+ imageUrl: "/assets/images/layout-display/left-layout.png",
17
+ label: "Đơn hàng bên trái",
18
+ },
19
+ {
20
+ value: "right",
21
+ imageUrl: "/assets/images/layout-display/right-layout.png",
22
+ label: "Đơn hàng bên phải",
23
+ },
24
+ ];
25
+
26
+ const LayoutDisplayModal = ({ isOpen, onClose }: TProps) => {
27
+ const layoutDisplayLocal = localStorageUtils.getLayoutDisplay();
28
+
29
+ const [layoutSelected, setLayoutSelected] = useState(
30
+ layoutDisplayLocal || "left"
31
+ );
32
+
33
+ const { setLayoutDisplay } = useHeaderStore();
34
+
35
+ const handleChooseLayout = () => {
36
+ setLayoutDisplay(layoutSelected as "left" | "right");
37
+ localStorageUtils.setLayoutDisplay(layoutSelected as "left" | "right");
38
+ onClose();
39
+ };
40
+
41
+ return (
42
+ <ModalZoom
43
+ isOpen={isOpen}
44
+ onClose={onClose}
45
+ modalClassName="rounded-2xl border-[0.5px] border-stroke-disabled bg-white w-[600px]"
46
+ title="Tuỳ chỉnh bố cục hiển thị"
47
+ headerClassName="px-5 py-4 border-b border-stroke-disabled"
48
+ className="px-5 py-4"
49
+ >
50
+ <div className="flex flex-col gap-4">
51
+ <p className="text-text-primary font-medium leading-6 tracking-[-0.24px]">
52
+ Chọn vị trí hiển thị thông tin đơn hàng theo sở thích của bạn
53
+ </p>
54
+
55
+ <div className="flex items-center justify-center w-full gap-6">
56
+ {LAYOUT_OPTIONS.map((item, index) => (
57
+ <div className="flex flex-col gap-3">
58
+ <div
59
+ key={index}
60
+ style={{
61
+ boxShadow:
62
+ item.value === layoutSelected
63
+ ? "0 0 0 3px rgba(255, 138, 0, 0.24)"
64
+ : "",
65
+ }}
66
+ onClick={() =>
67
+ setLayoutSelected(item.value as "left" | "right")
68
+ }
69
+ className={cn("flex-1 border-stroke-disabled rounded-[20px]", {
70
+ "border-primary border-2 p-2 ": layoutSelected === item.value,
71
+ "p-[9px]": layoutSelected !== item.value,
72
+ })}
73
+ >
74
+ <Image imageUrl={item.imageUrl} className="w-full" />
75
+ </div>
76
+
77
+ <p className="font-medium leading-6 text-center text-text-primary tracking-[-0.24px]">
78
+ {item.label}
79
+ </p>
80
+ </div>
81
+ ))}
82
+ </div>
83
+
84
+ <div className="w-full flex justify-end">
85
+ <button
86
+ className="w-[200px] h-11 bg-primary text-text-primary rounded-lg"
87
+ onClick={handleChooseLayout}
88
+ >
89
+ <span className="text-sm font-semibold leading-5 tracking-[-0.12px]">
90
+ Lưu
91
+ </span>
92
+ </button>
93
+ </div>
94
+ </div>
95
+ </ModalZoom>
96
+ );
97
+ };
98
+
99
+ export default LayoutDisplayModal;
@@ -0,0 +1,48 @@
1
+ import { IcSearch } from "@assets/icons/breadcrumbs-icon"
2
+ import { IcClose } from "@assets/icons/common"
3
+
4
+ type TProps = {
5
+ onClose: () => void
6
+ searchValue: string
7
+ onSearchChange: (value: string) => void
8
+ placeholder: string
9
+ isNumericMode?: boolean
10
+ }
11
+
12
+ const Search = ({
13
+ onClose,
14
+ searchValue,
15
+ onSearchChange,
16
+ placeholder,
17
+ isNumericMode = false,
18
+ }: TProps) => {
19
+ const handleClose = () => {
20
+ onClose()
21
+ onSearchChange("")
22
+ }
23
+
24
+ return (
25
+ <div className="w-full pl-4 h-[60px] flex items-center gap-2 bg-white pr-[6px] text-tertiary border-b-2 border-primary">
26
+ <IcSearch />
27
+
28
+ <input
29
+ inputMode={isNumericMode ? "numeric" : "text"}
30
+ pattern={isNumericMode ? "[0-9]*" : undefined}
31
+ value={searchValue}
32
+ onChange={(e) =>
33
+ onSearchChange(
34
+ isNumericMode ? e.target.value.replace(/\D/g, "") : e.target.value
35
+ )
36
+ }
37
+ className="flex-1 font-medium leading-6 text-text-primary tracking-[-0.24px] placeholder:text-tertiary outline-none border-none"
38
+ placeholder={placeholder}
39
+ />
40
+
41
+ <button onClick={handleClose}>
42
+ <IcClose />
43
+ </button>
44
+ </div>
45
+ )
46
+ }
47
+
48
+ export default Search
@@ -0,0 +1,59 @@
1
+ import { EmptyState } from "@components/common/empty-state";
2
+ import { usePosTable } from "@provider/pos-provider/table-provider";
3
+ import { TMapedTable } from "@type/table";
4
+ import { cn } from "@utils/functions";
5
+ import { TableItem } from "./table-item";
6
+
7
+ type TProps = {
8
+ filteredFloors: any[];
9
+ searchValue?: string;
10
+ };
11
+
12
+ const FilteredTables = ({ filteredFloors, searchValue }: TProps) => {
13
+ const { mapTablesWithOrder } = usePosTable();
14
+
15
+ return (
16
+ <div
17
+ className={cn("z-0 w-full h-full p-4 overflow-y-auto flex-1 ", {
18
+ "bg-white": filteredFloors && filteredFloors.length > 0,
19
+ })}
20
+ >
21
+ {filteredFloors && filteredFloors.length > 0 ? (
22
+ <div className="flex flex-col gap-4">
23
+ {filteredFloors.map((floor) => {
24
+ return (
25
+ <div className="flex flex-col gap-4" key={floor.id}>
26
+ <p className="px-2 py-1 rounded bg-neutral-100-96">
27
+ <span className="font-semibold text-text-primary leading-6 tracking-[-0.24px]">
28
+ {floor.name}
29
+ </span>
30
+ </p>
31
+ {mapTablesWithOrder?.map((item: TMapedTable) => (
32
+ <div
33
+ key={item.table.id}
34
+ className="grid gap-5 grid-cols-[repeat(auto-fill,minmax(157px,1fr))]"
35
+ >
36
+ <TableItem key={item.table.id} tableCard={item} />
37
+ </div>
38
+ ))}
39
+ </div>
40
+ );
41
+ })}
42
+ </div>
43
+ ) : searchValue ? (
44
+ <div className="z-0 h-full">
45
+ <EmptyState
46
+ image="/assets/images/empty-table-state.png"
47
+ imageAlt="No table"
48
+ description="Không có bàn bạn tìm kiếm"
49
+ imageClassName="w-[342px] h-[320px]"
50
+ />
51
+ </div>
52
+ ) : (
53
+ ""
54
+ )}
55
+ </div>
56
+ );
57
+ };
58
+
59
+ export default FilteredTables;
@@ -0,0 +1,65 @@
1
+ import { IcSearch } from "@assets/icons/breadcrumbs-icon";
2
+ import IcHomeGearLine from "@assets/icons/home-gear-line-icon";
3
+ import { ButtonIcon } from "@components/common/button-icon";
4
+ import { QUERY_KEYS } from "@constants/query.constant";
5
+ import { TFloor } from "@type/floor/floor";
6
+ import { Dispatch, SetStateAction } from "react";
7
+ import { useNavigate, useSearchParams } from "react-router-dom";
8
+ import { RefreshButton, TabsLayout } from "../../common/tabs-layout";
9
+ import POSPath from "@constants/routes.constants";
10
+
11
+ export const FloorTabs = ({
12
+ floorData,
13
+ onRefresh,
14
+ setOpenSearch,
15
+ }: {
16
+ floorData: TFloor[];
17
+ onRefresh: () => void;
18
+ setOpenSearch: Dispatch<SetStateAction<boolean>>;
19
+ }) => {
20
+ const navigate = useNavigate();
21
+ const [searchParams] = useSearchParams();
22
+
23
+ return (
24
+ <>
25
+ {floorData.length > 0 && (
26
+ <TabsLayout
27
+ tabs={floorData.map((floor) => ({
28
+ id: floor.id,
29
+ name: floor.name,
30
+ }))}
31
+ queryKey={QUERY_KEYS.FLOOR}
32
+ rightButton={
33
+ <>
34
+ <ButtonIcon
35
+ onClick={() => {
36
+ setOpenSearch(true);
37
+ }}
38
+ iconSrc={<IcSearch />}
39
+ />
40
+ <RefreshButton onRefresh={onRefresh} />
41
+ </>
42
+ }
43
+ alwaysShowButton={
44
+ <div
45
+ id="create-first-table"
46
+ data-menu-id={32}
47
+ data-menu-level={1}
48
+ data-tooltip-id={`menu-${32}`}
49
+ >
50
+ <ButtonIcon
51
+ onClick={() =>
52
+ navigate({
53
+ pathname: POSPath.MANAGEMENT_FLOOR,
54
+ search: searchParams.toString(),
55
+ })
56
+ }
57
+ iconSrc={<IcHomeGearLine />}
58
+ />
59
+ </div>
60
+ }
61
+ />
62
+ )}
63
+ </>
64
+ );
65
+ };
@@ -0,0 +1,76 @@
1
+ import Search from "@components/pos-management/search";
2
+ import { FloorTabs } from "@components/pos-management/table-content/floor-tabs";
3
+ import { AddTableModal } from "@components/restaurant-management/add-table-modal";
4
+ import { useFloor } from "@provider/pos-provider/floor-provider";
5
+ import { driver } from "driver.js";
6
+ import { useEffect, useMemo, useState } from "react";
7
+ import FilteredTables from "./filtered-tables";
8
+ import Tables from "./tables";
9
+
10
+ const TableContent = () => {
11
+ const { floors: floorData } = useFloor();
12
+ const [searchValue, setSearchValue] = useState("");
13
+ const [openSearch, setOpenSearch] = useState(false);
14
+ const [isOpenAddModal, setIsOpenAddModal] = useState(false);
15
+
16
+ const filteredFloors = useMemo(() => {
17
+ if (!floorData) return [];
18
+
19
+ if (!searchValue) return [];
20
+
21
+ return floorData;
22
+ }, [floorData, searchValue]);
23
+
24
+ useEffect(() => {
25
+ const numberTable = floorData.reduce((acc: number, floor: any) => {
26
+ return acc + floor?.table_ids?.length;
27
+ }, 0);
28
+
29
+ if (numberTable && numberTable < 1) {
30
+ const driverObj = driver();
31
+ driverObj.highlight({
32
+ element: "#create-first-table",
33
+ popover: {
34
+ title: "Tạo bàn đầu tiên",
35
+ description:
36
+ "Có vẻ như bạn chưa có bàn nào. Để tạo một bàn mới hãy nhấp vào biểu tượng ngôi nhà",
37
+ },
38
+ });
39
+ }
40
+ }, [floorData]);
41
+
42
+ return (
43
+ <div className="flex flex-col flex-1 size-full bg-white">
44
+ {openSearch ? (
45
+ <Search
46
+ onClose={() => setOpenSearch(false)}
47
+ searchValue={searchValue}
48
+ onSearchChange={setSearchValue}
49
+ placeholder="Tìm kiếm bàn"
50
+ isNumericMode
51
+ />
52
+ ) : (
53
+ <FloorTabs
54
+ floorData={floorData}
55
+ onRefresh={() => {}}
56
+ setOpenSearch={setOpenSearch}
57
+ />
58
+ )}
59
+
60
+ {!openSearch && <Tables onOpenAddModal={() => setIsOpenAddModal(true)} />}
61
+ {openSearch && (
62
+ <FilteredTables
63
+ filteredFloors={filteredFloors}
64
+ searchValue={searchValue}
65
+ />
66
+ )}
67
+
68
+ <AddTableModal
69
+ isOpen={isOpenAddModal}
70
+ onClose={() => setIsOpenAddModal(false)}
71
+ />
72
+ </div>
73
+ );
74
+ };
75
+
76
+ export default TableContent;
@@ -0,0 +1,127 @@
1
+ import { IcAvailableTable, IcSeatTable } from "@assets/icons/table-icon";
2
+ import Image from "@components/common/image";
3
+ import { QUERY_KEYS } from "@constants/query.constant";
4
+ import { useQueryParams } from "@hooks/common/use-query-params";
5
+ import { useOrder } from "@provider/pos-provider/order-provider";
6
+ import { TMapedTable } from "@type/table";
7
+ import { cn } from "@utils/functions";
8
+ import { useMemo } from "react";
9
+ import { useTranslation } from "react-i18next";
10
+
11
+ export const TableItem = ({ tableCard }: { tableCard: TMapedTable }) => {
12
+ const { table, isTakeAway, currentOrder } = tableCard;
13
+ const { t } = useTranslation();
14
+ const { getQuery, updateMultipleQuery } = useQueryParams();
15
+ const tableId = getQuery(QUERY_KEYS.TABLE_ID);
16
+ const orderId = getQuery(QUERY_KEYS.ORDER_ID);
17
+ const { handleCreateOrder, draftOrders } = useOrder();
18
+ const isActiveTable = useMemo(() => {
19
+ return ((currentOrder
20
+ ? currentOrder?.id?.toString() === orderId
21
+ : isTakeAway && !tableId && orderId) ?? false) as boolean;
22
+ }, [tableId, orderId, currentOrder]);
23
+
24
+ const takeAwayOrders = useMemo(() => {
25
+ return draftOrders.filter((order) => !order.table_id);
26
+ }, [draftOrders]);
27
+
28
+ const onClickTableItem = (table: TMapedTable) => {
29
+ if (table.isTakeAway) {
30
+ if (takeAwayOrders.length == 0) {
31
+ onCreateOrder();
32
+ } else if (tableId) {
33
+ updateMultipleQuery([
34
+ {
35
+ key: QUERY_KEYS.ORDER_ID,
36
+ value: String(takeAwayOrders[0]?.id),
37
+ },
38
+ {
39
+ key: QUERY_KEYS.TABLE_ID,
40
+ value: "",
41
+ },
42
+ ]);
43
+ }
44
+ } else if (table.currentOrder) {
45
+ updateMultipleQuery([
46
+ {
47
+ key: QUERY_KEYS.ORDER_ID,
48
+ value: table.currentOrder?.id?.toString() ?? "",
49
+ },
50
+ {
51
+ key: QUERY_KEYS.TABLE_ID,
52
+ value: table.table.id != 0 ? table.table.id?.toString() : "",
53
+ },
54
+ ]);
55
+ } else onCreateOrder(table.table.id);
56
+ };
57
+
58
+ const onCreateOrder = (tableId?: number) => {
59
+ handleCreateOrder(tableId);
60
+ };
61
+
62
+ return (
63
+ <div
64
+ className={cn(
65
+ "rounded-xl size-full flex flex-col items-center px-2 pb-2 gap-2 h-[100px] cursor-pointer",
66
+ {
67
+ "border-sub-secondary border": !currentOrder,
68
+ }
69
+ )}
70
+ style={{
71
+ background: isTakeAway
72
+ ? "var(--text-take-away-color)"
73
+ : currentOrder
74
+ ? "var(--text-unavailable-table-color)"
75
+ : "white",
76
+ boxShadow: isActiveTable ? `0 0 0 2px #FFF, 0 0 0 4px #0101FF` : "",
77
+ }}
78
+ onClick={() => onClickTableItem(tableCard)}
79
+ >
80
+ <div
81
+ className={`w-[110px] h-6 px-2 rounded-b-xl flex text-sm font-semibold items-center ${
82
+ !isTakeAway && !currentOrder ? "bg-neutral-100-96" : "bg-white"
83
+ } ${isTakeAway ? "justify-center" : "justify-between"} `}
84
+ >
85
+ <p className=" text-text-primary">
86
+ {isTakeAway ? "Mang đi" : `${t("table")} ${table.table_number}`}
87
+ </p>
88
+ {!isTakeAway && (
89
+ <div className="flex gap-1 items-center text-text-active">
90
+ <IcSeatTable />
91
+ <p className="text-sm font-semibold">{table.seats}</p>
92
+ </div>
93
+ )}
94
+ </div>
95
+ <div
96
+ className={`flex-1 w-full rounded-lg flex items-center justify-center ${
97
+ !isTakeAway && !currentOrder
98
+ ? "bg-[#FAFAFA] border-dashed border-stroke-disabled border text-text-active"
99
+ : "bg-white "
100
+ }`}
101
+ >
102
+ {isTakeAway ? (
103
+ <div className="flex items-center gap-[10px]">
104
+ <Image
105
+ imageUrl="/assets/images/take-away.png"
106
+ className="w-12 aspect-square"
107
+ />
108
+ <p className="text-sm font-medium text-text-primary">
109
+ {takeAwayOrders?.length ?? 0} đơn
110
+ </p>
111
+ </div>
112
+ ) : currentOrder ? (
113
+ <div className="flex flex-col gap-1 items-center justify-center">
114
+ <p className="text-sm font-medium text-text-disable leading-5 tracking-[-0.12px] text-text-active">
115
+ Đơn hàng
116
+ </p>
117
+ <p className="text-text-primary text-[18px] font-semibold leading-6">
118
+ #{currentOrder?.id}
119
+ </p>
120
+ </div>
121
+ ) : (
122
+ <IcAvailableTable />
123
+ )}
124
+ </div>
125
+ </div>
126
+ );
127
+ };