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,166 @@
1
+ import { IcPencil } from "@assets/icons/common";
2
+ import { IcCustomer } from "@assets/icons/user-icon";
3
+ import Input from "@components/common/input";
4
+ import ModalDirection from "@components/common/modal/modal-direction";
5
+ import { QUERY_KEYS } from "@constants/query.constant";
6
+ import { Button } from "@headlessui/react";
7
+ import { zodResolver } from "@hookform/resolvers/zod";
8
+ import { useQueryParams } from "@hooks/common/use-query-params";
9
+ import { useCustomer } from "@provider/pos-provider/customer-provider";
10
+ import { useSale } from "@provider/pos-provider/sale-provider";
11
+ import { Dispatch, SetStateAction, useEffect, useState } from "react";
12
+ import { useForm } from "react-hook-form";
13
+ import { useTranslation } from "react-i18next";
14
+ import { toast } from "react-toastify";
15
+ import z from "zod";
16
+
17
+ const schema = z.object({
18
+ phone: z.string(),
19
+ name: z.string().min(1, "Tên khách hàng là bắt buộc"),
20
+ email: z.string(),
21
+ });
22
+
23
+ type TProps = {
24
+ setCustomerPhoneNumber: Dispatch<SetStateAction<string>>;
25
+ };
26
+
27
+ export const CustomerInfoDrawer = (props: TProps) => {
28
+ const { setCustomerPhoneNumber } = props;
29
+ const { t } = useTranslation();
30
+ const { getQuery, removeParams } = useQueryParams();
31
+ const { getCustomer, updateCustomer } = useCustomer();
32
+ const { queryResult } = useSale();
33
+ const isOpen = getQuery(QUERY_KEYS.OPEN) === QUERY_KEYS.CUSTOMER_INFO;
34
+ const onClose = () => removeParams([QUERY_KEYS.OPEN, QUERY_KEYS.CUSTOMER_ID]);
35
+ const customerId = getQuery(QUERY_KEYS.CUSTOMER_ID);
36
+
37
+ const [isEditing, setIsEditing] = useState(false);
38
+
39
+ const { handleSubmit, register, setValue, getValues } = useForm({
40
+ defaultValues: {
41
+ phone: "",
42
+ name: "",
43
+ email: "",
44
+ },
45
+ resolver: zodResolver(schema),
46
+ });
47
+
48
+ const onGetCustomer = async () => {
49
+ const data: any = await getCustomer.mutateAsync({
50
+ customerId: Number(customerId),
51
+ });
52
+
53
+ setValue("phone", data[0]?.phone);
54
+ setValue("name", data[0]?.name);
55
+ setValue("email", data[0]?.email);
56
+ };
57
+
58
+ const onSubmit = handleSubmit(async (data) => {
59
+ try {
60
+ await updateCustomer.mutateAsync({
61
+ id: Number(customerId),
62
+ name: data.name,
63
+ phone: data.phone,
64
+ email: data.email,
65
+ });
66
+ setCustomerPhoneNumber("");
67
+
68
+ await queryResult.refetch();
69
+
70
+ toast.success(t("updateCustomerSuccess"));
71
+
72
+ onClose();
73
+ } catch (error) {
74
+ console.log(error);
75
+ }
76
+ });
77
+
78
+ const handleClose = () => {
79
+ setIsEditing(false);
80
+ onClose();
81
+ };
82
+
83
+ useEffect(() => {
84
+ onGetCustomer();
85
+ }, [customerId]);
86
+
87
+ return (
88
+ <ModalDirection
89
+ isOpen={isOpen}
90
+ onClose={handleClose}
91
+ direction="right"
92
+ title={t("detail_customer")}
93
+ className="max-w-md bg-white font-medium"
94
+ >
95
+ <form
96
+ onSubmit={onSubmit}
97
+ className="flex flex-col items-center gap-4 h-full"
98
+ >
99
+ <div className="flex-1 flex flex-col gap-6 w-full">
100
+ <div className="flex flex-col gap-4 items-center justify-center">
101
+ <div className="w-[88px] h-[88px] rounded-full bg-brand-50 flex items-center justify-center text-brand-default">
102
+ <span>
103
+ <IcCustomer />
104
+ </span>
105
+ </div>
106
+
107
+ <p className="text-lg font-semibold leading-[26px] text-text-primary">
108
+ {isEditing ? getValues("phone") : getValues("name")}
109
+ </p>
110
+ </div>
111
+
112
+ <div className="flex flex-col gap-6">
113
+ <Input
114
+ title={isEditing ? "Tên khách hàng" : "SĐT khách hàng"}
115
+ register={register(isEditing ? "name" : "phone")}
116
+ disabled={!isEditing}
117
+ />
118
+
119
+ <Input
120
+ title="Email"
121
+ register={register("email")}
122
+ disabled={!isEditing}
123
+ />
124
+
125
+ {!isEditing && (
126
+ <Button
127
+ onClick={() => setIsEditing(true)}
128
+ className="bg-neutral-50-98 rounded flex items-center justify-center gap-2 h-11 w-full"
129
+ >
130
+ <IcPencil />
131
+ <p className="text-sm font-medium leading-5 text-text-primary tracking-[-0.12px]">
132
+ {t("edit_info")}
133
+ </p>
134
+ </Button>
135
+ )}
136
+ </div>
137
+ </div>
138
+
139
+ <div
140
+ className={`w-full flex ${
141
+ !isEditing ? "flex-col" : "flex-row-reverse"
142
+ } gap-2`}
143
+ >
144
+ <Button
145
+ type="submit"
146
+ disabled={updateCustomer.isPending || queryResult.isFetching}
147
+ className="w-full bg-brand-default py-2 h-9 rounded-md"
148
+ >
149
+ <p className="text-sm text-white font-medium leading-5 tracking-[-0.12px]">
150
+ {isEditing ? "Lưu" : t("choose_customer")}
151
+ </p>
152
+ </Button>
153
+
154
+ <Button
155
+ onClick={isEditing ? () => setIsEditing(false) : onClose}
156
+ className="w-full border border-stroke-disabled py-2 h-9 rounded-md"
157
+ >
158
+ <p className="text-sm text-text-primary font-medium leading-5 tracking-[-0.12px]">
159
+ {t("cancel")}
160
+ </p>
161
+ </Button>
162
+ </div>
163
+ </form>
164
+ </ModalDirection>
165
+ );
166
+ };
@@ -0,0 +1,18 @@
1
+ import { UserLineIcon } from "@assets/icons/user-icon";
2
+ import { useTranslation } from "react-i18next";
3
+
4
+ const CustomerNoData = () => {
5
+ const { t } = useTranslation();
6
+
7
+ return (
8
+ <div className="flex flex-col items-center justify-center gap-6">
9
+ <UserLineIcon />
10
+
11
+ <p className="text-xs px-10 text-center leading-4 text-text-secondary">
12
+ {t("customerNotFound")}
13
+ </p>
14
+ </div>
15
+ );
16
+ };
17
+
18
+ export default CustomerNoData;
@@ -0,0 +1,59 @@
1
+ import { IcClose } from "@assets/icons/common";
2
+ import { LoadDataModel, useSale } from "@provider/pos-provider/sale-provider";
3
+ import { QRCodeSVG } from "qrcode.react";
4
+ import { useMemo } from "react";
5
+ import ModalZoom from "../common/modal/modal-zoom";
6
+ import { usePosAppProvider } from "@provider/app-provider";
7
+
8
+ type TProps = {
9
+ isOpen: boolean;
10
+ onClose: () => void;
11
+ tableId: number;
12
+ };
13
+
14
+ const EMenuQrCode = ({ isOpen, onClose, tableId }: TProps) => {
15
+ const { user } = usePosAppProvider();
16
+ const { getData } = useSale();
17
+
18
+ const shortName = useMemo(() => user?.userProfile?.data.short_name, [user]);
19
+ const posConfigData = getData(LoadDataModel.POS_CONFIG);
20
+
21
+ const posConfig = useMemo(() => {
22
+ return {
23
+ emenuUrl: posConfigData?.[0]?.emenu_url,
24
+ slugName: posConfigData?.[0]?.slug_name,
25
+ };
26
+ }, [posConfigData]);
27
+
28
+ const eMenuLink = `${posConfig.emenuUrl}/${shortName}/${posConfig.slugName}/${tableId}`;
29
+
30
+ return (
31
+ <ModalZoom isOpen={isOpen} onClose={onClose} className="p-6 w-[420px]">
32
+ <div className="flex flex-col gap-6">
33
+ <div className="flex items-center justify-between">
34
+ <p className="text-xl font-semibold leading-7 text-text-primary tracking-[-0.2px]">
35
+ Mã QR E-Emenu
36
+ </p>
37
+
38
+ <button onClick={onClose}>
39
+ <IcClose className="text-text-primary" />
40
+ </button>
41
+ </div>
42
+
43
+ {eMenuLink && (
44
+ <div className="flex items-center justify-center">
45
+ <QRCodeSVG
46
+ value={eMenuLink}
47
+ size={256}
48
+ bgColor={"#ffffff"}
49
+ fgColor={"#000000"}
50
+ level={"L"}
51
+ />
52
+ </div>
53
+ )}
54
+ </div>
55
+ </ModalZoom>
56
+ );
57
+ };
58
+
59
+ export default EMenuQrCode;
@@ -0,0 +1,67 @@
1
+ import { IcCopy } from "@assets/icons/common";
2
+ import { IcCheck, IcQR } from "@assets/icons/emenu-icon";
3
+ import { copyLinkButtonController } from "@fctc/widget-logic/widget";
4
+ import { QRCodeSVG } from "qrcode.react";
5
+ import { useState } from "react";
6
+ import { useTranslation } from "react-i18next";
7
+ import ModalZoom from "../common/modal/modal-zoom";
8
+ import { usePosAppProvider } from "@provider/app-provider";
9
+
10
+ const EMenuLink = (props: any) => {
11
+ const { formValues, pos_slug_key, value } = props;
12
+ const { t } = useTranslation();
13
+ const { user } = usePosAppProvider();
14
+ const [isOpenQr, setIsOpenQr] = useState(false);
15
+ const dataUser = user?.userProfile?.data;
16
+
17
+ const eMenuLink = `${value}/${dataUser?.short_name}/${formValues?.[pos_slug_key]}`;
18
+
19
+ const { handleCopyToClipboard, isCopied } = copyLinkButtonController({
20
+ value: eMenuLink,
21
+ defaultValue: eMenuLink,
22
+ });
23
+
24
+ return (
25
+ <div className="flex items-center justify-center gap-2">
26
+ <div className="border border-stroke-disabled rounded-lg flex max-w-[400px]">
27
+ <span className="p-[10px] border-r border-stroke-disabled text-sm font-medium text-tertiary truncate line-clamp-1 ">
28
+ {eMenuLink}
29
+ </span>
30
+ <button
31
+ className="cursor-pointer p-[12px]"
32
+ type="button"
33
+ onClick={() => handleCopyToClipboard(eMenuLink as string)}
34
+ >
35
+ {isCopied ? <IcCheck /> : <IcCopy />}
36
+ </button>
37
+ </div>
38
+ <button
39
+ type="button"
40
+ onClick={() => setIsOpenQr(!isOpenQr)}
41
+ className="p-[10px] border border-stroke-disabled rounded-xl"
42
+ >
43
+ <IcQR />
44
+ </button>
45
+ <ModalZoom
46
+ isOpen={isOpenQr}
47
+ onClose={() => setIsOpenQr(!isOpenQr)}
48
+ title={t("qr_e_menu")}
49
+ className=""
50
+ >
51
+ {eMenuLink && (
52
+ <div className="flex flex-col items-center gap-6">
53
+ <QRCodeSVG
54
+ value={eMenuLink}
55
+ size={220}
56
+ bgColor={"#ffffff"}
57
+ fgColor={"#000000"}
58
+ level={"L"}
59
+ />
60
+ </div>
61
+ )}
62
+ </ModalZoom>
63
+ </div>
64
+ );
65
+ };
66
+
67
+ export default EMenuLink;
@@ -0,0 +1,8 @@
1
+ export { default as EMenuLink } from "./emenu/menu-link";
2
+ export { default as KitchenTemplate } from "./kanban-template/kitchen-template";
3
+ export { default as PosOrderTemplate } from "./kanban-template/pos-order-template";
4
+ export { default as PosTemplate } from "./kanban-template/pos-template";
5
+ export { default as OpenSessionModal } from "./session-management/open-shift";
6
+
7
+ export { default as ProductContent } from "./pos-management/menu-content/product-content";
8
+ export { default as TableContent } from "./pos-management/table-content/index";
@@ -0,0 +1,60 @@
1
+ import { Line } from "@assets/icons/customer-view-icon";
2
+ import ButtonAction from "@components/common/button-action";
3
+ import KitchenStatus from "@components/kitchen-management/kitchen-status";
4
+ import POSPath from "@constants/routes.constants";
5
+ import { useMemo } from "react";
6
+ import { useTranslation } from "react-i18next";
7
+ import { generatePath, useNavigate } from "react-router-dom";
8
+
9
+ type TProps = {
10
+ columns: any[];
11
+ row: any;
12
+ onClickRow: any;
13
+ };
14
+
15
+ const KitchenTemplate = ({ columns, row, onClickRow }: TProps) => {
16
+ const navigate = useNavigate();
17
+ const kitchenId = useMemo(() => row["id"], [row]);
18
+ const { t } = useTranslation();
19
+
20
+ const onNavigateToOrderList = () => {
21
+ sessionStorage.setItem(
22
+ "enter_pincode",
23
+ window.location.href.split("console")[1]
24
+ );
25
+ localStorage.setItem("backUrl", window.location.href.split("console")[1]);
26
+ navigate(
27
+ `${generatePath(POSPath.ORDERS_KITCHEN_MANAGEMENT, { kitchenId })}?`
28
+ );
29
+ };
30
+
31
+ return (
32
+ <div
33
+ style={{
34
+ boxShadow: "0 2px 4px 0 rgba(27, 28, 29, 0.04)",
35
+ }}
36
+ className="p-4 rounded-2xl bg-white flex flex-col gap-4 h-fit border border-stroke-disabled"
37
+ onClick={() => onClickRow(columns, row)}
38
+ >
39
+ <div className="flex flex-col gap-2">
40
+ <p className="font-semibold leading-6 tracking-[-0.24px] text-strong-950">
41
+ {row["name"]}
42
+ </p>
43
+ <KitchenStatus stages={row["stage_ids"]} />
44
+ </div>
45
+
46
+ <Line />
47
+
48
+ <ButtonAction
49
+ onClick={(e) => {
50
+ e.stopPropagation();
51
+ onNavigateToOrderList();
52
+ }}
53
+ className="rounded-[6px] bg-primary h-11"
54
+ text={t("detail_button")}
55
+ />
56
+ </div>
57
+ );
58
+ };
59
+
60
+ export default KitchenTemplate;
@@ -0,0 +1,77 @@
1
+ import { Line } from "@assets/icons/customer-view-icon";
2
+ import { FileListIcon } from "@assets/icons/order-icon";
3
+ import OrderActions from "@components/order-management/order-actions";
4
+ import OrderStatus from "@components/order-management/order-status";
5
+ import { dd_mm_yyyy, hh_mm, formatOrderPrice } from "@utils/functions";
6
+ import { useMemo } from "react";
7
+
8
+ const PosOrderTemplate = ({
9
+ readOnly,
10
+ row,
11
+ handleClick,
12
+ onAddItem,
13
+ onPayment,
14
+ onIssueInvoice,
15
+ onPrintInvoice,
16
+ }: {
17
+ readOnly?: boolean;
18
+ row: any;
19
+ handleClick: () => void;
20
+ onAddItem?: () => void;
21
+ onPayment?: () => void;
22
+ onIssueInvoice?: () => void;
23
+ onPrintInvoice?: () => void;
24
+ }) => {
25
+ const orderDate: Date = useMemo(() => new Date(row["date_order"]), [row]);
26
+ return (
27
+ <div
28
+ onClick={() => handleClick()}
29
+ className="p-4 h-fit flex-1 rounded-2xl bg-white flex flex-col gap-3"
30
+ >
31
+ <div className="flex items-center justify-center gap-3">
32
+ <div className="w-14 aspect-square rounded-lg bg-neutral-100-96 flex items-center justify-center">
33
+ <FileListIcon />
34
+ </div>
35
+
36
+ <div className="flex flex-col flex-1 gap-2 justify-center">
37
+ <div className="flex items-center justify-between">
38
+ <p className="font-bold leading-6 text-text-primary tracking-[-0.16px]">
39
+ #{row["id"]}
40
+ </p>
41
+
42
+ <OrderStatus status={row["state"]} />
43
+ </div>
44
+
45
+ <p className="text-sm leading-5 text-text-secondary tracking-[-0.12px]">
46
+ {dd_mm_yyyy(orderDate)}{" "}
47
+ <span className="text-text-secondary">• {hh_mm(orderDate)}</span>
48
+ </p>
49
+ </div>
50
+ </div>
51
+
52
+ <div className="relative">
53
+ <div className="h-4 aspect-square bg-weak-50 rounded-full absolute -left-6 -top-2" />
54
+ <Line />
55
+
56
+ <div className="h-4 aspect-square bg-weak-50 rounded-full absolute -right-6 -top-2" />
57
+ </div>
58
+ <div className="flex justify-between items-center">
59
+ <p className="text-text-primary text-end font-semibold leading-6 tracking-[-0.24px]">
60
+ {formatOrderPrice(row["amount_total"])}{" "}
61
+ {row["currency_id"]?.display_name}
62
+ </p>
63
+ {!readOnly && (
64
+ <OrderActions
65
+ orderStatus={row["state"]}
66
+ onAddItem={onAddItem}
67
+ onPayment={onPayment}
68
+ onIssueInvoice={onIssueInvoice}
69
+ onPrintInvoice={onPrintInvoice}
70
+ />
71
+ )}
72
+ </div>
73
+ </div>
74
+ );
75
+ };
76
+
77
+ export default PosOrderTemplate;
@@ -0,0 +1,170 @@
1
+ import { Line } from "@assets/icons/customer-view-icon";
2
+ import { IcSetting } from "@assets/icons/kanban-icon";
3
+ import OpenSessionModal from "@components/session-management/open-shift";
4
+ import { QUERY_KEYS } from "@constants/query.constant";
5
+ import POSPath from "@constants/routes.constants";
6
+ import { dd_mm_yyyy, hh_mm } from "@utils/functions";
7
+ import { t } from "i18next";
8
+ import { Plus } from "lucide-react";
9
+ import { useMemo, useState } from "react";
10
+ import { useForm } from "react-hook-form";
11
+ import { createSearchParams, useNavigate } from "react-router-dom";
12
+
13
+ const PosTemplate = ({
14
+ row,
15
+ columns,
16
+ onClickRow,
17
+ settings_act_id,
18
+ res_model,
19
+ }: {
20
+ row: any;
21
+ columns: any;
22
+ onClickRow: any;
23
+ settings_act_id?: number;
24
+ res_model?: string;
25
+ }) => {
26
+ const opened =
27
+ row["pos_session_state"] === "opened" ||
28
+ row["pos_session_state"] === "closing_control";
29
+ const navigate = useNavigate();
30
+ const [openModal, setOpenModal] = useState(false);
31
+ const methods = useForm({
32
+ mode: "onBlur",
33
+ });
34
+ const date: Date = useMemo(
35
+ () => new Date(row["last_session_closing_date"]),
36
+ [row]
37
+ );
38
+
39
+ const navigateToPosManagement = () => {
40
+ const isModePosRestaurant = row["module_pos_restaurant"];
41
+ const sessionId = row["current_session_id"].id;
42
+ const posId = row["id"];
43
+ const query = createSearchParams({
44
+ [QUERY_KEYS.POS_ID]: posId,
45
+ [QUERY_KEYS.SESSION_ID]: sessionId,
46
+ })?.toString();
47
+ sessionStorage.setItem(
48
+ "enter_pincode",
49
+ window.location.href.split("console")[1]
50
+ );
51
+ localStorage.setItem("backUrl", window.location.href.split("console")[1]);
52
+ navigate(
53
+ `${isModePosRestaurant ? POSPath.TABLES : POSPath.MENUS}?${query}`
54
+ );
55
+ };
56
+
57
+ const navigateSettingManagement = async (e: any) => {
58
+ e.stopPropagation();
59
+ navigateSettingManagement({
60
+ aid: settings_act_id,
61
+ id: row?.id,
62
+ model: res_model,
63
+ });
64
+ };
65
+
66
+ return (
67
+ <>
68
+ <div
69
+ className="relative w-full p-4 border border-[--stroke-default] bg-white rounded-xl shadow-sm flex flex-col overflow-hidden min-h-[200px]"
70
+ onClick={() => onClickRow(columns, row)}
71
+ >
72
+ <div className="flex items-start justify-between">
73
+ <div className="flex space-x-2">
74
+ <img
75
+ src="/assets/images/cashier.svg"
76
+ alt="POS Icon"
77
+ className="size-12"
78
+ />
79
+ <p className="text-base text-[#0E121B] font-semibold">
80
+ {row["name"]}
81
+ </p>
82
+ </div>
83
+ <span
84
+ className={`px-3 py-1 rounded-[4px] text-xs font-medium border ${
85
+ opened
86
+ ? "bg-[#E0FAEB] text-[#12AF53] border-[#1FC163]"
87
+ : "bg-[#FFEBEC] text-[#E93544] border-[#FB2B3D]"
88
+ }`}
89
+ >
90
+ {opened ? t("opening") : t("closed")}
91
+ </span>
92
+ </div>
93
+
94
+ <div className="relative py-4">
95
+ <Line />
96
+ </div>
97
+
98
+ <div className="text-sm space-y-2 mt-3 flex-grow">
99
+ {row["last_session_closing_date"] && (
100
+ <div className="flex justify-between">
101
+ <span className="text-gray-500">
102
+ {" "}
103
+ {opened ? t("opening") : t("closed")}
104
+ </span>
105
+ <span className="font-medium text-[#0E121B]">
106
+ {hh_mm(date)} • {dd_mm_yyyy(date)}
107
+ </span>
108
+ </div>
109
+ )}
110
+
111
+ {opened && (
112
+ <div className="flex justify-between">
113
+ <span className="text-gray-500">{t("balance")}</span>
114
+ <span className="font-medium text-[#0E121B]">
115
+ {row["last_session_closing_cash"].toLocaleString("vi-VN")}đ
116
+ </span>
117
+ </div>
118
+ )}
119
+ </div>
120
+
121
+ <div className="flex justify-end mt-auto pt-4 gap-[10px]">
122
+ <button
123
+ onClick={async (e) => {
124
+ navigateSettingManagement(e);
125
+ }}
126
+ type="button"
127
+ className="button-secondary flex gap-2 items-center"
128
+ >
129
+ <IcSetting />
130
+ <span>{t("setting")}</span>
131
+ </button>
132
+ {opened ? (
133
+ <button
134
+ onClick={(e) => {
135
+ e.stopPropagation();
136
+ navigateToPosManagement();
137
+ }}
138
+ className="button-primary"
139
+ >
140
+ {t("continue_selling")}
141
+ </button>
142
+ ) : (
143
+ <button
144
+ onClick={(e) => {
145
+ e.stopPropagation();
146
+ setOpenModal(true);
147
+ }}
148
+ className="button-primary min-w-[150px] flex gap-2 items-center justify-center"
149
+ >
150
+ <Plus className="w-4 h-4" />
151
+ {t("open_session")}
152
+ </button>
153
+ )}
154
+ </div>
155
+ </div>
156
+
157
+ {openModal && (
158
+ <OpenSessionModal
159
+ openModal={openModal}
160
+ setOpenModal={setOpenModal}
161
+ methods={methods}
162
+ row={row}
163
+ record={row}
164
+ />
165
+ )}
166
+ </>
167
+ );
168
+ };
169
+
170
+ export default PosTemplate;
@@ -0,0 +1,61 @@
1
+ import ButtonAction from "@components/common/button-action";
2
+ import { useTranslation } from "react-i18next";
3
+ import ModalZoom from "../common/modal/modal-zoom";
4
+
5
+ type TProps = {
6
+ isOpen: boolean;
7
+ onClose: () => void;
8
+ orderId: number;
9
+ toOrderStatus: string;
10
+ onChangeOrderStatus: () => void;
11
+ };
12
+
13
+ const ChangeStatusConfirmModal = ({
14
+ isOpen,
15
+ onClose,
16
+ orderId,
17
+ toOrderStatus,
18
+ onChangeOrderStatus,
19
+ }: TProps) => {
20
+ const { t } = useTranslation();
21
+
22
+ return (
23
+ <ModalZoom
24
+ isOpen={isOpen}
25
+ onClose={onClose}
26
+ title="Xác nhận chuyển trạng thái" //multi-language
27
+ className="p-6 flex flex-col gap-6 rounded-2xl w-[420px]"
28
+ >
29
+ <img
30
+ src="/source/assets/images/modal-illustration.png"
31
+ alt="Status change illustration"
32
+ className="w-[232px] h-auto mx-auto"
33
+ />
34
+
35
+ <p className="text-sm font-medium text-text-secondary leading-5 tracking-[-0.12px]">
36
+ {t("changeOrderStatus")}
37
+ <span className="text-text-primary"> DH-{orderId}</span>{" "}
38
+ {t("fromOrderTo")}{" "}
39
+ <span className="text-text-primary">{toOrderStatus}</span>{" "}
40
+ {t("kitchenConfirmStatusQuestion")}
41
+ </p>
42
+
43
+ <div className="flex items-center gap-2">
44
+ <ButtonAction
45
+ onClick={onClose}
46
+ className="button-secondary"
47
+ text={t("Cancel")}
48
+ />
49
+ <ButtonAction
50
+ onClick={() => {
51
+ onChangeOrderStatus();
52
+ onClose();
53
+ }}
54
+ className="button-primary"
55
+ text={t("agree")}
56
+ />
57
+ </div>
58
+ </ModalZoom>
59
+ );
60
+ };
61
+ export default ChangeStatusConfirmModal;
@@ -0,0 +1 @@
1
+ export { default as OrdersKitchenManagement } from "./orders-kitchen-management";