hey-pharmacist-ecommerce 1.1.35 → 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 +934 -730
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +587 -383
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/AccountOrdersTab.tsx +3 -1
- package/src/components/CartItem.tsx +6 -2
- package/src/components/NotificationBell.tsx +74 -21
- package/src/components/NotificationModal.tsx +223 -0
- package/src/components/OrderCard.tsx +3 -1
- package/src/components/ProductCard.tsx +6 -1
- package/src/components/QuickViewModal.tsx +1 -1
- package/src/lib/constants/assets.ts +1 -0
- package/src/providers/EcommerceProvider.tsx +0 -2
- package/src/screens/CheckoutScreen.tsx +6 -4
- package/src/screens/OrderDetailScreen.tsx +7 -3
- package/src/screens/ProductDetailScreen.tsx +8 -6
- package/src/screens/ShopScreen.tsx +6 -4
- package/src/screens/WishlistScreen.tsx +4 -2
package/dist/index.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import
|
|
2
|
+
import React10, { createContext, forwardRef, useContext, useEffect, useState, useCallback, useRef, useMemo } from 'react';
|
|
3
3
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
4
4
|
import globalAxios21 from 'axios';
|
|
5
5
|
import { motion, AnimatePresence, useMotionValue, useTransform } from 'framer-motion';
|
|
6
|
-
import {
|
|
6
|
+
import { Eye, Star, ShoppingCart, Sparkles, ShieldCheck, TrendingUp, Search, Package, ArrowUpDown, ChevronDown, LayoutGrid, LayoutList, X, Clock, User, MessageCircle, Filter, ChevronLeft, Check, Heart, Truck, RotateCcw, Shield, Trash2, Minus, Plus, ShoppingBag, ArrowRight, CheckCircle2, MapPin, CreditCard, Edit3, AlertCircle, Lock, EyeOff, UserPlus, Mail, Send, ArrowLeft, MessageSquare, Settings, ChevronRight, ArrowUpRight, PackageCheck, Warehouse, BellRing, Crown, Phone, Grid, List, Loader2, Calendar, ExternalLink, Info, Bell, LogOut, Menu, Facebook, Twitter, Instagram, CheckCheck, BellOff, Shirt, Pill, Box, Gift, Tag, Globe, Home, TrendingDown, CheckCircle, Edit, AlertTriangle, XCircle } from 'lucide-react';
|
|
7
7
|
import { QueryClient, QueryClientProvider, useQuery } from '@tanstack/react-query';
|
|
8
8
|
import { useRouter, useSearchParams, useParams } from 'next/navigation';
|
|
9
9
|
import Image4 from 'next/image';
|
|
@@ -12681,286 +12681,18 @@ function NotificationCenterProvider({ children }) {
|
|
|
12681
12681
|
};
|
|
12682
12682
|
return /* @__PURE__ */ jsx(NotificationCenterContext.Provider, { value, children });
|
|
12683
12683
|
}
|
|
12684
|
-
var getNotificationIcon = (type) => {
|
|
12685
|
-
const className = "w-5 h-5";
|
|
12686
|
-
switch (type) {
|
|
12687
|
-
case "ORDER_CONFIRMATION":
|
|
12688
|
-
case "ORDER_SHIPPED":
|
|
12689
|
-
case "ORDER_DELIVERED":
|
|
12690
|
-
return /* @__PURE__ */ jsx(Package, { className });
|
|
12691
|
-
case "PAYMENT_FAILED":
|
|
12692
|
-
case "REFUND_PROCESSED":
|
|
12693
|
-
return /* @__PURE__ */ jsx(CreditCard, { className });
|
|
12694
|
-
case "PASSWORD_RESET":
|
|
12695
|
-
case "NEW_DEVICE_LOGIN":
|
|
12696
|
-
case "TWO_FA_CODE":
|
|
12697
|
-
return /* @__PURE__ */ jsx(Lock, { className });
|
|
12698
|
-
case "ABANDONED_CART_REMINDER":
|
|
12699
|
-
return /* @__PURE__ */ jsx(ShoppingCart, { className });
|
|
12700
|
-
case "PRICE_DROP_ALERT":
|
|
12701
|
-
return /* @__PURE__ */ jsx(TrendingDown, { className });
|
|
12702
|
-
case "BACK_IN_STOCK":
|
|
12703
|
-
default:
|
|
12704
|
-
return /* @__PURE__ */ jsx(Bell, { className });
|
|
12705
|
-
}
|
|
12706
|
-
};
|
|
12707
|
-
var getNotificationColor = (type) => {
|
|
12708
|
-
switch (type) {
|
|
12709
|
-
case "ORDER_CONFIRMATION":
|
|
12710
|
-
case "ORDER_DELIVERED":
|
|
12711
|
-
case "REFUND_PROCESSED":
|
|
12712
|
-
return "bg-green-100 text-green-600";
|
|
12713
|
-
case "ORDER_SHIPPED":
|
|
12714
|
-
return "bg-blue-100 text-blue-600";
|
|
12715
|
-
case "PAYMENT_FAILED":
|
|
12716
|
-
return "bg-red-100 text-red-600";
|
|
12717
|
-
case "PASSWORD_RESET":
|
|
12718
|
-
case "NEW_DEVICE_LOGIN":
|
|
12719
|
-
case "TWO_FA_CODE":
|
|
12720
|
-
return "bg-purple-100 text-purple-600";
|
|
12721
|
-
case "ABANDONED_CART_REMINDER":
|
|
12722
|
-
case "PRICE_DROP_ALERT":
|
|
12723
|
-
case "BACK_IN_STOCK":
|
|
12724
|
-
return "bg-orange-100 text-orange-600";
|
|
12725
|
-
default:
|
|
12726
|
-
return "bg-gray-100 text-gray-600";
|
|
12727
|
-
}
|
|
12728
|
-
};
|
|
12729
|
-
var formatRelativeTime = (dateString) => {
|
|
12730
|
-
const date = new Date(dateString);
|
|
12731
|
-
const diff = Date.now() - date.getTime();
|
|
12732
|
-
const mins = Math.floor(diff / 6e4);
|
|
12733
|
-
const hours = Math.floor(diff / 36e5);
|
|
12734
|
-
const days = Math.floor(diff / 864e5);
|
|
12735
|
-
if (mins < 1) return "Just now";
|
|
12736
|
-
if (mins < 60) return `${mins} min ago`;
|
|
12737
|
-
if (hours < 24) return `${hours} hour${hours > 1 ? "s" : ""} ago`;
|
|
12738
|
-
if (days < 7) return `${days} day${days > 1 ? "s" : ""} ago`;
|
|
12739
|
-
return date.toLocaleDateString();
|
|
12740
|
-
};
|
|
12741
|
-
function NotificationCard({
|
|
12742
|
-
notification,
|
|
12743
|
-
onMarkAsRead,
|
|
12744
|
-
onDelete
|
|
12745
|
-
}) {
|
|
12746
|
-
const router = useRouter();
|
|
12747
|
-
const { buildPath } = useBasePath();
|
|
12748
|
-
const hasDragged = useRef(false);
|
|
12749
|
-
const handleClick = () => {
|
|
12750
|
-
if (hasDragged.current) return;
|
|
12751
|
-
if (!notification.isRead) {
|
|
12752
|
-
onMarkAsRead(notification._id);
|
|
12753
|
-
}
|
|
12754
|
-
if (notification.data?.orderId) {
|
|
12755
|
-
router.push(buildPath(`/account/orders/${notification.data.orderId}`));
|
|
12756
|
-
} else if (notification.data?.productId) {
|
|
12757
|
-
router.push(buildPath(`/products/${notification.data.productId}`));
|
|
12758
|
-
}
|
|
12759
|
-
};
|
|
12760
|
-
const handleDelete = (e) => {
|
|
12761
|
-
e.stopPropagation();
|
|
12762
|
-
onDelete(notification._id);
|
|
12763
|
-
};
|
|
12764
|
-
return /* @__PURE__ */ jsxs("div", { className: "relative overflow-hidden rounded-lg", children: [
|
|
12765
|
-
/* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center justify-end px-6", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-1 text-white", children: [
|
|
12766
|
-
/* @__PURE__ */ jsx(Trash2, { className: "w-5 h-5" }),
|
|
12767
|
-
/* @__PURE__ */ jsx("span", { className: "text-[10px] font-bold uppercase tracking-wider", children: "Remove" })
|
|
12768
|
-
] }) }),
|
|
12769
|
-
/* @__PURE__ */ jsx(
|
|
12770
|
-
motion.div,
|
|
12771
|
-
{
|
|
12772
|
-
drag: "x",
|
|
12773
|
-
initial: { opacity: 0, x: 0 },
|
|
12774
|
-
animate: { opacity: 1, x: 0 },
|
|
12775
|
-
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"}`,
|
|
12776
|
-
onClick: handleClick,
|
|
12777
|
-
children: /* @__PURE__ */ jsxs("div", { className: "flex gap-3", children: [
|
|
12778
|
-
/* @__PURE__ */ jsx(
|
|
12779
|
-
"div",
|
|
12780
|
-
{
|
|
12781
|
-
className: `flex-shrink-0 w-10 h-10 rounded-full flex items-center justify-center ${getNotificationColor(
|
|
12782
|
-
notification.type
|
|
12783
|
-
)}`,
|
|
12784
|
-
children: getNotificationIcon(notification.type)
|
|
12785
|
-
}
|
|
12786
|
-
),
|
|
12787
|
-
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
12788
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-2", children: [
|
|
12789
|
-
/* @__PURE__ */ jsx("h4", { className: "font-semibold text-gray-900 text-sm line-clamp-1", children: notification.title }),
|
|
12790
|
-
/* @__PURE__ */ jsx(
|
|
12791
|
-
"button",
|
|
12792
|
-
{
|
|
12793
|
-
onClick: handleDelete,
|
|
12794
|
-
className: "flex-shrink-0 p-1 bg-gray-100 rounded-full hover:bg-red-50",
|
|
12795
|
-
"aria-label": "Delete notification",
|
|
12796
|
-
children: /* @__PURE__ */ jsx(X, { className: "w-4 h-4 text-gray-400 hover:text-red-500" })
|
|
12797
|
-
}
|
|
12798
|
-
)
|
|
12799
|
-
] }),
|
|
12800
|
-
/* @__PURE__ */ jsx("p", { className: "text-sm text-gray-600 mt-1 line-clamp-2", children: notification.body }),
|
|
12801
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mt-2", children: [
|
|
12802
|
-
/* @__PURE__ */ jsx("span", { className: "text-xs text-gray-500", children: formatRelativeTime(notification.createdAt) }),
|
|
12803
|
-
!notification.isRead && /* @__PURE__ */ jsx(
|
|
12804
|
-
"span",
|
|
12805
|
-
{
|
|
12806
|
-
className: "w-2 h-2 bg-blue-500 rounded-full",
|
|
12807
|
-
"aria-label": "Unread"
|
|
12808
|
-
}
|
|
12809
|
-
)
|
|
12810
|
-
] })
|
|
12811
|
-
] })
|
|
12812
|
-
] })
|
|
12813
|
-
}
|
|
12814
|
-
)
|
|
12815
|
-
] });
|
|
12816
|
-
}
|
|
12817
|
-
function NotificationDrawer() {
|
|
12818
|
-
const {
|
|
12819
|
-
isDrawerOpen,
|
|
12820
|
-
closeDrawer,
|
|
12821
|
-
notifications,
|
|
12822
|
-
unreadCount,
|
|
12823
|
-
isLoading,
|
|
12824
|
-
markAsRead,
|
|
12825
|
-
markAllAsRead,
|
|
12826
|
-
deleteNotification,
|
|
12827
|
-
loadMore,
|
|
12828
|
-
hasMore
|
|
12829
|
-
} = useNotificationCenter();
|
|
12830
|
-
const router = useRouter();
|
|
12831
|
-
const { buildPath } = useBasePath();
|
|
12832
|
-
const scrollContainerRef = useRef(null);
|
|
12833
|
-
const handleScroll = () => {
|
|
12834
|
-
if (!scrollContainerRef.current || isLoading || !hasMore) return;
|
|
12835
|
-
const { scrollTop, scrollHeight, clientHeight } = scrollContainerRef.current;
|
|
12836
|
-
const scrollPercentage = (scrollTop + clientHeight) / scrollHeight;
|
|
12837
|
-
if (scrollPercentage > 0.8) {
|
|
12838
|
-
loadMore();
|
|
12839
|
-
}
|
|
12840
|
-
};
|
|
12841
|
-
useEffect(() => {
|
|
12842
|
-
const handleEscape = (e) => {
|
|
12843
|
-
if (e.key === "Escape" && isDrawerOpen) {
|
|
12844
|
-
closeDrawer();
|
|
12845
|
-
}
|
|
12846
|
-
};
|
|
12847
|
-
document.addEventListener("keydown", handleEscape);
|
|
12848
|
-
return () => document.removeEventListener("keydown", handleEscape);
|
|
12849
|
-
}, [isDrawerOpen, closeDrawer]);
|
|
12850
|
-
useEffect(() => {
|
|
12851
|
-
if (isDrawerOpen) {
|
|
12852
|
-
document.body.style.overflow = "hidden";
|
|
12853
|
-
} else {
|
|
12854
|
-
document.body.style.overflow = "";
|
|
12855
|
-
}
|
|
12856
|
-
return () => {
|
|
12857
|
-
document.body.style.overflow = "";
|
|
12858
|
-
};
|
|
12859
|
-
}, [isDrawerOpen]);
|
|
12860
|
-
const handleSettingsClick = () => {
|
|
12861
|
-
closeDrawer();
|
|
12862
|
-
router.push(buildPath("/account/notifications"));
|
|
12863
|
-
};
|
|
12864
|
-
return /* @__PURE__ */ jsx(AnimatePresence, { children: isDrawerOpen && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
12865
|
-
/* @__PURE__ */ jsx(
|
|
12866
|
-
motion.div,
|
|
12867
|
-
{
|
|
12868
|
-
initial: { opacity: 0 },
|
|
12869
|
-
animate: { opacity: 1 },
|
|
12870
|
-
exit: { opacity: 0 },
|
|
12871
|
-
className: "fixed inset-0 bg-black/50 z-40",
|
|
12872
|
-
onClick: closeDrawer
|
|
12873
|
-
}
|
|
12874
|
-
),
|
|
12875
|
-
/* @__PURE__ */ jsxs(
|
|
12876
|
-
motion.div,
|
|
12877
|
-
{
|
|
12878
|
-
initial: { x: "100%" },
|
|
12879
|
-
animate: { x: 0 },
|
|
12880
|
-
exit: { x: "100%" },
|
|
12881
|
-
transition: { type: "spring", damping: 25, stiffness: 200 },
|
|
12882
|
-
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]",
|
|
12883
|
-
children: [
|
|
12884
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between p-4 border-b border-gray-200 bg-white", children: [
|
|
12885
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
12886
|
-
/* @__PURE__ */ jsx("h2", { className: "text-xl font-bold text-gray-900", children: "Notifications" }),
|
|
12887
|
-
unreadCount > 0 && /* @__PURE__ */ jsx("span", { className: "bg-red-500 text-white text-xs font-bold px-2 py-1 rounded-full", children: unreadCount })
|
|
12888
|
-
] }),
|
|
12889
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
12890
|
-
unreadCount > 0 && /* @__PURE__ */ jsx(
|
|
12891
|
-
"button",
|
|
12892
|
-
{
|
|
12893
|
-
onClick: markAllAsRead,
|
|
12894
|
-
className: "p-2 hover:bg-gray-100 rounded-lg transition-colors",
|
|
12895
|
-
title: "Mark all as read",
|
|
12896
|
-
children: /* @__PURE__ */ jsx(CheckCheck, { className: "w-5 h-5 text-gray-600" })
|
|
12897
|
-
}
|
|
12898
|
-
),
|
|
12899
|
-
/* @__PURE__ */ jsx(
|
|
12900
|
-
"button",
|
|
12901
|
-
{
|
|
12902
|
-
onClick: handleSettingsClick,
|
|
12903
|
-
className: "p-2 hover:bg-gray-100 rounded-lg transition-colors",
|
|
12904
|
-
title: "Notification settings",
|
|
12905
|
-
children: /* @__PURE__ */ jsx(Settings, { className: "w-5 h-5 text-gray-600" })
|
|
12906
|
-
}
|
|
12907
|
-
),
|
|
12908
|
-
/* @__PURE__ */ jsx(
|
|
12909
|
-
"button",
|
|
12910
|
-
{
|
|
12911
|
-
onClick: closeDrawer,
|
|
12912
|
-
className: "p-2 hover:bg-gray-100 rounded-lg transition-colors",
|
|
12913
|
-
"aria-label": "Close",
|
|
12914
|
-
children: /* @__PURE__ */ jsx(X, { className: "w-5 h-5 text-gray-600" })
|
|
12915
|
-
}
|
|
12916
|
-
)
|
|
12917
|
-
] })
|
|
12918
|
-
] }),
|
|
12919
|
-
/* @__PURE__ */ jsx(
|
|
12920
|
-
"div",
|
|
12921
|
-
{
|
|
12922
|
-
ref: scrollContainerRef,
|
|
12923
|
-
onScroll: handleScroll,
|
|
12924
|
-
className: "flex-1 overflow-y-auto p-4 space-y-3",
|
|
12925
|
-
children: notifications.length === 0 && !isLoading ? (
|
|
12926
|
-
// Empty state
|
|
12927
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center justify-center h-full text-center py-12", children: [
|
|
12928
|
-
/* @__PURE__ */ jsx("div", { className: "w-20 h-20 bg-gray-100 rounded-full flex items-center justify-center mb-4", children: /* @__PURE__ */ jsx(BellOff, { className: "w-10 h-10 text-gray-400" }) }),
|
|
12929
|
-
/* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold text-gray-900 mb-2", children: "No notifications yet" }),
|
|
12930
|
-
/* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500 max-w-xs", children: "When you receive notifications, they'll appear here" })
|
|
12931
|
-
] })
|
|
12932
|
-
) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
12933
|
-
notifications.map((notification) => /* @__PURE__ */ jsx(
|
|
12934
|
-
NotificationCard,
|
|
12935
|
-
{
|
|
12936
|
-
notification,
|
|
12937
|
-
onMarkAsRead: markAsRead,
|
|
12938
|
-
onDelete: deleteNotification
|
|
12939
|
-
},
|
|
12940
|
-
notification._id
|
|
12941
|
-
)),
|
|
12942
|
-
isLoading && /* @__PURE__ */ jsx("div", { className: "flex justify-center py-4", children: /* @__PURE__ */ jsx("div", { className: "w-6 h-6 border-2 border-primary-600 border-t-transparent rounded-full animate-spin" }) }),
|
|
12943
|
-
!hasMore && notifications.length > 0 && /* @__PURE__ */ jsx("div", { className: "text-center py-4 text-sm text-gray-500", children: "You're all caught up! \u{1F389}" })
|
|
12944
|
-
] })
|
|
12945
|
-
}
|
|
12946
|
-
)
|
|
12947
|
-
]
|
|
12948
|
-
}
|
|
12949
|
-
)
|
|
12950
|
-
] }) });
|
|
12951
|
-
}
|
|
12952
12684
|
function EcommerceProvider({ config, children, withToaster = true, basePath = "" }) {
|
|
12953
|
-
|
|
12685
|
+
React10.useMemo(() => {
|
|
12954
12686
|
initializeApiAdapter(config);
|
|
12955
12687
|
}, [config]);
|
|
12956
|
-
const [client] =
|
|
12688
|
+
const [client] = React10.useState(
|
|
12957
12689
|
new QueryClient({ defaultOptions: { queries: { staleTime: 5e3 } } })
|
|
12958
12690
|
);
|
|
12959
|
-
return /* @__PURE__ */ jsx(QueryClientProvider, { client, children: /* @__PURE__ */ jsx(ThemeProvider, { config, children: /* @__PURE__ */ jsx(BasePathProvider, { basePath, children: /* @__PURE__ */ jsx(AuthProvider, { children: /* @__PURE__ */ jsx(NotificationProvider, { children: /* @__PURE__ */ jsx(NotificationCenterProvider, { children: /* @__PURE__ */ jsx(CartProvider, { children: /* @__PURE__ */ jsx(DiscountProvider, { children: /* @__PURE__ */
|
|
12960
|
-
children,
|
|
12961
|
-
/* @__PURE__ */ jsx(NotificationDrawer, {})
|
|
12962
|
-
] }) }) }) }) }) }) }) }) });
|
|
12691
|
+
return /* @__PURE__ */ jsx(QueryClientProvider, { client, children: /* @__PURE__ */ jsx(ThemeProvider, { config, children: /* @__PURE__ */ jsx(BasePathProvider, { basePath, children: /* @__PURE__ */ jsx(AuthProvider, { children: /* @__PURE__ */ jsx(NotificationProvider, { children: /* @__PURE__ */ jsx(NotificationCenterProvider, { children: /* @__PURE__ */ jsx(CartProvider, { children: /* @__PURE__ */ jsx(DiscountProvider, { children: /* @__PURE__ */ jsx(WishlistProvider, { children }) }) }) }) }) }) }) }) });
|
|
12963
12692
|
}
|
|
12693
|
+
|
|
12694
|
+
// src/lib/constants/assets.ts
|
|
12695
|
+
var PLACEHOLDER_IMAGE_SRC = `data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAwIiBoZWlnaHQ9IjQwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICA8cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZjNmNGY2Ii8+CiAgPHRleHQgeD0iNTAlIiB5PSI1MCUiIGZvbnQtZmFtaWx5PSJBcmlhbCIgZm9udC1zaXplPSIyNCIgZmlsbD0iIzljYTNhZiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZG9taW5hbnQtYmFzZWxpbmU9Im1pZGRsZSI+Tm8gSW1hZ2U8L3RleHQ+CiAgPHJlY3QgeD0iMTUwIiB5PSIxMjAiIHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIiBzdHJva2U9IiM5Y2EzYWYiIHN0cm9rZS13aWR0aD0iNCIgZmlsbD0ibm9uZSIgcng9IjgiLz4KICA8cGF0aCBkPSJNMTUwIDE4MCBMMTcwIDE2MCBMMjAwIDE5MCBMMjIwIDE3MCBMMjUwIDIwMCBMMjUwIDIyMCBMMTUwIDIyMCBaIiBmaWxsPSIjOWNhM2FmIiBvcGFjaXR5PSIwLjUiLz4KPC9zdmc+`;
|
|
12964
12696
|
function QuickViewModal({ product, onClose, onNavigateToProduct }) {
|
|
12965
12697
|
const [selectedVariantIndex, setSelectedVariantIndex] = useState(0);
|
|
12966
12698
|
const [selectedSizeIndex, setSelectedSizeIndex] = useState(0);
|
|
@@ -13119,7 +12851,7 @@ function QuickViewModal({ product, onClose, onNavigateToProduct }) {
|
|
|
13119
12851
|
setSelectedSizeIndex(0);
|
|
13120
12852
|
setSelectedImageIndex(0);
|
|
13121
12853
|
},
|
|
13122
|
-
className: `size-10 rounded-full border-2 transition-all ${selectedVariantIndex === index ? "border-primary scale-110" : "border-gray-200 hover:border-primary
|
|
12854
|
+
className: `size-10 rounded-full border-2 transition-all ${selectedVariantIndex === index ? "border-primary scale-110" : "border-gray-200 hover:border-primary-50"}`,
|
|
13123
12855
|
style: { backgroundColor: variant.colorHex },
|
|
13124
12856
|
title: variant.color,
|
|
13125
12857
|
children: /* @__PURE__ */ jsx(
|
|
@@ -13287,7 +13019,7 @@ function ProductCard({
|
|
|
13287
13019
|
return selectedVariant ? selectedVariant.inventoryCount : product.variants?.[0]?.inventoryCount;
|
|
13288
13020
|
}, [selectedVariant, product.variants]);
|
|
13289
13021
|
const imageSource = useMemo(() => {
|
|
13290
|
-
const src = selectedVariantImage || selectedVariant?.media?.[0]?.file || product.media?.[0]?.file ||
|
|
13022
|
+
const src = selectedVariantImage || selectedVariant?.media?.[0]?.file || product.media?.[0]?.file || PLACEHOLDER_IMAGE_SRC;
|
|
13291
13023
|
return {
|
|
13292
13024
|
src,
|
|
13293
13025
|
alt: product.name || "Product image"
|
|
@@ -14392,7 +14124,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
14392
14124
|
type: "button",
|
|
14393
14125
|
onClick: applyCustomPrice,
|
|
14394
14126
|
disabled: !isCustomPriceDirty,
|
|
14395
|
-
className: "w-full rounded-lg border border-primary bg-primary
|
|
14127
|
+
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",
|
|
14396
14128
|
children: "Apply"
|
|
14397
14129
|
}
|
|
14398
14130
|
)
|
|
@@ -14460,7 +14192,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
14460
14192
|
animate: { opacity: 1, y: 0 },
|
|
14461
14193
|
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"}`,
|
|
14462
14194
|
children: /* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
14463
|
-
/* @__PURE__ */ 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
|
|
14195
|
+
/* @__PURE__ */ 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__ */ jsx(Package, { className: `size-6 ${!categoryFilter ? "text-white" : "text-primary"}` }) }),
|
|
14464
14196
|
/* @__PURE__ */ jsx("h3", { className: `font-['Poppins',sans-serif] font-semibold text-[14px] mb-1.5 ${!categoryFilter ? "text-white" : "text-secondary"}`, children: "All Products" }),
|
|
14465
14197
|
/* @__PURE__ */ jsx("p", { className: `font-['Poppins',sans-serif] text-[11px] ${!categoryFilter ? "text-white/80" : "text-muted"}`, children: "Browse Everything" })
|
|
14466
14198
|
] })
|
|
@@ -14479,7 +14211,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
14479
14211
|
onClick: () => handleCategoryChange(categoryId),
|
|
14480
14212
|
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"}`,
|
|
14481
14213
|
children: /* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
14482
|
-
/* @__PURE__ */ 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
|
|
14214
|
+
/* @__PURE__ */ 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__ */ jsx(Icon, { className: `size-6 ${isSelected ? "text-white" : "text-primary"}` }) }),
|
|
14483
14215
|
/* @__PURE__ */ jsx("h3", { className: `font-['Poppins',sans-serif] font-semibold text-[14px] mb-1.5 ${isSelected ? "text-white" : "text-secondary"}`, children: category.name }),
|
|
14484
14216
|
/* @__PURE__ */ jsx("p", { className: `font-['Poppins',sans-serif] text-[11px] ${isSelected ? "text-white/80" : "text-muted"}`, children: category.description })
|
|
14485
14217
|
] })
|
|
@@ -14590,7 +14322,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
14590
14322
|
/* @__PURE__ */ jsx("div", { className: "relative h-48 w-full overflow-hidden rounded-2xl bg-gray-100 md:h-40 md:w-40", children: /* @__PURE__ */ jsx(
|
|
14591
14323
|
Image4,
|
|
14592
14324
|
{
|
|
14593
|
-
src: product.media?.[0]?.file ||
|
|
14325
|
+
src: product.media?.[0]?.file || PLACEHOLDER_IMAGE_SRC,
|
|
14594
14326
|
alt: product.name,
|
|
14595
14327
|
fill: true,
|
|
14596
14328
|
className: "object-cover transition duration-500 group-hover:scale-105"
|
|
@@ -14887,7 +14619,7 @@ function StarRating({
|
|
|
14887
14619
|
onChange,
|
|
14888
14620
|
className
|
|
14889
14621
|
}) {
|
|
14890
|
-
const [hoverRating, setHoverRating] =
|
|
14622
|
+
const [hoverRating, setHoverRating] = React10.useState(0);
|
|
14891
14623
|
const handleClick = (index) => {
|
|
14892
14624
|
if (interactive && onChange) {
|
|
14893
14625
|
onChange(index + 1);
|
|
@@ -15019,7 +14751,7 @@ function ReviewCard({ review, showProductInfo = false }) {
|
|
|
15019
14751
|
function ReviewsList({ reviews, isLoading }) {
|
|
15020
14752
|
const [filterRating, setFilterRating] = useState("all");
|
|
15021
14753
|
const [sortBy, setSortBy] = useState("recent");
|
|
15022
|
-
const filteredReviews =
|
|
14754
|
+
const filteredReviews = React10.useMemo(() => {
|
|
15023
14755
|
let filtered = [...reviews];
|
|
15024
14756
|
if (filterRating !== "all") {
|
|
15025
14757
|
filtered = filtered.filter((review) => Math.floor(review.rating) === filterRating);
|
|
@@ -15422,7 +15154,7 @@ function ProductDetailScreen({ productId }) {
|
|
|
15422
15154
|
{
|
|
15423
15155
|
type: "button",
|
|
15424
15156
|
onClick: () => setActiveImageIndex(index),
|
|
15425
|
-
className: `relative aspect-square overflow-hidden rounded-lg border-2 transition-all ${activeImageIndex === index ? "border-primary
|
|
15157
|
+
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"}`,
|
|
15426
15158
|
children: /* @__PURE__ */ jsx(
|
|
15427
15159
|
Image4,
|
|
15428
15160
|
{
|
|
@@ -15510,13 +15242,13 @@ function ProductDetailScreen({ productId }) {
|
|
|
15510
15242
|
/* @__PURE__ */ jsx("h3", { className: "font-['Poppins',sans-serif] font-semibold text-[14px] text-secondary mb-3", children: "Select Variant" }),
|
|
15511
15243
|
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-3", children: product.variants.map((variant) => {
|
|
15512
15244
|
const isSelected = selectedVariant?._id === variant._id;
|
|
15513
|
-
const variantImage = variant.media?.[0]?.file || product.media?.[0]?.file || product.images?.[0] ||
|
|
15245
|
+
const variantImage = variant.media?.[0]?.file || product.media?.[0]?.file || product.images?.[0] || PLACEHOLDER_IMAGE_SRC;
|
|
15514
15246
|
return /* @__PURE__ */ jsxs(
|
|
15515
15247
|
"button",
|
|
15516
15248
|
{
|
|
15517
15249
|
type: "button",
|
|
15518
15250
|
onClick: () => handleVariantSelect(variant),
|
|
15519
|
-
className: `flex items-start gap-3 px-4 py-2.5 rounded-xl border-2 transition-all ${isSelected ? "border-primary bg-primary
|
|
15251
|
+
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"}`,
|
|
15520
15252
|
children: [
|
|
15521
15253
|
/* @__PURE__ */ jsx("div", { className: `relative h-12 w-12 shrink-0 overflow-hidden rounded-full border-2 ${isSelected ? "border-primary" : "border-slate-200"}`, children: /* @__PURE__ */ jsx(
|
|
15522
15254
|
Image4,
|
|
@@ -15595,7 +15327,7 @@ function ProductDetailScreen({ productId }) {
|
|
|
15595
15327
|
/* @__PURE__ */ jsx(
|
|
15596
15328
|
"button",
|
|
15597
15329
|
{
|
|
15598
|
-
className: "sm:w-auto px-6 py-4 rounded-full border-2 border-primary hover:bg-primary
|
|
15330
|
+
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",
|
|
15599
15331
|
onClick: handleToggleFavorite,
|
|
15600
15332
|
children: /* @__PURE__ */ jsx(Heart, { className: `h-4 w-4 ${isFavorited ? "fill-red-500 text-red-500" : "text-primary"}` })
|
|
15601
15333
|
}
|
|
@@ -15717,7 +15449,7 @@ function CartItem({ item }) {
|
|
|
15717
15449
|
/* @__PURE__ */ jsx("div", { className: "w-28 h-28 rounded-[16px] overflow-hidden bg-gray-50 shrink-0", children: /* @__PURE__ */ jsx(
|
|
15718
15450
|
Image4,
|
|
15719
15451
|
{
|
|
15720
|
-
src: item.productVariantData.media[0]?.file ||
|
|
15452
|
+
src: item.productVariantData.media[0]?.file || PLACEHOLDER_IMAGE_SRC,
|
|
15721
15453
|
alt: item.productVariantData.name,
|
|
15722
15454
|
className: "w-full h-full object-cover",
|
|
15723
15455
|
height: 112,
|
|
@@ -16855,7 +16587,7 @@ function CheckoutScreen() {
|
|
|
16855
16587
|
setIsSubmitting(false);
|
|
16856
16588
|
}
|
|
16857
16589
|
};
|
|
16858
|
-
|
|
16590
|
+
React10.useEffect(() => {
|
|
16859
16591
|
if (!cart || cart?.cartBody?.items?.length === 0 || !cart?.cartBody?.items) {
|
|
16860
16592
|
router.push(buildPath("/cart"));
|
|
16861
16593
|
}
|
|
@@ -17134,7 +16866,7 @@ function CheckoutScreen() {
|
|
|
17134
16866
|
/* @__PURE__ */ jsx("div", { className: "shrink-0", children: /* @__PURE__ */ jsx(
|
|
17135
16867
|
Image4,
|
|
17136
16868
|
{
|
|
17137
|
-
src: rate.providerImage75 ||
|
|
16869
|
+
src: rate.providerImage75 || PLACEHOLDER_IMAGE_SRC,
|
|
17138
16870
|
alt: rate.provider,
|
|
17139
16871
|
className: "w-12 h-12 rounded-lg object-contain bg-white border border-gray-200 p-1",
|
|
17140
16872
|
onError: (e) => {
|
|
@@ -17219,7 +16951,7 @@ function CheckoutScreen() {
|
|
|
17219
16951
|
/* @__PURE__ */ jsx("h2", { className: "font-['Poppins',sans-serif] font-semibold text-[#2B4B7C] mb-6 text-2xl", children: "Order Summary" }),
|
|
17220
16952
|
/* @__PURE__ */ jsxs("section", { className: "mt-8 pt-6 border-t border-slate-100", children: [
|
|
17221
16953
|
/* @__PURE__ */ jsx("div", { className: "space-y-4 mb-6", children: cart?.cartBody?.items?.map((item) => /* @__PURE__ */ jsxs("div", { className: "flex gap-3", children: [
|
|
17222
|
-
/* @__PURE__ */ jsx("div", { className: "w-16 h-16 rounded-xl overflow-hidden bg-white shrink-0", children: /* @__PURE__ */ jsx(Image4, { src: item.productVariantData?.media?.[0]?.file ||
|
|
16954
|
+
/* @__PURE__ */ jsx("div", { className: "w-16 h-16 rounded-xl overflow-hidden bg-white shrink-0", children: /* @__PURE__ */ jsx(Image4, { src: item.productVariantData?.media?.[0]?.file || PLACEHOLDER_IMAGE_SRC, alt: item.productVariantData.name, className: "w-full h-full object-cover", height: 200, width: 200 }) }),
|
|
17223
16955
|
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
17224
16956
|
/* @__PURE__ */ jsx("p", { className: "font-['Poppins',sans-serif] font-medium text-[12px] text-[#2B4B7C] mb-1", children: item?.productVariantData?.name }),
|
|
17225
16957
|
/* @__PURE__ */ jsxs("p", { className: "font-['Poppins',sans-serif] text-[11px] text-[#676c80]", children: [
|
|
@@ -18401,7 +18133,7 @@ function AccountOrdersTab() {
|
|
|
18401
18133
|
/* @__PURE__ */ jsx("div", { className: "relative w-12 h-12 rounded-lg bg-slate-100 shrink-0 overflow-hidden", children: /* @__PURE__ */ jsx(
|
|
18402
18134
|
Image4,
|
|
18403
18135
|
{
|
|
18404
|
-
src: item?.productVariantData?.media?.[0]?.file ||
|
|
18136
|
+
src: item?.productVariantData?.media?.[0]?.file || PLACEHOLDER_IMAGE_SRC,
|
|
18405
18137
|
alt: item?.productVariantData?.name || "Product image",
|
|
18406
18138
|
fill: true,
|
|
18407
18139
|
className: "object-cover",
|
|
@@ -18839,7 +18571,7 @@ function AccountPage() {
|
|
|
18839
18571
|
const [activeTab, setActiveTab] = useState("overview");
|
|
18840
18572
|
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
|
|
18841
18573
|
const [isLoggingOut, setIsLoggingOut] = useState(false);
|
|
18842
|
-
|
|
18574
|
+
React10.useEffect(() => {
|
|
18843
18575
|
const handleTabSwitch = (event) => {
|
|
18844
18576
|
setActiveTab(event.detail);
|
|
18845
18577
|
};
|
|
@@ -18957,7 +18689,7 @@ function OrderCard({ order, onDelete }) {
|
|
|
18957
18689
|
/* @__PURE__ */ jsx("div", { className: "relative w-12 h-12 rounded-sm bg-gray-100 shrink-0 overflow-hidden", children: /* @__PURE__ */ jsx(
|
|
18958
18690
|
Image4,
|
|
18959
18691
|
{
|
|
18960
|
-
src: item?.productVariantData?.media?.[0]?.file ||
|
|
18692
|
+
src: item?.productVariantData?.media?.[0]?.file || PLACEHOLDER_IMAGE_SRC,
|
|
18961
18693
|
alt: item?.productVariantData?.name || "Product image",
|
|
18962
18694
|
fill: true,
|
|
18963
18695
|
className: "object-cover",
|
|
@@ -20226,7 +19958,7 @@ function WishlistScreen() {
|
|
|
20226
19958
|
Image4,
|
|
20227
19959
|
{
|
|
20228
19960
|
fill: true,
|
|
20229
|
-
src: product.media?.[0]?.file ||
|
|
19961
|
+
src: product.media?.[0]?.file || PLACEHOLDER_IMAGE_SRC,
|
|
20230
19962
|
alt: product.name || "Wishlist item",
|
|
20231
19963
|
className: "h-full w-full object-cover"
|
|
20232
19964
|
}
|
|
@@ -20262,7 +19994,7 @@ function WishlistScreen() {
|
|
|
20262
19994
|
{
|
|
20263
19995
|
size: "sm",
|
|
20264
19996
|
onClick: () => router.push(buildPath(`/products/${product._id}`)),
|
|
20265
|
-
className: "bg-primary
|
|
19997
|
+
className: "bg-primary-90 text-white hover:bg-primary-70",
|
|
20266
19998
|
children: "View details"
|
|
20267
19999
|
}
|
|
20268
20000
|
),
|
|
@@ -21122,7 +20854,7 @@ function OrderReviewsScreen() {
|
|
|
21122
20854
|
const { orders, isLoading, error, refetch } = useCurrentOrders();
|
|
21123
20855
|
const [selectedOrder, setSelectedOrder] = useState(null);
|
|
21124
20856
|
const [selectedProduct, setSelectedProduct] = useState(null);
|
|
21125
|
-
|
|
20857
|
+
React10.useEffect(() => {
|
|
21126
20858
|
if (!isLoading && !isAuthenticated) {
|
|
21127
20859
|
router.push("/login");
|
|
21128
20860
|
}
|
|
@@ -21574,7 +21306,7 @@ function OrderDetailScreen({ id }) {
|
|
|
21574
21306
|
const { order, isLoading, error } = useOrder(id);
|
|
21575
21307
|
if (isLoading) {
|
|
21576
21308
|
return /* @__PURE__ */ jsxs("div", { className: "min-h-screen bg-slate-50 flex flex-col items-center justify-center p-4", children: [
|
|
21577
|
-
/* @__PURE__ */ jsx("div", { className: "w-16 h-16 border-4 border-primary
|
|
21309
|
+
/* @__PURE__ */ jsx("div", { className: "w-16 h-16 border-4 border-primary-20 border-t-primary rounded-full animate-spin mb-4" }),
|
|
21578
21310
|
/* @__PURE__ */ jsx("p", { className: "text-muted font-medium animate-pulse", children: "Retrieving order details..." })
|
|
21579
21311
|
] });
|
|
21580
21312
|
}
|
|
@@ -21672,7 +21404,7 @@ function OrderDetailScreen({ id }) {
|
|
|
21672
21404
|
/* @__PURE__ */ jsx("div", { className: "relative w-20 h-20 bg-slate-100 rounded-2xl overflow-hidden shrink-0 border border-slate-100 group-hover:scale-105 transition-transform duration-300", children: /* @__PURE__ */ jsx(
|
|
21673
21405
|
Image4,
|
|
21674
21406
|
{
|
|
21675
|
-
src: item.productVariantData?.media?.[0]?.file ||
|
|
21407
|
+
src: item.productVariantData?.media?.[0]?.file || PLACEHOLDER_IMAGE_SRC,
|
|
21676
21408
|
alt: item.productVariantData?.name || "Item",
|
|
21677
21409
|
fill: true,
|
|
21678
21410
|
className: "object-cover",
|
|
@@ -21744,7 +21476,7 @@ function OrderDetailScreen({ id }) {
|
|
|
21744
21476
|
{
|
|
21745
21477
|
initial: { opacity: 0, x: 20 },
|
|
21746
21478
|
animate: { opacity: 1, x: 0 },
|
|
21747
|
-
className: "bg-secondary p-8 rounded-[2rem] text-white shadow-xl shadow-secondary
|
|
21479
|
+
className: "bg-secondary p-8 rounded-[2rem] text-white shadow-xl shadow-secondary-20 sticky top-8",
|
|
21748
21480
|
children: [
|
|
21749
21481
|
/* @__PURE__ */ jsx("h2", { className: "text-xl font-bold mb-6 flex items-center gap-2", children: "Summary View" }),
|
|
21750
21482
|
/* @__PURE__ */ jsxs("div", { className: "space-y-4 mb-8", children: [
|
|
@@ -21846,103 +21578,440 @@ function ChangePasswordScreen() {
|
|
|
21846
21578
|
/* @__PURE__ */ jsx("h1", { className: "text-2xl font-semibold text-slate-900", children: "Change password" })
|
|
21847
21579
|
] })
|
|
21848
21580
|
] }),
|
|
21849
|
-
/* @__PURE__ */ 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." }),
|
|
21850
|
-
status && /* @__PURE__ */ jsxs(
|
|
21581
|
+
/* @__PURE__ */ 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." }),
|
|
21582
|
+
status && /* @__PURE__ */ jsxs(
|
|
21583
|
+
"div",
|
|
21584
|
+
{
|
|
21585
|
+
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"}`,
|
|
21586
|
+
children: [
|
|
21587
|
+
/* @__PURE__ */ jsx("span", { className: "mt-[2px] text-base", children: status.type === "success" ? "\u2714" : "!" }),
|
|
21588
|
+
/* @__PURE__ */ jsx("span", { children: status.message })
|
|
21589
|
+
]
|
|
21590
|
+
}
|
|
21591
|
+
),
|
|
21592
|
+
/* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit(onSubmit), className: "mt-8 space-y-5", children: [
|
|
21593
|
+
/* @__PURE__ */ jsx(
|
|
21594
|
+
Input,
|
|
21595
|
+
{
|
|
21596
|
+
type: "password",
|
|
21597
|
+
label: "Current password",
|
|
21598
|
+
placeholder: "Enter current password",
|
|
21599
|
+
...register("currentPassword"),
|
|
21600
|
+
error: errors.currentPassword?.message
|
|
21601
|
+
}
|
|
21602
|
+
),
|
|
21603
|
+
/* @__PURE__ */ jsx(
|
|
21604
|
+
Input,
|
|
21605
|
+
{
|
|
21606
|
+
type: "password",
|
|
21607
|
+
label: "New password",
|
|
21608
|
+
placeholder: "Enter new password",
|
|
21609
|
+
...register("newPassword"),
|
|
21610
|
+
error: errors.newPassword?.message
|
|
21611
|
+
}
|
|
21612
|
+
),
|
|
21613
|
+
/* @__PURE__ */ jsx(
|
|
21614
|
+
Input,
|
|
21615
|
+
{
|
|
21616
|
+
type: "password",
|
|
21617
|
+
label: "Confirm new password",
|
|
21618
|
+
placeholder: "Re-type new password",
|
|
21619
|
+
...register("confirmPassword"),
|
|
21620
|
+
error: errors.confirmPassword?.message
|
|
21621
|
+
}
|
|
21622
|
+
),
|
|
21623
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-3", children: [
|
|
21624
|
+
/* @__PURE__ */ jsx(
|
|
21625
|
+
Button,
|
|
21626
|
+
{
|
|
21627
|
+
variant: "primary",
|
|
21628
|
+
type: "submit",
|
|
21629
|
+
size: "lg",
|
|
21630
|
+
isLoading: isSubmitting,
|
|
21631
|
+
children: "Save password"
|
|
21632
|
+
}
|
|
21633
|
+
),
|
|
21634
|
+
/* @__PURE__ */ jsx(
|
|
21635
|
+
Button,
|
|
21636
|
+
{
|
|
21637
|
+
type: "button",
|
|
21638
|
+
variant: "outline-solid",
|
|
21639
|
+
size: "lg",
|
|
21640
|
+
className: "border-slate-300 text-slate-800 hover:bg-slate-50",
|
|
21641
|
+
onClick: () => router.push(buildPath("/account")),
|
|
21642
|
+
children: "Cancel"
|
|
21643
|
+
}
|
|
21644
|
+
)
|
|
21645
|
+
] })
|
|
21646
|
+
] }),
|
|
21647
|
+
/* @__PURE__ */ 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: [
|
|
21648
|
+
/* @__PURE__ */ jsx(ShieldCheck, { className: "h-4 w-4 text-primary-600" }),
|
|
21649
|
+
"Strong passwords and up-to-date contact details help pharmacists verify changes quickly."
|
|
21650
|
+
] })
|
|
21651
|
+
]
|
|
21652
|
+
}
|
|
21653
|
+
) }) });
|
|
21654
|
+
}
|
|
21655
|
+
var getNotificationIcon = (type) => {
|
|
21656
|
+
const className = "w-5 h-5";
|
|
21657
|
+
switch (type) {
|
|
21658
|
+
case "ORDER_CONFIRMATION":
|
|
21659
|
+
case "ORDER_SHIPPED":
|
|
21660
|
+
case "ORDER_DELIVERED":
|
|
21661
|
+
return /* @__PURE__ */ jsx(Package, { className });
|
|
21662
|
+
case "PAYMENT_FAILED":
|
|
21663
|
+
case "REFUND_PROCESSED":
|
|
21664
|
+
return /* @__PURE__ */ jsx(CreditCard, { className });
|
|
21665
|
+
case "PASSWORD_RESET":
|
|
21666
|
+
case "NEW_DEVICE_LOGIN":
|
|
21667
|
+
case "TWO_FA_CODE":
|
|
21668
|
+
return /* @__PURE__ */ jsx(Lock, { className });
|
|
21669
|
+
case "ABANDONED_CART_REMINDER":
|
|
21670
|
+
return /* @__PURE__ */ jsx(ShoppingCart, { className });
|
|
21671
|
+
case "PRICE_DROP_ALERT":
|
|
21672
|
+
return /* @__PURE__ */ jsx(TrendingDown, { className });
|
|
21673
|
+
case "BACK_IN_STOCK":
|
|
21674
|
+
default:
|
|
21675
|
+
return /* @__PURE__ */ jsx(Bell, { className });
|
|
21676
|
+
}
|
|
21677
|
+
};
|
|
21678
|
+
var getNotificationColor = (type) => {
|
|
21679
|
+
switch (type) {
|
|
21680
|
+
case "ORDER_CONFIRMATION":
|
|
21681
|
+
case "ORDER_DELIVERED":
|
|
21682
|
+
case "REFUND_PROCESSED":
|
|
21683
|
+
return "bg-green-100 text-green-600";
|
|
21684
|
+
case "ORDER_SHIPPED":
|
|
21685
|
+
return "bg-blue-100 text-blue-600";
|
|
21686
|
+
case "PAYMENT_FAILED":
|
|
21687
|
+
return "bg-red-100 text-red-600";
|
|
21688
|
+
case "PASSWORD_RESET":
|
|
21689
|
+
case "NEW_DEVICE_LOGIN":
|
|
21690
|
+
case "TWO_FA_CODE":
|
|
21691
|
+
return "bg-purple-100 text-purple-600";
|
|
21692
|
+
case "ABANDONED_CART_REMINDER":
|
|
21693
|
+
case "PRICE_DROP_ALERT":
|
|
21694
|
+
case "BACK_IN_STOCK":
|
|
21695
|
+
return "bg-orange-100 text-orange-600";
|
|
21696
|
+
default:
|
|
21697
|
+
return "bg-gray-100 text-gray-600";
|
|
21698
|
+
}
|
|
21699
|
+
};
|
|
21700
|
+
var formatRelativeTime = (dateString) => {
|
|
21701
|
+
const date = new Date(dateString);
|
|
21702
|
+
const diff = Date.now() - date.getTime();
|
|
21703
|
+
const mins = Math.floor(diff / 6e4);
|
|
21704
|
+
const hours = Math.floor(diff / 36e5);
|
|
21705
|
+
const days = Math.floor(diff / 864e5);
|
|
21706
|
+
if (mins < 1) return "Just now";
|
|
21707
|
+
if (mins < 60) return `${mins} min ago`;
|
|
21708
|
+
if (hours < 24) return `${hours} hour${hours > 1 ? "s" : ""} ago`;
|
|
21709
|
+
if (days < 7) return `${days} day${days > 1 ? "s" : ""} ago`;
|
|
21710
|
+
return date.toLocaleDateString();
|
|
21711
|
+
};
|
|
21712
|
+
function NotificationCard({
|
|
21713
|
+
notification,
|
|
21714
|
+
onMarkAsRead,
|
|
21715
|
+
onDelete
|
|
21716
|
+
}) {
|
|
21717
|
+
const router = useRouter();
|
|
21718
|
+
const { buildPath } = useBasePath();
|
|
21719
|
+
const hasDragged = useRef(false);
|
|
21720
|
+
const handleClick = () => {
|
|
21721
|
+
if (hasDragged.current) return;
|
|
21722
|
+
if (!notification.isRead) {
|
|
21723
|
+
onMarkAsRead(notification._id);
|
|
21724
|
+
}
|
|
21725
|
+
if (notification.data?.orderId) {
|
|
21726
|
+
router.push(buildPath(`/account/orders/${notification.data.orderId}`));
|
|
21727
|
+
} else if (notification.data?.productId) {
|
|
21728
|
+
router.push(buildPath(`/products/${notification.data.productId}`));
|
|
21729
|
+
}
|
|
21730
|
+
};
|
|
21731
|
+
const handleDelete = (e) => {
|
|
21732
|
+
e.stopPropagation();
|
|
21733
|
+
onDelete(notification._id);
|
|
21734
|
+
};
|
|
21735
|
+
return /* @__PURE__ */ jsxs("div", { className: "relative overflow-hidden rounded-lg", children: [
|
|
21736
|
+
/* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center justify-end px-6", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-1 text-white", children: [
|
|
21737
|
+
/* @__PURE__ */ jsx(Trash2, { className: "w-5 h-5" }),
|
|
21738
|
+
/* @__PURE__ */ jsx("span", { className: "text-[10px] font-bold uppercase tracking-wider", children: "Remove" })
|
|
21739
|
+
] }) }),
|
|
21740
|
+
/* @__PURE__ */ jsx(
|
|
21741
|
+
motion.div,
|
|
21742
|
+
{
|
|
21743
|
+
drag: "x",
|
|
21744
|
+
initial: { opacity: 0, x: 0 },
|
|
21745
|
+
animate: { opacity: 1, x: 0 },
|
|
21746
|
+
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"}`,
|
|
21747
|
+
onClick: handleClick,
|
|
21748
|
+
children: /* @__PURE__ */ jsxs("div", { className: "flex gap-3", children: [
|
|
21749
|
+
/* @__PURE__ */ jsx(
|
|
21750
|
+
"div",
|
|
21751
|
+
{
|
|
21752
|
+
className: `flex-shrink-0 w-10 h-10 rounded-full flex items-center justify-center ${getNotificationColor(
|
|
21753
|
+
notification.type
|
|
21754
|
+
)}`,
|
|
21755
|
+
children: getNotificationIcon(notification.type)
|
|
21756
|
+
}
|
|
21757
|
+
),
|
|
21758
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
21759
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-2", children: [
|
|
21760
|
+
/* @__PURE__ */ jsx("h4", { className: "font-semibold text-gray-900 text-sm line-clamp-1", children: notification.title }),
|
|
21761
|
+
/* @__PURE__ */ jsx(
|
|
21762
|
+
"button",
|
|
21763
|
+
{
|
|
21764
|
+
onClick: handleDelete,
|
|
21765
|
+
className: "flex-shrink-0 p-1 bg-gray-100 rounded-full hover:bg-red-50",
|
|
21766
|
+
"aria-label": "Delete notification",
|
|
21767
|
+
children: /* @__PURE__ */ jsx(X, { className: "w-4 h-4 text-gray-400 hover:text-red-500" })
|
|
21768
|
+
}
|
|
21769
|
+
)
|
|
21770
|
+
] }),
|
|
21771
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-gray-600 mt-1 line-clamp-2", children: notification.body }),
|
|
21772
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mt-2", children: [
|
|
21773
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-gray-500", children: formatRelativeTime(notification.createdAt) }),
|
|
21774
|
+
!notification.isRead && /* @__PURE__ */ jsx(
|
|
21775
|
+
"span",
|
|
21776
|
+
{
|
|
21777
|
+
className: "w-2 h-2 bg-blue-500 rounded-full",
|
|
21778
|
+
"aria-label": "Unread"
|
|
21779
|
+
}
|
|
21780
|
+
)
|
|
21781
|
+
] })
|
|
21782
|
+
] })
|
|
21783
|
+
] })
|
|
21784
|
+
}
|
|
21785
|
+
)
|
|
21786
|
+
] });
|
|
21787
|
+
}
|
|
21788
|
+
var modalVariants = {
|
|
21789
|
+
hidden: { opacity: 0, y: -8, scale: 0.96 },
|
|
21790
|
+
visible: { opacity: 1, y: 0, scale: 1 },
|
|
21791
|
+
exit: { opacity: 0, y: -8, scale: 0.96 }
|
|
21792
|
+
};
|
|
21793
|
+
function NotificationModal() {
|
|
21794
|
+
const {
|
|
21795
|
+
isDrawerOpen,
|
|
21796
|
+
closeDrawer,
|
|
21797
|
+
notifications,
|
|
21798
|
+
unreadCount,
|
|
21799
|
+
isLoading,
|
|
21800
|
+
markAsRead,
|
|
21801
|
+
markAllAsRead,
|
|
21802
|
+
deleteNotification,
|
|
21803
|
+
loadMore,
|
|
21804
|
+
hasMore
|
|
21805
|
+
} = useNotificationCenter();
|
|
21806
|
+
const router = useRouter();
|
|
21807
|
+
const { buildPath } = useBasePath();
|
|
21808
|
+
const scrollRef = useRef(null);
|
|
21809
|
+
const modalRef = useRef(null);
|
|
21810
|
+
const lastScrollTrigger = useRef(0);
|
|
21811
|
+
const handleScroll = useCallback(() => {
|
|
21812
|
+
if (!scrollRef.current || isLoading || !hasMore) return;
|
|
21813
|
+
const now = Date.now();
|
|
21814
|
+
if (now - lastScrollTrigger.current < 300) return;
|
|
21815
|
+
const { scrollTop, scrollHeight, clientHeight } = scrollRef.current;
|
|
21816
|
+
if ((scrollTop + clientHeight) / scrollHeight > 0.8) {
|
|
21817
|
+
lastScrollTrigger.current = now;
|
|
21818
|
+
loadMore();
|
|
21819
|
+
}
|
|
21820
|
+
}, [isLoading, hasMore, loadMore]);
|
|
21821
|
+
const handleSettingsClick = useCallback(() => {
|
|
21822
|
+
closeDrawer();
|
|
21823
|
+
router.push(buildPath("/account/notifications"));
|
|
21824
|
+
}, [closeDrawer, router, buildPath]);
|
|
21825
|
+
useEffect(() => {
|
|
21826
|
+
if (!isDrawerOpen) return;
|
|
21827
|
+
modalRef.current?.focus();
|
|
21828
|
+
const onKeyDown = (e) => {
|
|
21829
|
+
if (e.key === "Escape") closeDrawer();
|
|
21830
|
+
};
|
|
21831
|
+
document.addEventListener("keydown", onKeyDown);
|
|
21832
|
+
return () => document.removeEventListener("keydown", onKeyDown);
|
|
21833
|
+
}, [isDrawerOpen, closeDrawer]);
|
|
21834
|
+
useEffect(() => {
|
|
21835
|
+
if (!isDrawerOpen) return;
|
|
21836
|
+
const handleClickOutside = (e) => {
|
|
21837
|
+
const bellButton = document.getElementById("notification-bell-button");
|
|
21838
|
+
if (modalRef.current && !modalRef.current.contains(e.target) && !bellButton?.contains(e.target)) {
|
|
21839
|
+
closeDrawer();
|
|
21840
|
+
}
|
|
21841
|
+
};
|
|
21842
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
21843
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
21844
|
+
}, [isDrawerOpen, closeDrawer]);
|
|
21845
|
+
const hasNotifications = notifications.length > 0;
|
|
21846
|
+
return /* @__PURE__ */ jsx(AnimatePresence, { children: isDrawerOpen && /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(
|
|
21847
|
+
motion.div,
|
|
21848
|
+
{
|
|
21849
|
+
ref: modalRef,
|
|
21850
|
+
role: "dialog",
|
|
21851
|
+
"aria-modal": "true",
|
|
21852
|
+
"aria-labelledby": "notification-title",
|
|
21853
|
+
tabIndex: -1,
|
|
21854
|
+
variants: modalVariants,
|
|
21855
|
+
initial: "hidden",
|
|
21856
|
+
animate: "visible",
|
|
21857
|
+
exit: "exit",
|
|
21858
|
+
transition: { type: "spring", stiffness: 350, damping: 28 },
|
|
21859
|
+
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",
|
|
21860
|
+
style: { maxHeight: "calc(100vh - 120px)" },
|
|
21861
|
+
children: [
|
|
21862
|
+
/* @__PURE__ */ 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" }),
|
|
21863
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-4 py-3 border-b bg-gradient-to-r from-primary-50 to-white", children: [
|
|
21864
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
21865
|
+
/* @__PURE__ */ jsx(
|
|
21866
|
+
"h2",
|
|
21867
|
+
{
|
|
21868
|
+
id: "notification-title",
|
|
21869
|
+
className: "text-lg font-bold text-gray-900",
|
|
21870
|
+
children: "Notifications"
|
|
21871
|
+
}
|
|
21872
|
+
),
|
|
21873
|
+
/* @__PURE__ */ jsx(
|
|
21874
|
+
"span",
|
|
21875
|
+
{
|
|
21876
|
+
"aria-live": "polite",
|
|
21877
|
+
className: "bg-red-500 text-white text-xs font-bold px-2 py-0.5 rounded-full",
|
|
21878
|
+
children: unreadCount
|
|
21879
|
+
}
|
|
21880
|
+
)
|
|
21881
|
+
] }),
|
|
21882
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
21883
|
+
unreadCount > 0 && /* @__PURE__ */ jsx(
|
|
21884
|
+
"button",
|
|
21885
|
+
{
|
|
21886
|
+
onClick: markAllAsRead,
|
|
21887
|
+
title: "Mark all as read",
|
|
21888
|
+
className: "p-2 rounded-lg hover:bg-white transition",
|
|
21889
|
+
children: /* @__PURE__ */ jsx(CheckCheck, { className: "w-4 h-4 text-gray-600" })
|
|
21890
|
+
}
|
|
21891
|
+
),
|
|
21892
|
+
/* @__PURE__ */ jsx(
|
|
21893
|
+
"button",
|
|
21894
|
+
{
|
|
21895
|
+
onClick: handleSettingsClick,
|
|
21896
|
+
title: "Notification settings",
|
|
21897
|
+
className: "p-2 rounded-lg hover:bg-white transition",
|
|
21898
|
+
children: /* @__PURE__ */ jsx(Settings, { className: "w-4 h-4 text-gray-600" })
|
|
21899
|
+
}
|
|
21900
|
+
),
|
|
21901
|
+
/* @__PURE__ */ jsx(
|
|
21902
|
+
"button",
|
|
21903
|
+
{
|
|
21904
|
+
onClick: closeDrawer,
|
|
21905
|
+
"aria-label": "Close notifications",
|
|
21906
|
+
className: "p-2 rounded-lg hover:bg-red-50 transition",
|
|
21907
|
+
children: /* @__PURE__ */ jsx(X, { className: "w-4 h-4 text-gray-600" })
|
|
21908
|
+
}
|
|
21909
|
+
)
|
|
21910
|
+
] })
|
|
21911
|
+
] }),
|
|
21912
|
+
/* @__PURE__ */ jsx(
|
|
21851
21913
|
"div",
|
|
21852
21914
|
{
|
|
21853
|
-
|
|
21854
|
-
|
|
21855
|
-
|
|
21856
|
-
|
|
21857
|
-
|
|
21915
|
+
ref: scrollRef,
|
|
21916
|
+
onScroll: handleScroll,
|
|
21917
|
+
className: "flex-1 overflow-y-auto p-3 space-y-2 bg-gray-50 scrollbar-thin scrollbar-thumb-gray-300",
|
|
21918
|
+
children: !hasNotifications && !isLoading ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center justify-center py-14 text-center", children: [
|
|
21919
|
+
/* @__PURE__ */ jsx(BellOff, { className: "w-10 h-10 text-gray-400 mb-3" }),
|
|
21920
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-gray-700", children: "No notifications yet" }),
|
|
21921
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-gray-500 mt-1", children: "You\u2019re all caught up \u{1F389}" })
|
|
21922
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
21923
|
+
notifications.map((notification) => /* @__PURE__ */ jsx(
|
|
21924
|
+
NotificationCard,
|
|
21925
|
+
{
|
|
21926
|
+
notification,
|
|
21927
|
+
onMarkAsRead: markAsRead,
|
|
21928
|
+
onDelete: deleteNotification
|
|
21929
|
+
},
|
|
21930
|
+
notification._id
|
|
21931
|
+
)),
|
|
21932
|
+
isLoading && /* @__PURE__ */ jsx("div", { className: "space-y-2 py-2", children: [...Array(3)].map((_, i) => /* @__PURE__ */ jsx(
|
|
21933
|
+
"div",
|
|
21934
|
+
{
|
|
21935
|
+
className: "h-16 rounded-xl bg-gray-200 animate-pulse"
|
|
21936
|
+
},
|
|
21937
|
+
i
|
|
21938
|
+
)) }),
|
|
21939
|
+
!hasMore && hasNotifications && /* @__PURE__ */ jsx("div", { className: "text-center py-3 text-xs text-gray-500", children: "You\u2019re all caught up \u{1F389}" })
|
|
21940
|
+
] })
|
|
21858
21941
|
}
|
|
21859
|
-
)
|
|
21860
|
-
|
|
21861
|
-
|
|
21862
|
-
|
|
21863
|
-
|
|
21864
|
-
|
|
21865
|
-
|
|
21866
|
-
|
|
21867
|
-
|
|
21868
|
-
|
|
21869
|
-
|
|
21870
|
-
|
|
21871
|
-
|
|
21872
|
-
|
|
21873
|
-
|
|
21874
|
-
|
|
21875
|
-
|
|
21876
|
-
|
|
21877
|
-
|
|
21878
|
-
|
|
21879
|
-
|
|
21880
|
-
|
|
21942
|
+
)
|
|
21943
|
+
]
|
|
21944
|
+
}
|
|
21945
|
+
) }) });
|
|
21946
|
+
}
|
|
21947
|
+
function NotificationBell() {
|
|
21948
|
+
const { unreadCount, isDrawerOpen, openDrawer, closeDrawer } = useNotificationCenter();
|
|
21949
|
+
const handleToggle = (e) => {
|
|
21950
|
+
e.stopPropagation();
|
|
21951
|
+
if (isDrawerOpen) {
|
|
21952
|
+
closeDrawer();
|
|
21953
|
+
} else {
|
|
21954
|
+
openDrawer();
|
|
21955
|
+
}
|
|
21956
|
+
};
|
|
21957
|
+
return /* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
21958
|
+
/* @__PURE__ */ jsxs(
|
|
21959
|
+
motion.button,
|
|
21960
|
+
{
|
|
21961
|
+
id: "notification-bell-button",
|
|
21962
|
+
onClick: handleToggle,
|
|
21963
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
21964
|
+
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"}`,
|
|
21965
|
+
"aria-label": "Notifications",
|
|
21966
|
+
whileHover: isDrawerOpen ? {} : { scale: 1.05 },
|
|
21967
|
+
whileTap: { scale: 0.95 },
|
|
21968
|
+
children: [
|
|
21881
21969
|
/* @__PURE__ */ jsx(
|
|
21882
|
-
|
|
21970
|
+
Bell,
|
|
21883
21971
|
{
|
|
21884
|
-
|
|
21885
|
-
|
|
21886
|
-
placeholder: "Re-type new password",
|
|
21887
|
-
...register("confirmPassword"),
|
|
21888
|
-
error: errors.confirmPassword?.message
|
|
21972
|
+
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"}`,
|
|
21973
|
+
strokeWidth: 2
|
|
21889
21974
|
}
|
|
21890
21975
|
),
|
|
21891
|
-
/* @__PURE__ */
|
|
21976
|
+
/* @__PURE__ */ jsx(AnimatePresence, { children: unreadCount > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
21892
21977
|
/* @__PURE__ */ jsx(
|
|
21893
|
-
|
|
21978
|
+
motion.span,
|
|
21894
21979
|
{
|
|
21895
|
-
|
|
21896
|
-
|
|
21897
|
-
|
|
21898
|
-
|
|
21899
|
-
|
|
21980
|
+
initial: { scale: 0.8, opacity: 0 },
|
|
21981
|
+
animate: {
|
|
21982
|
+
scale: [1, 1.4, 1.4],
|
|
21983
|
+
opacity: [0.6, 0, 0]
|
|
21984
|
+
},
|
|
21985
|
+
exit: { scale: 0, opacity: 0 },
|
|
21986
|
+
transition: {
|
|
21987
|
+
duration: 2,
|
|
21988
|
+
repeat: Infinity,
|
|
21989
|
+
repeatDelay: 0.5
|
|
21990
|
+
},
|
|
21991
|
+
className: "absolute -top-0.5 -right-0.5 w-6 h-6 bg-red-500 rounded-full"
|
|
21900
21992
|
}
|
|
21901
21993
|
),
|
|
21902
21994
|
/* @__PURE__ */ jsx(
|
|
21903
|
-
|
|
21995
|
+
motion.span,
|
|
21904
21996
|
{
|
|
21905
|
-
|
|
21906
|
-
|
|
21907
|
-
|
|
21908
|
-
|
|
21909
|
-
|
|
21910
|
-
|
|
21997
|
+
initial: { scale: 0, rotate: -180 },
|
|
21998
|
+
animate: { scale: 1, rotate: 0 },
|
|
21999
|
+
exit: { scale: 0, rotate: 180 },
|
|
22000
|
+
transition: {
|
|
22001
|
+
type: "spring",
|
|
22002
|
+
damping: 15,
|
|
22003
|
+
stiffness: 300
|
|
22004
|
+
},
|
|
22005
|
+
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",
|
|
22006
|
+
children: unreadCount > 99 ? "99+" : unreadCount
|
|
21911
22007
|
}
|
|
21912
22008
|
)
|
|
21913
|
-
] })
|
|
21914
|
-
]
|
|
21915
|
-
|
|
21916
|
-
|
|
21917
|
-
|
|
21918
|
-
|
|
21919
|
-
]
|
|
21920
|
-
}
|
|
21921
|
-
) }) });
|
|
21922
|
-
}
|
|
21923
|
-
function NotificationBell() {
|
|
21924
|
-
const { unreadCount, openDrawer } = useNotificationCenter();
|
|
21925
|
-
return /* @__PURE__ */ jsxs(
|
|
21926
|
-
"button",
|
|
21927
|
-
{
|
|
21928
|
-
onClick: openDrawer,
|
|
21929
|
-
className: "relative p-2 hover:bg-gray-100 rounded-lg transition-colors",
|
|
21930
|
-
"aria-label": "Notifications",
|
|
21931
|
-
children: [
|
|
21932
|
-
/* @__PURE__ */ jsx(Bell, { className: "w-6 h-6 text-gray-700" }),
|
|
21933
|
-
/* @__PURE__ */ jsx(AnimatePresence, { children: unreadCount > 0 && /* @__PURE__ */ jsx(
|
|
21934
|
-
motion.span,
|
|
21935
|
-
{
|
|
21936
|
-
initial: { scale: 0 },
|
|
21937
|
-
animate: { scale: 1 },
|
|
21938
|
-
exit: { scale: 0 },
|
|
21939
|
-
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",
|
|
21940
|
-
children: unreadCount > 99 ? "99+" : unreadCount
|
|
21941
|
-
}
|
|
21942
|
-
) })
|
|
21943
|
-
]
|
|
21944
|
-
}
|
|
21945
|
-
);
|
|
22009
|
+
] }) })
|
|
22010
|
+
]
|
|
22011
|
+
}
|
|
22012
|
+
),
|
|
22013
|
+
/* @__PURE__ */ jsx(NotificationModal, {})
|
|
22014
|
+
] });
|
|
21946
22015
|
}
|
|
21947
22016
|
function Header() {
|
|
21948
22017
|
const { config } = useTheme();
|
|
@@ -22287,6 +22356,141 @@ function Footer() {
|
|
|
22287
22356
|
] })
|
|
22288
22357
|
] }) });
|
|
22289
22358
|
}
|
|
22359
|
+
function NotificationDrawer() {
|
|
22360
|
+
const {
|
|
22361
|
+
isDrawerOpen,
|
|
22362
|
+
closeDrawer,
|
|
22363
|
+
notifications,
|
|
22364
|
+
unreadCount,
|
|
22365
|
+
isLoading,
|
|
22366
|
+
markAsRead,
|
|
22367
|
+
markAllAsRead,
|
|
22368
|
+
deleteNotification,
|
|
22369
|
+
loadMore,
|
|
22370
|
+
hasMore
|
|
22371
|
+
} = useNotificationCenter();
|
|
22372
|
+
const router = useRouter();
|
|
22373
|
+
const { buildPath } = useBasePath();
|
|
22374
|
+
const scrollContainerRef = useRef(null);
|
|
22375
|
+
const handleScroll = () => {
|
|
22376
|
+
if (!scrollContainerRef.current || isLoading || !hasMore) return;
|
|
22377
|
+
const { scrollTop, scrollHeight, clientHeight } = scrollContainerRef.current;
|
|
22378
|
+
const scrollPercentage = (scrollTop + clientHeight) / scrollHeight;
|
|
22379
|
+
if (scrollPercentage > 0.8) {
|
|
22380
|
+
loadMore();
|
|
22381
|
+
}
|
|
22382
|
+
};
|
|
22383
|
+
useEffect(() => {
|
|
22384
|
+
const handleEscape = (e) => {
|
|
22385
|
+
if (e.key === "Escape" && isDrawerOpen) {
|
|
22386
|
+
closeDrawer();
|
|
22387
|
+
}
|
|
22388
|
+
};
|
|
22389
|
+
document.addEventListener("keydown", handleEscape);
|
|
22390
|
+
return () => document.removeEventListener("keydown", handleEscape);
|
|
22391
|
+
}, [isDrawerOpen, closeDrawer]);
|
|
22392
|
+
useEffect(() => {
|
|
22393
|
+
if (isDrawerOpen) {
|
|
22394
|
+
document.body.style.overflow = "hidden";
|
|
22395
|
+
} else {
|
|
22396
|
+
document.body.style.overflow = "";
|
|
22397
|
+
}
|
|
22398
|
+
return () => {
|
|
22399
|
+
document.body.style.overflow = "";
|
|
22400
|
+
};
|
|
22401
|
+
}, [isDrawerOpen]);
|
|
22402
|
+
const handleSettingsClick = () => {
|
|
22403
|
+
closeDrawer();
|
|
22404
|
+
router.push(buildPath("/account/notifications"));
|
|
22405
|
+
};
|
|
22406
|
+
return /* @__PURE__ */ jsx(AnimatePresence, { children: isDrawerOpen && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
22407
|
+
/* @__PURE__ */ jsx(
|
|
22408
|
+
motion.div,
|
|
22409
|
+
{
|
|
22410
|
+
initial: { opacity: 0 },
|
|
22411
|
+
animate: { opacity: 1 },
|
|
22412
|
+
exit: { opacity: 0 },
|
|
22413
|
+
className: "fixed inset-0 bg-black/50 z-40",
|
|
22414
|
+
onClick: closeDrawer
|
|
22415
|
+
}
|
|
22416
|
+
),
|
|
22417
|
+
/* @__PURE__ */ jsxs(
|
|
22418
|
+
motion.div,
|
|
22419
|
+
{
|
|
22420
|
+
initial: { x: "100%" },
|
|
22421
|
+
animate: { x: 0 },
|
|
22422
|
+
exit: { x: "100%" },
|
|
22423
|
+
transition: { type: "spring", damping: 25, stiffness: 200 },
|
|
22424
|
+
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]",
|
|
22425
|
+
children: [
|
|
22426
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between p-4 border-b border-gray-200 bg-white", children: [
|
|
22427
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
22428
|
+
/* @__PURE__ */ jsx("h2", { className: "text-xl font-bold text-gray-900", children: "Notifications" }),
|
|
22429
|
+
unreadCount > 0 && /* @__PURE__ */ jsx("span", { className: "bg-red-500 text-white text-xs font-bold px-2 py-1 rounded-full", children: unreadCount })
|
|
22430
|
+
] }),
|
|
22431
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
22432
|
+
unreadCount > 0 && /* @__PURE__ */ jsx(
|
|
22433
|
+
"button",
|
|
22434
|
+
{
|
|
22435
|
+
onClick: markAllAsRead,
|
|
22436
|
+
className: "p-2 hover:bg-gray-100 rounded-lg transition-colors",
|
|
22437
|
+
title: "Mark all as read",
|
|
22438
|
+
children: /* @__PURE__ */ jsx(CheckCheck, { className: "w-5 h-5 text-gray-600" })
|
|
22439
|
+
}
|
|
22440
|
+
),
|
|
22441
|
+
/* @__PURE__ */ jsx(
|
|
22442
|
+
"button",
|
|
22443
|
+
{
|
|
22444
|
+
onClick: handleSettingsClick,
|
|
22445
|
+
className: "p-2 hover:bg-gray-100 rounded-lg transition-colors",
|
|
22446
|
+
title: "Notification settings",
|
|
22447
|
+
children: /* @__PURE__ */ jsx(Settings, { className: "w-5 h-5 text-gray-600" })
|
|
22448
|
+
}
|
|
22449
|
+
),
|
|
22450
|
+
/* @__PURE__ */ jsx(
|
|
22451
|
+
"button",
|
|
22452
|
+
{
|
|
22453
|
+
onClick: closeDrawer,
|
|
22454
|
+
className: "p-2 hover:bg-gray-100 rounded-lg transition-colors",
|
|
22455
|
+
"aria-label": "Close",
|
|
22456
|
+
children: /* @__PURE__ */ jsx(X, { className: "w-5 h-5 text-gray-600" })
|
|
22457
|
+
}
|
|
22458
|
+
)
|
|
22459
|
+
] })
|
|
22460
|
+
] }),
|
|
22461
|
+
/* @__PURE__ */ jsx(
|
|
22462
|
+
"div",
|
|
22463
|
+
{
|
|
22464
|
+
ref: scrollContainerRef,
|
|
22465
|
+
onScroll: handleScroll,
|
|
22466
|
+
className: "flex-1 overflow-y-auto p-4 space-y-3",
|
|
22467
|
+
children: notifications.length === 0 && !isLoading ? (
|
|
22468
|
+
// Empty state
|
|
22469
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center justify-center h-full text-center py-12", children: [
|
|
22470
|
+
/* @__PURE__ */ jsx("div", { className: "w-20 h-20 bg-gray-100 rounded-full flex items-center justify-center mb-4", children: /* @__PURE__ */ jsx(BellOff, { className: "w-10 h-10 text-gray-400" }) }),
|
|
22471
|
+
/* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold text-gray-900 mb-2", children: "No notifications yet" }),
|
|
22472
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500 max-w-xs", children: "When you receive notifications, they'll appear here" })
|
|
22473
|
+
] })
|
|
22474
|
+
) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
22475
|
+
notifications.map((notification) => /* @__PURE__ */ jsx(
|
|
22476
|
+
NotificationCard,
|
|
22477
|
+
{
|
|
22478
|
+
notification,
|
|
22479
|
+
onMarkAsRead: markAsRead,
|
|
22480
|
+
onDelete: deleteNotification
|
|
22481
|
+
},
|
|
22482
|
+
notification._id
|
|
22483
|
+
)),
|
|
22484
|
+
isLoading && /* @__PURE__ */ jsx("div", { className: "flex justify-center py-4", children: /* @__PURE__ */ jsx("div", { className: "w-6 h-6 border-2 border-primary-600 border-t-transparent rounded-full animate-spin" }) }),
|
|
22485
|
+
!hasMore && notifications.length > 0 && /* @__PURE__ */ jsx("div", { className: "text-center py-4 text-sm text-gray-500", children: "You're all caught up! \u{1F389}" })
|
|
22486
|
+
] })
|
|
22487
|
+
}
|
|
22488
|
+
)
|
|
22489
|
+
]
|
|
22490
|
+
}
|
|
22491
|
+
)
|
|
22492
|
+
] }) });
|
|
22493
|
+
}
|
|
22290
22494
|
|
|
22291
22495
|
export { AccountReviewsTab, AddressAddressTypeEnum, AddressCreatedRequestAddressTypeEnum, AddressesScreen, ApiKeyInfoDtoKeyTypeEnum, AuthProvider, Badge, BulkChannelToggleDtoCategoryEnum, Button, CampaignDraftDtoStatusEnum, CampaignDraftScheduleDtoStatusEnum, CampaignDraftSendingDtoStatusEnum, CartItem, CartProvider, CartScreen, ChangePasswordScreen, CheckoutScreen, CreateAddressDtoAddressTypeEnum, CreateDiscountDtoStateEnum, CreateDiscountDtoTypeEnum, CreateDiscountDtoValueTypeEnum, CreateStoreAddressDtoAddressTypeEnum, CreateUserDtoCustomerTypeEnum, CreateUserDtoRoleEnum, CurrentOrdersScreen, DiscountStateEnum, DiscountTypeEnum, DiscountValueTypeEnum, EcommerceProvider, EditProfileScreen, EmptyState, Footer, ForgotPasswordScreen, Header, Input, LoginScreen, ManualDiscountDtoValueTypeEnum, ManualOrderDTOOrderStatusEnum, ManualOrderDTOPaymentMethodEnum, ManualOrderDTOPaymentStatusEnum, Modal, NewAddressPage as NewAddressScreen, NotificationBell, NotificationCard, NotificationCenterProvider, NotificationDrawer, NotificationSettingsScreen, OrderCard, OrderCardSkeleton, OrderDetailScreen, OrderOrderTypeEnum, OrderReviewsScreen, OrderTimeLineDTOTypeEnum, OrderTypeEnum, OrdersScreen, PaymentPaymentMethodEnum, PaymentPaymentStatusEnum, PaymentTimeLineDTOTitleEnum, PopulatedDiscountStateEnum, PopulatedDiscountTypeEnum, PopulatedDiscountValueTypeEnum, PopulatedOrderOrderTypeEnum, PopulatedOrderTypeEnum, PreferenceUpdateItemTypeEnum, ProductCard, ProductCardSkeleton, ProductDetailScreen, ProductReviewsSection, ProductVariantInventoryStatusEnum, AccountPage as ProfileScreen, RatingDistribution, RegisterScreen, ReorderProductsDtoContainerTypeEnum, ResetPasswordScreen, ReviewCard, ReviewForm, ReviewPromptBanner, ReviewsList, SearchPage as SearchResultsScreen, ShipmentDetailsDtoStatusEnum, ShippingInfoStatusEnum, ShopScreen, SingleProductMediaTypeEnum, Skeleton, StarRating, ThemeProvider, UpdateAddressDtoAddressTypeEnum, UpdateDiscountDtoStateEnum, UpdateDiscountDtoTypeEnum, UpdateDiscountDtoValueTypeEnum, UpdateManualShipmentStatusDtoStatusEnum, UpdateUserDtoCustomerTypeEnum, UpdateUserDtoRoleEnum, UserEntityCustomerTypeEnum, UserEntityRoleEnum, UserWithNoIdCustomerTypeEnum, UserWithNoIdRoleEnum, WishlistProvider, WishlistScreen, formatDate, formatPrice, generateColorShades, getApiConfiguration, getInitials, hexToRgb, initializeApiAdapter, truncate, useAddresses, useAuth, useBasePath, useCart, useCategories, useCreateReview, useCurrentOrders, useDeleteReview, useNotificationCenter, useOrder, useOrders, useProduct, useProductReviews, useProducts, useReviewStats, useReviewsByRating, useStoreCapabilities, useTheme, useUpdateReview, useUserReviews, useWishlist };
|
|
22292
22496
|
//# sourceMappingURL=index.mjs.map
|