hey-pharmacist-ecommerce 1.1.36 → 1.1.37
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.
- package/dist/index.js +921 -720
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +574 -373
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/NotificationBell.tsx +74 -21
- package/src/components/NotificationModal.tsx +223 -0
- package/src/components/QuickViewModal.tsx +1 -1
- package/src/providers/EcommerceProvider.tsx +0 -2
- package/src/screens/OrderDetailScreen.tsx +2 -2
- package/src/screens/ProductDetailScreen.tsx +5 -5
- package/src/screens/ShopScreen.tsx +3 -3
- package/src/screens/WishlistScreen.tsx +1 -1
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var
|
|
4
|
+
var React10 = require('react');
|
|
5
5
|
var jsxRuntime = require('react/jsx-runtime');
|
|
6
6
|
var globalAxios21 = require('axios');
|
|
7
7
|
var framerMotion = require('framer-motion');
|
|
@@ -18,7 +18,7 @@ var zod = require('zod');
|
|
|
18
18
|
|
|
19
19
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
20
20
|
|
|
21
|
-
var
|
|
21
|
+
var React10__default = /*#__PURE__*/_interopDefault(React10);
|
|
22
22
|
var globalAxios21__default = /*#__PURE__*/_interopDefault(globalAxios21);
|
|
23
23
|
var Image4__default = /*#__PURE__*/_interopDefault(Image4);
|
|
24
24
|
var Link9__default = /*#__PURE__*/_interopDefault(Link9);
|
|
@@ -228,16 +228,16 @@ function darken(r, g, b, amount) {
|
|
|
228
228
|
const newB = Math.round(b * (1 - amount));
|
|
229
229
|
return formatRgb(newR, newG, newB);
|
|
230
230
|
}
|
|
231
|
-
var ThemeContext =
|
|
231
|
+
var ThemeContext = React10.createContext(void 0);
|
|
232
232
|
function useTheme() {
|
|
233
|
-
const context =
|
|
233
|
+
const context = React10.useContext(ThemeContext);
|
|
234
234
|
if (!context) {
|
|
235
235
|
throw new Error("useTheme must be used within ThemeProvider");
|
|
236
236
|
}
|
|
237
237
|
return context;
|
|
238
238
|
}
|
|
239
239
|
function ThemeProvider({ config, children }) {
|
|
240
|
-
|
|
240
|
+
React10.useEffect(() => {
|
|
241
241
|
const primaryShades = generateColorShades(config.colors.primary);
|
|
242
242
|
const secondaryShades = generateColorShades(config.colors.secondary);
|
|
243
243
|
const accentShades = generateColorShades(config.colors.accent);
|
|
@@ -1994,17 +1994,17 @@ var AuthApi = class extends BaseAPI {
|
|
|
1994
1994
|
return AuthApiFp(this.configuration).verifyUserEmail(body, options).then((request) => request(this.axios, this.basePath));
|
|
1995
1995
|
}
|
|
1996
1996
|
};
|
|
1997
|
-
var AuthContext =
|
|
1997
|
+
var AuthContext = React10.createContext(void 0);
|
|
1998
1998
|
function useAuth() {
|
|
1999
|
-
const context =
|
|
1999
|
+
const context = React10.useContext(AuthContext);
|
|
2000
2000
|
if (!context) {
|
|
2001
2001
|
throw new Error("useAuth must be used within AuthProvider");
|
|
2002
2002
|
}
|
|
2003
2003
|
return context;
|
|
2004
2004
|
}
|
|
2005
2005
|
function AuthProvider({ children }) {
|
|
2006
|
-
const [user, setUser] =
|
|
2007
|
-
const [isLoading, setIsLoading] =
|
|
2006
|
+
const [user, setUser] = React10.useState(null);
|
|
2007
|
+
const [isLoading, setIsLoading] = React10.useState(true);
|
|
2008
2008
|
const getUserKey = () => {
|
|
2009
2009
|
if (typeof window === "undefined") return "ecommerce_user";
|
|
2010
2010
|
const token = getAuthToken();
|
|
@@ -2016,7 +2016,7 @@ function AuthProvider({ children }) {
|
|
|
2016
2016
|
return "ecommerce_user";
|
|
2017
2017
|
}
|
|
2018
2018
|
};
|
|
2019
|
-
const refreshUser =
|
|
2019
|
+
const refreshUser = React10.useCallback(async () => {
|
|
2020
2020
|
try {
|
|
2021
2021
|
const token = getAuthToken();
|
|
2022
2022
|
if (token) {
|
|
@@ -2030,7 +2030,7 @@ function AuthProvider({ children }) {
|
|
|
2030
2030
|
setIsLoading(false);
|
|
2031
2031
|
}
|
|
2032
2032
|
}, []);
|
|
2033
|
-
|
|
2033
|
+
React10.useEffect(() => {
|
|
2034
2034
|
if (typeof window !== "undefined") {
|
|
2035
2035
|
try {
|
|
2036
2036
|
const userKey = getUserKey();
|
|
@@ -11811,11 +11811,11 @@ var notificationConfig = {
|
|
|
11811
11811
|
}
|
|
11812
11812
|
};
|
|
11813
11813
|
function Notification2({ notification, onDismiss }) {
|
|
11814
|
-
const [progress, setProgress] =
|
|
11814
|
+
const [progress, setProgress] = React10.useState(100);
|
|
11815
11815
|
const config = notificationConfig[notification.type];
|
|
11816
11816
|
const Icon = config.icon;
|
|
11817
11817
|
const duration = notification.duration || 4e3;
|
|
11818
|
-
|
|
11818
|
+
React10.useEffect(() => {
|
|
11819
11819
|
const startTime = Date.now();
|
|
11820
11820
|
const timer = setInterval(() => {
|
|
11821
11821
|
const elapsed = Date.now() - startTime;
|
|
@@ -11878,17 +11878,17 @@ function Notification2({ notification, onDismiss }) {
|
|
|
11878
11878
|
function NotificationContainer({ notifications, onDismiss }) {
|
|
11879
11879
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "fixed top-4 right-4 z-50 flex flex-col gap-3 pointer-events-none", children: /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { mode: "popLayout", children: notifications.map((notification) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pointer-events-auto", children: /* @__PURE__ */ jsxRuntime.jsx(Notification2, { notification, onDismiss }) }, notification.id)) }) });
|
|
11880
11880
|
}
|
|
11881
|
-
var NotificationContext =
|
|
11881
|
+
var NotificationContext = React10.createContext(void 0);
|
|
11882
11882
|
function useNotification() {
|
|
11883
|
-
const context =
|
|
11883
|
+
const context = React10.useContext(NotificationContext);
|
|
11884
11884
|
if (!context) {
|
|
11885
11885
|
throw new Error("useNotification must be used within NotificationProvider");
|
|
11886
11886
|
}
|
|
11887
11887
|
return context;
|
|
11888
11888
|
}
|
|
11889
11889
|
function NotificationProvider({ children }) {
|
|
11890
|
-
const [notifications, setNotifications] =
|
|
11891
|
-
const addNotification =
|
|
11890
|
+
const [notifications, setNotifications] = React10.useState([]);
|
|
11891
|
+
const addNotification = React10.useCallback(
|
|
11892
11892
|
(type, message, description, duration) => {
|
|
11893
11893
|
const id = Math.random().toString(36).substring(2, 9);
|
|
11894
11894
|
const notification = {
|
|
@@ -11902,23 +11902,23 @@ function NotificationProvider({ children }) {
|
|
|
11902
11902
|
},
|
|
11903
11903
|
[]
|
|
11904
11904
|
);
|
|
11905
|
-
const dismissNotification =
|
|
11905
|
+
const dismissNotification = React10.useCallback((id) => {
|
|
11906
11906
|
setNotifications((prev) => prev.filter((n) => n.id !== id));
|
|
11907
11907
|
}, []);
|
|
11908
11908
|
const value = {
|
|
11909
|
-
success:
|
|
11909
|
+
success: React10.useCallback(
|
|
11910
11910
|
(message, description, duration) => addNotification("success", message, description, duration),
|
|
11911
11911
|
[addNotification]
|
|
11912
11912
|
),
|
|
11913
|
-
error:
|
|
11913
|
+
error: React10.useCallback(
|
|
11914
11914
|
(message, description, duration) => addNotification("error", message, description, duration),
|
|
11915
11915
|
[addNotification]
|
|
11916
11916
|
),
|
|
11917
|
-
warning:
|
|
11917
|
+
warning: React10.useCallback(
|
|
11918
11918
|
(message, description, duration) => addNotification("warning", message, description, duration),
|
|
11919
11919
|
[addNotification]
|
|
11920
11920
|
),
|
|
11921
|
-
info:
|
|
11921
|
+
info: React10.useCallback(
|
|
11922
11922
|
(message, description, duration) => addNotification("info", message, description, duration),
|
|
11923
11923
|
[addNotification]
|
|
11924
11924
|
)
|
|
@@ -11928,24 +11928,24 @@ function NotificationProvider({ children }) {
|
|
|
11928
11928
|
/* @__PURE__ */ jsxRuntime.jsx(NotificationContainer, { notifications, onDismiss: dismissNotification })
|
|
11929
11929
|
] });
|
|
11930
11930
|
}
|
|
11931
|
-
var CartContext =
|
|
11931
|
+
var CartContext = React10.createContext(void 0);
|
|
11932
11932
|
function useCart() {
|
|
11933
|
-
const context =
|
|
11933
|
+
const context = React10.useContext(CartContext);
|
|
11934
11934
|
if (!context) {
|
|
11935
11935
|
throw new Error("useCart must be used within CartProvider");
|
|
11936
11936
|
}
|
|
11937
11937
|
return context;
|
|
11938
11938
|
}
|
|
11939
11939
|
function CartProvider({ children }) {
|
|
11940
|
-
const [cart, setCart] =
|
|
11941
|
-
const [isLoading, setIsLoading] =
|
|
11940
|
+
const [cart, setCart] = React10.useState(null);
|
|
11941
|
+
const [isLoading, setIsLoading] = React10.useState(false);
|
|
11942
11942
|
const { isAuthenticated } = useAuth();
|
|
11943
11943
|
const notification = useNotification();
|
|
11944
|
-
const cartRef =
|
|
11945
|
-
|
|
11944
|
+
const cartRef = React10.useRef(cart);
|
|
11945
|
+
React10.useEffect(() => {
|
|
11946
11946
|
cartRef.current = cart;
|
|
11947
11947
|
}, [cart]);
|
|
11948
|
-
const refreshCart =
|
|
11948
|
+
const refreshCart = React10.useCallback(async () => {
|
|
11949
11949
|
if (!isAuthenticated) {
|
|
11950
11950
|
setCart(null);
|
|
11951
11951
|
return;
|
|
@@ -11959,10 +11959,10 @@ function CartProvider({ children }) {
|
|
|
11959
11959
|
console.error("Failed to fetch cart:", error);
|
|
11960
11960
|
}
|
|
11961
11961
|
}, [isAuthenticated]);
|
|
11962
|
-
|
|
11962
|
+
React10.useEffect(() => {
|
|
11963
11963
|
refreshCart();
|
|
11964
11964
|
}, [refreshCart]);
|
|
11965
|
-
const addToCart =
|
|
11965
|
+
const addToCart = React10.useCallback(async (productId, quantity = 1, variantId) => {
|
|
11966
11966
|
if (!isAuthenticated) return;
|
|
11967
11967
|
setIsLoading(true);
|
|
11968
11968
|
try {
|
|
@@ -12004,7 +12004,7 @@ function CartProvider({ children }) {
|
|
|
12004
12004
|
setIsLoading(false);
|
|
12005
12005
|
}
|
|
12006
12006
|
}, [isAuthenticated, notification]);
|
|
12007
|
-
const updateQuantity =
|
|
12007
|
+
const updateQuantity = React10.useCallback(async (productId, quantity) => {
|
|
12008
12008
|
const currentCart = cartRef.current;
|
|
12009
12009
|
if (!currentCart) return;
|
|
12010
12010
|
setIsLoading(true);
|
|
@@ -12050,7 +12050,7 @@ function CartProvider({ children }) {
|
|
|
12050
12050
|
setIsLoading(false);
|
|
12051
12051
|
}
|
|
12052
12052
|
}, [notification, refreshCart]);
|
|
12053
|
-
const removeFromCart =
|
|
12053
|
+
const removeFromCart = React10.useCallback(async (productId) => {
|
|
12054
12054
|
const currentCart = cartRef.current;
|
|
12055
12055
|
if (!currentCart) return;
|
|
12056
12056
|
setIsLoading(true);
|
|
@@ -12097,7 +12097,7 @@ function CartProvider({ children }) {
|
|
|
12097
12097
|
setIsLoading(false);
|
|
12098
12098
|
}
|
|
12099
12099
|
}, [notification]);
|
|
12100
|
-
const clearCart =
|
|
12100
|
+
const clearCart = React10.useCallback(async () => {
|
|
12101
12101
|
setIsLoading(true);
|
|
12102
12102
|
try {
|
|
12103
12103
|
await new CartApi(getApiConfiguration()).clearCart();
|
|
@@ -12153,9 +12153,9 @@ if (typeof window !== "undefined") {
|
|
|
12153
12153
|
AXIOS_CONFIG.baseOptions.signal = abortController.signal;
|
|
12154
12154
|
}
|
|
12155
12155
|
}
|
|
12156
|
-
var WishlistContext =
|
|
12156
|
+
var WishlistContext = React10.createContext(void 0);
|
|
12157
12157
|
function WishlistProvider({ children }) {
|
|
12158
|
-
const [state, setState] =
|
|
12158
|
+
const [state, setState] = React10.useState({
|
|
12159
12159
|
_id: "",
|
|
12160
12160
|
createdAt: /* @__PURE__ */ new Date(),
|
|
12161
12161
|
updatedAt: /* @__PURE__ */ new Date(),
|
|
@@ -12164,8 +12164,8 @@ function WishlistProvider({ children }) {
|
|
|
12164
12164
|
});
|
|
12165
12165
|
const { isAuthenticated } = useAuth() || {};
|
|
12166
12166
|
const notification = useNotification();
|
|
12167
|
-
const wishlistApi =
|
|
12168
|
-
const fetchWishlist =
|
|
12167
|
+
const wishlistApi = React10.useMemo(() => new WishlistApi(AXIOS_CONFIG), []);
|
|
12168
|
+
const fetchWishlist = React10.useCallback(async () => {
|
|
12169
12169
|
if (!isAuthenticated) {
|
|
12170
12170
|
setState((prev) => ({
|
|
12171
12171
|
...prev,
|
|
@@ -12194,7 +12194,7 @@ function WishlistProvider({ children }) {
|
|
|
12194
12194
|
}));
|
|
12195
12195
|
}
|
|
12196
12196
|
}, [isAuthenticated]);
|
|
12197
|
-
|
|
12197
|
+
React10.useEffect(() => {
|
|
12198
12198
|
fetchWishlist();
|
|
12199
12199
|
}, [fetchWishlist]);
|
|
12200
12200
|
const addToWishlist = async (product) => {
|
|
@@ -12297,13 +12297,13 @@ function WishlistProvider({ children }) {
|
|
|
12297
12297
|
);
|
|
12298
12298
|
}
|
|
12299
12299
|
var useWishlist = () => {
|
|
12300
|
-
const context =
|
|
12300
|
+
const context = React10.useContext(WishlistContext);
|
|
12301
12301
|
if (context === void 0) {
|
|
12302
12302
|
throw new Error("useWishlist must be used within a WishlistProvider");
|
|
12303
12303
|
}
|
|
12304
12304
|
return context;
|
|
12305
12305
|
};
|
|
12306
|
-
var BasePathContext =
|
|
12306
|
+
var BasePathContext = React10.createContext(void 0);
|
|
12307
12307
|
function BasePathProvider({ basePath = "", children }) {
|
|
12308
12308
|
const normalized = basePath ? basePath.startsWith("/") ? basePath : `/${basePath}` : "";
|
|
12309
12309
|
const buildPath = (path) => {
|
|
@@ -12316,7 +12316,7 @@ function BasePathProvider({ basePath = "", children }) {
|
|
|
12316
12316
|
return /* @__PURE__ */ jsxRuntime.jsx(BasePathContext.Provider, { value: { basePath: normalized, buildPath }, children });
|
|
12317
12317
|
}
|
|
12318
12318
|
function useBasePath() {
|
|
12319
|
-
const ctx =
|
|
12319
|
+
const ctx = React10.useContext(BasePathContext);
|
|
12320
12320
|
if (!ctx) throw new Error("useBasePath must be used within BasePathProvider");
|
|
12321
12321
|
return ctx;
|
|
12322
12322
|
}
|
|
@@ -12347,12 +12347,12 @@ function formatDiscountDisplay(discount) {
|
|
|
12347
12347
|
return `$${discount.value.toFixed(2)} OFF`;
|
|
12348
12348
|
}
|
|
12349
12349
|
}
|
|
12350
|
-
var DiscountContext =
|
|
12350
|
+
var DiscountContext = React10.createContext(void 0);
|
|
12351
12351
|
function DiscountProvider({ children }) {
|
|
12352
|
-
const [appliedCoupon, setAppliedCoupon] =
|
|
12353
|
-
const [couponError, setCouponError] =
|
|
12354
|
-
const [isValidatingCoupon, setIsValidatingCoupon] =
|
|
12355
|
-
const validateAndApplyCoupon =
|
|
12352
|
+
const [appliedCoupon, setAppliedCoupon] = React10.useState(null);
|
|
12353
|
+
const [couponError, setCouponError] = React10.useState(null);
|
|
12354
|
+
const [isValidatingCoupon, setIsValidatingCoupon] = React10.useState(false);
|
|
12355
|
+
const validateAndApplyCoupon = React10.useCallback(
|
|
12356
12356
|
async (code, userId) => {
|
|
12357
12357
|
setIsValidatingCoupon(true);
|
|
12358
12358
|
setCouponError(null);
|
|
@@ -12379,11 +12379,11 @@ function DiscountProvider({ children }) {
|
|
|
12379
12379
|
},
|
|
12380
12380
|
[]
|
|
12381
12381
|
);
|
|
12382
|
-
const removeCoupon =
|
|
12382
|
+
const removeCoupon = React10.useCallback(() => {
|
|
12383
12383
|
setAppliedCoupon(null);
|
|
12384
12384
|
setCouponError(null);
|
|
12385
12385
|
}, []);
|
|
12386
|
-
const calculateCouponDiscount =
|
|
12386
|
+
const calculateCouponDiscount = React10.useCallback(
|
|
12387
12387
|
(subtotal) => {
|
|
12388
12388
|
if (!appliedCoupon) {
|
|
12389
12389
|
return 0;
|
|
@@ -12404,16 +12404,16 @@ function DiscountProvider({ children }) {
|
|
|
12404
12404
|
return /* @__PURE__ */ jsxRuntime.jsx(DiscountContext.Provider, { value, children });
|
|
12405
12405
|
}
|
|
12406
12406
|
function useDiscountsContext() {
|
|
12407
|
-
const context =
|
|
12407
|
+
const context = React10.useContext(DiscountContext);
|
|
12408
12408
|
if (!context) {
|
|
12409
12409
|
throw new Error("useDiscountsContext must be used within DiscountProvider");
|
|
12410
12410
|
}
|
|
12411
12411
|
return context;
|
|
12412
12412
|
}
|
|
12413
12413
|
init_config();
|
|
12414
|
-
var NotificationCenterContext =
|
|
12414
|
+
var NotificationCenterContext = React10.createContext(void 0);
|
|
12415
12415
|
function useNotificationCenter() {
|
|
12416
|
-
const context =
|
|
12416
|
+
const context = React10.useContext(NotificationCenterContext);
|
|
12417
12417
|
if (!context) {
|
|
12418
12418
|
throw new Error("useNotificationCenter must be used within NotificationCenterProvider");
|
|
12419
12419
|
}
|
|
@@ -12421,16 +12421,16 @@ function useNotificationCenter() {
|
|
|
12421
12421
|
}
|
|
12422
12422
|
function NotificationCenterProvider({ children }) {
|
|
12423
12423
|
const { isAuthenticated } = useAuth();
|
|
12424
|
-
const [notifications, setNotifications] =
|
|
12425
|
-
const [unreadCount, setUnreadCount] =
|
|
12426
|
-
const [isLoading, setIsLoading] =
|
|
12427
|
-
const [isDrawerOpen, setIsDrawerOpen] =
|
|
12428
|
-
const [settings, setSettings] =
|
|
12429
|
-
const [page, setPage] =
|
|
12430
|
-
const [hasMore, setHasMore] =
|
|
12431
|
-
const eventSourceRef =
|
|
12432
|
-
const notificationsApi =
|
|
12433
|
-
const fetchUnreadCount =
|
|
12424
|
+
const [notifications, setNotifications] = React10.useState([]);
|
|
12425
|
+
const [unreadCount, setUnreadCount] = React10.useState(0);
|
|
12426
|
+
const [isLoading, setIsLoading] = React10.useState(false);
|
|
12427
|
+
const [isDrawerOpen, setIsDrawerOpen] = React10.useState(false);
|
|
12428
|
+
const [settings, setSettings] = React10.useState(null);
|
|
12429
|
+
const [page, setPage] = React10.useState(1);
|
|
12430
|
+
const [hasMore, setHasMore] = React10.useState(true);
|
|
12431
|
+
const eventSourceRef = React10.useRef(null);
|
|
12432
|
+
const notificationsApi = React10.useRef(new NotificationsApi(getApiConfiguration()));
|
|
12433
|
+
const fetchUnreadCount = React10.useCallback(async () => {
|
|
12434
12434
|
if (!isAuthenticated) return;
|
|
12435
12435
|
try {
|
|
12436
12436
|
const response = await notificationsApi.current.getUnreadCount();
|
|
@@ -12439,7 +12439,7 @@ function NotificationCenterProvider({ children }) {
|
|
|
12439
12439
|
console.error("Failed to fetch unread count:", error);
|
|
12440
12440
|
}
|
|
12441
12441
|
}, [isAuthenticated]);
|
|
12442
|
-
const fetchNotifications =
|
|
12442
|
+
const fetchNotifications = React10.useCallback(async (pageNum = 1, append = false) => {
|
|
12443
12443
|
if (!isAuthenticated) return;
|
|
12444
12444
|
setIsLoading(true);
|
|
12445
12445
|
try {
|
|
@@ -12476,7 +12476,7 @@ function NotificationCenterProvider({ children }) {
|
|
|
12476
12476
|
setIsLoading(false);
|
|
12477
12477
|
}
|
|
12478
12478
|
}, [isAuthenticated]);
|
|
12479
|
-
const fetchSettings =
|
|
12479
|
+
const fetchSettings = React10.useCallback(async () => {
|
|
12480
12480
|
if (!isAuthenticated) return;
|
|
12481
12481
|
setIsLoading(true);
|
|
12482
12482
|
try {
|
|
@@ -12532,7 +12532,7 @@ function NotificationCenterProvider({ children }) {
|
|
|
12532
12532
|
setIsLoading(false);
|
|
12533
12533
|
}
|
|
12534
12534
|
}, [isAuthenticated]);
|
|
12535
|
-
|
|
12535
|
+
React10.useEffect(() => {
|
|
12536
12536
|
if (!isAuthenticated) {
|
|
12537
12537
|
if (eventSourceRef.current) {
|
|
12538
12538
|
eventSourceRef.current.close();
|
|
@@ -12589,7 +12589,7 @@ function NotificationCenterProvider({ children }) {
|
|
|
12589
12589
|
console.error("Failed to establish SSE connection:", error);
|
|
12590
12590
|
}
|
|
12591
12591
|
}, [isAuthenticated, isDrawerOpen, fetchUnreadCount]);
|
|
12592
|
-
|
|
12592
|
+
React10.useEffect(() => {
|
|
12593
12593
|
if (isAuthenticated) {
|
|
12594
12594
|
fetchUnreadCount();
|
|
12595
12595
|
fetchNotifications(1);
|
|
@@ -12602,18 +12602,18 @@ function NotificationCenterProvider({ children }) {
|
|
|
12602
12602
|
setHasMore(true);
|
|
12603
12603
|
}
|
|
12604
12604
|
}, [isAuthenticated, fetchUnreadCount, fetchNotifications, fetchSettings]);
|
|
12605
|
-
|
|
12605
|
+
React10.useEffect(() => {
|
|
12606
12606
|
if ("Notification" in window && Notification.permission === "default") {
|
|
12607
12607
|
Notification.requestPermission();
|
|
12608
12608
|
}
|
|
12609
12609
|
}, []);
|
|
12610
|
-
const openDrawer =
|
|
12610
|
+
const openDrawer = React10.useCallback(() => {
|
|
12611
12611
|
setIsDrawerOpen(true);
|
|
12612
12612
|
}, []);
|
|
12613
|
-
const closeDrawer =
|
|
12613
|
+
const closeDrawer = React10.useCallback(() => {
|
|
12614
12614
|
setIsDrawerOpen(false);
|
|
12615
12615
|
}, []);
|
|
12616
|
-
const markAsRead =
|
|
12616
|
+
const markAsRead = React10.useCallback(async (id) => {
|
|
12617
12617
|
try {
|
|
12618
12618
|
await notificationsApi.current.markAsRead(id);
|
|
12619
12619
|
setNotifications(
|
|
@@ -12624,7 +12624,7 @@ function NotificationCenterProvider({ children }) {
|
|
|
12624
12624
|
console.error("Failed to mark notification as read:", error);
|
|
12625
12625
|
}
|
|
12626
12626
|
}, []);
|
|
12627
|
-
const markAllAsRead =
|
|
12627
|
+
const markAllAsRead = React10.useCallback(async () => {
|
|
12628
12628
|
try {
|
|
12629
12629
|
await notificationsApi.current.markAllAsRead();
|
|
12630
12630
|
setNotifications((prev) => prev.map((n) => ({ ...n, isRead: true })));
|
|
@@ -12633,7 +12633,7 @@ function NotificationCenterProvider({ children }) {
|
|
|
12633
12633
|
console.error("Failed to mark all as read:", error);
|
|
12634
12634
|
}
|
|
12635
12635
|
}, []);
|
|
12636
|
-
const deleteNotification =
|
|
12636
|
+
const deleteNotification = React10.useCallback(async (id) => {
|
|
12637
12637
|
try {
|
|
12638
12638
|
await notificationsApi.current.deleteNotification(id);
|
|
12639
12639
|
const notification = notifications.find((n) => n._id === id);
|
|
@@ -12645,15 +12645,15 @@ function NotificationCenterProvider({ children }) {
|
|
|
12645
12645
|
console.error("Failed to delete notification:", error);
|
|
12646
12646
|
}
|
|
12647
12647
|
}, [notifications]);
|
|
12648
|
-
const loadMore =
|
|
12648
|
+
const loadMore = React10.useCallback(async () => {
|
|
12649
12649
|
if (!hasMore || isLoading) return;
|
|
12650
12650
|
await fetchNotifications(page + 1, true);
|
|
12651
12651
|
}, [hasMore, isLoading, page, fetchNotifications]);
|
|
12652
|
-
const refreshNotifications =
|
|
12652
|
+
const refreshNotifications = React10.useCallback(async () => {
|
|
12653
12653
|
await fetchNotifications(1, false);
|
|
12654
12654
|
await fetchUnreadCount();
|
|
12655
12655
|
}, [fetchNotifications, fetchUnreadCount]);
|
|
12656
|
-
const updateSettings =
|
|
12656
|
+
const updateSettings = React10.useCallback(async (newSettings) => {
|
|
12657
12657
|
try {
|
|
12658
12658
|
const payload = {
|
|
12659
12659
|
_id: newSettings._id,
|
|
@@ -12691,297 +12691,26 @@ function NotificationCenterProvider({ children }) {
|
|
|
12691
12691
|
};
|
|
12692
12692
|
return /* @__PURE__ */ jsxRuntime.jsx(NotificationCenterContext.Provider, { value, children });
|
|
12693
12693
|
}
|
|
12694
|
-
var getNotificationIcon = (type) => {
|
|
12695
|
-
const className = "w-5 h-5";
|
|
12696
|
-
switch (type) {
|
|
12697
|
-
case "ORDER_CONFIRMATION":
|
|
12698
|
-
case "ORDER_SHIPPED":
|
|
12699
|
-
case "ORDER_DELIVERED":
|
|
12700
|
-
return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Package, { className });
|
|
12701
|
-
case "PAYMENT_FAILED":
|
|
12702
|
-
case "REFUND_PROCESSED":
|
|
12703
|
-
return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CreditCard, { className });
|
|
12704
|
-
case "PASSWORD_RESET":
|
|
12705
|
-
case "NEW_DEVICE_LOGIN":
|
|
12706
|
-
case "TWO_FA_CODE":
|
|
12707
|
-
return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Lock, { className });
|
|
12708
|
-
case "ABANDONED_CART_REMINDER":
|
|
12709
|
-
return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ShoppingCart, { className });
|
|
12710
|
-
case "PRICE_DROP_ALERT":
|
|
12711
|
-
return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.TrendingDown, { className });
|
|
12712
|
-
case "BACK_IN_STOCK":
|
|
12713
|
-
default:
|
|
12714
|
-
return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Bell, { className });
|
|
12715
|
-
}
|
|
12716
|
-
};
|
|
12717
|
-
var getNotificationColor = (type) => {
|
|
12718
|
-
switch (type) {
|
|
12719
|
-
case "ORDER_CONFIRMATION":
|
|
12720
|
-
case "ORDER_DELIVERED":
|
|
12721
|
-
case "REFUND_PROCESSED":
|
|
12722
|
-
return "bg-green-100 text-green-600";
|
|
12723
|
-
case "ORDER_SHIPPED":
|
|
12724
|
-
return "bg-blue-100 text-blue-600";
|
|
12725
|
-
case "PAYMENT_FAILED":
|
|
12726
|
-
return "bg-red-100 text-red-600";
|
|
12727
|
-
case "PASSWORD_RESET":
|
|
12728
|
-
case "NEW_DEVICE_LOGIN":
|
|
12729
|
-
case "TWO_FA_CODE":
|
|
12730
|
-
return "bg-purple-100 text-purple-600";
|
|
12731
|
-
case "ABANDONED_CART_REMINDER":
|
|
12732
|
-
case "PRICE_DROP_ALERT":
|
|
12733
|
-
case "BACK_IN_STOCK":
|
|
12734
|
-
return "bg-orange-100 text-orange-600";
|
|
12735
|
-
default:
|
|
12736
|
-
return "bg-gray-100 text-gray-600";
|
|
12737
|
-
}
|
|
12738
|
-
};
|
|
12739
|
-
var formatRelativeTime = (dateString) => {
|
|
12740
|
-
const date = new Date(dateString);
|
|
12741
|
-
const diff = Date.now() - date.getTime();
|
|
12742
|
-
const mins = Math.floor(diff / 6e4);
|
|
12743
|
-
const hours = Math.floor(diff / 36e5);
|
|
12744
|
-
const days = Math.floor(diff / 864e5);
|
|
12745
|
-
if (mins < 1) return "Just now";
|
|
12746
|
-
if (mins < 60) return `${mins} min ago`;
|
|
12747
|
-
if (hours < 24) return `${hours} hour${hours > 1 ? "s" : ""} ago`;
|
|
12748
|
-
if (days < 7) return `${days} day${days > 1 ? "s" : ""} ago`;
|
|
12749
|
-
return date.toLocaleDateString();
|
|
12750
|
-
};
|
|
12751
|
-
function NotificationCard({
|
|
12752
|
-
notification,
|
|
12753
|
-
onMarkAsRead,
|
|
12754
|
-
onDelete
|
|
12755
|
-
}) {
|
|
12756
|
-
const router = navigation.useRouter();
|
|
12757
|
-
const { buildPath } = useBasePath();
|
|
12758
|
-
const hasDragged = React12.useRef(false);
|
|
12759
|
-
const handleClick = () => {
|
|
12760
|
-
if (hasDragged.current) return;
|
|
12761
|
-
if (!notification.isRead) {
|
|
12762
|
-
onMarkAsRead(notification._id);
|
|
12763
|
-
}
|
|
12764
|
-
if (notification.data?.orderId) {
|
|
12765
|
-
router.push(buildPath(`/account/orders/${notification.data.orderId}`));
|
|
12766
|
-
} else if (notification.data?.productId) {
|
|
12767
|
-
router.push(buildPath(`/products/${notification.data.productId}`));
|
|
12768
|
-
}
|
|
12769
|
-
};
|
|
12770
|
-
const handleDelete = (e) => {
|
|
12771
|
-
e.stopPropagation();
|
|
12772
|
-
onDelete(notification._id);
|
|
12773
|
-
};
|
|
12774
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative overflow-hidden rounded-lg", children: [
|
|
12775
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-center justify-end px-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-1 text-white", children: [
|
|
12776
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "w-5 h-5" }),
|
|
12777
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-bold uppercase tracking-wider", children: "Remove" })
|
|
12778
|
-
] }) }),
|
|
12779
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
12780
|
-
framerMotion.motion.div,
|
|
12781
|
-
{
|
|
12782
|
-
drag: "x",
|
|
12783
|
-
initial: { opacity: 0, x: 0 },
|
|
12784
|
-
animate: { opacity: 1, x: 0 },
|
|
12785
|
-
className: `relative z-10 p-4 border cursor-pointer select-none touch-pan-y transition-colors ${notification.isRead ? "bg-white border-gray-200" : "bg-blue-50 border-blue-200"}`,
|
|
12786
|
-
onClick: handleClick,
|
|
12787
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-3", children: [
|
|
12788
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
12789
|
-
"div",
|
|
12790
|
-
{
|
|
12791
|
-
className: `flex-shrink-0 w-10 h-10 rounded-full flex items-center justify-center ${getNotificationColor(
|
|
12792
|
-
notification.type
|
|
12793
|
-
)}`,
|
|
12794
|
-
children: getNotificationIcon(notification.type)
|
|
12795
|
-
}
|
|
12796
|
-
),
|
|
12797
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
12798
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-2", children: [
|
|
12799
|
-
/* @__PURE__ */ jsxRuntime.jsx("h4", { className: "font-semibold text-gray-900 text-sm line-clamp-1", children: notification.title }),
|
|
12800
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
12801
|
-
"button",
|
|
12802
|
-
{
|
|
12803
|
-
onClick: handleDelete,
|
|
12804
|
-
className: "flex-shrink-0 p-1 bg-gray-100 rounded-full hover:bg-red-50",
|
|
12805
|
-
"aria-label": "Delete notification",
|
|
12806
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "w-4 h-4 text-gray-400 hover:text-red-500" })
|
|
12807
|
-
}
|
|
12808
|
-
)
|
|
12809
|
-
] }),
|
|
12810
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-gray-600 mt-1 line-clamp-2", children: notification.body }),
|
|
12811
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mt-2", children: [
|
|
12812
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-gray-500", children: formatRelativeTime(notification.createdAt) }),
|
|
12813
|
-
!notification.isRead && /* @__PURE__ */ jsxRuntime.jsx(
|
|
12814
|
-
"span",
|
|
12815
|
-
{
|
|
12816
|
-
className: "w-2 h-2 bg-blue-500 rounded-full",
|
|
12817
|
-
"aria-label": "Unread"
|
|
12818
|
-
}
|
|
12819
|
-
)
|
|
12820
|
-
] })
|
|
12821
|
-
] })
|
|
12822
|
-
] })
|
|
12823
|
-
}
|
|
12824
|
-
)
|
|
12825
|
-
] });
|
|
12826
|
-
}
|
|
12827
|
-
function NotificationDrawer() {
|
|
12828
|
-
const {
|
|
12829
|
-
isDrawerOpen,
|
|
12830
|
-
closeDrawer,
|
|
12831
|
-
notifications,
|
|
12832
|
-
unreadCount,
|
|
12833
|
-
isLoading,
|
|
12834
|
-
markAsRead,
|
|
12835
|
-
markAllAsRead,
|
|
12836
|
-
deleteNotification,
|
|
12837
|
-
loadMore,
|
|
12838
|
-
hasMore
|
|
12839
|
-
} = useNotificationCenter();
|
|
12840
|
-
const router = navigation.useRouter();
|
|
12841
|
-
const { buildPath } = useBasePath();
|
|
12842
|
-
const scrollContainerRef = React12.useRef(null);
|
|
12843
|
-
const handleScroll = () => {
|
|
12844
|
-
if (!scrollContainerRef.current || isLoading || !hasMore) return;
|
|
12845
|
-
const { scrollTop, scrollHeight, clientHeight } = scrollContainerRef.current;
|
|
12846
|
-
const scrollPercentage = (scrollTop + clientHeight) / scrollHeight;
|
|
12847
|
-
if (scrollPercentage > 0.8) {
|
|
12848
|
-
loadMore();
|
|
12849
|
-
}
|
|
12850
|
-
};
|
|
12851
|
-
React12.useEffect(() => {
|
|
12852
|
-
const handleEscape = (e) => {
|
|
12853
|
-
if (e.key === "Escape" && isDrawerOpen) {
|
|
12854
|
-
closeDrawer();
|
|
12855
|
-
}
|
|
12856
|
-
};
|
|
12857
|
-
document.addEventListener("keydown", handleEscape);
|
|
12858
|
-
return () => document.removeEventListener("keydown", handleEscape);
|
|
12859
|
-
}, [isDrawerOpen, closeDrawer]);
|
|
12860
|
-
React12.useEffect(() => {
|
|
12861
|
-
if (isDrawerOpen) {
|
|
12862
|
-
document.body.style.overflow = "hidden";
|
|
12863
|
-
} else {
|
|
12864
|
-
document.body.style.overflow = "";
|
|
12865
|
-
}
|
|
12866
|
-
return () => {
|
|
12867
|
-
document.body.style.overflow = "";
|
|
12868
|
-
};
|
|
12869
|
-
}, [isDrawerOpen]);
|
|
12870
|
-
const handleSettingsClick = () => {
|
|
12871
|
-
closeDrawer();
|
|
12872
|
-
router.push(buildPath("/account/notifications"));
|
|
12873
|
-
};
|
|
12874
|
-
return /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: isDrawerOpen && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
12875
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
12876
|
-
framerMotion.motion.div,
|
|
12877
|
-
{
|
|
12878
|
-
initial: { opacity: 0 },
|
|
12879
|
-
animate: { opacity: 1 },
|
|
12880
|
-
exit: { opacity: 0 },
|
|
12881
|
-
className: "fixed inset-0 bg-black/50 z-40",
|
|
12882
|
-
onClick: closeDrawer
|
|
12883
|
-
}
|
|
12884
|
-
),
|
|
12885
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
12886
|
-
framerMotion.motion.div,
|
|
12887
|
-
{
|
|
12888
|
-
initial: { x: "100%" },
|
|
12889
|
-
animate: { x: 0 },
|
|
12890
|
-
exit: { x: "100%" },
|
|
12891
|
-
transition: { type: "spring", damping: 25, stiffness: 200 },
|
|
12892
|
-
className: "fixed right-0 top-0 bottom-0 w-full sm:w-[480px] bg-white shadow-2xl z-50 flex flex-col max-w-[480px]",
|
|
12893
|
-
children: [
|
|
12894
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between p-4 border-b border-gray-200 bg-white", children: [
|
|
12895
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
12896
|
-
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-xl font-bold text-gray-900", children: "Notifications" }),
|
|
12897
|
-
unreadCount > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "bg-red-500 text-white text-xs font-bold px-2 py-1 rounded-full", children: unreadCount })
|
|
12898
|
-
] }),
|
|
12899
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
12900
|
-
unreadCount > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
12901
|
-
"button",
|
|
12902
|
-
{
|
|
12903
|
-
onClick: markAllAsRead,
|
|
12904
|
-
className: "p-2 hover:bg-gray-100 rounded-lg transition-colors",
|
|
12905
|
-
title: "Mark all as read",
|
|
12906
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckCheck, { className: "w-5 h-5 text-gray-600" })
|
|
12907
|
-
}
|
|
12908
|
-
),
|
|
12909
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
12910
|
-
"button",
|
|
12911
|
-
{
|
|
12912
|
-
onClick: handleSettingsClick,
|
|
12913
|
-
className: "p-2 hover:bg-gray-100 rounded-lg transition-colors",
|
|
12914
|
-
title: "Notification settings",
|
|
12915
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Settings, { className: "w-5 h-5 text-gray-600" })
|
|
12916
|
-
}
|
|
12917
|
-
),
|
|
12918
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
12919
|
-
"button",
|
|
12920
|
-
{
|
|
12921
|
-
onClick: closeDrawer,
|
|
12922
|
-
className: "p-2 hover:bg-gray-100 rounded-lg transition-colors",
|
|
12923
|
-
"aria-label": "Close",
|
|
12924
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "w-5 h-5 text-gray-600" })
|
|
12925
|
-
}
|
|
12926
|
-
)
|
|
12927
|
-
] })
|
|
12928
|
-
] }),
|
|
12929
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
12930
|
-
"div",
|
|
12931
|
-
{
|
|
12932
|
-
ref: scrollContainerRef,
|
|
12933
|
-
onScroll: handleScroll,
|
|
12934
|
-
className: "flex-1 overflow-y-auto p-4 space-y-3",
|
|
12935
|
-
children: notifications.length === 0 && !isLoading ? (
|
|
12936
|
-
// Empty state
|
|
12937
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center h-full text-center py-12", children: [
|
|
12938
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-20 h-20 bg-gray-100 rounded-full flex items-center justify-center mb-4", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.BellOff, { className: "w-10 h-10 text-gray-400" }) }),
|
|
12939
|
-
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold text-gray-900 mb-2", children: "No notifications yet" }),
|
|
12940
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-gray-500 max-w-xs", children: "When you receive notifications, they'll appear here" })
|
|
12941
|
-
] })
|
|
12942
|
-
) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
12943
|
-
notifications.map((notification) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
12944
|
-
NotificationCard,
|
|
12945
|
-
{
|
|
12946
|
-
notification,
|
|
12947
|
-
onMarkAsRead: markAsRead,
|
|
12948
|
-
onDelete: deleteNotification
|
|
12949
|
-
},
|
|
12950
|
-
notification._id
|
|
12951
|
-
)),
|
|
12952
|
-
isLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-4", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-6 h-6 border-2 border-primary-600 border-t-transparent rounded-full animate-spin" }) }),
|
|
12953
|
-
!hasMore && notifications.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-center py-4 text-sm text-gray-500", children: "You're all caught up! \u{1F389}" })
|
|
12954
|
-
] })
|
|
12955
|
-
}
|
|
12956
|
-
)
|
|
12957
|
-
]
|
|
12958
|
-
}
|
|
12959
|
-
)
|
|
12960
|
-
] }) });
|
|
12961
|
-
}
|
|
12962
12694
|
function EcommerceProvider({ config, children, withToaster = true, basePath = "" }) {
|
|
12963
|
-
|
|
12695
|
+
React10__default.default.useMemo(() => {
|
|
12964
12696
|
initializeApiAdapter(config);
|
|
12965
12697
|
}, [config]);
|
|
12966
|
-
const [client] =
|
|
12698
|
+
const [client] = React10__default.default.useState(
|
|
12967
12699
|
new reactQuery.QueryClient({ defaultOptions: { queries: { staleTime: 5e3 } } })
|
|
12968
12700
|
);
|
|
12969
|
-
return /* @__PURE__ */ jsxRuntime.jsx(reactQuery.QueryClientProvider, { client, children: /* @__PURE__ */ jsxRuntime.jsx(ThemeProvider, { config, children: /* @__PURE__ */ jsxRuntime.jsx(BasePathProvider, { basePath, children: /* @__PURE__ */ jsxRuntime.jsx(AuthProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(NotificationProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(NotificationCenterProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(CartProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(DiscountProvider, { children: /* @__PURE__ */ jsxRuntime.
|
|
12970
|
-
children,
|
|
12971
|
-
/* @__PURE__ */ jsxRuntime.jsx(NotificationDrawer, {})
|
|
12972
|
-
] }) }) }) }) }) }) }) }) });
|
|
12701
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactQuery.QueryClientProvider, { client, children: /* @__PURE__ */ jsxRuntime.jsx(ThemeProvider, { config, children: /* @__PURE__ */ jsxRuntime.jsx(BasePathProvider, { basePath, children: /* @__PURE__ */ jsxRuntime.jsx(AuthProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(NotificationProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(NotificationCenterProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(CartProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(DiscountProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(WishlistProvider, { children }) }) }) }) }) }) }) }) });
|
|
12973
12702
|
}
|
|
12974
12703
|
|
|
12975
12704
|
// src/lib/constants/assets.ts
|
|
12976
12705
|
var PLACEHOLDER_IMAGE_SRC = `data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAwIiBoZWlnaHQ9IjQwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICA8cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZjNmNGY2Ii8+CiAgPHRleHQgeD0iNTAlIiB5PSI1MCUiIGZvbnQtZmFtaWx5PSJBcmlhbCIgZm9udC1zaXplPSIyNCIgZmlsbD0iIzljYTNhZiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZG9taW5hbnQtYmFzZWxpbmU9Im1pZGRsZSI+Tm8gSW1hZ2U8L3RleHQ+CiAgPHJlY3QgeD0iMTUwIiB5PSIxMjAiIHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIiBzdHJva2U9IiM5Y2EzYWYiIHN0cm9rZS13aWR0aD0iNCIgZmlsbD0ibm9uZSIgcng9IjgiLz4KICA8cGF0aCBkPSJNMTUwIDE4MCBMMTcwIDE2MCBMMjAwIDE5MCBMMjIwIDE3MCBMMjUwIDIwMCBMMjUwIDIyMCBMMTUwIDIyMCBaIiBmaWxsPSIjOWNhM2FmIiBvcGFjaXR5PSIwLjUiLz4KPC9zdmc+`;
|
|
12977
12706
|
function QuickViewModal({ product, onClose, onNavigateToProduct }) {
|
|
12978
|
-
const [selectedVariantIndex, setSelectedVariantIndex] =
|
|
12979
|
-
const [selectedSizeIndex, setSelectedSizeIndex] =
|
|
12980
|
-
const [selectedImageIndex, setSelectedImageIndex] =
|
|
12981
|
-
const [addedToCart, setAddedToCart] =
|
|
12982
|
-
const [quantity, setQuantity] =
|
|
12707
|
+
const [selectedVariantIndex, setSelectedVariantIndex] = React10.useState(0);
|
|
12708
|
+
const [selectedSizeIndex, setSelectedSizeIndex] = React10.useState(0);
|
|
12709
|
+
const [selectedImageIndex, setSelectedImageIndex] = React10.useState(0);
|
|
12710
|
+
const [addedToCart, setAddedToCart] = React10.useState(false);
|
|
12711
|
+
const [quantity, setQuantity] = React10.useState(1);
|
|
12983
12712
|
const { addToCart } = useCart();
|
|
12984
|
-
const [isAddingToCart, setIsAddingToCart] =
|
|
12713
|
+
const [isAddingToCart, setIsAddingToCart] = React10.useState(false);
|
|
12985
12714
|
const notification = useNotification();
|
|
12986
12715
|
const handleQuantityChange = (newQuantity) => {
|
|
12987
12716
|
if (newQuantity >= 1 && newQuantity <= (selectedVariant.inventoryCount || 10)) {
|
|
@@ -13132,7 +12861,7 @@ function QuickViewModal({ product, onClose, onNavigateToProduct }) {
|
|
|
13132
12861
|
setSelectedSizeIndex(0);
|
|
13133
12862
|
setSelectedImageIndex(0);
|
|
13134
12863
|
},
|
|
13135
|
-
className: `size-10 rounded-full border-2 transition-all ${selectedVariantIndex === index ? "border-primary scale-110" : "border-gray-200 hover:border-primary
|
|
12864
|
+
className: `size-10 rounded-full border-2 transition-all ${selectedVariantIndex === index ? "border-primary scale-110" : "border-gray-200 hover:border-primary-50"}`,
|
|
13136
12865
|
style: { backgroundColor: variant.colorHex },
|
|
13137
12866
|
title: variant.color,
|
|
13138
12867
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -13229,28 +12958,28 @@ function ProductCard({
|
|
|
13229
12958
|
const router = navigation.useRouter();
|
|
13230
12959
|
const { isAuthenticated } = useAuth();
|
|
13231
12960
|
const { buildPath } = useBasePath();
|
|
13232
|
-
const [isFavorite, setIsFavorite] =
|
|
12961
|
+
const [isFavorite, setIsFavorite] = React10.useState(isFavorited);
|
|
13233
12962
|
const { addToWishlist, removeFromWishlist, isInWishlist } = useWishlist();
|
|
13234
12963
|
const { addToCart, isLoading: isAddingToCart } = useCart();
|
|
13235
|
-
const [isHovered, setIsHovered] =
|
|
13236
|
-
const [isImageLoaded, setIsImageLoaded] =
|
|
13237
|
-
const [selectedVariantImage, setSelectedVariantImage] =
|
|
13238
|
-
const [selectedVariantId, setSelectedVariantId] =
|
|
13239
|
-
const [showQuickView, setShowQuickView] =
|
|
12964
|
+
const [isHovered, setIsHovered] = React10.useState(false);
|
|
12965
|
+
const [isImageLoaded, setIsImageLoaded] = React10.useState(false);
|
|
12966
|
+
const [selectedVariantImage, setSelectedVariantImage] = React10.useState(null);
|
|
12967
|
+
const [selectedVariantId, setSelectedVariantId] = React10.useState(null);
|
|
12968
|
+
const [showQuickView, setShowQuickView] = React10.useState(false);
|
|
13240
12969
|
const notification = useNotification();
|
|
13241
|
-
const handleImageLoad =
|
|
12970
|
+
const handleImageLoad = React10.useCallback(() => {
|
|
13242
12971
|
setIsImageLoaded(true);
|
|
13243
12972
|
}, []);
|
|
13244
|
-
const handleCardClick =
|
|
12973
|
+
const handleCardClick = React10.useCallback((e) => {
|
|
13245
12974
|
if (onClickProduct) {
|
|
13246
12975
|
e.preventDefault();
|
|
13247
12976
|
onClickProduct(product);
|
|
13248
12977
|
}
|
|
13249
12978
|
}, [onClickProduct, product]);
|
|
13250
|
-
|
|
12979
|
+
React10.useEffect(() => {
|
|
13251
12980
|
setIsFavorite(isInWishlist(product?._id || "") || isFavorited);
|
|
13252
12981
|
}, [isFavorited, isInWishlist, product?._id]);
|
|
13253
|
-
|
|
12982
|
+
React10.useEffect(() => {
|
|
13254
12983
|
setSelectedVariantImage(null);
|
|
13255
12984
|
setSelectedVariantId(null);
|
|
13256
12985
|
setIsImageLoaded(false);
|
|
@@ -13268,7 +12997,7 @@ function ProductCard({
|
|
|
13268
12997
|
handleCardClick(e);
|
|
13269
12998
|
}
|
|
13270
12999
|
};
|
|
13271
|
-
const variantImages =
|
|
13000
|
+
const variantImages = React10.useMemo(() => {
|
|
13272
13001
|
if (!product.variants || product.variants.length === 0) {
|
|
13273
13002
|
return [];
|
|
13274
13003
|
}
|
|
@@ -13278,35 +13007,35 @@ function ProductCard({
|
|
|
13278
13007
|
image: variant.media[0].file
|
|
13279
13008
|
}));
|
|
13280
13009
|
}, [product.variants]);
|
|
13281
|
-
const selectedVariant =
|
|
13010
|
+
const selectedVariant = React10.useMemo(() => {
|
|
13282
13011
|
if (!selectedVariantId || !product.variants) return null;
|
|
13283
13012
|
return product.variants.find(
|
|
13284
13013
|
(variant) => (variant.id || variant._id) === selectedVariantId
|
|
13285
13014
|
);
|
|
13286
13015
|
}, [selectedVariantId, product.variants]);
|
|
13287
|
-
const displayFinalPrice =
|
|
13016
|
+
const displayFinalPrice = React10.useMemo(() => {
|
|
13288
13017
|
return selectedVariant?.finalPrice ?? product.variants?.[0]?.finalPrice ?? 0;
|
|
13289
13018
|
}, [selectedVariant, product.variants]);
|
|
13290
|
-
const displayPriceBeforeDiscount =
|
|
13019
|
+
const displayPriceBeforeDiscount = React10.useMemo(() => {
|
|
13291
13020
|
return selectedVariant?.retailPrice ?? product.variants?.[0]?.retailPrice ?? 0;
|
|
13292
13021
|
}, [selectedVariant, product.variants]);
|
|
13293
|
-
const displayIsDiscounted =
|
|
13022
|
+
const displayIsDiscounted = React10.useMemo(() => {
|
|
13294
13023
|
return selectedVariant ? selectedVariant.isDiscounted : product.variants?.[0]?.isDiscounted;
|
|
13295
13024
|
}, [selectedVariant, product.variants]);
|
|
13296
|
-
const displayDiscountAmount =
|
|
13025
|
+
const displayDiscountAmount = React10.useMemo(() => {
|
|
13297
13026
|
return selectedVariant ? selectedVariant.discountAmount : product.variants?.[0]?.discountAmount;
|
|
13298
13027
|
}, [selectedVariant, product.variants]);
|
|
13299
|
-
const displayInventoryCount =
|
|
13028
|
+
const displayInventoryCount = React10.useMemo(() => {
|
|
13300
13029
|
return selectedVariant ? selectedVariant.inventoryCount : product.variants?.[0]?.inventoryCount;
|
|
13301
13030
|
}, [selectedVariant, product.variants]);
|
|
13302
|
-
const imageSource =
|
|
13031
|
+
const imageSource = React10.useMemo(() => {
|
|
13303
13032
|
const src = selectedVariantImage || selectedVariant?.media?.[0]?.file || product.media?.[0]?.file || PLACEHOLDER_IMAGE_SRC;
|
|
13304
13033
|
return {
|
|
13305
13034
|
src,
|
|
13306
13035
|
alt: product.name || "Product image"
|
|
13307
13036
|
};
|
|
13308
13037
|
}, [product.media, product.name, selectedVariantImage]);
|
|
13309
|
-
|
|
13038
|
+
React10.useEffect(() => {
|
|
13310
13039
|
setIsImageLoaded(false);
|
|
13311
13040
|
}, [imageSource.src]);
|
|
13312
13041
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
@@ -13574,7 +13303,7 @@ function EmptyState({ icon: Icon, title, description, actionLabel, onAction }) {
|
|
|
13574
13303
|
actionLabel && onAction && /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: onAction, children: actionLabel })
|
|
13575
13304
|
] });
|
|
13576
13305
|
}
|
|
13577
|
-
var Input =
|
|
13306
|
+
var Input = React10.forwardRef(
|
|
13578
13307
|
({ label, error, helperText, className = "", ...props }, ref) => {
|
|
13579
13308
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full", children: [
|
|
13580
13309
|
label && /* @__PURE__ */ jsxRuntime.jsx("label", { className: "block text-sm font-medium text-gray-700 mb-2", children: label }),
|
|
@@ -13665,11 +13394,11 @@ function useProducts(filters, page = 1, limit = 20) {
|
|
|
13665
13394
|
};
|
|
13666
13395
|
}
|
|
13667
13396
|
function useProduct(id) {
|
|
13668
|
-
const [product, setProduct] =
|
|
13669
|
-
const [isLoading, setIsLoading] =
|
|
13670
|
-
const [error, setError] =
|
|
13397
|
+
const [product, setProduct] = React10.useState(null);
|
|
13398
|
+
const [isLoading, setIsLoading] = React10.useState(true);
|
|
13399
|
+
const [error, setError] = React10.useState(null);
|
|
13671
13400
|
console.log("product", product);
|
|
13672
|
-
|
|
13401
|
+
React10.useEffect(() => {
|
|
13673
13402
|
const fetchProduct = async () => {
|
|
13674
13403
|
setIsLoading(true);
|
|
13675
13404
|
setError(null);
|
|
@@ -13686,10 +13415,10 @@ function useProduct(id) {
|
|
|
13686
13415
|
return { product, isLoading, error };
|
|
13687
13416
|
}
|
|
13688
13417
|
function useCategories() {
|
|
13689
|
-
const [categories, setCategories] =
|
|
13690
|
-
const [isLoading, setIsLoading] =
|
|
13691
|
-
const [error, setError] =
|
|
13692
|
-
|
|
13418
|
+
const [categories, setCategories] = React10.useState([]);
|
|
13419
|
+
const [isLoading, setIsLoading] = React10.useState(true);
|
|
13420
|
+
const [error, setError] = React10.useState(null);
|
|
13421
|
+
React10.useEffect(() => {
|
|
13693
13422
|
const fetchCategories = async () => {
|
|
13694
13423
|
try {
|
|
13695
13424
|
setIsLoading(true);
|
|
@@ -13741,20 +13470,20 @@ function getInitials(firstName, lastName) {
|
|
|
13741
13470
|
function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
13742
13471
|
const router = navigation.useRouter();
|
|
13743
13472
|
const { buildPath } = useBasePath();
|
|
13744
|
-
const [filters, setFilters] =
|
|
13745
|
-
const [page, setPage] =
|
|
13746
|
-
const [showFilters, setShowFilters] =
|
|
13747
|
-
const [searchQuery, setSearchQuery] =
|
|
13748
|
-
const [isSearching, setIsSearching] =
|
|
13749
|
-
const [sortOption, setSortOption] =
|
|
13750
|
-
const [viewMode, setViewMode] =
|
|
13751
|
-
const [selectedPriceRange, setSelectedPriceRange] =
|
|
13752
|
-
const [customPrice, setCustomPrice] =
|
|
13473
|
+
const [filters, setFilters] = React10.useState(initialFilters);
|
|
13474
|
+
const [page, setPage] = React10.useState(1);
|
|
13475
|
+
const [showFilters, setShowFilters] = React10.useState(false);
|
|
13476
|
+
const [searchQuery, setSearchQuery] = React10.useState("");
|
|
13477
|
+
const [isSearching, setIsSearching] = React10.useState(false);
|
|
13478
|
+
const [sortOption, setSortOption] = React10.useState("featured");
|
|
13479
|
+
const [viewMode, setViewMode] = React10.useState("grid");
|
|
13480
|
+
const [selectedPriceRange, setSelectedPriceRange] = React10.useState(null);
|
|
13481
|
+
const [customPrice, setCustomPrice] = React10.useState({
|
|
13753
13482
|
min: "",
|
|
13754
13483
|
max: ""
|
|
13755
13484
|
});
|
|
13756
|
-
const [expandedCategories, setExpandedCategories] =
|
|
13757
|
-
const [expandedFilterSections, setExpandedFilterSections] =
|
|
13485
|
+
const [expandedCategories, setExpandedCategories] = React10.useState({});
|
|
13486
|
+
const [expandedFilterSections, setExpandedFilterSections] = React10.useState({
|
|
13758
13487
|
category: true
|
|
13759
13488
|
// Category section starts expanded
|
|
13760
13489
|
});
|
|
@@ -13781,7 +13510,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
13781
13510
|
}
|
|
13782
13511
|
}
|
|
13783
13512
|
};
|
|
13784
|
-
const priceRanges =
|
|
13513
|
+
const priceRanges = React10.useMemo(
|
|
13785
13514
|
() => [
|
|
13786
13515
|
{ label: `Under ${formatPrice(25)}`, value: "under-25", min: void 0, max: 25 },
|
|
13787
13516
|
{ label: `${formatPrice(25)} - ${formatPrice(50)}`, value: "25-50", min: 25, max: 50 },
|
|
@@ -13790,13 +13519,13 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
13790
13519
|
],
|
|
13791
13520
|
[]
|
|
13792
13521
|
);
|
|
13793
|
-
|
|
13522
|
+
React10.useEffect(() => {
|
|
13794
13523
|
setCustomPrice({
|
|
13795
13524
|
min: filters.minPrice !== void 0 ? String(filters.minPrice) : "",
|
|
13796
13525
|
max: filters.maxPrice !== void 0 ? String(filters.maxPrice) : ""
|
|
13797
13526
|
});
|
|
13798
13527
|
}, [filters.minPrice, filters.maxPrice]);
|
|
13799
|
-
|
|
13528
|
+
React10.useEffect(() => {
|
|
13800
13529
|
const updates = {};
|
|
13801
13530
|
if (filters.category) updates[filters.category] = true;
|
|
13802
13531
|
if (filters.subCategory) {
|
|
@@ -13810,18 +13539,18 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
13810
13539
|
setExpandedCategories((prev) => ({ ...prev, ...updates }));
|
|
13811
13540
|
}
|
|
13812
13541
|
}, [filters.category, filters.subCategory, categories]);
|
|
13813
|
-
const toggleCategoryExpand =
|
|
13542
|
+
const toggleCategoryExpand = React10.useCallback((id) => {
|
|
13814
13543
|
setExpandedCategories((prev) => ({ ...prev, [id]: !prev[id] }));
|
|
13815
13544
|
}, []);
|
|
13816
|
-
const sortedCategories =
|
|
13545
|
+
const sortedCategories = React10.useMemo(
|
|
13817
13546
|
() => [...categories].sort((a, b) => a.name?.localeCompare(b.name ?? "") ?? 0),
|
|
13818
13547
|
[categories]
|
|
13819
13548
|
);
|
|
13820
|
-
const topCategories =
|
|
13549
|
+
const topCategories = React10.useMemo(
|
|
13821
13550
|
() => [...categories].sort((a, b) => (b.productCount ?? 0) - (a.productCount ?? 0)).slice(0, 6),
|
|
13822
13551
|
[categories]
|
|
13823
13552
|
);
|
|
13824
|
-
const productInsights =
|
|
13553
|
+
const productInsights = React10.useMemo(() => {
|
|
13825
13554
|
if (!products.length) {
|
|
13826
13555
|
return { newArrivals: 0, inStockCount: 0 };
|
|
13827
13556
|
}
|
|
@@ -13834,7 +13563,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
13834
13563
|
});
|
|
13835
13564
|
return { newArrivals: newArrivals2, inStockCount };
|
|
13836
13565
|
}, [products]);
|
|
13837
|
-
|
|
13566
|
+
React10.useMemo(
|
|
13838
13567
|
() => [
|
|
13839
13568
|
{
|
|
13840
13569
|
id: "new",
|
|
@@ -13867,7 +13596,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
13867
13596
|
filters.newArrivals
|
|
13868
13597
|
]
|
|
13869
13598
|
);
|
|
13870
|
-
const filteredProducts =
|
|
13599
|
+
const filteredProducts = React10.useMemo(() => {
|
|
13871
13600
|
if (isLoading) return products;
|
|
13872
13601
|
let items = [...products];
|
|
13873
13602
|
if (filters.tags?.length) {
|
|
@@ -13882,7 +13611,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
13882
13611
|
}
|
|
13883
13612
|
return items;
|
|
13884
13613
|
}, [isLoading, products, filters.tags, filters.newArrivals, filters.brand]);
|
|
13885
|
-
const sortedProducts =
|
|
13614
|
+
const sortedProducts = React10.useMemo(() => {
|
|
13886
13615
|
if (isLoading) {
|
|
13887
13616
|
return filteredProducts;
|
|
13888
13617
|
}
|
|
@@ -13901,7 +13630,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
13901
13630
|
}
|
|
13902
13631
|
}, [isLoading, filteredProducts, sortOption]);
|
|
13903
13632
|
const displayedProducts = sortedProducts;
|
|
13904
|
-
const availableBrands =
|
|
13633
|
+
const availableBrands = React10.useMemo(() => {
|
|
13905
13634
|
const brandSet = /* @__PURE__ */ new Set();
|
|
13906
13635
|
products.forEach((product) => {
|
|
13907
13636
|
if (product.brand && product.brand.trim()) {
|
|
@@ -13910,14 +13639,14 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
13910
13639
|
});
|
|
13911
13640
|
return Array.from(brandSet).sort();
|
|
13912
13641
|
}, [products]);
|
|
13913
|
-
|
|
13642
|
+
React10.useMemo(() => {
|
|
13914
13643
|
const counts = /* @__PURE__ */ new Map();
|
|
13915
13644
|
products.forEach((p) => {
|
|
13916
13645
|
(p.tags || []).forEach((t) => counts.set(t, (counts.get(t) || 0) + 1));
|
|
13917
13646
|
});
|
|
13918
13647
|
return Array.from(counts.entries()).sort((a, b) => b[1] - a[1]).slice(0, 4).map(([tag]) => tag);
|
|
13919
13648
|
}, [products]);
|
|
13920
|
-
|
|
13649
|
+
React10.useCallback((term) => {
|
|
13921
13650
|
setSearchQuery("");
|
|
13922
13651
|
setFilters((current) => ({
|
|
13923
13652
|
...current,
|
|
@@ -13926,7 +13655,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
13926
13655
|
}));
|
|
13927
13656
|
setPage(1);
|
|
13928
13657
|
}, []);
|
|
13929
|
-
const handleCategoryChange =
|
|
13658
|
+
const handleCategoryChange = React10.useCallback(
|
|
13930
13659
|
(categorySlug) => {
|
|
13931
13660
|
setFilters((current) => {
|
|
13932
13661
|
if (current.category === categorySlug) {
|
|
@@ -13943,7 +13672,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
13943
13672
|
},
|
|
13944
13673
|
[]
|
|
13945
13674
|
);
|
|
13946
|
-
|
|
13675
|
+
React10.useCallback((parentCategoryId, subCategoryId) => {
|
|
13947
13676
|
setFilters((current) => {
|
|
13948
13677
|
if (current.subCategory === subCategoryId) {
|
|
13949
13678
|
const { subCategory, ...rest } = current;
|
|
@@ -13953,7 +13682,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
13953
13682
|
});
|
|
13954
13683
|
setPage(1);
|
|
13955
13684
|
}, []);
|
|
13956
|
-
const handleToggleStock =
|
|
13685
|
+
const handleToggleStock = React10.useCallback(() => {
|
|
13957
13686
|
setFilters((current) => {
|
|
13958
13687
|
if (current.inStock) {
|
|
13959
13688
|
const { inStock, ...rest } = current;
|
|
@@ -13963,7 +13692,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
13963
13692
|
});
|
|
13964
13693
|
setPage(1);
|
|
13965
13694
|
}, []);
|
|
13966
|
-
const handleToggleNewArrivals =
|
|
13695
|
+
const handleToggleNewArrivals = React10.useCallback(() => {
|
|
13967
13696
|
setFilters((current) => {
|
|
13968
13697
|
if (current.newArrivals) {
|
|
13969
13698
|
const { newArrivals: newArrivals2, ...rest } = current;
|
|
@@ -13973,28 +13702,28 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
13973
13702
|
});
|
|
13974
13703
|
setPage(1);
|
|
13975
13704
|
}, []);
|
|
13976
|
-
const handleClearCategory =
|
|
13705
|
+
const handleClearCategory = React10.useCallback(() => {
|
|
13977
13706
|
setFilters((current) => {
|
|
13978
13707
|
const { category, subCategory, ...rest } = current;
|
|
13979
13708
|
return rest;
|
|
13980
13709
|
});
|
|
13981
13710
|
setPage(1);
|
|
13982
13711
|
}, []);
|
|
13983
|
-
const handleClearFilters =
|
|
13712
|
+
const handleClearFilters = React10.useCallback(() => {
|
|
13984
13713
|
setFilters({});
|
|
13985
13714
|
setSearchQuery("");
|
|
13986
13715
|
setSelectedPriceRange(null);
|
|
13987
13716
|
setCustomPrice({ min: "", max: "" });
|
|
13988
13717
|
setPage(1);
|
|
13989
13718
|
}, []);
|
|
13990
|
-
const handleRemoveCategory =
|
|
13719
|
+
const handleRemoveCategory = React10.useCallback(() => {
|
|
13991
13720
|
setFilters((current) => {
|
|
13992
13721
|
const { category, subCategory, ...rest } = current;
|
|
13993
13722
|
return rest;
|
|
13994
13723
|
});
|
|
13995
13724
|
setPage(1);
|
|
13996
13725
|
}, []);
|
|
13997
|
-
const handleRemoveSubCategory =
|
|
13726
|
+
const handleRemoveSubCategory = React10.useCallback(() => {
|
|
13998
13727
|
setFilters((current) => {
|
|
13999
13728
|
const next = { ...current };
|
|
14000
13729
|
delete next.subCategory;
|
|
@@ -14002,7 +13731,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
14002
13731
|
});
|
|
14003
13732
|
setPage(1);
|
|
14004
13733
|
}, []);
|
|
14005
|
-
const handleRemoveSearch =
|
|
13734
|
+
const handleRemoveSearch = React10.useCallback(() => {
|
|
14006
13735
|
setFilters((current) => {
|
|
14007
13736
|
const { search, ...rest } = current;
|
|
14008
13737
|
return rest;
|
|
@@ -14010,14 +13739,14 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
14010
13739
|
setSearchQuery("");
|
|
14011
13740
|
setPage(1);
|
|
14012
13741
|
}, []);
|
|
14013
|
-
const handleRemoveInStock =
|
|
13742
|
+
const handleRemoveInStock = React10.useCallback(() => {
|
|
14014
13743
|
setFilters((current) => {
|
|
14015
13744
|
const { inStock, ...rest } = current;
|
|
14016
13745
|
return rest;
|
|
14017
13746
|
});
|
|
14018
13747
|
setPage(1);
|
|
14019
13748
|
}, []);
|
|
14020
|
-
const handleRemovePrice =
|
|
13749
|
+
const handleRemovePrice = React10.useCallback(() => {
|
|
14021
13750
|
setFilters((current) => {
|
|
14022
13751
|
const next = { ...current };
|
|
14023
13752
|
delete next.minPrice;
|
|
@@ -14028,7 +13757,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
14028
13757
|
setCustomPrice({ min: "", max: "" });
|
|
14029
13758
|
setPage(1);
|
|
14030
13759
|
}, []);
|
|
14031
|
-
const handleRemoveTag =
|
|
13760
|
+
const handleRemoveTag = React10.useCallback((tag) => {
|
|
14032
13761
|
setFilters((current) => {
|
|
14033
13762
|
if (!current.tags) return current;
|
|
14034
13763
|
const updated = current.tags.filter((item) => item !== tag);
|
|
@@ -14042,7 +13771,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
14042
13771
|
});
|
|
14043
13772
|
setPage(1);
|
|
14044
13773
|
}, []);
|
|
14045
|
-
const handleBrandChange =
|
|
13774
|
+
const handleBrandChange = React10.useCallback((brand) => {
|
|
14046
13775
|
setFilters((current) => {
|
|
14047
13776
|
if (current.brand === brand) {
|
|
14048
13777
|
const { brand: _, ...rest } = current;
|
|
@@ -14052,14 +13781,14 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
14052
13781
|
});
|
|
14053
13782
|
setPage(1);
|
|
14054
13783
|
}, []);
|
|
14055
|
-
const handleRemoveBrand =
|
|
13784
|
+
const handleRemoveBrand = React10.useCallback(() => {
|
|
14056
13785
|
setFilters((current) => {
|
|
14057
13786
|
const { brand, ...rest } = current;
|
|
14058
13787
|
return rest;
|
|
14059
13788
|
});
|
|
14060
13789
|
setPage(1);
|
|
14061
13790
|
}, []);
|
|
14062
|
-
const handlePriceRangeSelect =
|
|
13791
|
+
const handlePriceRangeSelect = React10.useCallback(
|
|
14063
13792
|
(value) => {
|
|
14064
13793
|
const range = priceRanges.find((item) => item.value === value);
|
|
14065
13794
|
if (selectedPriceRange === value) {
|
|
@@ -14098,7 +13827,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
14098
13827
|
},
|
|
14099
13828
|
[priceRanges, selectedPriceRange]
|
|
14100
13829
|
);
|
|
14101
|
-
const applyCustomPrice =
|
|
13830
|
+
const applyCustomPrice = React10.useCallback(() => {
|
|
14102
13831
|
const rawMin = customPrice.min.trim();
|
|
14103
13832
|
const rawMax = customPrice.max.trim();
|
|
14104
13833
|
const minValue = rawMin !== "" ? Number(rawMin) : void 0;
|
|
@@ -14136,7 +13865,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
14136
13865
|
newArrivals,
|
|
14137
13866
|
brand: brandFilter
|
|
14138
13867
|
} = filters;
|
|
14139
|
-
const activeFilterChips =
|
|
13868
|
+
const activeFilterChips = React10.useMemo(() => {
|
|
14140
13869
|
const chips = [];
|
|
14141
13870
|
if (searchFilter) {
|
|
14142
13871
|
chips.push({
|
|
@@ -14237,7 +13966,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
14237
13966
|
]);
|
|
14238
13967
|
const hasActiveFilters = activeFilterChips.length > 0;
|
|
14239
13968
|
const isCustomPriceDirty = customPrice.min.trim() !== "" || customPrice.max.trim() !== "";
|
|
14240
|
-
const toggleFilterSection =
|
|
13969
|
+
const toggleFilterSection = React10.useCallback((section) => {
|
|
14241
13970
|
setExpandedFilterSections((prev) => ({
|
|
14242
13971
|
...prev,
|
|
14243
13972
|
[section]: !prev[section]
|
|
@@ -14405,14 +14134,14 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
14405
14134
|
type: "button",
|
|
14406
14135
|
onClick: applyCustomPrice,
|
|
14407
14136
|
disabled: !isCustomPriceDirty,
|
|
14408
|
-
className: "w-full rounded-lg border border-primary bg-primary
|
|
14137
|
+
className: "w-full rounded-lg border border-primary bg-primary-10 px-4 py-2 text-sm font-medium text-primary transition hover:bg-primary-20 disabled:cursor-not-allowed disabled:border-slate-200 disabled:text-slate-400",
|
|
14409
14138
|
children: "Apply"
|
|
14410
14139
|
}
|
|
14411
14140
|
)
|
|
14412
14141
|
] })
|
|
14413
14142
|
] })
|
|
14414
14143
|
] }) }) }) });
|
|
14415
|
-
const displayCategories =
|
|
14144
|
+
const displayCategories = React10.useMemo(() => {
|
|
14416
14145
|
return topCategories.slice(0, 5);
|
|
14417
14146
|
}, [topCategories]);
|
|
14418
14147
|
const getCategoryIcon = (categoryName2) => {
|
|
@@ -14473,7 +14202,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
14473
14202
|
animate: { opacity: 1, y: 0 },
|
|
14474
14203
|
className: `group relative overflow-hidden rounded-[24px] p-6 min-h-[180px] min-w-[170px] transition-all duration-300 ${!categoryFilter ? "bg-linear-to-br from-primary to-secondary text-white shadow-xl scale-105" : "bg-linear-to-br from-gray-50 to-white hover:shadow-lg border-2 border-gray-100 hover:border-primary"}`,
|
|
14475
14204
|
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
14476
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: `size-12 rounded-full mb-3 mx-auto flex items-center justify-center transition-all ${!categoryFilter ? "bg-white/20" : "bg-linear-to-br from-primary
|
|
14205
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: `size-12 rounded-full mb-3 mx-auto flex items-center justify-center transition-all ${!categoryFilter ? "bg-white/20" : "bg-linear-to-br from-primary-10 to-secondary-10 group-hover:scale-110"}`, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Package, { className: `size-6 ${!categoryFilter ? "text-white" : "text-primary"}` }) }),
|
|
14477
14206
|
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: `font-['Poppins',sans-serif] font-semibold text-[14px] mb-1.5 ${!categoryFilter ? "text-white" : "text-secondary"}`, children: "All Products" }),
|
|
14478
14207
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: `font-['Poppins',sans-serif] text-[11px] ${!categoryFilter ? "text-white/80" : "text-muted"}`, children: "Browse Everything" })
|
|
14479
14208
|
] })
|
|
@@ -14492,7 +14221,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
14492
14221
|
onClick: () => handleCategoryChange(categoryId),
|
|
14493
14222
|
className: `group relative overflow-hidden rounded-[24px] p-6 min-h-[180px] min-w-[170px] transition-all duration-300 ${isSelected ? "bg-linear-to-br from-primary to-secondary text-white shadow-xl scale-105" : "bg-linear-to-br from-gray-50 to-white hover:shadow-lg border-2 border-gray-100 hover:border-primary"}`,
|
|
14494
14223
|
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
14495
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: `size-12 rounded-full mb-3 mx-auto flex items-center justify-center transition-all ${isSelected ? "bg-white/20" : "bg-linear-to-br from-primary
|
|
14224
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: `size-12 rounded-full mb-3 mx-auto flex items-center justify-center transition-all ${isSelected ? "bg-white/20" : "bg-linear-to-br from-primary-10 to-secondary-10 group-hover:scale-110"}`, children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: `size-6 ${isSelected ? "text-white" : "text-primary"}` }) }),
|
|
14496
14225
|
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: `font-['Poppins',sans-serif] font-semibold text-[14px] mb-1.5 ${isSelected ? "text-white" : "text-secondary"}`, children: category.name }),
|
|
14497
14226
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: `font-['Poppins',sans-serif] text-[11px] ${isSelected ? "text-white/80" : "text-muted"}`, children: category.description })
|
|
14498
14227
|
] })
|
|
@@ -14694,10 +14423,10 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
14694
14423
|
] });
|
|
14695
14424
|
}
|
|
14696
14425
|
function useProductReviews(productId) {
|
|
14697
|
-
const [reviews, setReviews] =
|
|
14698
|
-
const [isLoading, setIsLoading] =
|
|
14699
|
-
const [error, setError] =
|
|
14700
|
-
const fetchReviews =
|
|
14426
|
+
const [reviews, setReviews] = React10.useState([]);
|
|
14427
|
+
const [isLoading, setIsLoading] = React10.useState(true);
|
|
14428
|
+
const [error, setError] = React10.useState(null);
|
|
14429
|
+
const fetchReviews = React10.useCallback(async () => {
|
|
14701
14430
|
if (!productId) {
|
|
14702
14431
|
setIsLoading(false);
|
|
14703
14432
|
return;
|
|
@@ -14713,7 +14442,7 @@ function useProductReviews(productId) {
|
|
|
14713
14442
|
setIsLoading(false);
|
|
14714
14443
|
}
|
|
14715
14444
|
}, [productId]);
|
|
14716
|
-
|
|
14445
|
+
React10.useEffect(() => {
|
|
14717
14446
|
fetchReviews();
|
|
14718
14447
|
}, [fetchReviews]);
|
|
14719
14448
|
return {
|
|
@@ -14724,12 +14453,12 @@ function useProductReviews(productId) {
|
|
|
14724
14453
|
};
|
|
14725
14454
|
}
|
|
14726
14455
|
function useUserReviews(userId) {
|
|
14727
|
-
const [reviews, setReviews] =
|
|
14728
|
-
const [isLoading, setIsLoading] =
|
|
14729
|
-
const [error, setError] =
|
|
14456
|
+
const [reviews, setReviews] = React10.useState([]);
|
|
14457
|
+
const [isLoading, setIsLoading] = React10.useState(true);
|
|
14458
|
+
const [error, setError] = React10.useState(null);
|
|
14730
14459
|
const { user } = useAuth();
|
|
14731
14460
|
const resolvedUserId = userId || user?._id || user?.id;
|
|
14732
|
-
const fetchReviews =
|
|
14461
|
+
const fetchReviews = React10.useCallback(async () => {
|
|
14733
14462
|
if (!resolvedUserId) {
|
|
14734
14463
|
setIsLoading(false);
|
|
14735
14464
|
return;
|
|
@@ -14745,7 +14474,7 @@ function useUserReviews(userId) {
|
|
|
14745
14474
|
setIsLoading(false);
|
|
14746
14475
|
}
|
|
14747
14476
|
}, [resolvedUserId]);
|
|
14748
|
-
|
|
14477
|
+
React10.useEffect(() => {
|
|
14749
14478
|
fetchReviews();
|
|
14750
14479
|
}, [fetchReviews]);
|
|
14751
14480
|
return {
|
|
@@ -14756,10 +14485,10 @@ function useUserReviews(userId) {
|
|
|
14756
14485
|
};
|
|
14757
14486
|
}
|
|
14758
14487
|
function useReviewsByRating(rating) {
|
|
14759
|
-
const [reviews, setReviews] =
|
|
14760
|
-
const [isLoading, setIsLoading] =
|
|
14761
|
-
const [error, setError] =
|
|
14762
|
-
const fetchReviews =
|
|
14488
|
+
const [reviews, setReviews] = React10.useState([]);
|
|
14489
|
+
const [isLoading, setIsLoading] = React10.useState(true);
|
|
14490
|
+
const [error, setError] = React10.useState(null);
|
|
14491
|
+
const fetchReviews = React10.useCallback(async () => {
|
|
14763
14492
|
if (!rating || rating < 1 || rating > 5) {
|
|
14764
14493
|
setIsLoading(false);
|
|
14765
14494
|
return;
|
|
@@ -14775,7 +14504,7 @@ function useReviewsByRating(rating) {
|
|
|
14775
14504
|
setIsLoading(false);
|
|
14776
14505
|
}
|
|
14777
14506
|
}, [rating]);
|
|
14778
|
-
|
|
14507
|
+
React10.useEffect(() => {
|
|
14779
14508
|
fetchReviews();
|
|
14780
14509
|
}, [fetchReviews]);
|
|
14781
14510
|
return {
|
|
@@ -14786,10 +14515,10 @@ function useReviewsByRating(rating) {
|
|
|
14786
14515
|
};
|
|
14787
14516
|
}
|
|
14788
14517
|
function useCreateReview() {
|
|
14789
|
-
const [isLoading, setIsLoading] =
|
|
14790
|
-
const [error, setError] =
|
|
14791
|
-
const [success, setSuccess] =
|
|
14792
|
-
const createReview =
|
|
14518
|
+
const [isLoading, setIsLoading] = React10.useState(false);
|
|
14519
|
+
const [error, setError] = React10.useState(null);
|
|
14520
|
+
const [success, setSuccess] = React10.useState(false);
|
|
14521
|
+
const createReview = React10.useCallback(async (orderId, reviewData) => {
|
|
14793
14522
|
setIsLoading(true);
|
|
14794
14523
|
setError(null);
|
|
14795
14524
|
setSuccess(false);
|
|
@@ -14804,7 +14533,7 @@ function useCreateReview() {
|
|
|
14804
14533
|
setIsLoading(false);
|
|
14805
14534
|
}
|
|
14806
14535
|
}, []);
|
|
14807
|
-
const reset =
|
|
14536
|
+
const reset = React10.useCallback(() => {
|
|
14808
14537
|
setError(null);
|
|
14809
14538
|
setSuccess(false);
|
|
14810
14539
|
setIsLoading(false);
|
|
@@ -14818,9 +14547,9 @@ function useCreateReview() {
|
|
|
14818
14547
|
};
|
|
14819
14548
|
}
|
|
14820
14549
|
function useUpdateReview() {
|
|
14821
|
-
const [isLoading, setIsLoading] =
|
|
14822
|
-
const [error, setError] =
|
|
14823
|
-
const updateReview =
|
|
14550
|
+
const [isLoading, setIsLoading] = React10.useState(false);
|
|
14551
|
+
const [error, setError] = React10.useState(null);
|
|
14552
|
+
const updateReview = React10.useCallback(async (reviewId, reviewData) => {
|
|
14824
14553
|
setIsLoading(true);
|
|
14825
14554
|
setError(null);
|
|
14826
14555
|
try {
|
|
@@ -14840,9 +14569,9 @@ function useUpdateReview() {
|
|
|
14840
14569
|
};
|
|
14841
14570
|
}
|
|
14842
14571
|
function useDeleteReview() {
|
|
14843
|
-
const [isLoading, setIsLoading] =
|
|
14844
|
-
const [error, setError] =
|
|
14845
|
-
const deleteReview =
|
|
14572
|
+
const [isLoading, setIsLoading] = React10.useState(false);
|
|
14573
|
+
const [error, setError] = React10.useState(null);
|
|
14574
|
+
const deleteReview = React10.useCallback(async (reviewId) => {
|
|
14846
14575
|
setIsLoading(true);
|
|
14847
14576
|
setError(null);
|
|
14848
14577
|
try {
|
|
@@ -14861,10 +14590,10 @@ function useDeleteReview() {
|
|
|
14861
14590
|
};
|
|
14862
14591
|
}
|
|
14863
14592
|
function useReviewStats() {
|
|
14864
|
-
const [count, setCount] =
|
|
14865
|
-
const [isLoading, setIsLoading] =
|
|
14866
|
-
const [error, setError] =
|
|
14867
|
-
const fetchCount =
|
|
14593
|
+
const [count, setCount] = React10.useState(0);
|
|
14594
|
+
const [isLoading, setIsLoading] = React10.useState(true);
|
|
14595
|
+
const [error, setError] = React10.useState(null);
|
|
14596
|
+
const fetchCount = React10.useCallback(async () => {
|
|
14868
14597
|
setIsLoading(true);
|
|
14869
14598
|
setError(null);
|
|
14870
14599
|
try {
|
|
@@ -14876,7 +14605,7 @@ function useReviewStats() {
|
|
|
14876
14605
|
setIsLoading(false);
|
|
14877
14606
|
}
|
|
14878
14607
|
}, []);
|
|
14879
|
-
|
|
14608
|
+
React10.useEffect(() => {
|
|
14880
14609
|
fetchCount();
|
|
14881
14610
|
}, [fetchCount]);
|
|
14882
14611
|
return {
|
|
@@ -14900,7 +14629,7 @@ function StarRating({
|
|
|
14900
14629
|
onChange,
|
|
14901
14630
|
className
|
|
14902
14631
|
}) {
|
|
14903
|
-
const [hoverRating, setHoverRating] =
|
|
14632
|
+
const [hoverRating, setHoverRating] = React10__default.default.useState(0);
|
|
14904
14633
|
const handleClick = (index) => {
|
|
14905
14634
|
if (interactive && onChange) {
|
|
14906
14635
|
onChange(index + 1);
|
|
@@ -15030,9 +14759,9 @@ function ReviewCard({ review, showProductInfo = false }) {
|
|
|
15030
14759
|
] });
|
|
15031
14760
|
}
|
|
15032
14761
|
function ReviewsList({ reviews, isLoading }) {
|
|
15033
|
-
const [filterRating, setFilterRating] =
|
|
15034
|
-
const [sortBy, setSortBy] =
|
|
15035
|
-
const filteredReviews =
|
|
14762
|
+
const [filterRating, setFilterRating] = React10.useState("all");
|
|
14763
|
+
const [sortBy, setSortBy] = React10.useState("recent");
|
|
14764
|
+
const filteredReviews = React10__default.default.useMemo(() => {
|
|
15036
14765
|
let filtered = [...reviews];
|
|
15037
14766
|
if (filterRating !== "all") {
|
|
15038
14767
|
filtered = filtered.filter((review) => Math.floor(review.rating) === filterRating);
|
|
@@ -15169,18 +14898,18 @@ function ProductDetailScreen({ productId }) {
|
|
|
15169
14898
|
const { isAuthenticated } = useAuth();
|
|
15170
14899
|
const notification = useNotification();
|
|
15171
14900
|
const { reviews, isLoading: reviewsLoading } = useProductReviews(productId);
|
|
15172
|
-
const [selectedVariant, setSelectedVariant] =
|
|
15173
|
-
const [quantity, setQuantity] =
|
|
15174
|
-
const [isAddingToCart, setIsAddingToCart] =
|
|
15175
|
-
const [isFavorited, setIsFavorited] =
|
|
15176
|
-
const [relatedProducts, setRelatedProducts] =
|
|
15177
|
-
const [initialProductData, setInitialProductData] =
|
|
15178
|
-
const [activeImageIndex, setActiveImageIndex] =
|
|
15179
|
-
const [activeTab, setActiveTab] =
|
|
15180
|
-
|
|
14901
|
+
const [selectedVariant, setSelectedVariant] = React10.useState(null);
|
|
14902
|
+
const [quantity, setQuantity] = React10.useState(1);
|
|
14903
|
+
const [isAddingToCart, setIsAddingToCart] = React10.useState(false);
|
|
14904
|
+
const [isFavorited, setIsFavorited] = React10.useState(false);
|
|
14905
|
+
const [relatedProducts, setRelatedProducts] = React10.useState([]);
|
|
14906
|
+
const [initialProductData, setInitialProductData] = React10.useState(null);
|
|
14907
|
+
const [activeImageIndex, setActiveImageIndex] = React10.useState(0);
|
|
14908
|
+
const [activeTab, setActiveTab] = React10.useState("description");
|
|
14909
|
+
React10.useEffect(() => {
|
|
15181
14910
|
setActiveImageIndex(0);
|
|
15182
14911
|
}, [selectedVariant]);
|
|
15183
|
-
const product =
|
|
14912
|
+
const product = React10.useMemo(() => {
|
|
15184
14913
|
if (initialProductData && !productData) {
|
|
15185
14914
|
return initialProductData;
|
|
15186
14915
|
}
|
|
@@ -15197,7 +14926,7 @@ function ProductDetailScreen({ productId }) {
|
|
|
15197
14926
|
}
|
|
15198
14927
|
return productData;
|
|
15199
14928
|
}, [productData, selectedVariant, initialProductData]);
|
|
15200
|
-
const reviewStats =
|
|
14929
|
+
const reviewStats = React10.useMemo(() => {
|
|
15201
14930
|
if (!reviews || reviews.length === 0) {
|
|
15202
14931
|
return {
|
|
15203
14932
|
averageRating: product?.rating || 0,
|
|
@@ -15256,7 +14985,7 @@ function ProductDetailScreen({ productId }) {
|
|
|
15256
14985
|
);
|
|
15257
14986
|
currentVariant?.sku || product?.sku || "N/A";
|
|
15258
14987
|
currentVariant?.inventoryCount > 0;
|
|
15259
|
-
|
|
14988
|
+
React10.useEffect(() => {
|
|
15260
14989
|
if (typeof window === "undefined") return;
|
|
15261
14990
|
const searchParams = new URLSearchParams(window.location.search);
|
|
15262
14991
|
const productParam = searchParams.get("product");
|
|
@@ -15269,13 +14998,13 @@ function ProductDetailScreen({ productId }) {
|
|
|
15269
14998
|
}
|
|
15270
14999
|
}
|
|
15271
15000
|
}, []);
|
|
15272
|
-
|
|
15001
|
+
React10.useEffect(() => {
|
|
15273
15002
|
if (product?.productVariants?.length > 0) {
|
|
15274
15003
|
const newVariant = product?.productVariants?.[0];
|
|
15275
15004
|
setSelectedVariant(newVariant);
|
|
15276
15005
|
}
|
|
15277
15006
|
}, [product?.productVariants]);
|
|
15278
|
-
|
|
15007
|
+
React10.useEffect(() => {
|
|
15279
15008
|
if (!product?._id) return;
|
|
15280
15009
|
const fetchRelated = async () => {
|
|
15281
15010
|
try {
|
|
@@ -15324,7 +15053,7 @@ function ProductDetailScreen({ productId }) {
|
|
|
15324
15053
|
}
|
|
15325
15054
|
};
|
|
15326
15055
|
const { addToWishlist, removeFromWishlist, isInWishlist } = useWishlist();
|
|
15327
|
-
|
|
15056
|
+
React10.useEffect(() => {
|
|
15328
15057
|
if (product) {
|
|
15329
15058
|
setIsFavorited(isInWishlist(product._id));
|
|
15330
15059
|
}
|
|
@@ -15435,7 +15164,7 @@ function ProductDetailScreen({ productId }) {
|
|
|
15435
15164
|
{
|
|
15436
15165
|
type: "button",
|
|
15437
15166
|
onClick: () => setActiveImageIndex(index),
|
|
15438
|
-
className: `relative aspect-square overflow-hidden rounded-lg border-2 transition-all ${activeImageIndex === index ? "border-primary
|
|
15167
|
+
className: `relative aspect-square overflow-hidden rounded-lg border-2 transition-all ${activeImageIndex === index ? "border-primary-50 ring-2 ring-primary-80 ring-offset-2 shadow-md" : "border-slate-200 hover:border-primary-50"}`,
|
|
15439
15168
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
15440
15169
|
Image4__default.default,
|
|
15441
15170
|
{
|
|
@@ -15529,7 +15258,7 @@ function ProductDetailScreen({ productId }) {
|
|
|
15529
15258
|
{
|
|
15530
15259
|
type: "button",
|
|
15531
15260
|
onClick: () => handleVariantSelect(variant),
|
|
15532
|
-
className: `flex items-start gap-3 px-4 py-2.5 rounded-xl border-2 transition-all ${isSelected ? "border-primary bg-primary
|
|
15261
|
+
className: `flex items-start gap-3 px-4 py-2.5 rounded-xl border-2 transition-all ${isSelected ? "border-primary bg-primary-5" : "border-gray-200 hover:border-primary-50"}`,
|
|
15533
15262
|
children: [
|
|
15534
15263
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: `relative h-12 w-12 shrink-0 overflow-hidden rounded-full border-2 ${isSelected ? "border-primary" : "border-slate-200"}`, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
15535
15264
|
Image4__default.default,
|
|
@@ -15608,7 +15337,7 @@ function ProductDetailScreen({ productId }) {
|
|
|
15608
15337
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
15609
15338
|
"button",
|
|
15610
15339
|
{
|
|
15611
|
-
className: "sm:w-auto px-6 py-4 rounded-full border-2 border-primary hover:bg-primary
|
|
15340
|
+
className: "sm:w-auto px-6 py-4 rounded-full border-2 border-primary hover:bg-primary-5 transition-all flex items-center justify-center",
|
|
15612
15341
|
onClick: handleToggleFavorite,
|
|
15613
15342
|
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Heart, { className: `h-4 w-4 ${isFavorited ? "fill-red-500 text-red-500" : "text-primary"}` })
|
|
15614
15343
|
}
|
|
@@ -15697,8 +15426,8 @@ function ProductDetailScreen({ productId }) {
|
|
|
15697
15426
|
}
|
|
15698
15427
|
function CartItem({ item }) {
|
|
15699
15428
|
const { updateQuantity, removeFromCart } = useCart();
|
|
15700
|
-
const [isUpdating, setIsUpdating] =
|
|
15701
|
-
const [isRemoving, setIsRemoving] =
|
|
15429
|
+
const [isUpdating, setIsUpdating] = React10.useState(false);
|
|
15430
|
+
const [isRemoving, setIsRemoving] = React10.useState(false);
|
|
15702
15431
|
const handleUpdateQuantity = async (newQuantity) => {
|
|
15703
15432
|
if (newQuantity < 1) return;
|
|
15704
15433
|
setIsUpdating(true);
|
|
@@ -15952,20 +15681,20 @@ function CartScreen() {
|
|
|
15952
15681
|
] }) }) });
|
|
15953
15682
|
}
|
|
15954
15683
|
function useAddresses() {
|
|
15955
|
-
const [addresses, setAddresses] =
|
|
15956
|
-
const [isLoading, setIsLoading] =
|
|
15957
|
-
const [error, setError] =
|
|
15958
|
-
const refresh =
|
|
15684
|
+
const [addresses, setAddresses] = React10.useState([]);
|
|
15685
|
+
const [isLoading, setIsLoading] = React10.useState(true);
|
|
15686
|
+
const [error, setError] = React10.useState(null);
|
|
15687
|
+
const refresh = React10.useCallback(async () => {
|
|
15959
15688
|
setIsLoading(true);
|
|
15960
15689
|
setError(null);
|
|
15961
15690
|
const response = await new AddressesApi(AXIOS_CONFIG).getMyAddresses();
|
|
15962
15691
|
setAddresses(response.data || []);
|
|
15963
15692
|
setIsLoading(false);
|
|
15964
15693
|
}, []);
|
|
15965
|
-
|
|
15694
|
+
React10.useEffect(() => {
|
|
15966
15695
|
refresh();
|
|
15967
15696
|
}, [refresh]);
|
|
15968
|
-
const sortedAddresses =
|
|
15697
|
+
const sortedAddresses = React10.useMemo(() => {
|
|
15969
15698
|
return [...addresses].sort((a, b) => {
|
|
15970
15699
|
if (a.isDefault === b.isDefault) {
|
|
15971
15700
|
const dateA = a.updatedAt || "";
|
|
@@ -15975,26 +15704,26 @@ function useAddresses() {
|
|
|
15975
15704
|
return a.isDefault ? -1 : 1;
|
|
15976
15705
|
});
|
|
15977
15706
|
}, [addresses]);
|
|
15978
|
-
const defaultAddress =
|
|
15707
|
+
const defaultAddress = React10.useMemo(
|
|
15979
15708
|
() => sortedAddresses.find((address) => address.isDefault) || null,
|
|
15980
15709
|
[sortedAddresses]
|
|
15981
15710
|
);
|
|
15982
|
-
const addAddress =
|
|
15711
|
+
const addAddress = React10.useCallback(async (payload) => {
|
|
15983
15712
|
const response = await new AddressesApi(AXIOS_CONFIG).createAddressForUser(payload);
|
|
15984
15713
|
setAddresses((prev) => [...prev, response.data]);
|
|
15985
15714
|
return response.data;
|
|
15986
15715
|
}, []);
|
|
15987
|
-
const updateAddress =
|
|
15716
|
+
const updateAddress = React10.useCallback(async (id, payload) => {
|
|
15988
15717
|
const response = await new AddressesApi(AXIOS_CONFIG).updateUserAddress(payload, id);
|
|
15989
15718
|
setAddresses((prev) => prev.map((address) => address.id === id ? response.data : address));
|
|
15990
15719
|
return response.data;
|
|
15991
15720
|
}, []);
|
|
15992
|
-
const removeAddress =
|
|
15721
|
+
const removeAddress = React10.useCallback(async (id) => {
|
|
15993
15722
|
await new AddressesApi(AXIOS_CONFIG).deleteUserAddress(id);
|
|
15994
15723
|
setAddresses((prev) => prev.filter((address) => address.id !== id));
|
|
15995
15724
|
return;
|
|
15996
15725
|
}, []);
|
|
15997
|
-
const markAsDefault =
|
|
15726
|
+
const markAsDefault = React10.useCallback(async (id) => {
|
|
15998
15727
|
const response = await new AddressesApi(AXIOS_CONFIG).updateDefaultAddress(id);
|
|
15999
15728
|
setAddresses((prev) => prev.map((address) => address.id === id ? response.data : address));
|
|
16000
15729
|
return response.data;
|
|
@@ -16015,10 +15744,10 @@ init_config();
|
|
|
16015
15744
|
var cachedCapabilities = null;
|
|
16016
15745
|
var cacheStoreId = null;
|
|
16017
15746
|
function useStoreCapabilities() {
|
|
16018
|
-
const [capabilities, setCapabilities] =
|
|
16019
|
-
const [isLoading, setIsLoading] =
|
|
16020
|
-
const [error, setError] =
|
|
16021
|
-
const fetchCapabilities =
|
|
15747
|
+
const [capabilities, setCapabilities] = React10.useState(cachedCapabilities);
|
|
15748
|
+
const [isLoading, setIsLoading] = React10.useState(!cachedCapabilities);
|
|
15749
|
+
const [error, setError] = React10.useState(null);
|
|
15750
|
+
const fetchCapabilities = React10.useCallback(async (forceRefresh = false) => {
|
|
16022
15751
|
try {
|
|
16023
15752
|
const config = getCurrentConfig();
|
|
16024
15753
|
const storeId = config?.storeId;
|
|
@@ -16046,10 +15775,10 @@ function useStoreCapabilities() {
|
|
|
16046
15775
|
setIsLoading(false);
|
|
16047
15776
|
}
|
|
16048
15777
|
}, []);
|
|
16049
|
-
const refresh =
|
|
15778
|
+
const refresh = React10.useCallback(async () => {
|
|
16050
15779
|
await fetchCapabilities(true);
|
|
16051
15780
|
}, [fetchCapabilities]);
|
|
16052
|
-
|
|
15781
|
+
React10.useEffect(() => {
|
|
16053
15782
|
fetchCapabilities();
|
|
16054
15783
|
}, [fetchCapabilities]);
|
|
16055
15784
|
const showCardPayment = Boolean(capabilities?.hasStripeKey && capabilities?.cardPaymentEnabled);
|
|
@@ -16066,7 +15795,7 @@ function useStoreCapabilities() {
|
|
|
16066
15795
|
};
|
|
16067
15796
|
}
|
|
16068
15797
|
function Modal({ isOpen, onClose, title, children, size = "md" }) {
|
|
16069
|
-
|
|
15798
|
+
React10.useEffect(() => {
|
|
16070
15799
|
if (typeof window === "undefined") return;
|
|
16071
15800
|
if (isOpen) {
|
|
16072
15801
|
document.body.style.overflow = "hidden";
|
|
@@ -16130,7 +15859,7 @@ var addressSchema = zod.z.object({
|
|
|
16130
15859
|
phone: zod.z.string().min(10, "Phone number must be at least 10 characters").optional().or(zod.z.literal(""))
|
|
16131
15860
|
});
|
|
16132
15861
|
function AddressFormModal({ isOpen, onClose, onAddressAdded, onAddressUpdated, initialAddress }) {
|
|
16133
|
-
const [isSubmitting, setIsSubmitting] =
|
|
15862
|
+
const [isSubmitting, setIsSubmitting] = React10.useState(false);
|
|
16134
15863
|
const notification = useNotification();
|
|
16135
15864
|
const {
|
|
16136
15865
|
register,
|
|
@@ -16150,7 +15879,7 @@ function AddressFormModal({ isOpen, onClose, onAddressAdded, onAddressUpdated, i
|
|
|
16150
15879
|
country: initialAddress?.country || "United States"
|
|
16151
15880
|
}
|
|
16152
15881
|
});
|
|
16153
|
-
|
|
15882
|
+
React10.useEffect(() => {
|
|
16154
15883
|
reset({
|
|
16155
15884
|
name: initialAddress?.name || "",
|
|
16156
15885
|
phone: initialAddress?.phone || "",
|
|
@@ -16337,9 +16066,9 @@ function CouponCodeInput({
|
|
|
16337
16066
|
validateAndApplyCoupon,
|
|
16338
16067
|
removeCoupon
|
|
16339
16068
|
} = useDiscounts();
|
|
16340
|
-
const [localError, setLocalError] =
|
|
16341
|
-
const [isFocused, setIsFocused] =
|
|
16342
|
-
const inputRef =
|
|
16069
|
+
const [localError, setLocalError] = React10.useState(null);
|
|
16070
|
+
const [isFocused, setIsFocused] = React10.useState(false);
|
|
16071
|
+
const inputRef = React10.useRef(null);
|
|
16343
16072
|
const {
|
|
16344
16073
|
register,
|
|
16345
16074
|
handleSubmit,
|
|
@@ -16358,7 +16087,7 @@ function CouponCodeInput({
|
|
|
16358
16087
|
inputRef.current?.classList.remove("animate-shake");
|
|
16359
16088
|
}, 400);
|
|
16360
16089
|
};
|
|
16361
|
-
const onSubmit =
|
|
16090
|
+
const onSubmit = React10.useCallback(
|
|
16362
16091
|
async (data) => {
|
|
16363
16092
|
setLocalError(null);
|
|
16364
16093
|
const result = await validateAndApplyCoupon(data.code, userId);
|
|
@@ -16506,16 +16235,16 @@ function CheckoutScreen() {
|
|
|
16506
16235
|
const { cart, clearCart } = useCart();
|
|
16507
16236
|
const { isAuthenticated, user } = useAuth();
|
|
16508
16237
|
const { buildPath } = useBasePath();
|
|
16509
|
-
const [isSubmitting, setIsSubmitting] =
|
|
16510
|
-
const [isDelivery, setIsDelivery] =
|
|
16511
|
-
const [hasSetDefaultDelivery, setHasSetDefaultDelivery] =
|
|
16512
|
-
const [paymentMethod, setPaymentMethod] =
|
|
16513
|
-
const [error, setError] =
|
|
16514
|
-
const [selectedAddressId, setSelectedAddressId] =
|
|
16515
|
-
const [storeAddresses, setStoreAddresses] =
|
|
16516
|
-
const [isAddressModalOpen, setIsAddressModalOpen] =
|
|
16517
|
-
const [editingAddress, setEditingAddress] =
|
|
16518
|
-
const [shippingPrice, setShippingPrice] =
|
|
16238
|
+
const [isSubmitting, setIsSubmitting] = React10.useState(false);
|
|
16239
|
+
const [isDelivery, setIsDelivery] = React10.useState(null);
|
|
16240
|
+
const [hasSetDefaultDelivery, setHasSetDefaultDelivery] = React10.useState(false);
|
|
16241
|
+
const [paymentMethod, setPaymentMethod] = React10.useState(null);
|
|
16242
|
+
const [error, setError] = React10.useState(null);
|
|
16243
|
+
const [selectedAddressId, setSelectedAddressId] = React10.useState(null);
|
|
16244
|
+
const [storeAddresses, setStoreAddresses] = React10.useState([]);
|
|
16245
|
+
const [isAddressModalOpen, setIsAddressModalOpen] = React10.useState(false);
|
|
16246
|
+
const [editingAddress, setEditingAddress] = React10.useState(null);
|
|
16247
|
+
const [shippingPrice, setShippingPrice] = React10.useState(0);
|
|
16519
16248
|
const notification = useNotification();
|
|
16520
16249
|
const { appliedCoupon, calculateCouponDiscount } = useDiscounts();
|
|
16521
16250
|
const {
|
|
@@ -16535,13 +16264,13 @@ function CheckoutScreen() {
|
|
|
16535
16264
|
}
|
|
16536
16265
|
return true;
|
|
16537
16266
|
});
|
|
16538
|
-
|
|
16267
|
+
React10.useEffect(() => {
|
|
16539
16268
|
if (!capabilitiesLoading && paymentMethod === null && availablePaymentMethods.length > 0) {
|
|
16540
16269
|
const preferCard = availablePaymentMethods.find((pm) => pm.id === "Card");
|
|
16541
16270
|
setPaymentMethod(preferCard ? "Card" : availablePaymentMethods[0].value);
|
|
16542
16271
|
}
|
|
16543
16272
|
}, [capabilitiesLoading, paymentMethod, availablePaymentMethods]);
|
|
16544
|
-
|
|
16273
|
+
React10.useEffect(() => {
|
|
16545
16274
|
if (!capabilitiesLoading && !hasSetDefaultDelivery && capabilities) {
|
|
16546
16275
|
if (!showShippoDelivery && !showCustomDelivery) {
|
|
16547
16276
|
setIsDelivery(false);
|
|
@@ -16574,11 +16303,11 @@ function CheckoutScreen() {
|
|
|
16574
16303
|
desc: "Collect from pharmacy"
|
|
16575
16304
|
}
|
|
16576
16305
|
];
|
|
16577
|
-
const [selectedShippingRateId, setSelectedShippingRateId] =
|
|
16578
|
-
const [shippingRates, setShippingRates] =
|
|
16579
|
-
const [shippingRatesLoading, setShippingRatesLoading] =
|
|
16580
|
-
const [shippingRatesError, setShippingRatesError] =
|
|
16581
|
-
const [storeData, setStoreData] =
|
|
16306
|
+
const [selectedShippingRateId, setSelectedShippingRateId] = React10.useState(null);
|
|
16307
|
+
const [shippingRates, setShippingRates] = React10.useState([]);
|
|
16308
|
+
const [shippingRatesLoading, setShippingRatesLoading] = React10.useState(false);
|
|
16309
|
+
const [shippingRatesError, setShippingRatesError] = React10.useState(null);
|
|
16310
|
+
const [storeData, setStoreData] = React10.useState(null);
|
|
16582
16311
|
const { addresses, isLoading, refresh, removeAddress } = useAddresses();
|
|
16583
16312
|
const {
|
|
16584
16313
|
register,
|
|
@@ -16611,7 +16340,7 @@ function CheckoutScreen() {
|
|
|
16611
16340
|
}
|
|
16612
16341
|
});
|
|
16613
16342
|
const sameAsShipping = watch("sameAsShipping", true);
|
|
16614
|
-
|
|
16343
|
+
React10.useEffect(() => {
|
|
16615
16344
|
if (sameAsShipping) {
|
|
16616
16345
|
setValue("billing.name", watch("shipping.name"));
|
|
16617
16346
|
setValue("billing.phone", watch("shipping.phone"));
|
|
@@ -16623,7 +16352,7 @@ function CheckoutScreen() {
|
|
|
16623
16352
|
setValue("billing.country", watch("shipping.country"));
|
|
16624
16353
|
}
|
|
16625
16354
|
}, [sameAsShipping, watch("shipping.name"), watch("shipping.phone"), watch("shipping.street1"), watch("shipping.street2"), watch("shipping.city"), watch("shipping.state"), watch("shipping.zip"), watch("shipping.country")]);
|
|
16626
|
-
|
|
16355
|
+
React10.useEffect(() => {
|
|
16627
16356
|
if (defaultAddress && !selectedAddressId) {
|
|
16628
16357
|
setSelectedAddressId(defaultAddress.id);
|
|
16629
16358
|
setValue("shipping.name", defaultAddress.name);
|
|
@@ -16661,7 +16390,7 @@ function CheckoutScreen() {
|
|
|
16661
16390
|
setShippingRates([]);
|
|
16662
16391
|
setSelectedShippingRateId(null);
|
|
16663
16392
|
};
|
|
16664
|
-
|
|
16393
|
+
React10.useEffect(() => {
|
|
16665
16394
|
if (isDelivery !== true || !selectedAddressId || !cart || cart?.cartBody?.items?.length === 0 || !cart?.cartBody?.items) {
|
|
16666
16395
|
setShippingRates([]);
|
|
16667
16396
|
setSelectedShippingRateId(null);
|
|
@@ -16690,7 +16419,7 @@ function CheckoutScreen() {
|
|
|
16690
16419
|
}
|
|
16691
16420
|
})();
|
|
16692
16421
|
}, [isDelivery, selectedAddressId, cart]);
|
|
16693
|
-
|
|
16422
|
+
React10.useEffect(() => {
|
|
16694
16423
|
let cancelled = false;
|
|
16695
16424
|
if (isDelivery === false) {
|
|
16696
16425
|
(async () => {
|
|
@@ -16868,7 +16597,7 @@ function CheckoutScreen() {
|
|
|
16868
16597
|
setIsSubmitting(false);
|
|
16869
16598
|
}
|
|
16870
16599
|
};
|
|
16871
|
-
|
|
16600
|
+
React10__default.default.useEffect(() => {
|
|
16872
16601
|
if (!cart || cart?.cartBody?.items?.length === 0 || !cart?.cartBody?.items) {
|
|
16873
16602
|
router.push(buildPath("/cart"));
|
|
16874
16603
|
}
|
|
@@ -17369,9 +17098,9 @@ function LoginScreen() {
|
|
|
17369
17098
|
const searchParams = navigation.useSearchParams();
|
|
17370
17099
|
const redirectUrl = searchParams?.get("redirect") || buildPath("/");
|
|
17371
17100
|
const { login, user, isLoading } = useAuth();
|
|
17372
|
-
const [showPassword, setShowPassword] =
|
|
17373
|
-
const [isSubmitting, setIsSubmitting] =
|
|
17374
|
-
const [status, setStatus] =
|
|
17101
|
+
const [showPassword, setShowPassword] = React10.useState(false);
|
|
17102
|
+
const [isSubmitting, setIsSubmitting] = React10.useState(false);
|
|
17103
|
+
const [status, setStatus] = React10.useState(
|
|
17375
17104
|
null
|
|
17376
17105
|
);
|
|
17377
17106
|
const {
|
|
@@ -17528,9 +17257,9 @@ function RegisterScreen() {
|
|
|
17528
17257
|
const router = navigation.useRouter();
|
|
17529
17258
|
const { register: registerUser } = useAuth();
|
|
17530
17259
|
const { buildPath } = useBasePath();
|
|
17531
|
-
const [showPassword, setShowPassword] =
|
|
17532
|
-
const [showConfirmPassword, setShowConfirmPassword] =
|
|
17533
|
-
const [isSubmitting, setIsSubmitting] =
|
|
17260
|
+
const [showPassword, setShowPassword] = React10.useState(false);
|
|
17261
|
+
const [showConfirmPassword, setShowConfirmPassword] = React10.useState(false);
|
|
17262
|
+
const [isSubmitting, setIsSubmitting] = React10.useState(false);
|
|
17534
17263
|
const notification = useNotification();
|
|
17535
17264
|
const {
|
|
17536
17265
|
register,
|
|
@@ -17736,8 +17465,8 @@ var forgotPasswordSchema = zod.z.object({
|
|
|
17736
17465
|
});
|
|
17737
17466
|
function ForgotPasswordScreen() {
|
|
17738
17467
|
const { buildPath } = useBasePath();
|
|
17739
|
-
const [isSubmitting, setIsSubmitting] =
|
|
17740
|
-
const [status, setStatus] =
|
|
17468
|
+
const [isSubmitting, setIsSubmitting] = React10.useState(false);
|
|
17469
|
+
const [status, setStatus] = React10.useState(
|
|
17741
17470
|
null
|
|
17742
17471
|
);
|
|
17743
17472
|
const {
|
|
@@ -17876,10 +17605,10 @@ function ResetPasswordScreen() {
|
|
|
17876
17605
|
const params = navigation.useParams();
|
|
17877
17606
|
const token = params?.token;
|
|
17878
17607
|
const storeId = params?.storeId;
|
|
17879
|
-
const [showPassword, setShowPassword] =
|
|
17880
|
-
const [showConfirmPassword, setShowConfirmPassword] =
|
|
17881
|
-
const [isSubmitting, setIsSubmitting] =
|
|
17882
|
-
const [status, setStatus] =
|
|
17608
|
+
const [showPassword, setShowPassword] = React10.useState(false);
|
|
17609
|
+
const [showConfirmPassword, setShowConfirmPassword] = React10.useState(false);
|
|
17610
|
+
const [isSubmitting, setIsSubmitting] = React10.useState(false);
|
|
17611
|
+
const [status, setStatus] = React10.useState(
|
|
17883
17612
|
null
|
|
17884
17613
|
);
|
|
17885
17614
|
const {
|
|
@@ -17889,7 +17618,7 @@ function ResetPasswordScreen() {
|
|
|
17889
17618
|
} = reactHookForm.useForm({
|
|
17890
17619
|
resolver: zod$1.zodResolver(resetPasswordSchema)
|
|
17891
17620
|
});
|
|
17892
|
-
|
|
17621
|
+
React10.useEffect(() => {
|
|
17893
17622
|
if (!token) {
|
|
17894
17623
|
setStatus({
|
|
17895
17624
|
type: "error",
|
|
@@ -18071,10 +17800,10 @@ function TabNavigation({ tabs: tabs2, activeTab, onTabChange }) {
|
|
|
18071
17800
|
}) }) });
|
|
18072
17801
|
}
|
|
18073
17802
|
function useOrders(page = 1, limit = 10, orderStatus, paymentStatus) {
|
|
18074
|
-
const [orders, setOrders] =
|
|
18075
|
-
const [isLoading, setIsLoading] =
|
|
18076
|
-
const [error, setError] =
|
|
18077
|
-
const [pagination, setPagination] =
|
|
17803
|
+
const [orders, setOrders] = React10.useState([]);
|
|
17804
|
+
const [isLoading, setIsLoading] = React10.useState(true);
|
|
17805
|
+
const [error, setError] = React10.useState(null);
|
|
17806
|
+
const [pagination, setPagination] = React10.useState({
|
|
18078
17807
|
page: 1,
|
|
18079
17808
|
limit: 10,
|
|
18080
17809
|
total: 0,
|
|
@@ -18082,7 +17811,7 @@ function useOrders(page = 1, limit = 10, orderStatus, paymentStatus) {
|
|
|
18082
17811
|
});
|
|
18083
17812
|
const { user } = useAuth();
|
|
18084
17813
|
const resolvedUserId = user?._id || user?.id;
|
|
18085
|
-
const fetchOrders =
|
|
17814
|
+
const fetchOrders = React10.useCallback(async () => {
|
|
18086
17815
|
setIsLoading(true);
|
|
18087
17816
|
setError(null);
|
|
18088
17817
|
try {
|
|
@@ -18109,7 +17838,7 @@ function useOrders(page = 1, limit = 10, orderStatus, paymentStatus) {
|
|
|
18109
17838
|
setIsLoading(false);
|
|
18110
17839
|
}
|
|
18111
17840
|
}, [page, limit, resolvedUserId, orderStatus, paymentStatus]);
|
|
18112
|
-
|
|
17841
|
+
React10.useEffect(() => {
|
|
18113
17842
|
fetchOrders();
|
|
18114
17843
|
}, [fetchOrders]);
|
|
18115
17844
|
const deleteOrder = async (id) => {
|
|
@@ -18132,10 +17861,10 @@ function useOrders(page = 1, limit = 10, orderStatus, paymentStatus) {
|
|
|
18132
17861
|
};
|
|
18133
17862
|
}
|
|
18134
17863
|
function useOrder(id) {
|
|
18135
|
-
const [order, setOrder] =
|
|
18136
|
-
const [isLoading, setIsLoading] =
|
|
18137
|
-
const [error, setError] =
|
|
18138
|
-
const fetchOrder =
|
|
17864
|
+
const [order, setOrder] = React10.useState(null);
|
|
17865
|
+
const [isLoading, setIsLoading] = React10.useState(true);
|
|
17866
|
+
const [error, setError] = React10.useState(null);
|
|
17867
|
+
const fetchOrder = React10.useCallback(async () => {
|
|
18139
17868
|
setIsLoading(true);
|
|
18140
17869
|
setError(null);
|
|
18141
17870
|
try {
|
|
@@ -18147,7 +17876,7 @@ function useOrder(id) {
|
|
|
18147
17876
|
setIsLoading(false);
|
|
18148
17877
|
}
|
|
18149
17878
|
}, [id]);
|
|
18150
|
-
|
|
17879
|
+
React10.useEffect(() => {
|
|
18151
17880
|
if (id) {
|
|
18152
17881
|
fetchOrder();
|
|
18153
17882
|
}
|
|
@@ -18155,10 +17884,10 @@ function useOrder(id) {
|
|
|
18155
17884
|
return { order, isLoading, error, refetch: fetchOrder };
|
|
18156
17885
|
}
|
|
18157
17886
|
function useCurrentOrders() {
|
|
18158
|
-
const [orders, setOrders] =
|
|
18159
|
-
const [isLoading, setIsLoading] =
|
|
18160
|
-
const [error, setError] =
|
|
18161
|
-
const fetchCurrentOrders =
|
|
17887
|
+
const [orders, setOrders] = React10.useState([]);
|
|
17888
|
+
const [isLoading, setIsLoading] = React10.useState(true);
|
|
17889
|
+
const [error, setError] = React10.useState(null);
|
|
17890
|
+
const fetchCurrentOrders = React10.useCallback(async () => {
|
|
18162
17891
|
setIsLoading(true);
|
|
18163
17892
|
setError(null);
|
|
18164
17893
|
try {
|
|
@@ -18170,7 +17899,7 @@ function useCurrentOrders() {
|
|
|
18170
17899
|
setIsLoading(false);
|
|
18171
17900
|
}
|
|
18172
17901
|
}, []);
|
|
18173
|
-
|
|
17902
|
+
React10.useEffect(() => {
|
|
18174
17903
|
fetchCurrentOrders();
|
|
18175
17904
|
}, [fetchCurrentOrders]);
|
|
18176
17905
|
return { orders, isLoading, error, refetch: fetchCurrentOrders };
|
|
@@ -18492,11 +18221,11 @@ function ConfirmModal({
|
|
|
18492
18221
|
}
|
|
18493
18222
|
function AccountAddressesTab() {
|
|
18494
18223
|
const { addresses, isLoading, error, removeAddress, markAsDefault, refresh } = useAddresses();
|
|
18495
|
-
const [deletingId, setDeletingId] =
|
|
18496
|
-
const [editingAddress, setEditingAddress] =
|
|
18497
|
-
const [isAddressModalOpen, setIsAddressModalOpen] =
|
|
18498
|
-
const [selectedAddressId, setSelectedAddressId] =
|
|
18499
|
-
const [addressToDelete, setAddressToDelete] =
|
|
18224
|
+
const [deletingId, setDeletingId] = React10.useState(null);
|
|
18225
|
+
const [editingAddress, setEditingAddress] = React10.useState(void 0);
|
|
18226
|
+
const [isAddressModalOpen, setIsAddressModalOpen] = React10.useState(false);
|
|
18227
|
+
const [selectedAddressId, setSelectedAddressId] = React10.useState(null);
|
|
18228
|
+
const [addressToDelete, setAddressToDelete] = React10.useState(null);
|
|
18500
18229
|
const notification = useNotification();
|
|
18501
18230
|
const handleConfirmDelete = async () => {
|
|
18502
18231
|
if (!addressToDelete) return;
|
|
@@ -18648,9 +18377,9 @@ function AccountSettingsTab() {
|
|
|
18648
18377
|
const router = navigation.useRouter();
|
|
18649
18378
|
const { buildPath } = useBasePath();
|
|
18650
18379
|
const { logout } = useAuth();
|
|
18651
|
-
const [showDeleteModal, setShowDeleteModal] =
|
|
18652
|
-
const [isDeleting, setIsDeleting] =
|
|
18653
|
-
const [deleteError, setDeleteError] =
|
|
18380
|
+
const [showDeleteModal, setShowDeleteModal] = React10.useState(false);
|
|
18381
|
+
const [isDeleting, setIsDeleting] = React10.useState(false);
|
|
18382
|
+
const [deleteError, setDeleteError] = React10.useState(null);
|
|
18654
18383
|
const handleDeleteAccount = async () => {
|
|
18655
18384
|
setIsDeleting(true);
|
|
18656
18385
|
setDeleteError(null);
|
|
@@ -18849,10 +18578,10 @@ function AccountPage() {
|
|
|
18849
18578
|
const router = navigation.useRouter();
|
|
18850
18579
|
const { user, logout, isLoading } = useAuth();
|
|
18851
18580
|
const { buildPath } = useBasePath();
|
|
18852
|
-
const [activeTab, setActiveTab] =
|
|
18853
|
-
const [isDropdownOpen, setIsDropdownOpen] =
|
|
18854
|
-
const [isLoggingOut, setIsLoggingOut] =
|
|
18855
|
-
|
|
18581
|
+
const [activeTab, setActiveTab] = React10.useState("overview");
|
|
18582
|
+
const [isDropdownOpen, setIsDropdownOpen] = React10.useState(false);
|
|
18583
|
+
const [isLoggingOut, setIsLoggingOut] = React10.useState(false);
|
|
18584
|
+
React10__default.default.useEffect(() => {
|
|
18856
18585
|
const handleTabSwitch = (event) => {
|
|
18857
18586
|
setActiveTab(event.detail);
|
|
18858
18587
|
};
|
|
@@ -18898,7 +18627,7 @@ function AccountPage() {
|
|
|
18898
18627
|
function OrderCard({ order, onDelete }) {
|
|
18899
18628
|
const router = navigation.useRouter();
|
|
18900
18629
|
const { buildPath } = useBasePath();
|
|
18901
|
-
const [isDragging, setIsDragging] =
|
|
18630
|
+
const [isDragging, setIsDragging] = React10.useState(false);
|
|
18902
18631
|
const dragX = framerMotion.useMotionValue(0);
|
|
18903
18632
|
const deleteOpacity = framerMotion.useTransform(dragX, [-100, -20], [1, 0]);
|
|
18904
18633
|
const config = order.orderStatus;
|
|
@@ -19054,9 +18783,9 @@ function FilterChips({
|
|
|
19054
18783
|
maxVisible = 4,
|
|
19055
18784
|
variant = "primary"
|
|
19056
18785
|
}) {
|
|
19057
|
-
const [isOverflowOpen, setIsOverflowOpen] =
|
|
19058
|
-
const overflowMenuRef =
|
|
19059
|
-
const { visibleFilters, overflowFilters } =
|
|
18786
|
+
const [isOverflowOpen, setIsOverflowOpen] = React10.useState(false);
|
|
18787
|
+
const overflowMenuRef = React10.useRef(null);
|
|
18788
|
+
const { visibleFilters, overflowFilters } = React10.useMemo(() => {
|
|
19060
18789
|
const basePrimary = filters.slice(0, maxVisible);
|
|
19061
18790
|
if (basePrimary.includes(selected)) {
|
|
19062
18791
|
return {
|
|
@@ -19076,7 +18805,7 @@ function FilterChips({
|
|
|
19076
18805
|
overflowFilters: filters.filter((filter) => !uniquePrimary.includes(filter))
|
|
19077
18806
|
};
|
|
19078
18807
|
}, [filters, maxVisible, selected]);
|
|
19079
|
-
|
|
18808
|
+
React10.useEffect(() => {
|
|
19080
18809
|
function handleClickOutside(event) {
|
|
19081
18810
|
if (overflowMenuRef.current && !overflowMenuRef.current.contains(event.target)) {
|
|
19082
18811
|
setIsOverflowOpen(false);
|
|
@@ -19175,8 +18904,8 @@ function ReviewPromptBanner({
|
|
|
19175
18904
|
}) {
|
|
19176
18905
|
const router = navigation.useRouter();
|
|
19177
18906
|
const { buildPath } = useBasePath();
|
|
19178
|
-
const [isVisible, setIsVisible] =
|
|
19179
|
-
|
|
18907
|
+
const [isVisible, setIsVisible] = React10.useState(false);
|
|
18908
|
+
React10.useEffect(() => {
|
|
19180
18909
|
const dismissedPrompts = JSON.parse(
|
|
19181
18910
|
localStorage.getItem("dismissedReviewPrompts") || "[]"
|
|
19182
18911
|
);
|
|
@@ -19243,23 +18972,23 @@ var PAYMENT_FILTERS = ["All", ...Object.values(PaymentPaymentStatusEnum)];
|
|
|
19243
18972
|
function OrdersScreen() {
|
|
19244
18973
|
const router = navigation.useRouter();
|
|
19245
18974
|
const { buildPath } = useBasePath();
|
|
19246
|
-
const [page, setPage] =
|
|
19247
|
-
const [selectedFilter, setSelectedFilter] =
|
|
19248
|
-
const [selectedPaymentFilter, setSelectedPaymentFilter] =
|
|
18975
|
+
const [page, setPage] = React10.useState(1);
|
|
18976
|
+
const [selectedFilter, setSelectedFilter] = React10.useState("All");
|
|
18977
|
+
const [selectedPaymentFilter, setSelectedPaymentFilter] = React10.useState("All");
|
|
19249
18978
|
const { orders, isLoading, pagination, deleteOrder } = useOrders(
|
|
19250
18979
|
page,
|
|
19251
18980
|
10,
|
|
19252
18981
|
selectedFilter,
|
|
19253
18982
|
selectedPaymentFilter
|
|
19254
18983
|
);
|
|
19255
|
-
const filteredOrders =
|
|
18984
|
+
const filteredOrders = React10.useMemo(() => {
|
|
19256
18985
|
return orders.filter((order) => {
|
|
19257
18986
|
const matchesStatus = selectedFilter === "All" || order?.orderStatus?.toLowerCase() === selectedFilter.toLowerCase();
|
|
19258
18987
|
const matchesPayment = selectedPaymentFilter === "All" || order?.payment?.paymentStatus?.toLowerCase() === selectedPaymentFilter.toLowerCase();
|
|
19259
18988
|
return matchesStatus && matchesPayment;
|
|
19260
18989
|
});
|
|
19261
18990
|
}, [orders, selectedFilter, selectedPaymentFilter]);
|
|
19262
|
-
const completedOrderForPrompt =
|
|
18991
|
+
const completedOrderForPrompt = React10.useMemo(() => {
|
|
19263
18992
|
return filteredOrders.find(
|
|
19264
18993
|
(order) => order.orderStatus && ["Delivered", "Picked Up", "Fulfilled"].includes(order.orderStatus)
|
|
19265
18994
|
);
|
|
@@ -19534,9 +19263,9 @@ function AddressesScreen() {
|
|
|
19534
19263
|
removeAddress,
|
|
19535
19264
|
markAsDefault
|
|
19536
19265
|
} = useAddresses();
|
|
19537
|
-
const [isModalOpen, setIsModalOpen] =
|
|
19538
|
-
const [editingAddress, setEditingAddress] =
|
|
19539
|
-
const [banner, setBanner] =
|
|
19266
|
+
const [isModalOpen, setIsModalOpen] = React10.useState(false);
|
|
19267
|
+
const [editingAddress, setEditingAddress] = React10.useState(null);
|
|
19268
|
+
const [banner, setBanner] = React10.useState(
|
|
19540
19269
|
null
|
|
19541
19270
|
);
|
|
19542
19271
|
const {
|
|
@@ -19548,7 +19277,7 @@ function AddressesScreen() {
|
|
|
19548
19277
|
resolver: zod$1.zodResolver(addressFormSchema),
|
|
19549
19278
|
defaultValues: FORM_DEFAULTS
|
|
19550
19279
|
});
|
|
19551
|
-
|
|
19280
|
+
React10.useEffect(() => {
|
|
19552
19281
|
if (editingAddress) {
|
|
19553
19282
|
reset({
|
|
19554
19283
|
fullName: editingAddress.name,
|
|
@@ -19645,7 +19374,7 @@ You can add it back at any time.`
|
|
|
19645
19374
|
});
|
|
19646
19375
|
}
|
|
19647
19376
|
};
|
|
19648
|
-
const stats =
|
|
19377
|
+
const stats = React10.useMemo(() => {
|
|
19649
19378
|
const shippingCount = addresses.filter((address) => address.addressType !== "Billing").length;
|
|
19650
19379
|
const billingCount = addresses.filter((address) => address.addressType !== "Shipping").length;
|
|
19651
19380
|
return [
|
|
@@ -19939,15 +19668,15 @@ You can add it back at any time.`
|
|
|
19939
19668
|
] });
|
|
19940
19669
|
}
|
|
19941
19670
|
function useWishlistProducts(productIds = []) {
|
|
19942
|
-
const [products, setProducts] =
|
|
19943
|
-
const [isLoading, setIsLoading] =
|
|
19944
|
-
const [error, setError] =
|
|
19945
|
-
const [cache] =
|
|
19946
|
-
const uniqueIds =
|
|
19671
|
+
const [products, setProducts] = React10.useState([]);
|
|
19672
|
+
const [isLoading, setIsLoading] = React10.useState(false);
|
|
19673
|
+
const [error, setError] = React10.useState(null);
|
|
19674
|
+
const [cache] = React10.useState(() => /* @__PURE__ */ new Map());
|
|
19675
|
+
const uniqueIds = React10.useMemo(
|
|
19947
19676
|
() => Array.from(new Set((productIds || []).filter(Boolean))),
|
|
19948
19677
|
[productIds]
|
|
19949
19678
|
);
|
|
19950
|
-
const fetchProducts =
|
|
19679
|
+
const fetchProducts = React10.useCallback(async () => {
|
|
19951
19680
|
if (uniqueIds.length === 0) {
|
|
19952
19681
|
setProducts([]);
|
|
19953
19682
|
setIsLoading(false);
|
|
@@ -19975,7 +19704,7 @@ function useWishlistProducts(productIds = []) {
|
|
|
19975
19704
|
setIsLoading(false);
|
|
19976
19705
|
}
|
|
19977
19706
|
}, [cache, uniqueIds]);
|
|
19978
|
-
|
|
19707
|
+
React10.useEffect(() => {
|
|
19979
19708
|
fetchProducts();
|
|
19980
19709
|
}, [fetchProducts]);
|
|
19981
19710
|
return {
|
|
@@ -20008,10 +19737,10 @@ function WishlistScreen() {
|
|
|
20008
19737
|
const { products: wishlistProducts, isLoading, error } = useWishlistProducts(
|
|
20009
19738
|
wishlistItems
|
|
20010
19739
|
);
|
|
20011
|
-
const [onlyInStock, setOnlyInStock] =
|
|
20012
|
-
const [viewMode, setViewMode] =
|
|
20013
|
-
const [sortOption, setSortOption] =
|
|
20014
|
-
|
|
19740
|
+
const [onlyInStock, setOnlyInStock] = React10.useState(false);
|
|
19741
|
+
const [viewMode, setViewMode] = React10.useState("list");
|
|
19742
|
+
const [sortOption, setSortOption] = React10.useState("featured");
|
|
19743
|
+
React10.useEffect(() => {
|
|
20015
19744
|
if (error) {
|
|
20016
19745
|
notification.error(
|
|
20017
19746
|
"Could not load wishlist",
|
|
@@ -20036,11 +19765,11 @@ function WishlistScreen() {
|
|
|
20036
19765
|
console.error("Error clearing wishlist:", err);
|
|
20037
19766
|
}
|
|
20038
19767
|
};
|
|
20039
|
-
const totalValue =
|
|
19768
|
+
const totalValue = React10.useMemo(
|
|
20040
19769
|
() => wishlistProducts.reduce((sum, product) => sum + (product.summary?.minPrice ?? 0), 0),
|
|
20041
19770
|
[wishlistProducts]
|
|
20042
19771
|
);
|
|
20043
|
-
|
|
19772
|
+
React10.useMemo(
|
|
20044
19773
|
() => wishlistProducts.reduce((sum, product) => {
|
|
20045
19774
|
if (product.summary?.hasDiscount) {
|
|
20046
19775
|
const maxPrice = product.summary?.maxPrice ?? 0;
|
|
@@ -20051,11 +19780,11 @@ function WishlistScreen() {
|
|
|
20051
19780
|
}, 0),
|
|
20052
19781
|
[wishlistProducts]
|
|
20053
19782
|
);
|
|
20054
|
-
|
|
19783
|
+
React10.useMemo(
|
|
20055
19784
|
() => wishlistProducts.filter((product) => (product.summary?.totalInventory ?? 0) > 0).length,
|
|
20056
19785
|
[wishlistProducts]
|
|
20057
19786
|
);
|
|
20058
|
-
const processedProducts =
|
|
19787
|
+
const processedProducts = React10.useMemo(() => {
|
|
20059
19788
|
let list = [...wishlistProducts];
|
|
20060
19789
|
if (onlyInStock) {
|
|
20061
19790
|
list = list.filter((product) => (product.summary?.totalInventory ?? 0) > 0);
|
|
@@ -20275,7 +20004,7 @@ function WishlistScreen() {
|
|
|
20275
20004
|
{
|
|
20276
20005
|
size: "sm",
|
|
20277
20006
|
onClick: () => router.push(buildPath(`/products/${product._id}`)),
|
|
20278
|
-
className: "bg-primary
|
|
20007
|
+
className: "bg-primary-90 text-white hover:bg-primary-70",
|
|
20279
20008
|
children: "View details"
|
|
20280
20009
|
}
|
|
20281
20010
|
),
|
|
@@ -20317,15 +20046,15 @@ function SearchPage() {
|
|
|
20317
20046
|
const { buildPath } = useBasePath();
|
|
20318
20047
|
const searchParams = navigation.useSearchParams();
|
|
20319
20048
|
const searchQuery = searchParams.get("q") || "";
|
|
20320
|
-
const [products, setProducts] =
|
|
20321
|
-
const [isLoading, setIsLoading] =
|
|
20322
|
-
const [searchInput, setSearchInput] =
|
|
20323
|
-
const [hasSearched, setHasSearched] =
|
|
20049
|
+
const [products, setProducts] = React10.useState([]);
|
|
20050
|
+
const [isLoading, setIsLoading] = React10.useState(true);
|
|
20051
|
+
const [searchInput, setSearchInput] = React10.useState(searchQuery);
|
|
20052
|
+
const [hasSearched, setHasSearched] = React10.useState(false);
|
|
20324
20053
|
const { isInWishlist } = useWishlist();
|
|
20325
|
-
const [suggestions, setSuggestions] =
|
|
20326
|
-
const [showSuggestions, setShowSuggestions] =
|
|
20327
|
-
const [recentSearches, setRecentSearches] =
|
|
20328
|
-
|
|
20054
|
+
const [suggestions, setSuggestions] = React10.useState([]);
|
|
20055
|
+
const [showSuggestions, setShowSuggestions] = React10.useState(false);
|
|
20056
|
+
const [recentSearches, setRecentSearches] = React10.useState([]);
|
|
20057
|
+
React10.useEffect(() => {
|
|
20329
20058
|
const stored = localStorage.getItem("recent_searches");
|
|
20330
20059
|
if (stored) {
|
|
20331
20060
|
try {
|
|
@@ -20335,7 +20064,7 @@ function SearchPage() {
|
|
|
20335
20064
|
}
|
|
20336
20065
|
}
|
|
20337
20066
|
}, []);
|
|
20338
|
-
const saveRecentSearch =
|
|
20067
|
+
const saveRecentSearch = React10.useCallback((query) => {
|
|
20339
20068
|
if (!query.trim()) return;
|
|
20340
20069
|
setRecentSearches((prev) => {
|
|
20341
20070
|
const updated = [query, ...prev.filter((s) => s !== query)].slice(0, 5);
|
|
@@ -20343,7 +20072,7 @@ function SearchPage() {
|
|
|
20343
20072
|
return updated;
|
|
20344
20073
|
});
|
|
20345
20074
|
}, []);
|
|
20346
|
-
const generateSuggestions =
|
|
20075
|
+
const generateSuggestions = React10.useMemo(() => {
|
|
20347
20076
|
if (!searchInput.trim() || searchInput.length < 2) {
|
|
20348
20077
|
return [];
|
|
20349
20078
|
}
|
|
@@ -20364,15 +20093,15 @@ function SearchPage() {
|
|
|
20364
20093
|
});
|
|
20365
20094
|
return Array.from(suggestionSet).slice(0, 5);
|
|
20366
20095
|
}, [searchInput, products]);
|
|
20367
|
-
|
|
20096
|
+
React10.useEffect(() => {
|
|
20368
20097
|
setSuggestions(generateSuggestions);
|
|
20369
20098
|
}, [generateSuggestions]);
|
|
20370
|
-
const sanitizeSearchInput =
|
|
20099
|
+
const sanitizeSearchInput = React10.useCallback((input) => {
|
|
20371
20100
|
let sanitized = input.trim();
|
|
20372
20101
|
sanitized = sanitized.replace(/\s+/g, " ");
|
|
20373
20102
|
return sanitized;
|
|
20374
20103
|
}, []);
|
|
20375
|
-
|
|
20104
|
+
React10.useEffect(() => {
|
|
20376
20105
|
const fetchSearchResults = async () => {
|
|
20377
20106
|
const sanitizedQuery = sanitizeSearchInput(searchQuery);
|
|
20378
20107
|
if (!sanitizedQuery) {
|
|
@@ -20631,7 +20360,7 @@ function SearchPage() {
|
|
|
20631
20360
|
}
|
|
20632
20361
|
function NewAddressPage() {
|
|
20633
20362
|
const router = navigation.useRouter();
|
|
20634
|
-
const [isSubmitting, setIsSubmitting] =
|
|
20363
|
+
const [isSubmitting, setIsSubmitting] = React10.useState(false);
|
|
20635
20364
|
const notification = useNotification();
|
|
20636
20365
|
const {
|
|
20637
20366
|
register,
|
|
@@ -20814,8 +20543,8 @@ function EditProfileScreen() {
|
|
|
20814
20543
|
const router = navigation.useRouter();
|
|
20815
20544
|
const { user, updateUser } = useAuth();
|
|
20816
20545
|
const { buildPath } = useBasePath();
|
|
20817
|
-
const [isSubmitting, setIsSubmitting] =
|
|
20818
|
-
const [status, setStatus] =
|
|
20546
|
+
const [isSubmitting, setIsSubmitting] = React10.useState(false);
|
|
20547
|
+
const [status, setStatus] = React10.useState(
|
|
20819
20548
|
null
|
|
20820
20549
|
);
|
|
20821
20550
|
const {
|
|
@@ -20969,7 +20698,7 @@ function ReviewForm({
|
|
|
20969
20698
|
onSuccess,
|
|
20970
20699
|
onCancel
|
|
20971
20700
|
}) {
|
|
20972
|
-
const [rating, setRating] =
|
|
20701
|
+
const [rating, setRating] = React10.useState(0);
|
|
20973
20702
|
const { createReview, isLoading } = useCreateReview();
|
|
20974
20703
|
const notification = useNotification();
|
|
20975
20704
|
const {
|
|
@@ -21133,9 +20862,9 @@ function OrderReviewsScreen() {
|
|
|
21133
20862
|
const router = navigation.useRouter();
|
|
21134
20863
|
const { isAuthenticated } = useAuth();
|
|
21135
20864
|
const { orders, isLoading, error, refetch } = useCurrentOrders();
|
|
21136
|
-
const [selectedOrder, setSelectedOrder] =
|
|
21137
|
-
const [selectedProduct, setSelectedProduct] =
|
|
21138
|
-
|
|
20865
|
+
const [selectedOrder, setSelectedOrder] = React10.useState(null);
|
|
20866
|
+
const [selectedProduct, setSelectedProduct] = React10.useState(null);
|
|
20867
|
+
React10__default.default.useEffect(() => {
|
|
21139
20868
|
if (!isLoading && !isAuthenticated) {
|
|
21140
20869
|
router.push("/login");
|
|
21141
20870
|
}
|
|
@@ -21438,10 +21167,10 @@ var Switch = ({ checked, onChange, disabled }) => /* @__PURE__ */ jsxRuntime.jsx
|
|
|
21438
21167
|
);
|
|
21439
21168
|
function NotificationSettingsScreen() {
|
|
21440
21169
|
const { settings, updateSettings, isLoading } = useNotificationCenter();
|
|
21441
|
-
const [localSettings, setLocalSettings] =
|
|
21442
|
-
const [isSaving, setIsSaving] =
|
|
21443
|
-
const [hasChanges, setHasChanges] =
|
|
21444
|
-
|
|
21170
|
+
const [localSettings, setLocalSettings] = React10.useState(settings);
|
|
21171
|
+
const [isSaving, setIsSaving] = React10.useState(false);
|
|
21172
|
+
const [hasChanges, setHasChanges] = React10.useState(false);
|
|
21173
|
+
React10.useEffect(() => {
|
|
21445
21174
|
if (settings) {
|
|
21446
21175
|
setLocalSettings(settings);
|
|
21447
21176
|
}
|
|
@@ -21587,7 +21316,7 @@ function OrderDetailScreen({ id }) {
|
|
|
21587
21316
|
const { order, isLoading, error } = useOrder(id);
|
|
21588
21317
|
if (isLoading) {
|
|
21589
21318
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-h-screen bg-slate-50 flex flex-col items-center justify-center p-4", children: [
|
|
21590
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-16 h-16 border-4 border-primary
|
|
21319
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-16 h-16 border-4 border-primary-20 border-t-primary rounded-full animate-spin mb-4" }),
|
|
21591
21320
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted font-medium animate-pulse", children: "Retrieving order details..." })
|
|
21592
21321
|
] });
|
|
21593
21322
|
}
|
|
@@ -21757,7 +21486,7 @@ function OrderDetailScreen({ id }) {
|
|
|
21757
21486
|
{
|
|
21758
21487
|
initial: { opacity: 0, x: 20 },
|
|
21759
21488
|
animate: { opacity: 1, x: 0 },
|
|
21760
|
-
className: "bg-secondary p-8 rounded-[2rem] text-white shadow-xl shadow-secondary
|
|
21489
|
+
className: "bg-secondary p-8 rounded-[2rem] text-white shadow-xl shadow-secondary-20 sticky top-8",
|
|
21761
21490
|
children: [
|
|
21762
21491
|
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-xl font-bold mb-6 flex items-center gap-2", children: "Summary View" }),
|
|
21763
21492
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4 mb-8", children: [
|
|
@@ -21814,8 +21543,8 @@ function ChangePasswordScreen() {
|
|
|
21814
21543
|
const router = navigation.useRouter();
|
|
21815
21544
|
const { user } = useAuth();
|
|
21816
21545
|
const { buildPath } = useBasePath();
|
|
21817
|
-
const [isSubmitting, setIsSubmitting] =
|
|
21818
|
-
const [status, setStatus] =
|
|
21546
|
+
const [isSubmitting, setIsSubmitting] = React10.useState(false);
|
|
21547
|
+
const [status, setStatus] = React10.useState(
|
|
21819
21548
|
null
|
|
21820
21549
|
);
|
|
21821
21550
|
const {
|
|
@@ -21859,103 +21588,440 @@ function ChangePasswordScreen() {
|
|
|
21859
21588
|
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-2xl font-semibold text-slate-900", children: "Change password" })
|
|
21860
21589
|
] })
|
|
21861
21590
|
] }),
|
|
21862
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-3 text-sm text-slate-600", children: "Use a strong password that you have not used elsewhere. Updating your password will sign you out of other active sessions." }),
|
|
21863
|
-
status && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
21591
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-3 text-sm text-slate-600", children: "Use a strong password that you have not used elsewhere. Updating your password will sign you out of other active sessions." }),
|
|
21592
|
+
status && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
21593
|
+
"div",
|
|
21594
|
+
{
|
|
21595
|
+
className: `mt-4 flex items-start gap-2 rounded-2xl border px-4 py-3 text-sm ${status.type === "success" ? "border-green-200 bg-green-50 text-green-800" : "border-red-200 bg-red-50 text-red-700"}`,
|
|
21596
|
+
children: [
|
|
21597
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "mt-[2px] text-base", children: status.type === "success" ? "\u2714" : "!" }),
|
|
21598
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: status.message })
|
|
21599
|
+
]
|
|
21600
|
+
}
|
|
21601
|
+
),
|
|
21602
|
+
/* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handleSubmit(onSubmit), className: "mt-8 space-y-5", children: [
|
|
21603
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
21604
|
+
Input,
|
|
21605
|
+
{
|
|
21606
|
+
type: "password",
|
|
21607
|
+
label: "Current password",
|
|
21608
|
+
placeholder: "Enter current password",
|
|
21609
|
+
...register("currentPassword"),
|
|
21610
|
+
error: errors.currentPassword?.message
|
|
21611
|
+
}
|
|
21612
|
+
),
|
|
21613
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
21614
|
+
Input,
|
|
21615
|
+
{
|
|
21616
|
+
type: "password",
|
|
21617
|
+
label: "New password",
|
|
21618
|
+
placeholder: "Enter new password",
|
|
21619
|
+
...register("newPassword"),
|
|
21620
|
+
error: errors.newPassword?.message
|
|
21621
|
+
}
|
|
21622
|
+
),
|
|
21623
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
21624
|
+
Input,
|
|
21625
|
+
{
|
|
21626
|
+
type: "password",
|
|
21627
|
+
label: "Confirm new password",
|
|
21628
|
+
placeholder: "Re-type new password",
|
|
21629
|
+
...register("confirmPassword"),
|
|
21630
|
+
error: errors.confirmPassword?.message
|
|
21631
|
+
}
|
|
21632
|
+
),
|
|
21633
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-3", children: [
|
|
21634
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
21635
|
+
Button,
|
|
21636
|
+
{
|
|
21637
|
+
variant: "primary",
|
|
21638
|
+
type: "submit",
|
|
21639
|
+
size: "lg",
|
|
21640
|
+
isLoading: isSubmitting,
|
|
21641
|
+
children: "Save password"
|
|
21642
|
+
}
|
|
21643
|
+
),
|
|
21644
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
21645
|
+
Button,
|
|
21646
|
+
{
|
|
21647
|
+
type: "button",
|
|
21648
|
+
variant: "outline-solid",
|
|
21649
|
+
size: "lg",
|
|
21650
|
+
className: "border-slate-300 text-slate-800 hover:bg-slate-50",
|
|
21651
|
+
onClick: () => router.push(buildPath("/account")),
|
|
21652
|
+
children: "Cancel"
|
|
21653
|
+
}
|
|
21654
|
+
)
|
|
21655
|
+
] })
|
|
21656
|
+
] }),
|
|
21657
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-6 flex items-center gap-2 rounded-2xl border border-slate-200 bg-slate-50 px-4 py-3 text-sm text-slate-600", children: [
|
|
21658
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ShieldCheck, { className: "h-4 w-4 text-primary-600" }),
|
|
21659
|
+
"Strong passwords and up-to-date contact details help pharmacists verify changes quickly."
|
|
21660
|
+
] })
|
|
21661
|
+
]
|
|
21662
|
+
}
|
|
21663
|
+
) }) });
|
|
21664
|
+
}
|
|
21665
|
+
var getNotificationIcon = (type) => {
|
|
21666
|
+
const className = "w-5 h-5";
|
|
21667
|
+
switch (type) {
|
|
21668
|
+
case "ORDER_CONFIRMATION":
|
|
21669
|
+
case "ORDER_SHIPPED":
|
|
21670
|
+
case "ORDER_DELIVERED":
|
|
21671
|
+
return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Package, { className });
|
|
21672
|
+
case "PAYMENT_FAILED":
|
|
21673
|
+
case "REFUND_PROCESSED":
|
|
21674
|
+
return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CreditCard, { className });
|
|
21675
|
+
case "PASSWORD_RESET":
|
|
21676
|
+
case "NEW_DEVICE_LOGIN":
|
|
21677
|
+
case "TWO_FA_CODE":
|
|
21678
|
+
return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Lock, { className });
|
|
21679
|
+
case "ABANDONED_CART_REMINDER":
|
|
21680
|
+
return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ShoppingCart, { className });
|
|
21681
|
+
case "PRICE_DROP_ALERT":
|
|
21682
|
+
return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.TrendingDown, { className });
|
|
21683
|
+
case "BACK_IN_STOCK":
|
|
21684
|
+
default:
|
|
21685
|
+
return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Bell, { className });
|
|
21686
|
+
}
|
|
21687
|
+
};
|
|
21688
|
+
var getNotificationColor = (type) => {
|
|
21689
|
+
switch (type) {
|
|
21690
|
+
case "ORDER_CONFIRMATION":
|
|
21691
|
+
case "ORDER_DELIVERED":
|
|
21692
|
+
case "REFUND_PROCESSED":
|
|
21693
|
+
return "bg-green-100 text-green-600";
|
|
21694
|
+
case "ORDER_SHIPPED":
|
|
21695
|
+
return "bg-blue-100 text-blue-600";
|
|
21696
|
+
case "PAYMENT_FAILED":
|
|
21697
|
+
return "bg-red-100 text-red-600";
|
|
21698
|
+
case "PASSWORD_RESET":
|
|
21699
|
+
case "NEW_DEVICE_LOGIN":
|
|
21700
|
+
case "TWO_FA_CODE":
|
|
21701
|
+
return "bg-purple-100 text-purple-600";
|
|
21702
|
+
case "ABANDONED_CART_REMINDER":
|
|
21703
|
+
case "PRICE_DROP_ALERT":
|
|
21704
|
+
case "BACK_IN_STOCK":
|
|
21705
|
+
return "bg-orange-100 text-orange-600";
|
|
21706
|
+
default:
|
|
21707
|
+
return "bg-gray-100 text-gray-600";
|
|
21708
|
+
}
|
|
21709
|
+
};
|
|
21710
|
+
var formatRelativeTime = (dateString) => {
|
|
21711
|
+
const date = new Date(dateString);
|
|
21712
|
+
const diff = Date.now() - date.getTime();
|
|
21713
|
+
const mins = Math.floor(diff / 6e4);
|
|
21714
|
+
const hours = Math.floor(diff / 36e5);
|
|
21715
|
+
const days = Math.floor(diff / 864e5);
|
|
21716
|
+
if (mins < 1) return "Just now";
|
|
21717
|
+
if (mins < 60) return `${mins} min ago`;
|
|
21718
|
+
if (hours < 24) return `${hours} hour${hours > 1 ? "s" : ""} ago`;
|
|
21719
|
+
if (days < 7) return `${days} day${days > 1 ? "s" : ""} ago`;
|
|
21720
|
+
return date.toLocaleDateString();
|
|
21721
|
+
};
|
|
21722
|
+
function NotificationCard({
|
|
21723
|
+
notification,
|
|
21724
|
+
onMarkAsRead,
|
|
21725
|
+
onDelete
|
|
21726
|
+
}) {
|
|
21727
|
+
const router = navigation.useRouter();
|
|
21728
|
+
const { buildPath } = useBasePath();
|
|
21729
|
+
const hasDragged = React10.useRef(false);
|
|
21730
|
+
const handleClick = () => {
|
|
21731
|
+
if (hasDragged.current) return;
|
|
21732
|
+
if (!notification.isRead) {
|
|
21733
|
+
onMarkAsRead(notification._id);
|
|
21734
|
+
}
|
|
21735
|
+
if (notification.data?.orderId) {
|
|
21736
|
+
router.push(buildPath(`/account/orders/${notification.data.orderId}`));
|
|
21737
|
+
} else if (notification.data?.productId) {
|
|
21738
|
+
router.push(buildPath(`/products/${notification.data.productId}`));
|
|
21739
|
+
}
|
|
21740
|
+
};
|
|
21741
|
+
const handleDelete = (e) => {
|
|
21742
|
+
e.stopPropagation();
|
|
21743
|
+
onDelete(notification._id);
|
|
21744
|
+
};
|
|
21745
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative overflow-hidden rounded-lg", children: [
|
|
21746
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-center justify-end px-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-1 text-white", children: [
|
|
21747
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "w-5 h-5" }),
|
|
21748
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-bold uppercase tracking-wider", children: "Remove" })
|
|
21749
|
+
] }) }),
|
|
21750
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
21751
|
+
framerMotion.motion.div,
|
|
21752
|
+
{
|
|
21753
|
+
drag: "x",
|
|
21754
|
+
initial: { opacity: 0, x: 0 },
|
|
21755
|
+
animate: { opacity: 1, x: 0 },
|
|
21756
|
+
className: `relative z-10 p-4 border cursor-pointer select-none touch-pan-y transition-colors ${notification.isRead ? "bg-white border-gray-200" : "bg-blue-50 border-blue-200"}`,
|
|
21757
|
+
onClick: handleClick,
|
|
21758
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-3", children: [
|
|
21759
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
21760
|
+
"div",
|
|
21761
|
+
{
|
|
21762
|
+
className: `flex-shrink-0 w-10 h-10 rounded-full flex items-center justify-center ${getNotificationColor(
|
|
21763
|
+
notification.type
|
|
21764
|
+
)}`,
|
|
21765
|
+
children: getNotificationIcon(notification.type)
|
|
21766
|
+
}
|
|
21767
|
+
),
|
|
21768
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
21769
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-2", children: [
|
|
21770
|
+
/* @__PURE__ */ jsxRuntime.jsx("h4", { className: "font-semibold text-gray-900 text-sm line-clamp-1", children: notification.title }),
|
|
21771
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
21772
|
+
"button",
|
|
21773
|
+
{
|
|
21774
|
+
onClick: handleDelete,
|
|
21775
|
+
className: "flex-shrink-0 p-1 bg-gray-100 rounded-full hover:bg-red-50",
|
|
21776
|
+
"aria-label": "Delete notification",
|
|
21777
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "w-4 h-4 text-gray-400 hover:text-red-500" })
|
|
21778
|
+
}
|
|
21779
|
+
)
|
|
21780
|
+
] }),
|
|
21781
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-gray-600 mt-1 line-clamp-2", children: notification.body }),
|
|
21782
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mt-2", children: [
|
|
21783
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-gray-500", children: formatRelativeTime(notification.createdAt) }),
|
|
21784
|
+
!notification.isRead && /* @__PURE__ */ jsxRuntime.jsx(
|
|
21785
|
+
"span",
|
|
21786
|
+
{
|
|
21787
|
+
className: "w-2 h-2 bg-blue-500 rounded-full",
|
|
21788
|
+
"aria-label": "Unread"
|
|
21789
|
+
}
|
|
21790
|
+
)
|
|
21791
|
+
] })
|
|
21792
|
+
] })
|
|
21793
|
+
] })
|
|
21794
|
+
}
|
|
21795
|
+
)
|
|
21796
|
+
] });
|
|
21797
|
+
}
|
|
21798
|
+
var modalVariants = {
|
|
21799
|
+
hidden: { opacity: 0, y: -8, scale: 0.96 },
|
|
21800
|
+
visible: { opacity: 1, y: 0, scale: 1 },
|
|
21801
|
+
exit: { opacity: 0, y: -8, scale: 0.96 }
|
|
21802
|
+
};
|
|
21803
|
+
function NotificationModal() {
|
|
21804
|
+
const {
|
|
21805
|
+
isDrawerOpen,
|
|
21806
|
+
closeDrawer,
|
|
21807
|
+
notifications,
|
|
21808
|
+
unreadCount,
|
|
21809
|
+
isLoading,
|
|
21810
|
+
markAsRead,
|
|
21811
|
+
markAllAsRead,
|
|
21812
|
+
deleteNotification,
|
|
21813
|
+
loadMore,
|
|
21814
|
+
hasMore
|
|
21815
|
+
} = useNotificationCenter();
|
|
21816
|
+
const router = navigation.useRouter();
|
|
21817
|
+
const { buildPath } = useBasePath();
|
|
21818
|
+
const scrollRef = React10.useRef(null);
|
|
21819
|
+
const modalRef = React10.useRef(null);
|
|
21820
|
+
const lastScrollTrigger = React10.useRef(0);
|
|
21821
|
+
const handleScroll = React10.useCallback(() => {
|
|
21822
|
+
if (!scrollRef.current || isLoading || !hasMore) return;
|
|
21823
|
+
const now = Date.now();
|
|
21824
|
+
if (now - lastScrollTrigger.current < 300) return;
|
|
21825
|
+
const { scrollTop, scrollHeight, clientHeight } = scrollRef.current;
|
|
21826
|
+
if ((scrollTop + clientHeight) / scrollHeight > 0.8) {
|
|
21827
|
+
lastScrollTrigger.current = now;
|
|
21828
|
+
loadMore();
|
|
21829
|
+
}
|
|
21830
|
+
}, [isLoading, hasMore, loadMore]);
|
|
21831
|
+
const handleSettingsClick = React10.useCallback(() => {
|
|
21832
|
+
closeDrawer();
|
|
21833
|
+
router.push(buildPath("/account/notifications"));
|
|
21834
|
+
}, [closeDrawer, router, buildPath]);
|
|
21835
|
+
React10.useEffect(() => {
|
|
21836
|
+
if (!isDrawerOpen) return;
|
|
21837
|
+
modalRef.current?.focus();
|
|
21838
|
+
const onKeyDown = (e) => {
|
|
21839
|
+
if (e.key === "Escape") closeDrawer();
|
|
21840
|
+
};
|
|
21841
|
+
document.addEventListener("keydown", onKeyDown);
|
|
21842
|
+
return () => document.removeEventListener("keydown", onKeyDown);
|
|
21843
|
+
}, [isDrawerOpen, closeDrawer]);
|
|
21844
|
+
React10.useEffect(() => {
|
|
21845
|
+
if (!isDrawerOpen) return;
|
|
21846
|
+
const handleClickOutside = (e) => {
|
|
21847
|
+
const bellButton = document.getElementById("notification-bell-button");
|
|
21848
|
+
if (modalRef.current && !modalRef.current.contains(e.target) && !bellButton?.contains(e.target)) {
|
|
21849
|
+
closeDrawer();
|
|
21850
|
+
}
|
|
21851
|
+
};
|
|
21852
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
21853
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
21854
|
+
}, [isDrawerOpen, closeDrawer]);
|
|
21855
|
+
const hasNotifications = notifications.length > 0;
|
|
21856
|
+
return /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: isDrawerOpen && /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
21857
|
+
framerMotion.motion.div,
|
|
21858
|
+
{
|
|
21859
|
+
ref: modalRef,
|
|
21860
|
+
role: "dialog",
|
|
21861
|
+
"aria-modal": "true",
|
|
21862
|
+
"aria-labelledby": "notification-title",
|
|
21863
|
+
tabIndex: -1,
|
|
21864
|
+
variants: modalVariants,
|
|
21865
|
+
initial: "hidden",
|
|
21866
|
+
animate: "visible",
|
|
21867
|
+
exit: "exit",
|
|
21868
|
+
transition: { type: "spring", stiffness: 350, damping: 28 },
|
|
21869
|
+
className: "absolute top-full lg:right-0 mt-1 lg:w-screen lg:max-w-sm bg-white rounded-2xl shadow-[0_20px_50px_-12px_rgba(0,0,0,0.15)] z-[100] flex flex-col overflow-hidden border border-gray-100 origin-top-right rounded-lg border border-slate-200 bg-white shadow-lg",
|
|
21870
|
+
style: { maxHeight: "calc(100vh - 120px)" },
|
|
21871
|
+
children: [
|
|
21872
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute -top-1 right-5 w-3 h-3 bg-white border-l border-t border-gray-100 transform rotate-45 z-10" }),
|
|
21873
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-4 py-3 border-b bg-gradient-to-r from-primary-50 to-white", children: [
|
|
21874
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
21875
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
21876
|
+
"h2",
|
|
21877
|
+
{
|
|
21878
|
+
id: "notification-title",
|
|
21879
|
+
className: "text-lg font-bold text-gray-900",
|
|
21880
|
+
children: "Notifications"
|
|
21881
|
+
}
|
|
21882
|
+
),
|
|
21883
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
21884
|
+
"span",
|
|
21885
|
+
{
|
|
21886
|
+
"aria-live": "polite",
|
|
21887
|
+
className: "bg-red-500 text-white text-xs font-bold px-2 py-0.5 rounded-full",
|
|
21888
|
+
children: unreadCount
|
|
21889
|
+
}
|
|
21890
|
+
)
|
|
21891
|
+
] }),
|
|
21892
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
21893
|
+
unreadCount > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
21894
|
+
"button",
|
|
21895
|
+
{
|
|
21896
|
+
onClick: markAllAsRead,
|
|
21897
|
+
title: "Mark all as read",
|
|
21898
|
+
className: "p-2 rounded-lg hover:bg-white transition",
|
|
21899
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckCheck, { className: "w-4 h-4 text-gray-600" })
|
|
21900
|
+
}
|
|
21901
|
+
),
|
|
21902
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
21903
|
+
"button",
|
|
21904
|
+
{
|
|
21905
|
+
onClick: handleSettingsClick,
|
|
21906
|
+
title: "Notification settings",
|
|
21907
|
+
className: "p-2 rounded-lg hover:bg-white transition",
|
|
21908
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Settings, { className: "w-4 h-4 text-gray-600" })
|
|
21909
|
+
}
|
|
21910
|
+
),
|
|
21911
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
21912
|
+
"button",
|
|
21913
|
+
{
|
|
21914
|
+
onClick: closeDrawer,
|
|
21915
|
+
"aria-label": "Close notifications",
|
|
21916
|
+
className: "p-2 rounded-lg hover:bg-red-50 transition",
|
|
21917
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "w-4 h-4 text-gray-600" })
|
|
21918
|
+
}
|
|
21919
|
+
)
|
|
21920
|
+
] })
|
|
21921
|
+
] }),
|
|
21922
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
21864
21923
|
"div",
|
|
21865
21924
|
{
|
|
21866
|
-
|
|
21867
|
-
|
|
21868
|
-
|
|
21869
|
-
|
|
21870
|
-
|
|
21925
|
+
ref: scrollRef,
|
|
21926
|
+
onScroll: handleScroll,
|
|
21927
|
+
className: "flex-1 overflow-y-auto p-3 space-y-2 bg-gray-50 scrollbar-thin scrollbar-thumb-gray-300",
|
|
21928
|
+
children: !hasNotifications && !isLoading ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center py-14 text-center", children: [
|
|
21929
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.BellOff, { className: "w-10 h-10 text-gray-400 mb-3" }),
|
|
21930
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-gray-700", children: "No notifications yet" }),
|
|
21931
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-gray-500 mt-1", children: "You\u2019re all caught up \u{1F389}" })
|
|
21932
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
21933
|
+
notifications.map((notification) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
21934
|
+
NotificationCard,
|
|
21935
|
+
{
|
|
21936
|
+
notification,
|
|
21937
|
+
onMarkAsRead: markAsRead,
|
|
21938
|
+
onDelete: deleteNotification
|
|
21939
|
+
},
|
|
21940
|
+
notification._id
|
|
21941
|
+
)),
|
|
21942
|
+
isLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2 py-2", children: [...Array(3)].map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
21943
|
+
"div",
|
|
21944
|
+
{
|
|
21945
|
+
className: "h-16 rounded-xl bg-gray-200 animate-pulse"
|
|
21946
|
+
},
|
|
21947
|
+
i
|
|
21948
|
+
)) }),
|
|
21949
|
+
!hasMore && hasNotifications && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-center py-3 text-xs text-gray-500", children: "You\u2019re all caught up \u{1F389}" })
|
|
21950
|
+
] })
|
|
21871
21951
|
}
|
|
21872
|
-
)
|
|
21873
|
-
|
|
21874
|
-
|
|
21875
|
-
|
|
21876
|
-
|
|
21877
|
-
|
|
21878
|
-
|
|
21879
|
-
|
|
21880
|
-
|
|
21881
|
-
|
|
21882
|
-
|
|
21883
|
-
|
|
21884
|
-
|
|
21885
|
-
|
|
21886
|
-
|
|
21887
|
-
|
|
21888
|
-
|
|
21889
|
-
|
|
21890
|
-
|
|
21891
|
-
|
|
21892
|
-
|
|
21893
|
-
|
|
21952
|
+
)
|
|
21953
|
+
]
|
|
21954
|
+
}
|
|
21955
|
+
) }) });
|
|
21956
|
+
}
|
|
21957
|
+
function NotificationBell() {
|
|
21958
|
+
const { unreadCount, isDrawerOpen, openDrawer, closeDrawer } = useNotificationCenter();
|
|
21959
|
+
const handleToggle = (e) => {
|
|
21960
|
+
e.stopPropagation();
|
|
21961
|
+
if (isDrawerOpen) {
|
|
21962
|
+
closeDrawer();
|
|
21963
|
+
} else {
|
|
21964
|
+
openDrawer();
|
|
21965
|
+
}
|
|
21966
|
+
};
|
|
21967
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
21968
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
21969
|
+
framerMotion.motion.button,
|
|
21970
|
+
{
|
|
21971
|
+
id: "notification-bell-button",
|
|
21972
|
+
onClick: handleToggle,
|
|
21973
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
21974
|
+
className: `relative p-2.5 rounded-xl transition-all duration-300 group flex items-center justify-center ${isDrawerOpen ? "bg-primary-50 text-primary-600" : "hover:bg-gradient-to-br hover:from-primary-50 hover:to-primary-100/50 text-gray-700"}`,
|
|
21975
|
+
"aria-label": "Notifications",
|
|
21976
|
+
whileHover: isDrawerOpen ? {} : { scale: 1.05 },
|
|
21977
|
+
whileTap: { scale: 0.95 },
|
|
21978
|
+
children: [
|
|
21894
21979
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
21895
|
-
|
|
21980
|
+
lucideReact.Bell,
|
|
21896
21981
|
{
|
|
21897
|
-
|
|
21898
|
-
|
|
21899
|
-
placeholder: "Re-type new password",
|
|
21900
|
-
...register("confirmPassword"),
|
|
21901
|
-
error: errors.confirmPassword?.message
|
|
21982
|
+
className: `w-6 h-6 transition-colors duration-300 ${isDrawerOpen ? "text-primary-600 bg-gray-100 rounded-lg p-2 w-10 h-10 transition-all duration-300" : "group-hover:text-primary-600"}`,
|
|
21983
|
+
strokeWidth: 2
|
|
21902
21984
|
}
|
|
21903
21985
|
),
|
|
21904
|
-
/* @__PURE__ */ jsxRuntime.
|
|
21986
|
+
/* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: unreadCount > 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
21905
21987
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
21906
|
-
|
|
21988
|
+
framerMotion.motion.span,
|
|
21907
21989
|
{
|
|
21908
|
-
|
|
21909
|
-
|
|
21910
|
-
|
|
21911
|
-
|
|
21912
|
-
|
|
21990
|
+
initial: { scale: 0.8, opacity: 0 },
|
|
21991
|
+
animate: {
|
|
21992
|
+
scale: [1, 1.4, 1.4],
|
|
21993
|
+
opacity: [0.6, 0, 0]
|
|
21994
|
+
},
|
|
21995
|
+
exit: { scale: 0, opacity: 0 },
|
|
21996
|
+
transition: {
|
|
21997
|
+
duration: 2,
|
|
21998
|
+
repeat: Infinity,
|
|
21999
|
+
repeatDelay: 0.5
|
|
22000
|
+
},
|
|
22001
|
+
className: "absolute -top-0.5 -right-0.5 w-6 h-6 bg-red-500 rounded-full"
|
|
21913
22002
|
}
|
|
21914
22003
|
),
|
|
21915
22004
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
21916
|
-
|
|
22005
|
+
framerMotion.motion.span,
|
|
21917
22006
|
{
|
|
21918
|
-
|
|
21919
|
-
|
|
21920
|
-
|
|
21921
|
-
|
|
21922
|
-
|
|
21923
|
-
|
|
22007
|
+
initial: { scale: 0, rotate: -180 },
|
|
22008
|
+
animate: { scale: 1, rotate: 0 },
|
|
22009
|
+
exit: { scale: 0, rotate: 180 },
|
|
22010
|
+
transition: {
|
|
22011
|
+
type: "spring",
|
|
22012
|
+
damping: 15,
|
|
22013
|
+
stiffness: 300
|
|
22014
|
+
},
|
|
22015
|
+
className: "absolute -top-1 -right-1 min-w-[20px] h-5 bg-gradient-to-br from-red-500 to-red-600 text-white text-[10px] font-bold rounded-full flex items-center justify-center px-1.5 shadow-lg shadow-red-500/40 border-2 border-white",
|
|
22016
|
+
children: unreadCount > 99 ? "99+" : unreadCount
|
|
21924
22017
|
}
|
|
21925
22018
|
)
|
|
21926
|
-
] })
|
|
21927
|
-
]
|
|
21928
|
-
|
|
21929
|
-
|
|
21930
|
-
|
|
21931
|
-
|
|
21932
|
-
]
|
|
21933
|
-
}
|
|
21934
|
-
) }) });
|
|
21935
|
-
}
|
|
21936
|
-
function NotificationBell() {
|
|
21937
|
-
const { unreadCount, openDrawer } = useNotificationCenter();
|
|
21938
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
21939
|
-
"button",
|
|
21940
|
-
{
|
|
21941
|
-
onClick: openDrawer,
|
|
21942
|
-
className: "relative p-2 hover:bg-gray-100 rounded-lg transition-colors",
|
|
21943
|
-
"aria-label": "Notifications",
|
|
21944
|
-
children: [
|
|
21945
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Bell, { className: "w-6 h-6 text-gray-700" }),
|
|
21946
|
-
/* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: unreadCount > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
21947
|
-
framerMotion.motion.span,
|
|
21948
|
-
{
|
|
21949
|
-
initial: { scale: 0 },
|
|
21950
|
-
animate: { scale: 1 },
|
|
21951
|
-
exit: { scale: 0 },
|
|
21952
|
-
className: "absolute -top-1 -right-1 bg-red-500 text-white text-xs font-bold rounded-full w-5 h-5 flex items-center justify-center",
|
|
21953
|
-
children: unreadCount > 99 ? "99+" : unreadCount
|
|
21954
|
-
}
|
|
21955
|
-
) })
|
|
21956
|
-
]
|
|
21957
|
-
}
|
|
21958
|
-
);
|
|
22019
|
+
] }) })
|
|
22020
|
+
]
|
|
22021
|
+
}
|
|
22022
|
+
),
|
|
22023
|
+
/* @__PURE__ */ jsxRuntime.jsx(NotificationModal, {})
|
|
22024
|
+
] });
|
|
21959
22025
|
}
|
|
21960
22026
|
function Header() {
|
|
21961
22027
|
const { config } = useTheme();
|
|
@@ -21963,11 +22029,11 @@ function Header() {
|
|
|
21963
22029
|
const { cart } = useCart() || { cart: { } };
|
|
21964
22030
|
const { getWishlistCount } = useWishlist();
|
|
21965
22031
|
const wishlistCount = getWishlistCount?.() || 0;
|
|
21966
|
-
const [isMobileMenuOpen, setIsMobileMenuOpen] =
|
|
21967
|
-
const [isSearchOpen, setIsSearchOpen] =
|
|
21968
|
-
const [isDropdownOpen, setIsDropdownOpen] =
|
|
21969
|
-
const [isLoggingOut, setIsLoggingOut] =
|
|
21970
|
-
const [searchQuery, setSearchQuery] =
|
|
22032
|
+
const [isMobileMenuOpen, setIsMobileMenuOpen] = React10.useState(false);
|
|
22033
|
+
const [isSearchOpen, setIsSearchOpen] = React10.useState(false);
|
|
22034
|
+
const [isDropdownOpen, setIsDropdownOpen] = React10.useState(false);
|
|
22035
|
+
const [isLoggingOut, setIsLoggingOut] = React10.useState(false);
|
|
22036
|
+
const [searchQuery, setSearchQuery] = React10.useState("");
|
|
21971
22037
|
const { buildPath } = useBasePath();
|
|
21972
22038
|
const router = navigation.useRouter();
|
|
21973
22039
|
const handleLogout = async () => {
|
|
@@ -22300,6 +22366,141 @@ function Footer() {
|
|
|
22300
22366
|
] })
|
|
22301
22367
|
] }) });
|
|
22302
22368
|
}
|
|
22369
|
+
function NotificationDrawer() {
|
|
22370
|
+
const {
|
|
22371
|
+
isDrawerOpen,
|
|
22372
|
+
closeDrawer,
|
|
22373
|
+
notifications,
|
|
22374
|
+
unreadCount,
|
|
22375
|
+
isLoading,
|
|
22376
|
+
markAsRead,
|
|
22377
|
+
markAllAsRead,
|
|
22378
|
+
deleteNotification,
|
|
22379
|
+
loadMore,
|
|
22380
|
+
hasMore
|
|
22381
|
+
} = useNotificationCenter();
|
|
22382
|
+
const router = navigation.useRouter();
|
|
22383
|
+
const { buildPath } = useBasePath();
|
|
22384
|
+
const scrollContainerRef = React10.useRef(null);
|
|
22385
|
+
const handleScroll = () => {
|
|
22386
|
+
if (!scrollContainerRef.current || isLoading || !hasMore) return;
|
|
22387
|
+
const { scrollTop, scrollHeight, clientHeight } = scrollContainerRef.current;
|
|
22388
|
+
const scrollPercentage = (scrollTop + clientHeight) / scrollHeight;
|
|
22389
|
+
if (scrollPercentage > 0.8) {
|
|
22390
|
+
loadMore();
|
|
22391
|
+
}
|
|
22392
|
+
};
|
|
22393
|
+
React10.useEffect(() => {
|
|
22394
|
+
const handleEscape = (e) => {
|
|
22395
|
+
if (e.key === "Escape" && isDrawerOpen) {
|
|
22396
|
+
closeDrawer();
|
|
22397
|
+
}
|
|
22398
|
+
};
|
|
22399
|
+
document.addEventListener("keydown", handleEscape);
|
|
22400
|
+
return () => document.removeEventListener("keydown", handleEscape);
|
|
22401
|
+
}, [isDrawerOpen, closeDrawer]);
|
|
22402
|
+
React10.useEffect(() => {
|
|
22403
|
+
if (isDrawerOpen) {
|
|
22404
|
+
document.body.style.overflow = "hidden";
|
|
22405
|
+
} else {
|
|
22406
|
+
document.body.style.overflow = "";
|
|
22407
|
+
}
|
|
22408
|
+
return () => {
|
|
22409
|
+
document.body.style.overflow = "";
|
|
22410
|
+
};
|
|
22411
|
+
}, [isDrawerOpen]);
|
|
22412
|
+
const handleSettingsClick = () => {
|
|
22413
|
+
closeDrawer();
|
|
22414
|
+
router.push(buildPath("/account/notifications"));
|
|
22415
|
+
};
|
|
22416
|
+
return /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: isDrawerOpen && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
22417
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
22418
|
+
framerMotion.motion.div,
|
|
22419
|
+
{
|
|
22420
|
+
initial: { opacity: 0 },
|
|
22421
|
+
animate: { opacity: 1 },
|
|
22422
|
+
exit: { opacity: 0 },
|
|
22423
|
+
className: "fixed inset-0 bg-black/50 z-40",
|
|
22424
|
+
onClick: closeDrawer
|
|
22425
|
+
}
|
|
22426
|
+
),
|
|
22427
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
22428
|
+
framerMotion.motion.div,
|
|
22429
|
+
{
|
|
22430
|
+
initial: { x: "100%" },
|
|
22431
|
+
animate: { x: 0 },
|
|
22432
|
+
exit: { x: "100%" },
|
|
22433
|
+
transition: { type: "spring", damping: 25, stiffness: 200 },
|
|
22434
|
+
className: "fixed right-0 top-0 bottom-0 w-full sm:w-[480px] bg-white shadow-2xl z-50 flex flex-col max-w-[480px]",
|
|
22435
|
+
children: [
|
|
22436
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between p-4 border-b border-gray-200 bg-white", children: [
|
|
22437
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
22438
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-xl font-bold text-gray-900", children: "Notifications" }),
|
|
22439
|
+
unreadCount > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "bg-red-500 text-white text-xs font-bold px-2 py-1 rounded-full", children: unreadCount })
|
|
22440
|
+
] }),
|
|
22441
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
22442
|
+
unreadCount > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
22443
|
+
"button",
|
|
22444
|
+
{
|
|
22445
|
+
onClick: markAllAsRead,
|
|
22446
|
+
className: "p-2 hover:bg-gray-100 rounded-lg transition-colors",
|
|
22447
|
+
title: "Mark all as read",
|
|
22448
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckCheck, { className: "w-5 h-5 text-gray-600" })
|
|
22449
|
+
}
|
|
22450
|
+
),
|
|
22451
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
22452
|
+
"button",
|
|
22453
|
+
{
|
|
22454
|
+
onClick: handleSettingsClick,
|
|
22455
|
+
className: "p-2 hover:bg-gray-100 rounded-lg transition-colors",
|
|
22456
|
+
title: "Notification settings",
|
|
22457
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Settings, { className: "w-5 h-5 text-gray-600" })
|
|
22458
|
+
}
|
|
22459
|
+
),
|
|
22460
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
22461
|
+
"button",
|
|
22462
|
+
{
|
|
22463
|
+
onClick: closeDrawer,
|
|
22464
|
+
className: "p-2 hover:bg-gray-100 rounded-lg transition-colors",
|
|
22465
|
+
"aria-label": "Close",
|
|
22466
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "w-5 h-5 text-gray-600" })
|
|
22467
|
+
}
|
|
22468
|
+
)
|
|
22469
|
+
] })
|
|
22470
|
+
] }),
|
|
22471
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
22472
|
+
"div",
|
|
22473
|
+
{
|
|
22474
|
+
ref: scrollContainerRef,
|
|
22475
|
+
onScroll: handleScroll,
|
|
22476
|
+
className: "flex-1 overflow-y-auto p-4 space-y-3",
|
|
22477
|
+
children: notifications.length === 0 && !isLoading ? (
|
|
22478
|
+
// Empty state
|
|
22479
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center h-full text-center py-12", children: [
|
|
22480
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-20 h-20 bg-gray-100 rounded-full flex items-center justify-center mb-4", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.BellOff, { className: "w-10 h-10 text-gray-400" }) }),
|
|
22481
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold text-gray-900 mb-2", children: "No notifications yet" }),
|
|
22482
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-gray-500 max-w-xs", children: "When you receive notifications, they'll appear here" })
|
|
22483
|
+
] })
|
|
22484
|
+
) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
22485
|
+
notifications.map((notification) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
22486
|
+
NotificationCard,
|
|
22487
|
+
{
|
|
22488
|
+
notification,
|
|
22489
|
+
onMarkAsRead: markAsRead,
|
|
22490
|
+
onDelete: deleteNotification
|
|
22491
|
+
},
|
|
22492
|
+
notification._id
|
|
22493
|
+
)),
|
|
22494
|
+
isLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-4", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-6 h-6 border-2 border-primary-600 border-t-transparent rounded-full animate-spin" }) }),
|
|
22495
|
+
!hasMore && notifications.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-center py-4 text-sm text-gray-500", children: "You're all caught up! \u{1F389}" })
|
|
22496
|
+
] })
|
|
22497
|
+
}
|
|
22498
|
+
)
|
|
22499
|
+
]
|
|
22500
|
+
}
|
|
22501
|
+
)
|
|
22502
|
+
] }) });
|
|
22503
|
+
}
|
|
22303
22504
|
|
|
22304
22505
|
exports.AccountReviewsTab = AccountReviewsTab;
|
|
22305
22506
|
exports.AddressAddressTypeEnum = AddressAddressTypeEnum;
|