@lmnto/h-mall-shared 1.0.1

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 (262) hide show
  1. package/app.css +457 -0
  2. package/bitbucket-pipelines.yml +223 -0
  3. package/package.json +43 -0
  4. package/public/gif/balloon.gif +0 -0
  5. package/public/gif/gift.gif +0 -0
  6. package/public/img/ai-dialog.png +0 -0
  7. package/public/img/ai-x1-banner.png +0 -0
  8. package/public/img/ai-x1.png +0 -0
  9. package/public/img/alert-Icon.png +0 -0
  10. package/public/img/aleta-payment-kyc-require.png +0 -0
  11. package/public/img/aleta-payment-pending.png +0 -0
  12. package/public/img/aleta-payment-rejected.png +0 -0
  13. package/public/img/aleta-payment-subscription-required.png +0 -0
  14. package/public/img/boost-banner-bg.png +0 -0
  15. package/public/img/boost-banner-right.png +0 -0
  16. package/public/img/boost-banner.png +0 -0
  17. package/public/img/boost-dialog-bg.png +0 -0
  18. package/public/img/boostPower.png +0 -0
  19. package/public/img/boostTooltip.png +0 -0
  20. package/public/img/brand-icon.svg +23 -0
  21. package/public/img/brand-text.svg +11 -0
  22. package/public/img/card-icon.png +0 -0
  23. package/public/img/cashback-Icon.png +0 -0
  24. package/public/img/crown.svg +9 -0
  25. package/public/img/empty-box.png +0 -0
  26. package/public/img/gen3-dialog.png +0 -0
  27. package/public/img/gen3-home-banner-bg.png +0 -0
  28. package/public/img/gen3-image.png +0 -0
  29. package/public/img/gift.png +0 -0
  30. package/public/img/img-placeholder-illustration.svg +6 -0
  31. package/public/img/logo.svg +31 -0
  32. package/public/img/offerBanner.png +0 -0
  33. package/public/img/pagenotfound.png +0 -0
  34. package/public/img/partial-pay-payment-successful.png +0 -0
  35. package/public/img/phoneShippingBG.png +0 -0
  36. package/public/img/placeholder-image.jpg +0 -0
  37. package/public/img/powerIcon.png +0 -0
  38. package/public/img/product-01.png +0 -0
  39. package/public/img/product-02.jpg +0 -0
  40. package/public/img/product-03.jpg +0 -0
  41. package/public/img/product-04.jpg +0 -0
  42. package/public/img/product-05.png +0 -0
  43. package/public/img/product-06.png +0 -0
  44. package/public/img/profile-avatar.svg +12 -0
  45. package/public/img/promotion-icon.png +0 -0
  46. package/public/img/session-expired.png +0 -0
  47. package/public/img/shipping-alert-icon.png +0 -0
  48. package/public/img/shippingIcon.png +0 -0
  49. package/public/img/smart-pay-banner-how.png +0 -0
  50. package/public/img/smart-pay-banner-own.png +0 -0
  51. package/public/img/smart-pay-chose.png +0 -0
  52. package/public/img/smart-pay-easy.png +0 -0
  53. package/public/img/smart-pay-payment.png +0 -0
  54. package/public/img/smart-plan-fire.gif +0 -0
  55. package/public/img/smart-plan-sparkle.gif +0 -0
  56. package/public/img/special.png +0 -0
  57. package/public/img/specialOfferBg.png +0 -0
  58. package/public/img/stop-shipping-banner.png +0 -0
  59. package/public/img/subscriptionBanner.png +0 -0
  60. package/public/img/subscriptionIcon.png +0 -0
  61. package/public/img/successIcon.png +0 -0
  62. package/public/img/wallet-icon.png +0 -0
  63. package/public/img/world-wide-shipping.png +0 -0
  64. package/public/next.svg +1 -0
  65. package/public/vercel.svg +1 -0
  66. package/shared/components/AddressFormComponent.tsx +215 -0
  67. package/shared/components/AddressShippingFormComponent.tsx +223 -0
  68. package/shared/components/AiPaymentDialog.tsx +95 -0
  69. package/shared/components/AppLoadingComponent.tsx +15 -0
  70. package/shared/components/AppLoadingComponentV2.tsx +18 -0
  71. package/shared/components/Button.tsx +48 -0
  72. package/shared/components/BuySubscriptionDialog.tsx +75 -0
  73. package/shared/components/CartDrawerComponent.tsx +324 -0
  74. package/shared/components/CashbackComponent.tsx +48 -0
  75. package/shared/components/CashbackMigrationComponent.tsx +41 -0
  76. package/shared/components/CommissionNonEligibleComponent.tsx +27 -0
  77. package/shared/components/CustomNextImage.tsx +50 -0
  78. package/shared/components/CustomNextLink.tsx +46 -0
  79. package/shared/components/EditAddressFormComponent.tsx +254 -0
  80. package/shared/components/EmptyCartMessageComponent.tsx +25 -0
  81. package/shared/components/EmptyCartMessageForCartPage.tsx +61 -0
  82. package/shared/components/EmptyLegacyOrderMessageForOrdersPage.tsx +52 -0
  83. package/shared/components/EmptyOrderMessageForOrdersPage.tsx +62 -0
  84. package/shared/components/EmptyOrderMessageForShippingOrdersPage.tsx +62 -0
  85. package/shared/components/Footer.tsx +71 -0
  86. package/shared/components/GreetingDialog.tsx +96 -0
  87. package/shared/components/Header.tsx +106 -0
  88. package/shared/components/HoldShippingDialog.tsx +165 -0
  89. package/shared/components/HomeBanners.tsx +298 -0
  90. package/shared/components/InactiveCartDialog.tsx +69 -0
  91. package/shared/components/InputCartQuantity.tsx +342 -0
  92. package/shared/components/Inputfield.tsx +110 -0
  93. package/shared/components/ListItemComponent.tsx +82 -0
  94. package/shared/components/LoadingIconComponent.tsx +284 -0
  95. package/shared/components/OrderNotFoundComponent.tsx +56 -0
  96. package/shared/components/PageHeader.tsx +42 -0
  97. package/shared/components/PhoneNumberCountries.tsx +133 -0
  98. package/shared/components/PhoneShippingDialog.tsx +77 -0
  99. package/shared/components/PickupDialog.tsx +92 -0
  100. package/shared/components/ProductNotFoundComponent.tsx +56 -0
  101. package/shared/components/ProductPriceComponent.tsx +32 -0
  102. package/shared/components/ProfileMenu.tsx +120 -0
  103. package/shared/components/RequestCreditNoteInvoiceDialog.tsx +214 -0
  104. package/shared/components/RequestInvoiceDialog.tsx +194 -0
  105. package/shared/components/SelectCities.tsx +133 -0
  106. package/shared/components/SelectComponent.tsx +334 -0
  107. package/shared/components/SelectCountries.tsx +179 -0
  108. package/shared/components/SelectPickUpStore.tsx +131 -0
  109. package/shared/components/SelectStates.tsx +144 -0
  110. package/shared/components/ServerTime.tsx +68 -0
  111. package/shared/components/SessionDialogComponent.tsx +60 -0
  112. package/shared/components/ShippingAddressFormDialogComponent.tsx +51 -0
  113. package/shared/components/Sidebar.tsx +281 -0
  114. package/shared/components/SpecialOfferDialog.tsx +193 -0
  115. package/shared/components/StatusComponents.tsx +25 -0
  116. package/shared/components/StepperComponent.tsx +79 -0
  117. package/shared/components/StepperSmartPayComponent.tsx +97 -0
  118. package/shared/components/SubscriptionPurchaseDialogComponent.tsx +81 -0
  119. package/shared/components/TableComponent.tsx +144 -0
  120. package/shared/components/TablePaginationComponent.tsx +151 -0
  121. package/shared/components/aleta/AletaManagerComponent.tsx +52 -0
  122. package/shared/components/aleta/KycPendingStatus.tsx +33 -0
  123. package/shared/components/aleta/KycRejectedStatus.tsx +53 -0
  124. package/shared/components/aleta/KycRequiredStatus.tsx +53 -0
  125. package/shared/components/aleta/SubscriptionRequiredStatus.tsx +45 -0
  126. package/shared/components/icons/AletaWalletIcon.tsx +21 -0
  127. package/shared/components/icons/BrandIcon.tsx +97 -0
  128. package/shared/components/icons/BrandText.tsx +47 -0
  129. package/shared/components/icons/CartIcon.tsx +21 -0
  130. package/shared/components/icons/DoneIcon.tsx +27 -0
  131. package/shared/components/icons/HomnifiIcon.tsx +23 -0
  132. package/shared/components/icons/InfoIcon.tsx +16 -0
  133. package/shared/components/icons/SmartPayProductIcon.tsx +31 -0
  134. package/shared/components/payments/DisclaimerAlertDialog.tsx +205 -0
  135. package/shared/components/payments/EmptyAssets.tsx +23 -0
  136. package/shared/components/payments/PaybyWalletItemComponent.tsx +116 -0
  137. package/shared/components/payments/PaymentAssetItemComponent.tsx +101 -0
  138. package/shared/components/payments/RequestProcessingDialog.tsx +123 -0
  139. package/shared/components/payments/WalletSectionManager.tsx +82 -0
  140. package/shared/components/payments/WalletSliderComponent.tsx +326 -0
  141. package/shared/components/payments/WalletTermsAndConditionComponent.tsx +88 -0
  142. package/shared/constants/address-shipping.schema.ts +56 -0
  143. package/shared/constants/address.schema.ts +56 -0
  144. package/shared/constants/app.ts +323 -0
  145. package/shared/constants/environment.ts +23 -0
  146. package/shared/constants/feature-flags.ts +15 -0
  147. package/shared/constants/query-keys.ts +106 -0
  148. package/shared/constants/routes.ts +41 -0
  149. package/shared/constants/socket.ts +15 -0
  150. package/shared/contexts/HomeProductsContext.tsx +51 -0
  151. package/shared/contexts/MainWrapperContext.tsx +289 -0
  152. package/shared/contexts/WebSocketContext.tsx +155 -0
  153. package/shared/hooks/useAddressForm.ts +169 -0
  154. package/shared/hooks/useAddresses.ts +28 -0
  155. package/shared/hooks/useAppForm.ts +39 -0
  156. package/shared/hooks/useCart.ts +207 -0
  157. package/shared/hooks/useCopy.ts +45 -0
  158. package/shared/hooks/useCountries.ts +27 -0
  159. package/shared/hooks/useCustomRouter.ts +51 -0
  160. package/shared/hooks/useDebounce.ts +21 -0
  161. package/shared/hooks/useInvoice.ts +41 -0
  162. package/shared/hooks/useOnlineUser.ts +38 -0
  163. package/shared/hooks/usePayments.ts +101 -0
  164. package/shared/hooks/useShippingAddressForm.ts +70 -0
  165. package/shared/hooks/useShippingAddresses.ts +33 -0
  166. package/shared/hooks/useStores.ts +29 -0
  167. package/shared/hooks/useUserActivity.ts +43 -0
  168. package/shared/i18n/client.ts +27 -0
  169. package/shared/i18n/locales/en.ts +383 -0
  170. package/shared/i18n/locales/it.ts +373 -0
  171. package/shared/i18n/server.ts +7 -0
  172. package/shared/services/addresses.service.ts +27 -0
  173. package/shared/services/api/core/ApiError.ts +29 -0
  174. package/shared/services/api/core/ApiRequestOptions.ts +25 -0
  175. package/shared/services/api/core/ApiResult.ts +11 -0
  176. package/shared/services/api/core/CancelablePromise.ts +130 -0
  177. package/shared/services/api/core/OpenAPI.ts +37 -0
  178. package/shared/services/api/core/request.ts +376 -0
  179. package/shared/services/api/index.ts +64 -0
  180. package/shared/services/api/models/AddAllProductToShippingCartDto.ts +7 -0
  181. package/shared/services/api/models/AddProductToCartDto.ts +8 -0
  182. package/shared/services/api/models/AddProductToShippingCartDto.ts +8 -0
  183. package/shared/services/api/models/AdminPlaceOrderDto.ts +16 -0
  184. package/shared/services/api/models/AssignPickupSerialNumberDto.ts +10 -0
  185. package/shared/services/api/models/CreateUserAddressDto.ts +19 -0
  186. package/shared/services/api/models/DeletCartProductsArrayDto.ts +7 -0
  187. package/shared/services/api/models/GenerateInvoiceDto.ts +7 -0
  188. package/shared/services/api/models/OrderConfirmationEmailDto.ts +8 -0
  189. package/shared/services/api/models/PlaceOrderDto.ts +9 -0
  190. package/shared/services/api/models/PlaceShipmentOrderDto.ts +8 -0
  191. package/shared/services/api/models/ProductBoostDto.ts +18 -0
  192. package/shared/services/api/models/RemoveAssignedSerialNumberDto.ts +9 -0
  193. package/shared/services/api/models/RemoveProductToCartDto.ts +8 -0
  194. package/shared/services/api/models/ShipmentItem.ts +8 -0
  195. package/shared/services/api/models/ShippingCartUpdateBillingAddressesDto.ts +7 -0
  196. package/shared/services/api/models/ShippingCartUpdateShippingMethodDto.ts +7 -0
  197. package/shared/services/api/models/UnfreezeWalletDto.ts +8 -0
  198. package/shared/services/api/models/UpdateCartBillingAddressesDto.ts +7 -0
  199. package/shared/services/api/models/UpdateCartPaymentMethodDto.ts +9 -0
  200. package/shared/services/api/models/UpdateCartShippingMethodDto.ts +7 -0
  201. package/shared/services/api/models/UpdateCartStoreDto.ts +7 -0
  202. package/shared/services/api/models/UpdateProductDto.ts +11 -0
  203. package/shared/services/api/models/UpdateShipmentItemStatusDto.ts +24 -0
  204. package/shared/services/api/models/UpdateShippingCartPaymentMethodDto.ts +9 -0
  205. package/shared/services/api/models/UpdateUserAddressDto.ts +19 -0
  206. package/shared/services/api/models/ValidateAuthCodeDto.ts +8 -0
  207. package/shared/services/api/models/WithdrawOrderWalletDto.ts +8 -0
  208. package/shared/services/api/services/AddressesService.ts +160 -0
  209. package/shared/services/api/services/AdminsDevicesService.ts +28 -0
  210. package/shared/services/api/services/AdminsOrdersService.ts +117 -0
  211. package/shared/services/api/services/AdminsPickupsService.ts +57 -0
  212. package/shared/services/api/services/AdminsProductsService.ts +86 -0
  213. package/shared/services/api/services/CartsService.ts +190 -0
  214. package/shared/services/api/services/CashBackQueueService.ts +39 -0
  215. package/shared/services/api/services/CategoriesService.ts +65 -0
  216. package/shared/services/api/services/DefaultService.ts +19 -0
  217. package/shared/services/api/services/FeaturesFlagsService.ts +20 -0
  218. package/shared/services/api/services/IossQueueService.ts +39 -0
  219. package/shared/services/api/services/OrderCallbackService.ts +67 -0
  220. package/shared/services/api/services/OrderEmailsService.ts +40 -0
  221. package/shared/services/api/services/OrderImportService.ts +228 -0
  222. package/shared/services/api/services/OrdersService.ts +183 -0
  223. package/shared/services/api/services/PaymentGatewayService.ts +19 -0
  224. package/shared/services/api/services/PaymentsService.ts +88 -0
  225. package/shared/services/api/services/ProductsService.ts +67 -0
  226. package/shared/services/api/services/ShipmentOrderCallbackService.ts +67 -0
  227. package/shared/services/api/services/ShipmentOrdersService.ts +88 -0
  228. package/shared/services/api/services/ShipmentsService.ts +30 -0
  229. package/shared/services/api/services/ShippingCartService.ts +247 -0
  230. package/shared/services/api/services/ShippingMethodsService.ts +20 -0
  231. package/shared/services/api/services/StoresService.ts +25 -0
  232. package/shared/services/api/services/SyncServiceQueueService.ts +39 -0
  233. package/shared/services/api/services/UpgradeOrdersService.ts +26 -0
  234. package/shared/services/api/services/UsersAuthService.ts +45 -0
  235. package/shared/services/api/services/UsersService.ts +53 -0
  236. package/shared/services/api/services/XeraQueueService.ts +39 -0
  237. package/shared/services/index.ts +0 -0
  238. package/shared/services/payment-method.service.ts +29 -0
  239. package/shared/stores/cartStore.ts +108 -0
  240. package/shared/stores/countriesStore.ts +62 -0
  241. package/shared/stores/formStore.ts +19 -0
  242. package/shared/stores/loadingStore.ts +12 -0
  243. package/shared/stores/userStore.ts +32 -0
  244. package/shared/types/SelectComponent.types.ts +31 -0
  245. package/shared/types/addressForm.ts +27 -0
  246. package/shared/types/cart.ts +208 -0
  247. package/shared/types/category.ts +6 -0
  248. package/shared/types/creditNote.ts +0 -0
  249. package/shared/types/feature-flags.ts +5 -0
  250. package/shared/types/icon.ts +5 -0
  251. package/shared/types/index.d.ts +84 -0
  252. package/shared/types/order.ts +332 -0
  253. package/shared/types/pagination.ts +5 -0
  254. package/shared/types/payments.ts +68 -0
  255. package/shared/types/product.ts +54 -0
  256. package/shared/types/shoppingCart.ts +219 -0
  257. package/shared/types/upgradeCart.ts +226 -0
  258. package/shared/types/user.ts +36 -0
  259. package/shared/utils/app.util.ts +261 -0
  260. package/shared/utils/notifications.util.ts +39 -0
  261. package/shared/utils/user-session.util.ts +171 -0
  262. package/tailwind.config.ts +234 -0
@@ -0,0 +1,281 @@
1
+ "use client";
2
+
3
+ import { IconButton, List, Typography } from "@material-tailwind/react";
4
+ import { usePathname } from "next/navigation";
5
+ import { useMemo } from "react";
6
+ import { BsBoxSeam, BsCart2 } from "react-icons/bs";
7
+ import { FiHeadphones } from "react-icons/fi";
8
+ import { HiOutlineUser } from "react-icons/hi";
9
+ import { IoDocumentTextOutline } from "react-icons/io5";
10
+ import { IoClose } from "react-icons/io5";
11
+ import { LiaWalletSolid } from "react-icons/lia";
12
+ import { MdContentCopy, MdOutlineLogout } from "react-icons/md";
13
+ import { TbHistory } from "react-icons/tb";
14
+ import { toast } from "react-toastify";
15
+
16
+ import { KYC_STATUS } from "../constants/app";
17
+ import { FeatureCodes } from "../constants/feature-flags";
18
+ import { ROUTES } from "../constants/routes";
19
+ import { useMainContext } from "../contexts/MainWrapperContext";
20
+ import useCopy from "../hooks/useCopy";
21
+ import useCustomRouter from "../hooks/useCustomRouter";
22
+ import useOnlineUser from "../hooks/useOnlineUser";
23
+ import { _useScopedI18n } from "../i18n/client";
24
+ import { useLoadingStore } from "../stores/loadingStore";
25
+ import { useUserStore } from "../stores/userStore";
26
+ import ButtonCustom from "./Button";
27
+ import { BrandIcon } from "./icons/BrandIcon";
28
+ import ListItemComponent from "./ListItemComponent";
29
+ import ServerTime from "./ServerTime";
30
+
31
+ export type SidebarProps = {
32
+ bidNumber: string;
33
+ onClose: () => void;
34
+ handleLogout: () => void;
35
+ cartProductsCount: number;
36
+ };
37
+
38
+ export default function Sidebar({
39
+ bidNumber,
40
+ onClose,
41
+ handleLogout,
42
+ cartProductsCount,
43
+ }: SidebarProps) {
44
+ //
45
+ const { handleCopy } = useCopy();
46
+ const { getAletaAuth } = useOnlineUser();
47
+ const { push } = useCustomRouter();
48
+ const { setLoading: setAppLoading } = useLoadingStore();
49
+ const { user } = useUserStore();
50
+
51
+ const pathname = usePathname();
52
+
53
+ const scopeT = _useScopedI18n("sideBarMenu");
54
+
55
+ const { featureFlags } = useMainContext();
56
+
57
+ const MENU_ITEMS = useMemo(() => {
58
+ //
59
+ const iconClassName = `h-5 w-5`;
60
+
61
+ return {
62
+ primary: [
63
+ {
64
+ icon: <BsBoxSeam className={iconClassName} />,
65
+ title: scopeT("products"),
66
+ href: ROUTES.dashboard.products,
67
+ badge: null,
68
+ active: pathname.startsWith(ROUTES.dashboard.products),
69
+ enable: true,
70
+ customActionEnable: false,
71
+ customAction: () => {},
72
+ },
73
+ {
74
+ icon: <BsCart2 className={iconClassName} />,
75
+ title: scopeT("myCart"),
76
+ href: ROUTES.dashboard.cart,
77
+ // badge: cartQty > 0 ? cartQty : null,
78
+ badge: cartProductsCount,
79
+ active:
80
+ pathname.startsWith(ROUTES.dashboard.cart) ||
81
+ pathname.startsWith(ROUTES.dashboard.checkout) ||
82
+ pathname.startsWith(ROUTES.dashboard.payment) ||
83
+ pathname.startsWith(ROUTES.dashboard.payment),
84
+ enable: true,
85
+ customActionEnable: false,
86
+ customAction: () => {},
87
+ },
88
+ {
89
+ icon: <TbHistory className={iconClassName} />,
90
+ title: scopeT("orderHistory"),
91
+ href: ROUTES.dashboard.orders,
92
+ badge: null,
93
+ active: pathname.startsWith(ROUTES.dashboard.orders),
94
+ enable: true,
95
+ customActionEnable: false,
96
+ customAction: () => {},
97
+ },
98
+ {
99
+ icon: <LiaWalletSolid className={iconClassName} />,
100
+ title: scopeT("AletaPay"),
101
+ href: "#",
102
+ badge:
103
+ (user &&
104
+ user?.pgUser?.aletaState === KYC_STATUS.SUBSCRIPTION_REQUIRED) ||
105
+ user?.pgUser?.aletaState === KYC_STATUS.KYC_REQUIRED ? (
106
+ <div className="text-xs">Setup Now</div>
107
+ ) : null,
108
+ active: pathname.startsWith("aleta"),
109
+ enable: !featureFlags?.[FeatureCodes.ALETA_PAYMENT]
110
+ ? false
111
+ : featureFlags?.[FeatureCodes.ALETA_PAYMENT]?.isActive === true,
112
+ customActionEnable: true,
113
+ customAction: async () => {
114
+ setAppLoading(true);
115
+ const result = await getAletaAuth();
116
+ if (result.isSuccess) {
117
+ push(result.data.authUrl);
118
+ } else {
119
+ toast.error(
120
+ <>
121
+ <span>
122
+ Failed to fetch aleta auth code, please try again later
123
+ </span>
124
+ </>,
125
+ {
126
+ position: "top-right",
127
+ autoClose: 2000,
128
+ },
129
+ );
130
+ }
131
+ setAppLoading(false);
132
+ },
133
+ },
134
+ ],
135
+ secondary: [
136
+ {
137
+ icon: <HiOutlineUser className={iconClassName} />,
138
+ title: scopeT("profile"),
139
+ href: ROUTES.dashboard.profile,
140
+ badge: null,
141
+ active: pathname.startsWith(ROUTES.dashboard.profile),
142
+ enable: true,
143
+ },
144
+ {
145
+ icon: <IoDocumentTextOutline className={iconClassName} />,
146
+ title: scopeT("wiki"),
147
+ href: ROUTES.dashboard.wiki,
148
+ badge: null,
149
+ active: false,
150
+ target: "_blank",
151
+ enable: true,
152
+ },
153
+ {
154
+ icon: <FiHeadphones className={iconClassName} />,
155
+ title: scopeT("support"),
156
+ href: ROUTES.dashboard.support,
157
+ badge: null,
158
+ active: false,
159
+ target: "_blank",
160
+ enable: true,
161
+ },
162
+ ],
163
+ };
164
+ }, [
165
+ pathname,
166
+ cartProductsCount,
167
+ scopeT,
168
+ featureFlags,
169
+ getAletaAuth,
170
+ push,
171
+ setAppLoading,
172
+ user,
173
+ ]);
174
+
175
+ return (
176
+ <>
177
+ <div className="bg-white">
178
+ <div className="md:h-[4.36rem] px-2 py-3 md:p-3 border-b border-b-slate-50 border-r-slate-50 flex justify-between lg:justify-center items-center z-50">
179
+ <a href="/products" className="w-36 brandIcon">
180
+ <BrandIcon width={150} height={34} />
181
+ </a>
182
+ <IconButton
183
+ onClick={onClose}
184
+ className="bg-gray-50 h-10 w-10 !max-h-10 !max-w-10 shadow-none border border-slate-50 lg:hidden"
185
+ >
186
+ <IoClose className="h-6 w-6 text-black-500" />
187
+ </IconButton>
188
+ </div>
189
+
190
+ <div className="sidebar-body p-2">
191
+ <div className="md:hidden mt-2">
192
+ <ServerTime />
193
+ </div>
194
+
195
+ {/* <div className="py-4 px-3">
196
+ <Typography
197
+ variant="h6"
198
+ className="text-xs text-gray-500 font-normal"
199
+ >
200
+ {scopeT("navigation")}
201
+ </Typography>
202
+ </div> */}
203
+ <List className="p-0 text-gray-500 gap-0 lg:gap-1 w-full min-w-full mt-1">
204
+ {MENU_ITEMS.primary.map(
205
+ (
206
+ {
207
+ icon,
208
+ title,
209
+ href,
210
+ badge,
211
+ active,
212
+ enable,
213
+ customAction,
214
+ customActionEnable,
215
+ },
216
+ index,
217
+ ) =>
218
+ enable && (
219
+ <ListItemComponent
220
+ key={index}
221
+ href={href}
222
+ prefix={icon}
223
+ ListItemName={title}
224
+ active={active}
225
+ cartProductsCount={badge}
226
+ customAction={customAction}
227
+ customActionEnable={customActionEnable}
228
+ onClick={onClose}
229
+ />
230
+ ),
231
+ )}
232
+
233
+ <hr className="m-3 block border-slate-50" />
234
+
235
+ {MENU_ITEMS.secondary.map(
236
+ ({ icon, title, href, badge, active, target, enable }, index) =>
237
+ enable && (
238
+ <ListItemComponent
239
+ key={index}
240
+ href={href}
241
+ prefix={icon}
242
+ ListItemName={title}
243
+ active={active}
244
+ target={target}
245
+ cartProductsCount={badge}
246
+ onClick={onClose}
247
+ />
248
+ ),
249
+ )}
250
+ </List>
251
+
252
+ <div className="p-3 flex justify-between items-center lg:hidden">
253
+ <Typography
254
+ as="span"
255
+ variant="small"
256
+ className="text-black-500 text-base font-medium"
257
+ >
258
+ Bid : {bidNumber}
259
+ </Typography>
260
+ <IconButton
261
+ variant="outlined"
262
+ className="p-0 rounded-full bg-gray-100/40 border-none"
263
+ onClick={() => handleCopy(bidNumber)}
264
+ >
265
+ <MdContentCopy className="h-4 w-4" />
266
+ </IconButton>
267
+ </div>
268
+ <div className="p-3 mt-5 lg:hidden">
269
+ <ButtonCustom
270
+ onClick={handleLogout}
271
+ icon={<MdOutlineLogout className="h-5 w-5" />}
272
+ className="gap-2 font-medium text-sm w-full p-3.5"
273
+ >
274
+ {scopeT("logout")}
275
+ </ButtonCustom>
276
+ </div>
277
+ </div>
278
+ </div>
279
+ </>
280
+ );
281
+ }
@@ -0,0 +1,193 @@
1
+ import {
2
+ Badge,
3
+ Dialog,
4
+ DialogBody,
5
+ DialogFooter,
6
+ DialogHeader,
7
+ Typography,
8
+ } from "@material-tailwind/react";
9
+ import React, { useEffect, useState } from "react";
10
+
11
+ import balloon from "../../public/gif/balloon.gif";
12
+ import gift from "../../public/gif/gift.gif";
13
+ import special from "../../public/img/special.png";
14
+ import { _useScopedI18n } from "../i18n/client";
15
+ import { useUpgradeCartStore } from "../stores/upgradeCartStore";
16
+ import ButtonCustom from "./Button";
17
+ import CustomNextImage from "./CustomNextImage";
18
+ import ProductPriceComponent from "./ProductPriceComponent";
19
+
20
+ export type SpecialOfferDialogProps = {
21
+ open: boolean;
22
+ onClose: () => void;
23
+ };
24
+
25
+ export function SpecialOfferDialog({ open, onClose }: SpecialOfferDialogProps) {
26
+ // const { upgradeCart, setUpgradeCart } = useUpgradeCartStore();
27
+ // const { addShippingCartProductAPI } =
28
+ // useShippingOrders();
29
+
30
+ const { upgradeCart, loading } = useUpgradeCartStore();
31
+
32
+ const scopeT = _useScopedI18n("cart");
33
+ return (
34
+ <>
35
+ <Dialog
36
+ open={open}
37
+ handler={onClose}
38
+ dismiss={{ outsidePress: false }}
39
+ size="sm"
40
+ className="
41
+ max-w-[95%]
42
+ md:max-w-[90%] md:min-w-[90%] md:w-[90%]
43
+ lg:max-w-[60%] lg:min-w-[60%] lg:w-[60%]
44
+ xl:max-w-[40%] xl:min-w-[40%] xl:w-[40%]
45
+ specialOfferBG
46
+ relative
47
+ "
48
+ >
49
+ <CustomNextImage
50
+ src={balloon.src}
51
+ alt="Special offer balloon"
52
+ width={125}
53
+ height={125}
54
+ className="absolute top-[-60px] right-0 md:right-[-60px]"
55
+ />
56
+ <CustomNextImage
57
+ src={balloon.src}
58
+ alt="Special offer balloon"
59
+ width={125}
60
+ height={125}
61
+ className="absolute top-[-60px] left-0 md:left-[-60px]"
62
+ />
63
+ <DialogHeader className="w-full rounded-tl-lg rounded-tr-lg p-8 pb-14">
64
+ <div className="flex flex-col items-center md:w-1/2 mx-auto">
65
+ <CustomNextImage
66
+ src={special.src}
67
+ alt="power icon"
68
+ width={270}
69
+ height={98}
70
+ />
71
+ <Typography
72
+ variant="h6"
73
+ className="text-base md:text-xl font-semibold text-black-500 text-center"
74
+ >
75
+ {scopeT("discountApplied")}
76
+ </Typography>
77
+ </div>
78
+ </DialogHeader>
79
+
80
+ <ul>
81
+ <DialogBody className="p-3 mt-5 md:px-4 md:py-0 max-h-[50vh] overflow-y-auto overflow-x-hidden">
82
+ {loading ? (
83
+ <div className="flex justify-center items-center">
84
+ <div
85
+ className="inline-block h-4 w-4 animate-spin rounded-full border-4 border-solid border-current border-r-transparent align-[-0.125em] motion-reduce:animate-[spin_1.5s_linear_infinite]"
86
+ role="status"
87
+ >
88
+ <span className="!absolute !-m-px !h-px !w-px !overflow-hidden !whitespace-nowrap !border-0 !p-0 ![clip:rect(0,0,0,0)]">
89
+ {scopeT("loading")}
90
+ </span>
91
+ </div>
92
+ </div>
93
+ ) : (
94
+ <>
95
+ {upgradeCart?.cartProducts?.map((item) => (
96
+ <li
97
+ key={item.id}
98
+ className="flex flex-wrap gap-4 justify-between items-center border-b border-b-slate-50 py-4 first-of-type:pt-0"
99
+ >
100
+ <div className="relative py-5">
101
+ <div className="absolute right-1 top-1">
102
+ <Badge
103
+ content={item?.quantity}
104
+ className="text-[0.688rem] min-w-5 min-h-fit py-0.5 px-1.5"
105
+ >
106
+ {" "}
107
+ </Badge>
108
+ </div>
109
+ <div className="w-[40px] md:w-[55px] border border-slate-50 rounded-md ">
110
+ <CustomNextImage
111
+ src={item.product.featureImage}
112
+ alt={item.product.name}
113
+ height={55}
114
+ width={55}
115
+ />
116
+ </div>
117
+ </div>
118
+ <div className="flex flex-col justify-center flex-1 h-full">
119
+ <Typography
120
+ variant="h5"
121
+ className="text-lg font-medium text-black-500 mb-0 md:mb-2 line-clamp-2 font-box"
122
+ >
123
+ {item.product.name}
124
+ </Typography>
125
+ </div>
126
+ <PriceDisplayWithGif item={item} />
127
+ </li>
128
+ ))}
129
+ </>
130
+ )}
131
+ </DialogBody>
132
+ <DialogFooter className="gap-4 flex justify-center">
133
+ <ButtonCustom
134
+ variant="filled"
135
+ className="!py-3 !text-sm"
136
+ icon={undefined}
137
+ onClick={() => {
138
+ onClose();
139
+ }}
140
+ >
141
+ {scopeT("proceed")}
142
+ </ButtonCustom>
143
+ </DialogFooter>
144
+ </ul>
145
+ </Dialog>
146
+ </>
147
+ );
148
+ }
149
+
150
+ const PriceDisplayWithGif = ({ item }) => {
151
+ const [showGif, setShowGif] = useState(true);
152
+
153
+ useEffect(() => {
154
+ // Show gif for 3 seconds then switch to price display
155
+ const timer = setTimeout(() => {
156
+ setShowGif(false);
157
+ }, 1500);
158
+
159
+ // Cleanup timer on component unmount
160
+ return () => clearTimeout(timer);
161
+ }, []); // Empty dependency array means this runs once on mount
162
+
163
+ return (
164
+ <>
165
+ {showGif ? (
166
+ <CustomNextImage
167
+ src={gift.src}
168
+ alt="Special offer gift"
169
+ width={100}
170
+ height={100}
171
+ className="gift-animation"
172
+ />
173
+ ) : (
174
+ <div className="flex gap-3 items-center">
175
+ <Typography
176
+ variant="h5"
177
+ className="text-2xl font-semibold text-[#9451A0] mb-0 md:mb-3"
178
+ >
179
+ <ProductPriceComponent amount={item.price} />
180
+ </Typography>
181
+ {item.discount > 0 && (
182
+ <Typography
183
+ variant="small"
184
+ className="text-base font-semibold line-through text-black-500 mb-0 md:mb-3"
185
+ >
186
+ <ProductPriceComponent amount={item.originalPrice} />
187
+ </Typography>
188
+ )}
189
+ </div>
190
+ )}
191
+ </>
192
+ );
193
+ };
@@ -0,0 +1,25 @@
1
+ import { Chip } from "@material-tailwind/react";
2
+ import React from "react";
3
+
4
+ export type StatusComponentsProps = {
5
+ color: any;
6
+ value: string;
7
+ className: string;
8
+ };
9
+
10
+ export default function StatusComponents({
11
+ color,
12
+ value,
13
+ className,
14
+ }: StatusComponentsProps) {
15
+ return (
16
+ <div className="relative w-fit">
17
+ <Chip
18
+ variant="ghost"
19
+ value={value.toUpperCase()}
20
+ color={color}
21
+ className={className}
22
+ />
23
+ </div>
24
+ );
25
+ }
@@ -0,0 +1,79 @@
1
+ "use client";
2
+
3
+ import { Step, Stepper, Typography } from "@material-tailwind/react";
4
+ import { useEffect, useState } from "react";
5
+ import { FaCircle } from "react-icons/fa";
6
+ import { FaRegCircleCheck } from "react-icons/fa6";
7
+
8
+ import { CART_STATUS } from "../constants/app";
9
+ import { _useScopedI18n } from "../i18n/client";
10
+ import { ICart } from "../types/cart";
11
+
12
+ type StepperComponentProb = {
13
+ cart: ICart;
14
+ };
15
+
16
+ const stepperStateValues = {
17
+ [CART_STATUS.shopping]: 0,
18
+ [CART_STATUS.checkout]: 1,
19
+ [CART_STATUS.payment]: 2,
20
+ };
21
+
22
+ export default function StepperComponent({ cart }: StepperComponentProb) {
23
+ //
24
+ const scopeT = _useScopedI18n("sharedComponents.cartStepperComponent");
25
+
26
+ const steps = [
27
+ { label: scopeT("first") },
28
+ { label: scopeT("second") },
29
+ { label: scopeT("third") },
30
+ { label: scopeT("four") },
31
+ ];
32
+
33
+ const [activeStep, setActiveStep] = useState(
34
+ stepperStateValues[cart?.cartState] ?? 0,
35
+ );
36
+
37
+ useEffect(() => {
38
+ if (cart) {
39
+ (async () =>
40
+ await setActiveStep(stepperStateValues[cart?.cartState] ?? 0))();
41
+ }
42
+ }, [cart]);
43
+
44
+ return (
45
+ <>
46
+ <div className="md:flex-1 w-full md:mb-8 py-2 md:px-20 md:py-2 z-0">
47
+ <Stepper
48
+ activeStep={activeStep}
49
+ lineClassName="bg-slate-50 h-1"
50
+ activeLineClassName="bg-sushiGreen"
51
+ >
52
+ {steps.map((step, index) => (
53
+ <Step
54
+ key={index}
55
+ className="h-7 w-7 bg-slate-50 border-4 border-transparent"
56
+ activeClassName="border-4 border-sushiGreen bg-white text-black"
57
+ completedClassName="bg-sushiGreen text-black"
58
+ >
59
+ {index === activeStep ? (
60
+ <FaCircle className="h-3 w-3 text-sushiGreen" />
61
+ ) : index < activeStep ? (
62
+ <FaRegCircleCheck className="h-4 w-4 text-white" />
63
+ ) : null}
64
+
65
+ <div className="absolute -bottom-8 w-max text-center">
66
+ <Typography
67
+ variant="h6"
68
+ className={`${index === activeStep ? "text-black-500" : "text-slate-500"} text-sm font-medium hidden md:block`}
69
+ >
70
+ {step.label}
71
+ </Typography>
72
+ </div>
73
+ </Step>
74
+ ))}
75
+ </Stepper>
76
+ </div>
77
+ </>
78
+ );
79
+ }
@@ -0,0 +1,97 @@
1
+ "use client";
2
+
3
+ import { Step, Stepper, Typography } from "@material-tailwind/react";
4
+ import { useEffect, useState } from "react";
5
+ import { FaCircle } from "react-icons/fa";
6
+ import { FaRegCircleCheck } from "react-icons/fa6";
7
+
8
+ import { CART_STATUS } from "../constants/app";
9
+ import { _useScopedI18n } from "../i18n/client";
10
+ import { ICart } from "../types/cart";
11
+
12
+ type StepperSmartPayComponentProb = {
13
+ cart: ICart;
14
+ };
15
+
16
+ const stepperStateValues = {
17
+ [CART_STATUS.shopping]: 0,
18
+ [CART_STATUS.checkout]: 1,
19
+ [CART_STATUS.payment]: 2,
20
+ [CART_STATUS.review]: 3,
21
+ [CART_STATUS.deliveryPayment]: 4,
22
+ };
23
+
24
+ export default function StepperSmartPayComponent({
25
+ cart,
26
+ }: StepperSmartPayComponentProb) {
27
+ //
28
+ const scopeT = _useScopedI18n("sharedComponents.cartStepperComponent");
29
+
30
+ const steps = [
31
+ { label: scopeT("first") },
32
+ { label: scopeT("second") },
33
+ { label: scopeT("productPayment") },
34
+ { label: scopeT("review") },
35
+ { label: scopeT("deliveryPayment") },
36
+ ];
37
+
38
+ const [activeStep, setActiveStep] = useState(
39
+ stepperStateValues[cart?.cartState] ?? 0,
40
+ );
41
+
42
+ useEffect(() => {
43
+ if (cart) {
44
+ (async () =>
45
+ await setActiveStep(stepperStateValues[cart?.cartState] ?? 0))();
46
+ }
47
+ }, [cart]);
48
+
49
+ return (
50
+ <>
51
+ <div className="flex items-center justify-between gap-4 md:flex-1 w-full md:mb-8 py-2 px-20 md:px-[15%] lg:px-[20%] md:py-2 z-0">
52
+ <Stepper
53
+ activeStep={activeStep}
54
+ lineClassName="bg-slate-50 h-1"
55
+ activeLineClassName="bg-sushiGreen"
56
+ >
57
+ {steps.map((step, index) => (
58
+ <Step
59
+ key={index}
60
+ className="h-7 w-7 bg-slate-50 border-4 border-transparent"
61
+ activeClassName="border-4 border-sushiGreen bg-white text-black"
62
+ completedClassName="bg-sushiGreen text-black"
63
+ >
64
+ {index === 4 ? (
65
+ <div className="absolute top-[-10px] left-[-10px] rounded-[8px] bg-[#FCFDFF] border-solid border-[#E3E9F6] border-[5px] py-[15px] px-[20px]">
66
+ <Typography
67
+ variant="h6"
68
+ className={`font-semibold text-xs hidden md:block`}
69
+ >
70
+ {step.label}
71
+ </Typography>
72
+ </div>
73
+ ) : (
74
+ <>
75
+ {index === activeStep ? (
76
+ <FaCircle className="h-3 w-3 text-sushiGreen" />
77
+ ) : index < activeStep ? (
78
+ <FaRegCircleCheck className="h-4 w-4 text-white" />
79
+ ) : null}
80
+
81
+ <div className="absolute -bottom-8 w-max text-center">
82
+ <Typography
83
+ variant="h6"
84
+ className={`${index === activeStep ? "text-black-500" : "text-slate-500"} text-sm font-medium hidden md:block`}
85
+ >
86
+ {step.label}
87
+ </Typography>
88
+ </div>
89
+ </>
90
+ )}
91
+ </Step>
92
+ ))}
93
+ </Stepper>
94
+ </div>
95
+ </>
96
+ );
97
+ }