hey-pharmacist-ecommerce 1.1.13 → 1.1.15
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.d.mts +2 -4
- package/dist/index.d.ts +2 -4
- package/dist/index.js +1039 -857
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1039 -856
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/src/components/AccountAddressesTab.tsx +209 -0
- package/src/components/AccountOrdersTab.tsx +151 -0
- package/src/components/AccountOverviewTab.tsx +209 -0
- package/src/components/AccountPaymentTab.tsx +116 -0
- package/src/components/AccountSavedItemsTab.tsx +76 -0
- package/src/components/AccountSettingsTab.tsx +116 -0
- package/src/components/AddressFormModal.tsx +23 -10
- package/src/components/CartItem.tsx +60 -56
- package/src/components/Header.tsx +69 -16
- package/src/components/Notification.tsx +148 -0
- package/src/components/ProductCard.tsx +215 -178
- package/src/components/QuickViewModal.tsx +314 -0
- package/src/components/TabNavigation.tsx +48 -0
- package/src/components/ui/Button.tsx +1 -1
- package/src/components/ui/ConfirmModal.tsx +84 -0
- package/src/hooks/usePaymentMethods.ts +58 -0
- package/src/index.ts +0 -1
- package/src/providers/CartProvider.tsx +22 -6
- package/src/providers/EcommerceProvider.tsx +8 -7
- package/src/providers/FavoritesProvider.tsx +10 -3
- package/src/providers/NotificationProvider.tsx +79 -0
- package/src/providers/WishlistProvider.tsx +34 -9
- package/src/screens/AddressesScreen.tsx +72 -61
- package/src/screens/CartScreen.tsx +48 -32
- package/src/screens/ChangePasswordScreen.tsx +155 -0
- package/src/screens/CheckoutScreen.tsx +162 -125
- package/src/screens/EditProfileScreen.tsx +165 -0
- package/src/screens/LoginScreen.tsx +59 -72
- package/src/screens/NewAddressScreen.tsx +16 -10
- package/src/screens/ProductDetailScreen.tsx +334 -234
- package/src/screens/ProfileScreen.tsx +190 -200
- package/src/screens/RegisterScreen.tsx +51 -70
- package/src/screens/SearchResultsScreen.tsx +2 -1
- package/src/screens/ShopScreen.tsx +260 -384
- package/src/screens/WishlistScreen.tsx +226 -224
- package/src/styles/globals.css +9 -0
- package/src/screens/CategoriesScreen.tsx +0 -122
- package/src/screens/HomeScreen.tsx +0 -211
package/dist/index.mjs
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import React21, { createContext, forwardRef, useContext, useEffect, useState, useCallback, useMemo, useRef } from 'react';
|
|
3
3
|
import globalAxios4 from 'axios';
|
|
4
|
-
import { Toaster, toast } from 'sonner';
|
|
5
|
-
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
6
4
|
import { motion, AnimatePresence } from 'framer-motion';
|
|
7
|
-
import {
|
|
8
|
-
import
|
|
5
|
+
import { Eye, Star, ShoppingCart, Sparkles, ShieldCheck, TrendingUp, Search, ArrowUpDown, ChevronDown, LayoutGrid, LayoutList, X, Clock, Package, ChevronLeft, Check, Heart, Truck, RotateCcw, Shield, Trash2, Minus, Plus, ShoppingBag, ArrowRight, CheckCircle2, Edit3, MapPin, CreditCard, Lock, EyeOff, UserPlus, LogOut, HeartPulse, Mail, Phone, User, Filter, ChevronRight, ArrowUpRight, PackageCheck, Warehouse, BellRing, Crown, Grid, List, ArrowLeft, Menu, Facebook, Twitter, Instagram, Shirt, Pill, Box, ExternalLink, Globe, Home, Info, AlertCircle, XCircle } from 'lucide-react';
|
|
6
|
+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
9
7
|
import { useRouter, useSearchParams } from 'next/navigation';
|
|
8
|
+
import Image4 from 'next/image';
|
|
10
9
|
import dynamic from 'next/dynamic';
|
|
11
|
-
import
|
|
10
|
+
import Link7 from 'next/link';
|
|
12
11
|
import { useForm } from 'react-hook-form';
|
|
13
12
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
14
13
|
import { z } from 'zod';
|
|
@@ -6757,6 +6756,144 @@ var PaymentPaymentStatusEnum = /* @__PURE__ */ ((PaymentPaymentStatusEnum2) => {
|
|
|
6757
6756
|
|
|
6758
6757
|
// src/lib/api-adapter/index.ts
|
|
6759
6758
|
init_config();
|
|
6759
|
+
var notificationConfig = {
|
|
6760
|
+
success: {
|
|
6761
|
+
icon: CheckCircle2,
|
|
6762
|
+
gradient: "from-emerald-500 to-green-600",
|
|
6763
|
+
iconColor: "text-emerald-600",
|
|
6764
|
+
bgColor: "bg-emerald-50",
|
|
6765
|
+
borderColor: "border-emerald-200"
|
|
6766
|
+
},
|
|
6767
|
+
error: {
|
|
6768
|
+
icon: XCircle,
|
|
6769
|
+
gradient: "from-red-500 to-rose-600",
|
|
6770
|
+
iconColor: "text-red-600",
|
|
6771
|
+
bgColor: "bg-red-50",
|
|
6772
|
+
borderColor: "border-red-200"
|
|
6773
|
+
},
|
|
6774
|
+
warning: {
|
|
6775
|
+
icon: AlertCircle,
|
|
6776
|
+
gradient: "from-orange-500 to-amber-600",
|
|
6777
|
+
iconColor: "text-orange-600",
|
|
6778
|
+
bgColor: "bg-orange-50",
|
|
6779
|
+
borderColor: "border-orange-200"
|
|
6780
|
+
},
|
|
6781
|
+
info: {
|
|
6782
|
+
icon: Info,
|
|
6783
|
+
gradient: "from-blue-500 to-indigo-600",
|
|
6784
|
+
iconColor: "text-blue-600",
|
|
6785
|
+
bgColor: "bg-blue-50",
|
|
6786
|
+
borderColor: "border-blue-200"
|
|
6787
|
+
}
|
|
6788
|
+
};
|
|
6789
|
+
function Notification({ notification, onDismiss }) {
|
|
6790
|
+
const [progress, setProgress] = useState(100);
|
|
6791
|
+
const config = notificationConfig[notification.type];
|
|
6792
|
+
const Icon = config.icon;
|
|
6793
|
+
const duration = notification.duration || 4e3;
|
|
6794
|
+
useEffect(() => {
|
|
6795
|
+
const startTime = Date.now();
|
|
6796
|
+
const timer = setInterval(() => {
|
|
6797
|
+
const elapsed = Date.now() - startTime;
|
|
6798
|
+
const remaining = Math.max(0, 100 - elapsed / duration * 100);
|
|
6799
|
+
setProgress(remaining);
|
|
6800
|
+
if (remaining === 0) {
|
|
6801
|
+
clearInterval(timer);
|
|
6802
|
+
onDismiss(notification.id);
|
|
6803
|
+
}
|
|
6804
|
+
}, 16);
|
|
6805
|
+
return () => clearInterval(timer);
|
|
6806
|
+
}, [notification.id, duration, onDismiss]);
|
|
6807
|
+
return /* @__PURE__ */ React21.createElement(
|
|
6808
|
+
motion.div,
|
|
6809
|
+
{
|
|
6810
|
+
initial: { opacity: 0, y: -20, scale: 0.95 },
|
|
6811
|
+
animate: { opacity: 1, y: 0, scale: 1 },
|
|
6812
|
+
exit: { opacity: 0, x: 100, scale: 0.95 },
|
|
6813
|
+
transition: { type: "spring", stiffness: 500, damping: 30 },
|
|
6814
|
+
className: `relative bg-white rounded-2xl border-2 ${config.borderColor} shadow-xl overflow-hidden min-w-[320px] max-w-[420px]`
|
|
6815
|
+
},
|
|
6816
|
+
/* @__PURE__ */ React21.createElement("div", { className: `h-1 bg-gradient-to-r ${config.gradient}` }),
|
|
6817
|
+
/* @__PURE__ */ React21.createElement("div", { className: "p-4 flex items-start gap-3" }, /* @__PURE__ */ React21.createElement(
|
|
6818
|
+
motion.div,
|
|
6819
|
+
{
|
|
6820
|
+
initial: { scale: 0, rotate: -180 },
|
|
6821
|
+
animate: { scale: 1, rotate: 0 },
|
|
6822
|
+
transition: { delay: 0.1, type: "spring", stiffness: 500 },
|
|
6823
|
+
className: `size-10 rounded-full ${config.bgColor} flex items-center justify-center shrink-0`
|
|
6824
|
+
},
|
|
6825
|
+
/* @__PURE__ */ React21.createElement(Icon, { className: `size-5 ${config.iconColor}` })
|
|
6826
|
+
), /* @__PURE__ */ React21.createElement("div", { className: "flex-1 min-w-0" }, /* @__PURE__ */ React21.createElement("p", { className: "font-['Poppins',sans-serif] font-semibold text-[14px] text-[#2B4B7C] mb-1" }, notification.message), notification.description && /* @__PURE__ */ React21.createElement("p", { className: "font-['Poppins',sans-serif] text-[12px] text-[#676c80] leading-relaxed" }, notification.description)), /* @__PURE__ */ React21.createElement(
|
|
6827
|
+
"button",
|
|
6828
|
+
{
|
|
6829
|
+
onClick: () => onDismiss(notification.id),
|
|
6830
|
+
className: "p-1.5 hover:bg-gray-100 rounded-full transition-colors shrink-0",
|
|
6831
|
+
"aria-label": "Dismiss notification"
|
|
6832
|
+
},
|
|
6833
|
+
/* @__PURE__ */ React21.createElement(X, { className: "size-4 text-[#676c80]" })
|
|
6834
|
+
)),
|
|
6835
|
+
/* @__PURE__ */ React21.createElement("div", { className: "h-1 bg-gray-100" }, /* @__PURE__ */ React21.createElement(
|
|
6836
|
+
motion.div,
|
|
6837
|
+
{
|
|
6838
|
+
className: `h-full bg-gradient-to-r ${config.gradient}`,
|
|
6839
|
+
style: { width: `${progress}%` },
|
|
6840
|
+
transition: { duration: 0.016, ease: "linear" }
|
|
6841
|
+
}
|
|
6842
|
+
))
|
|
6843
|
+
);
|
|
6844
|
+
}
|
|
6845
|
+
function NotificationContainer({ notifications, onDismiss }) {
|
|
6846
|
+
return /* @__PURE__ */ React21.createElement("div", { className: "fixed top-4 right-4 z-[9999] flex flex-col gap-3 pointer-events-none" }, /* @__PURE__ */ React21.createElement(AnimatePresence, { mode: "popLayout" }, notifications.map((notification) => /* @__PURE__ */ React21.createElement("div", { key: notification.id, className: "pointer-events-auto" }, /* @__PURE__ */ React21.createElement(Notification, { notification, onDismiss })))));
|
|
6847
|
+
}
|
|
6848
|
+
|
|
6849
|
+
// src/providers/NotificationProvider.tsx
|
|
6850
|
+
var NotificationContext = createContext(void 0);
|
|
6851
|
+
function useNotification() {
|
|
6852
|
+
const context = useContext(NotificationContext);
|
|
6853
|
+
if (!context) {
|
|
6854
|
+
throw new Error("useNotification must be used within NotificationProvider");
|
|
6855
|
+
}
|
|
6856
|
+
return context;
|
|
6857
|
+
}
|
|
6858
|
+
function NotificationProvider({ children }) {
|
|
6859
|
+
const [notifications, setNotifications] = useState([]);
|
|
6860
|
+
const addNotification = useCallback(
|
|
6861
|
+
(type, message, description, duration) => {
|
|
6862
|
+
const id = Math.random().toString(36).substring(2, 9);
|
|
6863
|
+
const notification = {
|
|
6864
|
+
id,
|
|
6865
|
+
type,
|
|
6866
|
+
message,
|
|
6867
|
+
description,
|
|
6868
|
+
duration: duration || 4e3
|
|
6869
|
+
};
|
|
6870
|
+
setNotifications((prev) => [...prev, notification]);
|
|
6871
|
+
},
|
|
6872
|
+
[]
|
|
6873
|
+
);
|
|
6874
|
+
const dismissNotification = useCallback((id) => {
|
|
6875
|
+
setNotifications((prev) => prev.filter((n) => n.id !== id));
|
|
6876
|
+
}, []);
|
|
6877
|
+
const value = {
|
|
6878
|
+
success: useCallback(
|
|
6879
|
+
(message, description, duration) => addNotification("success", message, description, duration),
|
|
6880
|
+
[addNotification]
|
|
6881
|
+
),
|
|
6882
|
+
error: useCallback(
|
|
6883
|
+
(message, description, duration) => addNotification("error", message, description, duration),
|
|
6884
|
+
[addNotification]
|
|
6885
|
+
),
|
|
6886
|
+
warning: useCallback(
|
|
6887
|
+
(message, description, duration) => addNotification("warning", message, description, duration),
|
|
6888
|
+
[addNotification]
|
|
6889
|
+
),
|
|
6890
|
+
info: useCallback(
|
|
6891
|
+
(message, description, duration) => addNotification("info", message, description, duration),
|
|
6892
|
+
[addNotification]
|
|
6893
|
+
)
|
|
6894
|
+
};
|
|
6895
|
+
return /* @__PURE__ */ React21.createElement(NotificationContext.Provider, { value }, children, /* @__PURE__ */ React21.createElement(NotificationContainer, { notifications, onDismiss: dismissNotification }));
|
|
6896
|
+
}
|
|
6760
6897
|
|
|
6761
6898
|
// src/providers/CartProvider.tsx
|
|
6762
6899
|
var CartContext = createContext(void 0);
|
|
@@ -6771,6 +6908,7 @@ function CartProvider({ children }) {
|
|
|
6771
6908
|
const [cart, setCart] = useState(null);
|
|
6772
6909
|
const [isLoading, setIsLoading] = useState(false);
|
|
6773
6910
|
const { isAuthenticated } = useAuth();
|
|
6911
|
+
const notification = useNotification();
|
|
6774
6912
|
const refreshCart = useCallback(async () => {
|
|
6775
6913
|
if (!isAuthenticated) {
|
|
6776
6914
|
setCart(null);
|
|
@@ -6808,9 +6946,15 @@ function CartProvider({ children }) {
|
|
|
6808
6946
|
}
|
|
6809
6947
|
const response = await new CartApi(getApiConfiguration()).handleUserCart({ items });
|
|
6810
6948
|
setCart(response.data);
|
|
6811
|
-
|
|
6949
|
+
notification.success(
|
|
6950
|
+
"Added to cart",
|
|
6951
|
+
"The item was added to your cart."
|
|
6952
|
+
);
|
|
6812
6953
|
} catch (error) {
|
|
6813
|
-
|
|
6954
|
+
notification.error(
|
|
6955
|
+
"Could not add to cart",
|
|
6956
|
+
error.response?.data?.message || "Something went wrong while adding this item to your cart."
|
|
6957
|
+
);
|
|
6814
6958
|
throw error;
|
|
6815
6959
|
} finally {
|
|
6816
6960
|
setIsLoading(false);
|
|
@@ -6832,7 +6976,10 @@ function CartProvider({ children }) {
|
|
|
6832
6976
|
const response = await new CartApi(getApiConfiguration()).handleUserCart({ items });
|
|
6833
6977
|
setCart(response.data);
|
|
6834
6978
|
} catch (error) {
|
|
6835
|
-
|
|
6979
|
+
notification.error(
|
|
6980
|
+
"Could not update cart",
|
|
6981
|
+
error.response?.data?.message || "There was a problem updating the item quantity. Please try again."
|
|
6982
|
+
);
|
|
6836
6983
|
throw error;
|
|
6837
6984
|
} finally {
|
|
6838
6985
|
setIsLoading(false);
|
|
@@ -6846,7 +6993,10 @@ function CartProvider({ children }) {
|
|
|
6846
6993
|
const response = await new CartApi(getApiConfiguration()).handleUserCart({ items });
|
|
6847
6994
|
setCart(response.data);
|
|
6848
6995
|
} catch (error) {
|
|
6849
|
-
|
|
6996
|
+
notification.error(
|
|
6997
|
+
"Could not remove item",
|
|
6998
|
+
error.response?.data?.message || "There was a problem removing this item from your cart."
|
|
6999
|
+
);
|
|
6850
7000
|
throw error;
|
|
6851
7001
|
} finally {
|
|
6852
7002
|
setIsLoading(false);
|
|
@@ -6858,7 +7008,10 @@ function CartProvider({ children }) {
|
|
|
6858
7008
|
const response = await new CartApi(getApiConfiguration()).clearCart();
|
|
6859
7009
|
setCart(null);
|
|
6860
7010
|
} catch (error) {
|
|
6861
|
-
|
|
7011
|
+
notification.error(
|
|
7012
|
+
"Could not clear cart",
|
|
7013
|
+
error.response?.data?.message || "We could not clear your cart. Please try again."
|
|
7014
|
+
);
|
|
6862
7015
|
throw error;
|
|
6863
7016
|
} finally {
|
|
6864
7017
|
setIsLoading(false);
|
|
@@ -6924,6 +7077,7 @@ function WishlistProvider({ children }) {
|
|
|
6924
7077
|
products: []
|
|
6925
7078
|
});
|
|
6926
7079
|
const { isAuthenticated } = useAuth() || {};
|
|
7080
|
+
const notification = useNotification();
|
|
6927
7081
|
const wishlistApi = useMemo(() => new WishlistApi(AXIOS_CONFIG), []);
|
|
6928
7082
|
const fetchWishlist = useCallback(async () => {
|
|
6929
7083
|
if (!isAuthenticated) {
|
|
@@ -6959,20 +7113,32 @@ function WishlistProvider({ children }) {
|
|
|
6959
7113
|
}, [fetchWishlist]);
|
|
6960
7114
|
const addToWishlist = async (product) => {
|
|
6961
7115
|
if (!isAuthenticated) {
|
|
6962
|
-
|
|
7116
|
+
notification.error(
|
|
7117
|
+
"Sign-in required",
|
|
7118
|
+
"Please sign in to add items to your wishlist."
|
|
7119
|
+
);
|
|
6963
7120
|
return;
|
|
6964
7121
|
}
|
|
6965
7122
|
try {
|
|
6966
7123
|
if (isInWishlist(product?._id || "")) {
|
|
6967
|
-
|
|
7124
|
+
notification.info(
|
|
7125
|
+
"Already saved",
|
|
7126
|
+
"This item is already in your wishlist."
|
|
7127
|
+
);
|
|
6968
7128
|
return;
|
|
6969
7129
|
}
|
|
6970
7130
|
await wishlistApi.addToWishlist(product?._id || "");
|
|
6971
7131
|
await fetchWishlist();
|
|
6972
|
-
|
|
7132
|
+
notification.success(
|
|
7133
|
+
"Added to wishlist",
|
|
7134
|
+
`${product?.name || "Item"} was added to your wishlist.`
|
|
7135
|
+
);
|
|
6973
7136
|
} catch (error) {
|
|
6974
7137
|
console.error("Error adding to wishlist:", error);
|
|
6975
|
-
|
|
7138
|
+
notification.error(
|
|
7139
|
+
"Could not add to wishlist",
|
|
7140
|
+
"Something went wrong while adding this item. Please try again."
|
|
7141
|
+
);
|
|
6976
7142
|
throw error;
|
|
6977
7143
|
}
|
|
6978
7144
|
};
|
|
@@ -6986,10 +7152,16 @@ function WishlistProvider({ children }) {
|
|
|
6986
7152
|
products: newProducts
|
|
6987
7153
|
};
|
|
6988
7154
|
});
|
|
6989
|
-
|
|
7155
|
+
notification.success(
|
|
7156
|
+
"Removed from wishlist",
|
|
7157
|
+
"The item has been removed from your wishlist."
|
|
7158
|
+
);
|
|
6990
7159
|
} catch (error) {
|
|
6991
7160
|
console.error("Error removing from wishlist:", error);
|
|
6992
|
-
|
|
7161
|
+
notification.error(
|
|
7162
|
+
"Could not remove item",
|
|
7163
|
+
"Something went wrong while removing this item. Please try again."
|
|
7164
|
+
);
|
|
6993
7165
|
throw error;
|
|
6994
7166
|
}
|
|
6995
7167
|
};
|
|
@@ -7000,10 +7172,16 @@ function WishlistProvider({ children }) {
|
|
|
7000
7172
|
...prev,
|
|
7001
7173
|
products: []
|
|
7002
7174
|
}));
|
|
7003
|
-
|
|
7175
|
+
notification.success(
|
|
7176
|
+
"Wishlist cleared",
|
|
7177
|
+
"All items have been removed from your wishlist."
|
|
7178
|
+
);
|
|
7004
7179
|
} catch (error) {
|
|
7005
7180
|
console.error("Error clearing wishlist:", error);
|
|
7006
|
-
|
|
7181
|
+
notification.error(
|
|
7182
|
+
"Could not clear wishlist",
|
|
7183
|
+
"We could not clear your wishlist. Please try again."
|
|
7184
|
+
);
|
|
7007
7185
|
throw error;
|
|
7008
7186
|
}
|
|
7009
7187
|
};
|
|
@@ -7063,7 +7241,7 @@ function EcommerceProvider({ config, children, withToaster = true, basePath = ""
|
|
|
7063
7241
|
const [client] = React21.useState(
|
|
7064
7242
|
new QueryClient({ defaultOptions: { queries: { staleTime: 5e3 } } })
|
|
7065
7243
|
);
|
|
7066
|
-
return /* @__PURE__ */ React21.createElement(QueryClientProvider, { client }, /* @__PURE__ */ React21.createElement(ThemeProvider, { config }, /* @__PURE__ */ React21.createElement(BasePathProvider, { basePath }, /* @__PURE__ */ React21.createElement(AuthProvider, null, /* @__PURE__ */ React21.createElement(
|
|
7244
|
+
return /* @__PURE__ */ React21.createElement(QueryClientProvider, { client }, /* @__PURE__ */ React21.createElement(ThemeProvider, { config }, /* @__PURE__ */ React21.createElement(BasePathProvider, { basePath }, /* @__PURE__ */ React21.createElement(AuthProvider, null, /* @__PURE__ */ React21.createElement(NotificationProvider, null, /* @__PURE__ */ React21.createElement(CartProvider, null, /* @__PURE__ */ React21.createElement(WishlistProvider, null, children)))))));
|
|
7067
7245
|
}
|
|
7068
7246
|
|
|
7069
7247
|
// src/lib/utils/format.ts
|
|
@@ -7097,6 +7275,158 @@ function truncate(text, maxLength) {
|
|
|
7097
7275
|
function getInitials(firstName, lastName) {
|
|
7098
7276
|
return `${firstName?.charAt(0)}${lastName?.charAt(0)}`.toUpperCase();
|
|
7099
7277
|
}
|
|
7278
|
+
function QuickViewModal({ product, onClose, onNavigateToProduct }) {
|
|
7279
|
+
const [selectedVariantIndex, setSelectedVariantIndex] = useState(0);
|
|
7280
|
+
const [selectedSizeIndex, setSelectedSizeIndex] = useState(0);
|
|
7281
|
+
const [selectedImageIndex, setSelectedImageIndex] = useState(0);
|
|
7282
|
+
const [addedToCart, setAddedToCart] = useState(false);
|
|
7283
|
+
const [quantity, setQuantity] = useState(1);
|
|
7284
|
+
const { addToCart } = useCart();
|
|
7285
|
+
const [isAddingToCart, setIsAddingToCart] = useState(false);
|
|
7286
|
+
const notification = useNotification();
|
|
7287
|
+
const handleQuantityChange = (newQuantity) => {
|
|
7288
|
+
if (newQuantity >= 1 && newQuantity <= (selectedVariant.inventoryCount || 10)) {
|
|
7289
|
+
setQuantity(newQuantity);
|
|
7290
|
+
}
|
|
7291
|
+
};
|
|
7292
|
+
const selectedVariant = product.productVariants[selectedVariantIndex];
|
|
7293
|
+
selectedVariant.productMedia[selectedSizeIndex];
|
|
7294
|
+
const displayPrice = product.finalPrice;
|
|
7295
|
+
const handleAddToCart = async () => {
|
|
7296
|
+
if (!product || !selectedVariant) return;
|
|
7297
|
+
setIsAddingToCart(true);
|
|
7298
|
+
try {
|
|
7299
|
+
console.log(selectedVariant);
|
|
7300
|
+
await addToCart(
|
|
7301
|
+
product.id,
|
|
7302
|
+
quantity,
|
|
7303
|
+
selectedVariant._id
|
|
7304
|
+
);
|
|
7305
|
+
notification.success(
|
|
7306
|
+
"Added to cart",
|
|
7307
|
+
`${quantity} \xD7 ${product.name}${selectedVariant.name ? ` (${selectedVariant.name})` : ""} added to your cart.`
|
|
7308
|
+
);
|
|
7309
|
+
} catch (error) {
|
|
7310
|
+
console.error("Failed to add to cart", error);
|
|
7311
|
+
notification.error(
|
|
7312
|
+
"Could not add to cart",
|
|
7313
|
+
"Something went wrong while adding this item. Please try again."
|
|
7314
|
+
);
|
|
7315
|
+
} finally {
|
|
7316
|
+
setIsAddingToCart(false);
|
|
7317
|
+
}
|
|
7318
|
+
};
|
|
7319
|
+
return /* @__PURE__ */ React.createElement(
|
|
7320
|
+
"div",
|
|
7321
|
+
{
|
|
7322
|
+
className: "fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm",
|
|
7323
|
+
onClick: onClose
|
|
7324
|
+
},
|
|
7325
|
+
/* @__PURE__ */ React.createElement(
|
|
7326
|
+
"div",
|
|
7327
|
+
{
|
|
7328
|
+
className: "bg-white rounded-[32px] max-w-5xl w-full max-h-[90vh] overflow-y-auto",
|
|
7329
|
+
onClick: (e) => e.stopPropagation()
|
|
7330
|
+
},
|
|
7331
|
+
/* @__PURE__ */ React.createElement("div", { className: "p-8" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-start justify-between mb-6" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { className: "font-['Poppins',sans-serif] text-[11px] text-primary uppercase tracking-wide font-medium mb-2" }, product.brand, " \u2022 ", product.parentCategories[0].name), /* @__PURE__ */ React.createElement("h2", { className: "font-['Poppins',sans-serif] font-semibold text-secondary tracking-[-1px]" }, product.name), /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-2 mt-2" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-0.5" }, [...Array(5)].map((_, i) => /* @__PURE__ */ React.createElement(
|
|
7332
|
+
Star,
|
|
7333
|
+
{
|
|
7334
|
+
key: i,
|
|
7335
|
+
className: `size-4 ${i < Math.floor(product.rating ? product.rating : 0) ? "text-accent fill-accent" : "text-gray-300"}`
|
|
7336
|
+
}
|
|
7337
|
+
))), /* @__PURE__ */ React.createElement("span", { className: "font-['Poppins',sans-serif] text-[13px] text-muted" }, product.rating, " (", product.reviews ? product.reviews.length : 0, " reviews)"))), /* @__PURE__ */ React.createElement(
|
|
7338
|
+
"button",
|
|
7339
|
+
{
|
|
7340
|
+
onClick: onClose,
|
|
7341
|
+
className: "p-2 hover:bg-gray-100 rounded-full transition-colors"
|
|
7342
|
+
},
|
|
7343
|
+
/* @__PURE__ */ React.createElement(X, { className: "size-6 text-muted" })
|
|
7344
|
+
)), /* @__PURE__ */ React.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-8" }, /* @__PURE__ */ React.createElement("div", { className: "space-y-4" }, /* @__PURE__ */ React.createElement("div", { className: "relative aspect-[3/4] rounded-[24px] overflow-hidden bg-gray-50" }, /* @__PURE__ */ React.createElement(
|
|
7345
|
+
"img",
|
|
7346
|
+
{
|
|
7347
|
+
src: selectedVariant.productMedia[selectedImageIndex]?.file || selectedVariant.productMedia[0]?.file,
|
|
7348
|
+
alt: product.name,
|
|
7349
|
+
className: "w-full h-full object-cover"
|
|
7350
|
+
}
|
|
7351
|
+
), /* @__PURE__ */ React.createElement("div", { className: "absolute top-4 left-4 flex flex-col gap-2" }, product.finalPrice && /* @__PURE__ */ React.createElement("div", { className: "bg-accent text-white rounded-full px-3 py-1.5" }, /* @__PURE__ */ React.createElement("span", { className: "font-['Poppins',sans-serif] font-bold text-[11px] uppercase" }, "-", product.discountAmount, "%")))), selectedVariant.productMedia.length > 1 && /* @__PURE__ */ React.createElement("div", { className: "grid grid-cols-4 gap-3" }, selectedVariant.productMedia.map((image, index) => /* @__PURE__ */ React.createElement(
|
|
7352
|
+
"div",
|
|
7353
|
+
{
|
|
7354
|
+
key: index,
|
|
7355
|
+
className: `aspect-square rounded-xl overflow-hidden cursor-pointer transition-opacity ${selectedImageIndex === index ? "ring-2 ring-primary" : "bg-gray-50 hover:opacity-75"}`,
|
|
7356
|
+
onClick: () => setSelectedImageIndex(index)
|
|
7357
|
+
},
|
|
7358
|
+
/* @__PURE__ */ React.createElement(
|
|
7359
|
+
"img",
|
|
7360
|
+
{
|
|
7361
|
+
src: image.file,
|
|
7362
|
+
alt: `${product.name} ${index + 1}`,
|
|
7363
|
+
className: "w-full h-full object-cover"
|
|
7364
|
+
}
|
|
7365
|
+
)
|
|
7366
|
+
)))), /* @__PURE__ */ React.createElement("div", { className: "flex flex-col" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-3 mb-4" }, /* @__PURE__ */ React.createElement("span", { className: "font-['Poppins',sans-serif] font-bold text-[32px] text-accent" }, "$", displayPrice.toFixed(2)), product.isDiscounted && /* @__PURE__ */ React.createElement("span", { className: "font-['Poppins',sans-serif] text-[20px] text-muted line-through" }, "$", product.finalPrice.toFixed(2))), /* @__PURE__ */ React.createElement("div", { className: "mb-6" }, selectedVariant.inventoryCount === 0 ? /* @__PURE__ */ React.createElement("span", { className: "font-['Poppins',sans-serif] text-[12px] text-red-500 font-medium" }, "Out of Stock") : selectedVariant.inventoryCount <= 10 ? /* @__PURE__ */ React.createElement("span", { className: "font-['Poppins',sans-serif] text-[12px] text-orange-500 font-medium flex items-center gap-1" }, /* @__PURE__ */ React.createElement(Package, { className: "size-3" }), "Only ", selectedVariant.inventoryCount, " left in stock") : /* @__PURE__ */ React.createElement("span", { className: "font-['Poppins',sans-serif] text-[12px] text-green-600 font-medium flex items-center gap-1" }, /* @__PURE__ */ React.createElement(Package, { className: "size-3" }), "In Stock")), /* @__PURE__ */ React.createElement("p", { className: "font-['Poppins',sans-serif] text-[14px] text-muted leading-[1.7] mb-6" }, /* @__PURE__ */ React.createElement("div", { dangerouslySetInnerHTML: { __html: product.description } })), /* @__PURE__ */ React.createElement("div", { className: "mb-6" }, /* @__PURE__ */ React.createElement("h3", { className: "font-['Poppins',sans-serif] font-semibold text-[13px] text-secondary mb-3" }, "Selected Variant: ", /* @__PURE__ */ React.createElement("span", { className: "font-normal text-muted" }, product.productVariants[selectedVariantIndex].name)), /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap gap-3" }, product.productVariants.map((variant, index) => /* @__PURE__ */ React.createElement(
|
|
7367
|
+
"button",
|
|
7368
|
+
{
|
|
7369
|
+
key: variant.id,
|
|
7370
|
+
onClick: () => {
|
|
7371
|
+
setSelectedVariantIndex(index);
|
|
7372
|
+
setSelectedSizeIndex(0);
|
|
7373
|
+
setSelectedImageIndex(0);
|
|
7374
|
+
},
|
|
7375
|
+
className: `size-10 rounded-full border-2 transition-all ${selectedVariantIndex === index ? "border-primary scale-110" : "border-gray-200 hover:border-primary/50"}`,
|
|
7376
|
+
style: { backgroundColor: variant.colorHex },
|
|
7377
|
+
title: variant.color
|
|
7378
|
+
},
|
|
7379
|
+
/* @__PURE__ */ React.createElement(
|
|
7380
|
+
Image4,
|
|
7381
|
+
{
|
|
7382
|
+
src: variant.productMedia?.[0]?.file || "",
|
|
7383
|
+
alt: variant.color || `Variant ${index + 1}`,
|
|
7384
|
+
className: "object-cover",
|
|
7385
|
+
height: 32,
|
|
7386
|
+
width: 32
|
|
7387
|
+
}
|
|
7388
|
+
)
|
|
7389
|
+
)))), /* @__PURE__ */ React.createElement("div", { className: "mb-6 p-4 bg-gray-50 rounded-xl" }, /* @__PURE__ */ React.createElement("ul", { className: "space-y-2" }, product.tags.slice(0, 3).map((feature, index) => /* @__PURE__ */ React.createElement("li", { key: index, className: "flex items-start gap-2" }, /* @__PURE__ */ React.createElement(Check, { className: "size-4 text-primary shrink-0 mt-0.5" }), /* @__PURE__ */ React.createElement("span", { className: "font-['Poppins',sans-serif] text-[12px] text-muted" }, feature))))), /* @__PURE__ */ React.createElement("div", { className: "mb-6" }, /* @__PURE__ */ React.createElement("h3", { className: "font-['Poppins',sans-serif] font-semibold text-[13px] text-secondary mb-3" }, "Quantity"), /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-4" }, /* @__PURE__ */ React.createElement(
|
|
7390
|
+
"button",
|
|
7391
|
+
{
|
|
7392
|
+
onClick: () => handleQuantityChange(quantity - 1),
|
|
7393
|
+
disabled: quantity <= 1,
|
|
7394
|
+
className: "p-2 rounded-full border border-gray-200 hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed"
|
|
7395
|
+
},
|
|
7396
|
+
/* @__PURE__ */ React.createElement(Minus, { className: "size-4 text-secondary" })
|
|
7397
|
+
), /* @__PURE__ */ React.createElement("span", { className: "w-8 text-center font-medium" }, quantity), /* @__PURE__ */ React.createElement(
|
|
7398
|
+
"button",
|
|
7399
|
+
{
|
|
7400
|
+
onClick: () => handleQuantityChange(quantity + 1),
|
|
7401
|
+
disabled: quantity >= (selectedVariant.inventoryCount || 10),
|
|
7402
|
+
className: "p-2 rounded-full border border-gray-200 hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed"
|
|
7403
|
+
},
|
|
7404
|
+
/* @__PURE__ */ React.createElement(Plus, { className: "size-4 text-secondary" })
|
|
7405
|
+
))), /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-3 mt-auto" }, /* @__PURE__ */ React.createElement(
|
|
7406
|
+
"button",
|
|
7407
|
+
{
|
|
7408
|
+
onClick: handleAddToCart,
|
|
7409
|
+
disabled: addedToCart || selectedVariant.inventoryCount === 0,
|
|
7410
|
+
className: `w-full font-['Poppins',sans-serif] font-medium text-[14px] px-6 py-4 rounded-full transition-all duration-300 flex items-center justify-center gap-3 ${addedToCart ? "bg-green-500 text-white" : "bg-accent text-white hover:bg-[#d66f45] hover:shadow-lg disabled:opacity-50 disabled:cursor-not-allowed"}`
|
|
7411
|
+
},
|
|
7412
|
+
isAddingToCart ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("svg", { className: "animate-spin h-5 w-5", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", "aria-hidden": "true" }, /* @__PURE__ */ React.createElement("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), /* @__PURE__ */ React.createElement("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })), "Loading...") : /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(ShoppingCart, { className: "h-4 w-4" }), !selectedVariant ? "Select a variant" : selectedVariant.inventoryStatus === "OUT_OF_STOCK" /* OUTOFSTOCK */ ? "Out of Stock" : "Add to Cart")
|
|
7413
|
+
), /* @__PURE__ */ React.createElement(
|
|
7414
|
+
"button",
|
|
7415
|
+
{
|
|
7416
|
+
onClick: () => {
|
|
7417
|
+
onClose();
|
|
7418
|
+
onNavigateToProduct?.(product.id);
|
|
7419
|
+
},
|
|
7420
|
+
className: "w-full font-['Poppins',sans-serif] font-medium text-[13px] px-6 py-3 rounded-full bg-white text-secondary border-2 border-primary hover:bg-gray-50 transition-all flex items-center justify-center gap-2"
|
|
7421
|
+
},
|
|
7422
|
+
"View Full Details",
|
|
7423
|
+
/* @__PURE__ */ React.createElement(ExternalLink, { className: "size-4" })
|
|
7424
|
+
)))))
|
|
7425
|
+
)
|
|
7426
|
+
);
|
|
7427
|
+
}
|
|
7428
|
+
|
|
7429
|
+
// src/components/ProductCard.tsx
|
|
7100
7430
|
function ProductCard({
|
|
7101
7431
|
product,
|
|
7102
7432
|
onClickProduct,
|
|
@@ -7105,7 +7435,7 @@ function ProductCard({
|
|
|
7105
7435
|
showFavoriteButton = true,
|
|
7106
7436
|
className
|
|
7107
7437
|
}) {
|
|
7108
|
-
|
|
7438
|
+
useRouter();
|
|
7109
7439
|
const { buildPath } = useBasePath();
|
|
7110
7440
|
const [isFavorite, setIsFavorite] = useState(isFavorited);
|
|
7111
7441
|
const { addToWishlist, removeFromWishlist, isInWishlist } = useWishlist();
|
|
@@ -7114,6 +7444,8 @@ function ProductCard({
|
|
|
7114
7444
|
const [isImageLoaded, setIsImageLoaded] = useState(false);
|
|
7115
7445
|
const [selectedVariantImage, setSelectedVariantImage] = useState(null);
|
|
7116
7446
|
const [selectedVariantId, setSelectedVariantId] = useState(null);
|
|
7447
|
+
const [showQuickView, setShowQuickView] = useState(false);
|
|
7448
|
+
const notification = useNotification();
|
|
7117
7449
|
const handleImageLoad = useCallback(() => {
|
|
7118
7450
|
setIsImageLoaded(true);
|
|
7119
7451
|
}, []);
|
|
@@ -7123,24 +7455,6 @@ function ProductCard({
|
|
|
7123
7455
|
onClickProduct(product);
|
|
7124
7456
|
}
|
|
7125
7457
|
}, [onClickProduct, product]);
|
|
7126
|
-
const handleFavorite = async (e) => {
|
|
7127
|
-
e.stopPropagation();
|
|
7128
|
-
try {
|
|
7129
|
-
if (isInWishlist(product?._id || "")) {
|
|
7130
|
-
await removeFromWishlist(product?._id || "");
|
|
7131
|
-
setIsFavorite(false);
|
|
7132
|
-
toast.success("Removed from wishlist");
|
|
7133
|
-
} else {
|
|
7134
|
-
await addToWishlist(product);
|
|
7135
|
-
setIsFavorite(true);
|
|
7136
|
-
toast.success("Added to wishlist");
|
|
7137
|
-
}
|
|
7138
|
-
onFavorite?.(product);
|
|
7139
|
-
} catch (error) {
|
|
7140
|
-
console.error("Error updating wishlist:", error);
|
|
7141
|
-
toast.error("Failed to update wishlist");
|
|
7142
|
-
}
|
|
7143
|
-
};
|
|
7144
7458
|
useEffect(() => {
|
|
7145
7459
|
setIsFavorite(isInWishlist(product?._id || "") || isFavorited);
|
|
7146
7460
|
}, [isFavorited, isInWishlist, product?._id]);
|
|
@@ -7148,7 +7462,14 @@ function ProductCard({
|
|
|
7148
7462
|
setSelectedVariantImage(null);
|
|
7149
7463
|
setSelectedVariantId(null);
|
|
7150
7464
|
setIsImageLoaded(false);
|
|
7151
|
-
|
|
7465
|
+
if (product.productVariants && product.productVariants.length > 0) {
|
|
7466
|
+
const firstVariant = product.productVariants[0];
|
|
7467
|
+
if (firstVariant.productMedia && firstVariant.productMedia.length > 0) {
|
|
7468
|
+
setSelectedVariantImage(firstVariant.productMedia[0].file);
|
|
7469
|
+
setSelectedVariantId(firstVariant.id || firstVariant._id || null);
|
|
7470
|
+
}
|
|
7471
|
+
}
|
|
7472
|
+
}, [product._id, product.productVariants]);
|
|
7152
7473
|
const handleKeyDown = (e) => {
|
|
7153
7474
|
if (e.key === "Enter" || e.key === " ") {
|
|
7154
7475
|
e.preventDefault();
|
|
@@ -7185,10 +7506,10 @@ function ProductCard({
|
|
|
7185
7506
|
useEffect(() => {
|
|
7186
7507
|
setIsImageLoaded(false);
|
|
7187
7508
|
}, [imageSource.src]);
|
|
7188
|
-
return /* @__PURE__ */ React21.createElement(
|
|
7189
|
-
motion.
|
|
7509
|
+
return /* @__PURE__ */ React21.createElement(React21.Fragment, null, /* @__PURE__ */ React21.createElement(
|
|
7510
|
+
motion.div,
|
|
7190
7511
|
{
|
|
7191
|
-
className: "
|
|
7512
|
+
className: "bg-white rounded-[16px] overflow-hidden border-2 border-gray-100 hover:border-[#5B9BD5] hover:shadow-lg transition-all duration-300 group h-full flex flex-col",
|
|
7192
7513
|
whileHover: { y: -4 },
|
|
7193
7514
|
onMouseEnter: () => setIsHovered(true),
|
|
7194
7515
|
onMouseLeave: () => setIsHovered(false),
|
|
@@ -7198,59 +7519,46 @@ function ProductCard({
|
|
|
7198
7519
|
onClick: handleCardClick,
|
|
7199
7520
|
onKeyDown: handleKeyDown
|
|
7200
7521
|
},
|
|
7201
|
-
/* @__PURE__ */ React21.createElement(
|
|
7202
|
-
|
|
7203
|
-
{
|
|
7204
|
-
className: "absolute inset-0 bg-gray-200 animate-pulse",
|
|
7205
|
-
initial: { opacity: 1 },
|
|
7206
|
-
exit: { opacity: 0 },
|
|
7207
|
-
transition: { duration: 0.2 }
|
|
7208
|
-
}
|
|
7209
|
-
)), /* @__PURE__ */ React21.createElement(
|
|
7210
|
-
Image3,
|
|
7211
|
-
{
|
|
7212
|
-
src: imageSource.src,
|
|
7213
|
-
alt: imageSource.alt,
|
|
7214
|
-
fill: true,
|
|
7215
|
-
className: `h-full w-full object-cover object-center transition-opacity duration-300 ${product.inventoryCount === 0 ? "opacity-60" : ""} ${isImageLoaded ? "opacity-100" : "opacity-0"}`,
|
|
7216
|
-
sizes: "(max-width: 640px) 100vw, (max-width: 768px) 50vw, 33vw",
|
|
7217
|
-
priority: false,
|
|
7218
|
-
onLoad: handleImageLoad,
|
|
7219
|
-
onError: () => setIsImageLoaded(true),
|
|
7220
|
-
key: imageSource.src
|
|
7221
|
-
}
|
|
7222
|
-
), /* @__PURE__ */ React21.createElement("div", { className: "absolute top-3 left-3 flex flex-col gap-2 z-10" }, product.isDiscounted && /* @__PURE__ */ React21.createElement(
|
|
7223
|
-
motion.span,
|
|
7224
|
-
{
|
|
7225
|
-
initial: { scale: 0.9, opacity: 0 },
|
|
7226
|
-
animate: { scale: 1, opacity: 1 },
|
|
7227
|
-
className: "inline-flex items-center justify-center px-2.5 py-1 rounded-full text-xs font-bold text-white bg-green-600 shadow-md"
|
|
7228
|
-
},
|
|
7229
|
-
"-",
|
|
7230
|
-
product.discountAmount,
|
|
7231
|
-
"%"
|
|
7232
|
-
), product.inventoryCount === 0 && /* @__PURE__ */ React21.createElement(
|
|
7233
|
-
motion.span,
|
|
7522
|
+
/* @__PURE__ */ React21.createElement(
|
|
7523
|
+
"div",
|
|
7234
7524
|
{
|
|
7235
|
-
|
|
7236
|
-
|
|
7237
|
-
className: "inline-flex items-center justify-center px-2.5 py-1 rounded-full text-xs font-bold text-white bg-red-600"
|
|
7525
|
+
onClick: handleCardClick,
|
|
7526
|
+
className: "relative aspect-square overflow-hidden bg-gray-50 cursor-pointer flex-shrink-0"
|
|
7238
7527
|
},
|
|
7239
|
-
|
|
7240
|
-
|
|
7241
|
-
|
|
7528
|
+
/* @__PURE__ */ React21.createElement(
|
|
7529
|
+
Image4,
|
|
7530
|
+
{
|
|
7531
|
+
src: imageSource.src,
|
|
7532
|
+
alt: imageSource.alt,
|
|
7533
|
+
className: "w-full h-full object-cover group-hover:scale-105 transition-transform duration-300",
|
|
7534
|
+
height: 300,
|
|
7535
|
+
width: 300,
|
|
7536
|
+
priority: false,
|
|
7537
|
+
onLoad: handleImageLoad,
|
|
7538
|
+
onError: () => setIsImageLoaded(true),
|
|
7539
|
+
key: imageSource.src
|
|
7540
|
+
}
|
|
7541
|
+
),
|
|
7542
|
+
/* @__PURE__ */ React21.createElement(
|
|
7543
|
+
"button",
|
|
7544
|
+
{
|
|
7545
|
+
onClick: (e) => {
|
|
7546
|
+
e.stopPropagation();
|
|
7547
|
+
setShowQuickView(true);
|
|
7548
|
+
},
|
|
7549
|
+
className: "absolute top-2 left-2 p-2 rounded-full bg-white/90 backdrop-blur-sm hover:bg-white shadow-md opacity-0 group-hover:opacity-100 transition-all"
|
|
7550
|
+
},
|
|
7551
|
+
/* @__PURE__ */ React21.createElement(Eye, { className: "size-4 text-[#2B4B7C]" })
|
|
7552
|
+
),
|
|
7553
|
+
product.inventoryCount === 0 && /* @__PURE__ */ React21.createElement("div", { className: "absolute inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center" }, /* @__PURE__ */ React21.createElement("div", { className: "bg-white rounded-full px-4 py-2" }, /* @__PURE__ */ React21.createElement("span", { className: "font-['Poppins',sans-serif] font-bold text-[11px] text-[#2B4B7C] uppercase" }, "Out of Stock")))
|
|
7554
|
+
),
|
|
7555
|
+
/* @__PURE__ */ React21.createElement("div", { className: "p-4 flex-1 flex flex-col" }, /* @__PURE__ */ React21.createElement("div", { className: "p-0 flex-1 flex flex-col" }, /* @__PURE__ */ React21.createElement("div", { className: "flex items-center gap-1 mb-2 flex-wrap" }, product.isDiscounted && /* @__PURE__ */ React21.createElement("span", { className: "bg-[#E67E50] text-white rounded-full px-2 py-0.5 flex items-center gap-1" }, /* @__PURE__ */ React21.createElement("span", { className: "font-['Poppins',sans-serif] font-bold text-[8px] uppercase" }, "-", product.discountAmount, "%"))), /* @__PURE__ */ React21.createElement("div", { className: "mb-1" }, /* @__PURE__ */ React21.createElement("p", { className: "font-['Poppins',sans-serif] text-xs text-[#5B9BD5] uppercase tracking-wide font-medium" }, product.brand)), /* @__PURE__ */ React21.createElement("h3", { className: "text-sm font-['Poppins',sans-serif] font-semibold text-[#2B4B7C] mb-3" }, displayName), /* @__PURE__ */ React21.createElement("div", { className: "flex items-center gap-1.5 mb-2" }, /* @__PURE__ */ React21.createElement("div", { className: "flex items-center gap-0.5" }, [...Array(5)].map((_, i) => /* @__PURE__ */ React21.createElement(
|
|
7556
|
+
Star,
|
|
7242
7557
|
{
|
|
7243
|
-
|
|
7244
|
-
|
|
7245
|
-
|
|
7246
|
-
|
|
7247
|
-
whileTap: { scale: 0.95 },
|
|
7248
|
-
"aria-label": isFavorite ? "Remove from wishlist" : "Add to wishlist"
|
|
7249
|
-
},
|
|
7250
|
-
/* @__PURE__ */ React21.createElement(Heart, { className: `w-5 h-5 ${isFavorite ? "fill-red-500 text-red-500" : ""}` })
|
|
7251
|
-
)),
|
|
7252
|
-
/* @__PURE__ */ React21.createElement("div", { className: "absolute top-4 left-4 flex flex-col gap-2" }, product.inventoryCount === 0 && /* @__PURE__ */ React21.createElement("span", { className: "px-3 py-1 rounded-full text-sm font-bold bg-red-100 text-red-800" }, "Out of Stock")),
|
|
7253
|
-
/* @__PURE__ */ React21.createElement("div", { className: "p-4" }, product.parentCategories && product.parentCategories?.length > 0 && /* @__PURE__ */ React21.createElement("p", { className: "text-xs text-gray-500 uppercase tracking-wider mb-1" }, product.parentCategories?.map((category) => category?.name).join(", ") || "No categories"), /* @__PURE__ */ React21.createElement("div", { className: "mb-2" }, /* @__PURE__ */ React21.createElement("h3", { className: "text-lg font-semibold text-gray-900 line-clamp-1 group-hover:text-primary-600 transition-colors" }, displayName)), /* @__PURE__ */ React21.createElement("div", { className: "flex items-baseline gap-2" }, /* @__PURE__ */ React21.createElement("div", { className: "flex flex-col" }, /* @__PURE__ */ React21.createElement("span", { className: "text-2xl font-bold text-gray-900" }, formatPrice(product.finalPrice)), product.inventoryCount > 0 && /* @__PURE__ */ React21.createElement("span", { className: "text-xs text-gray-500" }, product.inventoryCount > 0 ? "In Stock" : "Out of Stock")), product.priceBeforeDiscount && product.priceBeforeDiscount > product.finalPrice && /* @__PURE__ */ React21.createElement("span", { className: "text-sm text-gray-500 line-through" }, formatPrice(product.priceBeforeDiscount))), variantImages.length > 0 && /* @__PURE__ */ React21.createElement("div", { className: "flex items-center gap-2 mt-3" }, variantImages.map((variant, index) => /* @__PURE__ */ React21.createElement(
|
|
7558
|
+
key: i,
|
|
7559
|
+
className: `size-4 ${i < Math.floor(product.rating ? product.rating : 0) ? "text-[#E67E50] fill-[#E67E50]" : "text-gray-300"}`
|
|
7560
|
+
}
|
|
7561
|
+
))), /* @__PURE__ */ React21.createElement("span", { className: "font-['Poppins',sans-serif] text-[10px] text-[#676c80]" }, "(", product.reviews?.length || 0, ")")), /* @__PURE__ */ React21.createElement("div", { className: "flex items-center gap-1.5 mb-3" }, /* @__PURE__ */ React21.createElement("span", { className: "font-['Poppins',sans-serif] font-bold text-md text-primary-600" }, "$", product.finalPrice.toFixed(2)), product.isDiscounted && /* @__PURE__ */ React21.createElement("span", { className: "font-['Poppins',sans-serif] text-sm text-[#676c80] line-through" }, "$", formatPrice(product.priceBeforeDiscount))), variantImages.length > 0 && /* @__PURE__ */ React21.createElement("div", { className: "flex items-center gap-1.5 mb-3" }, variantImages.map((variant, index) => /* @__PURE__ */ React21.createElement(
|
|
7254
7562
|
"button",
|
|
7255
7563
|
{
|
|
7256
7564
|
key: variant.variantId || index,
|
|
@@ -7270,7 +7578,7 @@ function ProductCard({
|
|
|
7270
7578
|
"aria-label": `Select ${variant.color || "variant"} color`
|
|
7271
7579
|
},
|
|
7272
7580
|
/* @__PURE__ */ React21.createElement(
|
|
7273
|
-
|
|
7581
|
+
Image4,
|
|
7274
7582
|
{
|
|
7275
7583
|
src: variant.image,
|
|
7276
7584
|
alt: variant.color || `Variant ${index + 1}`,
|
|
@@ -7279,15 +7587,17 @@ function ProductCard({
|
|
|
7279
7587
|
sizes: "32px"
|
|
7280
7588
|
}
|
|
7281
7589
|
)
|
|
7282
|
-
)))),
|
|
7283
|
-
/* @__PURE__ */ React21.createElement("div", { className: "mt-auto p-4 pt-0" }, /* @__PURE__ */ React21.createElement(
|
|
7590
|
+
)))), /* @__PURE__ */ React21.createElement(
|
|
7284
7591
|
"button",
|
|
7285
7592
|
{
|
|
7286
7593
|
type: "button",
|
|
7287
7594
|
onClick: async (e) => {
|
|
7288
7595
|
e.stopPropagation();
|
|
7289
7596
|
if (!selectedVariantId && variantImages.length > 0) {
|
|
7290
|
-
|
|
7597
|
+
notification.error(
|
|
7598
|
+
"Select a variant",
|
|
7599
|
+
"Please choose a variant before adding this item to your cart."
|
|
7600
|
+
);
|
|
7291
7601
|
return;
|
|
7292
7602
|
}
|
|
7293
7603
|
try {
|
|
@@ -7301,23 +7611,19 @@ function ProductCard({
|
|
|
7301
7611
|
}
|
|
7302
7612
|
},
|
|
7303
7613
|
disabled: isAddingToCart || variantImages.length > 0 && !selectedVariantId,
|
|
7304
|
-
className: "w-full
|
|
7614
|
+
className: "w-full font-['Poppins',sans-serif] font-medium text-[11px] px-3 py-2 rounded-full bg-[#5B9BD5] text-white hover:bg-[#4a8ac4] hover:shadow-lg transition-all duration-300 flex items-center justify-center gap-1.5 disabled:opacity-50 disabled:cursor-not-allowed"
|
|
7305
7615
|
},
|
|
7306
7616
|
/* @__PURE__ */ React21.createElement(ShoppingCart, { className: "h-4 w-4" }),
|
|
7307
|
-
"Add to Cart"
|
|
7308
|
-
), /* @__PURE__ */ React21.createElement(
|
|
7309
|
-
"button",
|
|
7310
|
-
{
|
|
7311
|
-
type: "button",
|
|
7312
|
-
onClick: (e) => {
|
|
7313
|
-
e.stopPropagation();
|
|
7314
|
-
router.push(buildPath(`/products/${product._id}`));
|
|
7315
|
-
},
|
|
7316
|
-
className: "mt-2 w-full flex items-center justify-center rounded-full border border-gray-300 bg-white px-3 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 transition-colors"
|
|
7317
|
-
},
|
|
7318
|
-
"View More"
|
|
7617
|
+
selectedVariant?.inventoryCount === 0 ? "Out of Stock" : "Add to Cart"
|
|
7319
7618
|
))
|
|
7320
|
-
)
|
|
7619
|
+
), showQuickView && /* @__PURE__ */ React21.createElement(
|
|
7620
|
+
QuickViewModal,
|
|
7621
|
+
{
|
|
7622
|
+
product,
|
|
7623
|
+
onClose: () => setShowQuickView(false),
|
|
7624
|
+
onNavigateToProduct: () => handleCardClick
|
|
7625
|
+
}
|
|
7626
|
+
));
|
|
7321
7627
|
}
|
|
7322
7628
|
function Skeleton({ className = "" }) {
|
|
7323
7629
|
return /* @__PURE__ */ React21.createElement("div", { className: `animate-pulse bg-gradient-to-r from-gray-200 via-gray-300 to-gray-200 bg-[length:200%_100%] rounded ${className}` });
|
|
@@ -7340,7 +7646,7 @@ function Button({
|
|
|
7340
7646
|
children,
|
|
7341
7647
|
...props
|
|
7342
7648
|
}) {
|
|
7343
|
-
const baseStyles = "font-medium rounded-
|
|
7649
|
+
const baseStyles = "font-medium rounded-full transition-all duration-200 inline-flex items-center justify-center gap-2 disabled:opacity-50 disabled:cursor-not-allowed focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-primary-500";
|
|
7344
7650
|
const variants = {
|
|
7345
7651
|
primary: "bg-primary-600 text-white hover:bg-primary-700 shadow-lg shadow-primary-500/30 hover:shadow-xl hover:shadow-primary-500/40",
|
|
7346
7652
|
secondary: "bg-secondary-600 text-white hover:bg-secondary-700 shadow-lg shadow-secondary-500/30 hover:shadow-xl hover:shadow-secondary-500/40",
|
|
@@ -7509,8 +7815,6 @@ function useCategories() {
|
|
|
7509
7815
|
}, []);
|
|
7510
7816
|
return { categories, isLoading, error };
|
|
7511
7817
|
}
|
|
7512
|
-
|
|
7513
|
-
// src/screens/ShopScreen.tsx
|
|
7514
7818
|
function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
7515
7819
|
const router = useRouter();
|
|
7516
7820
|
const { buildPath } = useBasePath();
|
|
@@ -7711,7 +8015,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7711
8015
|
},
|
|
7712
8016
|
[]
|
|
7713
8017
|
);
|
|
7714
|
-
|
|
8018
|
+
useCallback((parentCategoryId, subCategoryId) => {
|
|
7715
8019
|
setFilters((current) => {
|
|
7716
8020
|
if (current.subCategory === subCategoryId) {
|
|
7717
8021
|
const { subCategory, ...rest } = current;
|
|
@@ -8019,124 +8323,83 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
8019
8323
|
if (name.includes("care") || name.includes("personal")) return Heart;
|
|
8020
8324
|
return Package;
|
|
8021
8325
|
};
|
|
8022
|
-
const renderFiltersPanel = () => /* @__PURE__ */ React21.createElement(React21.Fragment, null, /* @__PURE__ */ React21.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React21.createElement("
|
|
8326
|
+
const renderFiltersPanel = () => /* @__PURE__ */ React21.createElement(React21.Fragment, null, /* @__PURE__ */ React21.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React21.createElement("div", { className: `lg:w-72 ${showFilters ? "block rounded-full" : "hidden lg:block"}` }, /* @__PURE__ */ React21.createElement("div", { className: "bg-white rounded-[24px] p-6 border-2 border-gray-100 sticky top-24" }, /* @__PURE__ */ React21.createElement("h3", { className: "font-['Poppins',sans-serif] font-semibold text-secondary" }, "Filters"), /* @__PURE__ */ React21.createElement("div", { className: "mb-6" }, /* @__PURE__ */ React21.createElement("label", { className: "font-['Poppins',sans-serif] text-[12px] text-muted mb-2 block font-medium" }, "Search Products"), /* @__PURE__ */ React21.createElement("div", { className: "relative" }, /* @__PURE__ */ React21.createElement(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 size-4 text-muted" }), /* @__PURE__ */ React21.createElement(
|
|
8023
8327
|
"input",
|
|
8024
8328
|
{
|
|
8025
8329
|
type: "text",
|
|
8026
8330
|
placeholder: "Search...",
|
|
8027
8331
|
value: searchQuery,
|
|
8028
8332
|
onChange: handleInputChange,
|
|
8029
|
-
className: "w-full
|
|
8333
|
+
className: "w-full pl-10 pr-4 py-2.5 rounded-xl border-2 border-gray-200 focus:border-primary focus:outline-none font-['Poppins',sans-serif] text-[13px] text-secondary"
|
|
8030
8334
|
}
|
|
8031
|
-
))), /* @__PURE__ */ React21.createElement("div", { className: "
|
|
8335
|
+
))), /* @__PURE__ */ React21.createElement("div", { className: "mb-6" }, /* @__PURE__ */ React21.createElement(
|
|
8032
8336
|
"button",
|
|
8033
8337
|
{
|
|
8034
|
-
type: "button",
|
|
8035
8338
|
onClick: () => toggleFilterSection("category"),
|
|
8036
|
-
className: "
|
|
8037
|
-
},
|
|
8038
|
-
/* @__PURE__ */ React21.createElement("span", null, "Category"),
|
|
8039
|
-
expandedFilterSections.category ? /* @__PURE__ */ React21.createElement(ChevronUp, { className: "h-4 w-4" }) : /* @__PURE__ */ React21.createElement(ChevronDown, { className: "h-4 w-4" })
|
|
8040
|
-
), expandedFilterSections.category && /* @__PURE__ */ React21.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React21.createElement(
|
|
8041
|
-
"button",
|
|
8042
|
-
{
|
|
8043
|
-
type: "button",
|
|
8044
|
-
onClick: handleClearCategory,
|
|
8045
|
-
className: `flex w-full items-center gap-3 rounded-lg px-3 py-2.5 text-sm font-medium transition ${!categoryFilter ? "bg-primary-600 text-white" : "bg-white text-slate-700 border border-slate-200 hover:border-primary-300"}`
|
|
8339
|
+
className: "w-full flex items-center justify-between mb-3"
|
|
8046
8340
|
},
|
|
8047
|
-
/* @__PURE__ */ React21.createElement("
|
|
8048
|
-
/* @__PURE__ */ React21.createElement("
|
|
8049
|
-
), sortedCategories.map((category) => {
|
|
8341
|
+
/* @__PURE__ */ React21.createElement("label", { className: "font-['Poppins',sans-serif] text-[12px] text-muted font-medium cursor-pointer" }, "Category"),
|
|
8342
|
+
expandedFilterSections.category ? /* @__PURE__ */ React21.createElement(ChevronDown, { className: `size-4 text-muted transition-transform ${expandedFilterSections.category ? "rotate-180" : ""}` }) : /* @__PURE__ */ React21.createElement(ChevronDown, { className: `size-4 text-muted transition-transform ${expandedFilterSections.category ? "rotate-180" : ""}` })
|
|
8343
|
+
), expandedFilterSections.category && /* @__PURE__ */ React21.createElement("div", { className: "space-y-2" }, sortedCategories.map((category) => {
|
|
8050
8344
|
const isCategoryActive = categoryFilter === category.id;
|
|
8051
8345
|
const isExpanded = !!expandedCategories[category.id];
|
|
8052
8346
|
const Icon = getCategoryIconForFilter(category.name ?? "");
|
|
8053
|
-
return /* @__PURE__ */ React21.createElement(
|
|
8347
|
+
return /* @__PURE__ */ React21.createElement(
|
|
8054
8348
|
"button",
|
|
8055
8349
|
{
|
|
8056
|
-
|
|
8350
|
+
key: category.id,
|
|
8057
8351
|
onClick: () => {
|
|
8058
8352
|
if (!isExpanded) toggleCategoryExpand(category.id ?? "");
|
|
8059
8353
|
handleCategoryChange(category.id ?? "");
|
|
8060
8354
|
},
|
|
8061
|
-
className: `
|
|
8355
|
+
className: `w-full text-left px-4 py-3 rounded-xl font-['Poppins',sans-serif] text-[13px] transition-all flex items-center gap-3 ${isCategoryActive ? "bg-primary text-white shadow-lg" : "text-secondary hover:bg-gray-50 border-2 border-gray-100"}`
|
|
8062
8356
|
},
|
|
8063
|
-
/* @__PURE__ */ React21.createElement(
|
|
8064
|
-
|
|
8065
|
-
|
|
8066
|
-
|
|
8067
|
-
{
|
|
8068
|
-
type: "button",
|
|
8069
|
-
onClick: (e) => {
|
|
8070
|
-
e.stopPropagation();
|
|
8071
|
-
toggleCategoryExpand(category.id ?? "");
|
|
8072
|
-
},
|
|
8073
|
-
className: "p-1"
|
|
8074
|
-
},
|
|
8075
|
-
/* @__PURE__ */ React21.createElement(ChevronDown, { className: `h-4 w-4 transition-transform ${isExpanded ? "rotate-180" : ""} ${isCategoryActive ? "text-white" : "text-slate-400"}` })
|
|
8076
|
-
)
|
|
8077
|
-
), isExpanded && Array.isArray(category.categorySubCategories) && category.categorySubCategories.length > 0 && /* @__PURE__ */ React21.createElement("div", { className: "ml-9 space-y-1" }, category.categorySubCategories.map((sub) => {
|
|
8078
|
-
const isSubActive = subCategoryFilter === sub.id;
|
|
8079
|
-
return /* @__PURE__ */ React21.createElement(
|
|
8080
|
-
"button",
|
|
8081
|
-
{
|
|
8082
|
-
key: sub.id,
|
|
8083
|
-
type: "button",
|
|
8084
|
-
onClick: () => handleSubCategoryChange(category.id ?? "", sub.id),
|
|
8085
|
-
className: `block w-full rounded-lg px-3 py-2 text-sm text-left transition ${isSubActive ? "bg-primary-50 text-primary-700 font-medium" : "text-slate-600 hover:bg-slate-50"}`
|
|
8086
|
-
},
|
|
8087
|
-
sub.name
|
|
8088
|
-
);
|
|
8089
|
-
})));
|
|
8090
|
-
}))), /* @__PURE__ */ React21.createElement("div", { className: "space-y-3" }, /* @__PURE__ */ React21.createElement(
|
|
8357
|
+
/* @__PURE__ */ React21.createElement(Icon, { className: "size-4" }),
|
|
8358
|
+
category.name
|
|
8359
|
+
);
|
|
8360
|
+
}))), /* @__PURE__ */ React21.createElement("div", { className: "mb-6" }, /* @__PURE__ */ React21.createElement(
|
|
8091
8361
|
"button",
|
|
8092
8362
|
{
|
|
8093
|
-
type: "button",
|
|
8094
8363
|
onClick: () => toggleFilterSection("brand"),
|
|
8095
|
-
className: "
|
|
8364
|
+
className: "w-full flex items-center justify-between mb-3"
|
|
8096
8365
|
},
|
|
8097
|
-
/* @__PURE__ */ React21.createElement("
|
|
8098
|
-
|
|
8099
|
-
), expandedFilterSections.brand && /* @__PURE__ */ React21.createElement("div", { className: "space-y-
|
|
8366
|
+
/* @__PURE__ */ React21.createElement("label", { className: "font-['Poppins',sans-serif] text-[12px] text-muted font-medium cursor-pointer" }, "Brand"),
|
|
8367
|
+
/* @__PURE__ */ React21.createElement(ChevronDown, { className: `size-4 text-muted transition-transform ${expandedFilterSections.brand ? "rotate-180" : ""}` })
|
|
8368
|
+
), expandedFilterSections.brand && /* @__PURE__ */ React21.createElement("div", { className: "space-y-2" }, availableBrands.length === 0 ? /* @__PURE__ */ React21.createElement("div", { className: "text-xs text-slate-500" }, "No brands available") : availableBrands.map((brand) => {
|
|
8100
8369
|
const isSelected = brandFilter === brand;
|
|
8101
8370
|
return /* @__PURE__ */ React21.createElement(
|
|
8102
8371
|
"button",
|
|
8103
8372
|
{
|
|
8104
8373
|
key: brand,
|
|
8105
|
-
type: "button",
|
|
8106
8374
|
onClick: () => handleBrandChange(brand),
|
|
8107
|
-
className: `
|
|
8375
|
+
className: `w-full text-left px-4 py-3 rounded-xl font-['Poppins',sans-serif] text-[13px] transition-all ${isSelected ? "bg-primary text-white shadow-lg" : "text-secondary hover:bg-gray-50 border-2 border-gray-100"}`
|
|
8108
8376
|
},
|
|
8109
|
-
|
|
8110
|
-
isSelected && /* @__PURE__ */ React21.createElement(Check, { className: "h-3 w-3 text-primary-600 flex-shrink-0 ml-2" })
|
|
8377
|
+
brand
|
|
8111
8378
|
);
|
|
8112
|
-
}))), /* @__PURE__ */ React21.createElement("div", { className: "
|
|
8379
|
+
}))), /* @__PURE__ */ React21.createElement("div", { className: "mb-6" }, /* @__PURE__ */ React21.createElement(
|
|
8113
8380
|
"button",
|
|
8114
8381
|
{
|
|
8115
|
-
type: "button",
|
|
8116
8382
|
onClick: () => toggleFilterSection("availability"),
|
|
8117
|
-
className: "
|
|
8383
|
+
className: "w-full flex items-center justify-between mb-3"
|
|
8118
8384
|
},
|
|
8119
|
-
/* @__PURE__ */ React21.createElement("
|
|
8120
|
-
|
|
8385
|
+
/* @__PURE__ */ React21.createElement("label", { className: "font-['Poppins',sans-serif] text-[12px] text-muted font-medium cursor-pointer" }, "Availability"),
|
|
8386
|
+
/* @__PURE__ */ React21.createElement(ChevronDown, { className: `size-4 text-muted transition-transform ${expandedFilterSections.availability ? "rotate-180" : ""}` })
|
|
8121
8387
|
), expandedFilterSections.availability && /* @__PURE__ */ React21.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React21.createElement(
|
|
8122
8388
|
"button",
|
|
8123
8389
|
{
|
|
8124
|
-
type: "button",
|
|
8125
8390
|
onClick: handleToggleStock,
|
|
8126
|
-
className: `
|
|
8391
|
+
className: `w-full flex items-center justify-between px-4 py-3 rounded-xl font-['Poppins',sans-serif] text-[13px] transition-all border-2 ${inStockOnly ? "bg-primary text-white shadow-lg" : "text-secondary hover:bg-gray-50 border-2 border-gray-100"}`
|
|
8127
8392
|
},
|
|
8128
|
-
|
|
8129
|
-
|
|
8130
|
-
))), /* @__PURE__ */ React21.createElement("div", { className: "space-y-3" }, /* @__PURE__ */ React21.createElement(
|
|
8393
|
+
"In Stock Only"
|
|
8394
|
+
))), /* @__PURE__ */ React21.createElement("div", { className: "mb-6" }, /* @__PURE__ */ React21.createElement(
|
|
8131
8395
|
"button",
|
|
8132
8396
|
{
|
|
8133
|
-
type: "button",
|
|
8134
8397
|
onClick: () => toggleFilterSection("price"),
|
|
8135
|
-
className: "
|
|
8398
|
+
className: "w-full flex items-center justify-between mb-3"
|
|
8136
8399
|
},
|
|
8137
|
-
/* @__PURE__ */ React21.createElement("
|
|
8138
|
-
|
|
8139
|
-
), expandedFilterSections.price && /* @__PURE__ */ React21.createElement("div", { className: "space-y-
|
|
8400
|
+
/* @__PURE__ */ React21.createElement("label", { className: "font-['Poppins',sans-serif] text-[12px] text-muted font-medium cursor-pointer" }, "Price Range"),
|
|
8401
|
+
/* @__PURE__ */ React21.createElement(ChevronDown, { className: `size-4 text-muted transition-transform ${expandedFilterSections.price ? "rotate-180" : ""}` })
|
|
8402
|
+
), expandedFilterSections.price && /* @__PURE__ */ React21.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React21.createElement("div", { className: "flex flex-wrap gap-2" }, priceRanges.map((range) => {
|
|
8140
8403
|
const isActive = selectedPriceRange === range.value;
|
|
8141
8404
|
return /* @__PURE__ */ React21.createElement(
|
|
8142
8405
|
"button",
|
|
@@ -8144,7 +8407,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
8144
8407
|
type: "button",
|
|
8145
8408
|
key: range.value,
|
|
8146
8409
|
onClick: () => handlePriceRangeSelect(range.value),
|
|
8147
|
-
className: `
|
|
8410
|
+
className: `w-full flex items-center justify-between px-4 py-3 rounded-xl font-['Poppins',sans-serif] text-[13px] transition-all border-2 ${isActive ? "bg-primary text-white shadow-lg" : "text-secondary hover:bg-gray-50 border-2 border-gray-100"}`
|
|
8148
8411
|
},
|
|
8149
8412
|
range.label
|
|
8150
8413
|
);
|
|
@@ -8156,7 +8419,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
8156
8419
|
placeholder: "Min",
|
|
8157
8420
|
value: customPrice.min,
|
|
8158
8421
|
onChange: (event) => setCustomPrice((current) => ({ ...current, min: event.target.value })),
|
|
8159
|
-
className: "text-
|
|
8422
|
+
className: "w-1/2 px-4 py-2.5 rounded-xl border-2 border-gray-200 focus:border-primary focus:outline-none font-['Poppins',sans-serif] text-[13px] text-secondary"
|
|
8160
8423
|
}
|
|
8161
8424
|
), /* @__PURE__ */ React21.createElement(
|
|
8162
8425
|
Input,
|
|
@@ -8166,7 +8429,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
8166
8429
|
placeholder: "Max",
|
|
8167
8430
|
value: customPrice.max,
|
|
8168
8431
|
onChange: (event) => setCustomPrice((current) => ({ ...current, max: event.target.value })),
|
|
8169
|
-
className: "text-
|
|
8432
|
+
className: "w-1/2 px-4 py-2.5 rounded-xl border-2 border-gray-200 focus:border-primary focus:outline-none font-['Poppins',sans-serif] text-[13px] text-secondary"
|
|
8170
8433
|
}
|
|
8171
8434
|
)), /* @__PURE__ */ React21.createElement(
|
|
8172
8435
|
"button",
|
|
@@ -8174,10 +8437,10 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
8174
8437
|
type: "button",
|
|
8175
8438
|
onClick: applyCustomPrice,
|
|
8176
8439
|
disabled: !isCustomPriceDirty,
|
|
8177
|
-
className: "w-full rounded-lg border border-primary
|
|
8440
|
+
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"
|
|
8178
8441
|
},
|
|
8179
8442
|
"Apply"
|
|
8180
|
-
)))));
|
|
8443
|
+
)))))));
|
|
8181
8444
|
const displayCategories = useMemo(() => {
|
|
8182
8445
|
return topCategories.slice(0, 5);
|
|
8183
8446
|
}, [topCategories]);
|
|
@@ -8189,7 +8452,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
8189
8452
|
if (name.includes("care") || name.includes("personal")) return Heart;
|
|
8190
8453
|
return Package;
|
|
8191
8454
|
};
|
|
8192
|
-
return /* @__PURE__ */ React21.createElement("div", { className: "min-h-screen bg-[#F9FAFB]" }, /* @__PURE__ */ React21.createElement("section", { className: "relative overflow-hidden bg-
|
|
8455
|
+
return /* @__PURE__ */ React21.createElement("div", { className: "min-h-screen bg-[#F9FAFB]" }, /* @__PURE__ */ React21.createElement("section", { className: "relative overflow-hidden bg-primary-bg py-16 md:py-24" }, /* @__PURE__ */ React21.createElement("div", { className: "container mx-auto px-4" }, /* @__PURE__ */ React21.createElement(
|
|
8193
8456
|
motion.div,
|
|
8194
8457
|
{
|
|
8195
8458
|
initial: { opacity: 0, y: 24 },
|
|
@@ -8218,33 +8481,20 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
8218
8481
|
}
|
|
8219
8482
|
))
|
|
8220
8483
|
)
|
|
8221
|
-
))), /* @__PURE__ */ React21.createElement("section", { className: "
|
|
8222
|
-
// Skeleton loaders
|
|
8223
|
-
/* @__PURE__ */ React21.createElement(React21.Fragment, null, Array.from({ length: 6 }).map((_, index) => /* @__PURE__ */ React21.createElement(
|
|
8224
|
-
"div",
|
|
8225
|
-
{
|
|
8226
|
-
key: index,
|
|
8227
|
-
className: "rounded-xl border border-slate-200 bg-white p-8"
|
|
8228
|
-
},
|
|
8229
|
-
/* @__PURE__ */ React21.createElement(Skeleton, { className: "h-10 w-10 mb-4 rounded-lg" }),
|
|
8230
|
-
/* @__PURE__ */ React21.createElement(Skeleton, { className: "h-6 w-3/4 mb-2 rounded" }),
|
|
8231
|
-
/* @__PURE__ */ React21.createElement(Skeleton, { className: "h-4 w-1/2 rounded" })
|
|
8232
|
-
)))
|
|
8233
|
-
) : /* @__PURE__ */ React21.createElement(React21.Fragment, null, /* @__PURE__ */ React21.createElement(
|
|
8234
|
-
motion.button,
|
|
8235
|
-
{
|
|
8236
|
-
initial: { opacity: 0, y: 20 },
|
|
8237
|
-
animate: { opacity: 1, y: 0 },
|
|
8238
|
-
onClick: handleClearCategory,
|
|
8239
|
-
className: `group relative overflow-hidden rounded-xl p-8 text-left transition ${!categoryFilter ? "bg-gradient-to-b from-primary-500 to-primary-300 text-white shadow-lg scale-105" : "border border-slate-200 bg-white hover:border-primary-300 hover:shadow-md"}`
|
|
8240
|
-
},
|
|
8241
|
-
/* @__PURE__ */ React21.createElement(ShoppingBag, { className: `h-10 w-10 mb-4 ${!categoryFilter ? "text-white" : "text-primary-500"}` }),
|
|
8242
|
-
/* @__PURE__ */ React21.createElement("h3", { className: `text-xl font-bold mb-2 ${!categoryFilter ? "text-white" : "text-slate-900 group-hover:text-primary-600"}` }, "All Products"),
|
|
8243
|
-
/* @__PURE__ */ React21.createElement("p", { className: `text-sm ${!categoryFilter ? "text-white/90" : "text-slate-500"}` }, "Browse everything")
|
|
8244
|
-
), displayCategories.map((category, index) => {
|
|
8484
|
+
))), /* @__PURE__ */ React21.createElement("section", { className: "py-8 bg-white" }, /* @__PURE__ */ React21.createElement("div", { className: "max-w-[1400px] mx-auto px-8 md:px-12" }, /* @__PURE__ */ React21.createElement("h2", { className: "text-2xl md:text-3xl font-['Poppins',sans-serif] font-semibold text-secondary mb-6" }, "Shop by Category"), /* @__PURE__ */ React21.createElement("div", { className: "grid grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-4" }, displayCategories.map((category, index) => {
|
|
8245
8485
|
const Icon = getCategoryIcon(category.name ?? "");
|
|
8246
8486
|
const isSelected = categoryFilter === category.id;
|
|
8247
|
-
return /* @__PURE__ */ React21.createElement(
|
|
8487
|
+
return /* @__PURE__ */ React21.createElement(React21.Fragment, null, /* @__PURE__ */ React21.createElement(
|
|
8488
|
+
motion.button,
|
|
8489
|
+
{
|
|
8490
|
+
onClick: handleClearCategory,
|
|
8491
|
+
initial: { opacity: 0, y: 20 },
|
|
8492
|
+
animate: { opacity: 1, y: 0 },
|
|
8493
|
+
transition: { delay: index * 0.1 },
|
|
8494
|
+
className: `group relative overflow-hidden rounded-[24px] p-6 transition-all duration-300 ${!categoryFilter ? "bg-gradient-to-br from-primary to-secondary text-white shadow-xl scale-105" : "bg-gradient-to-br from-gray-50 to-white hover:shadow-lg border-2 border-gray-100 hover:border-primary"}`
|
|
8495
|
+
},
|
|
8496
|
+
/* @__PURE__ */ React21.createElement("div", { className: "relative" }, /* @__PURE__ */ React21.createElement("div", { className: `size-12 rounded-full mb-3 mx-auto flex items-center justify-center transition-all ${!categoryFilter ? "bg-white/20" : "bg-gradient-to-br from-primary/10 to-secondary/10 group-hover:scale-110"}` }, /* @__PURE__ */ React21.createElement(Icon, { className: `size-6 ${!categoryFilter ? "text-white" : "text-primary"}` })), /* @__PURE__ */ React21.createElement("h3", { className: `font-['Poppins',sans-serif] font-semibold text-[14px] mb-1.5 ${!categoryFilter ? "text-white" : "text-secondary"}` }, "All Products"), /* @__PURE__ */ React21.createElement("p", { className: `font-['Poppins',sans-serif] text-[11px] ${!categoryFilter ? "text-white/80" : "text-muted"}` }, "Browse Everything"))
|
|
8497
|
+
), /* @__PURE__ */ React21.createElement(
|
|
8248
8498
|
motion.button,
|
|
8249
8499
|
{
|
|
8250
8500
|
key: category.id,
|
|
@@ -8252,56 +8502,42 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
8252
8502
|
animate: { opacity: 1, y: 0 },
|
|
8253
8503
|
transition: { delay: index * 0.1 },
|
|
8254
8504
|
onClick: () => handleCategoryChange(category.id ?? ""),
|
|
8255
|
-
className: `group rounded-
|
|
8505
|
+
className: `group relative overflow-hidden rounded-[24px] p-6 transition-all duration-300 ${isSelected ? "bg-gradient-to-br from-primary to-secondary text-white shadow-xl scale-105" : "bg-gradient-to-br from-gray-50 to-white hover:shadow-lg border-2 border-gray-100 hover:border-primary"}`
|
|
8256
8506
|
},
|
|
8257
|
-
/* @__PURE__ */ React21.createElement(
|
|
8258
|
-
|
|
8259
|
-
|
|
8260
|
-
);
|
|
8261
|
-
}))))), /* @__PURE__ */ React21.createElement("div", { className: "relative z-10 pb-16 mt-8" }, /* @__PURE__ */ React21.createElement("div", { className: "container mx-auto px-4" }, /* @__PURE__ */ React21.createElement("div", { className: "flex flex-col gap-8 lg:flex-row" }, /* @__PURE__ */ React21.createElement("aside", { className: "hidden w-72 flex-shrink-0 lg:block" }, /* @__PURE__ */ React21.createElement("div", { className: "sticky top-24 rounded-lg bg-white p-6" }, renderFiltersPanel())), /* @__PURE__ */ React21.createElement("main", { className: "flex-1 space-y-6" }, /* @__PURE__ */ React21.createElement("div", { className: "rounded-3xl border border-gray-100 bg-white p-6 shadow-sm" }, /* @__PURE__ */ React21.createElement("div", { className: "flex flex-col gap-6 md:flex-row md:items-center md:justify-between" }, /* @__PURE__ */ React21.createElement("div", null, /* @__PURE__ */ React21.createElement("h2", { className: "text-base font-medium text-gray-700" }, isLoading ? "Loading products..." : `Showing ${displayedProducts.length} of ${pagination.total || displayedProducts.length} products`)), /* @__PURE__ */ React21.createElement("div", { className: "flex flex-col gap-3 md:flex-row md:items-center" }, /* @__PURE__ */ React21.createElement("div", { className: "relative" }, /* @__PURE__ */ React21.createElement(ArrowUpDown, { className: "pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400" }), /* @__PURE__ */ React21.createElement(
|
|
8507
|
+
/* @__PURE__ */ React21.createElement("div", { className: "relative" }, /* @__PURE__ */ React21.createElement("div", { className: `size-12 rounded-full mb-3 mx-auto flex items-center justify-center transition-all ${isSelected ? "bg-white/20" : "bg-gradient-to-br from-primary/10 to-secondary/10 group-hover:scale-110"}` }, /* @__PURE__ */ React21.createElement(Icon, { className: `size-6 ${isSelected ? "text-white" : "text-primary"}` })), /* @__PURE__ */ React21.createElement("h3", { className: `font-['Poppins',sans-serif] font-semibold text-[14px] mb-1.5 ${isSelected ? "text-white" : "text-secondary"}` }, category.name), /* @__PURE__ */ React21.createElement("p", { className: `font-['Poppins',sans-serif] text-[11px] ${isSelected ? "text-white/80" : "text-muted"}` }, category.description))
|
|
8508
|
+
));
|
|
8509
|
+
})))), /* @__PURE__ */ React21.createElement("div", { className: "relative pb-16 mt-8" }, /* @__PURE__ */ React21.createElement("div", { className: "container mx-auto px-4" }, /* @__PURE__ */ React21.createElement("div", { className: "flex flex-col gap-8 lg:flex-row" }, /* @__PURE__ */ React21.createElement("aside", { className: "hidden w-72 flex-shrink-0 lg:block" }, /* @__PURE__ */ React21.createElement("div", { className: "sticky top-24 rounded-lg bg-white" }, renderFiltersPanel())), /* @__PURE__ */ React21.createElement("main", { className: "flex-1 space-y-6" }, /* @__PURE__ */ React21.createElement("div", { className: "rounded-3xl border border-gray-100 bg-white p-6 shadow-sm" }, /* @__PURE__ */ React21.createElement("div", { className: "flex flex-col gap-6 md:flex-row md:items-center md:justify-between" }, /* @__PURE__ */ React21.createElement("div", null, /* @__PURE__ */ React21.createElement("h2", { className: "text-base font-medium text-gray-700" }, isLoading ? "Loading products..." : `${displayedProducts.length} products found`)), /* @__PURE__ */ React21.createElement("div", { className: "flex flex-col gap-3 md:flex-row md:items-center" }, /* @__PURE__ */ React21.createElement("div", { className: "relative" }, /* @__PURE__ */ React21.createElement(ArrowUpDown, { className: "pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400" }), /* @__PURE__ */ React21.createElement(
|
|
8262
8510
|
"select",
|
|
8263
8511
|
{
|
|
8264
8512
|
value: sortOption,
|
|
8265
8513
|
onChange: (event) => {
|
|
8266
8514
|
setSortOption(event.target.value);
|
|
8267
8515
|
},
|
|
8268
|
-
className: "appearance-none rounded-
|
|
8516
|
+
className: "appearance-none rounded-full border border-gray-200 bg-white py-2.5 pl-10 pr-9 text-sm font-medium text-gray-700 shadow-sm transition focus:outline-none focus:ring-1 focus:ring-secondary focus:border-primary"
|
|
8269
8517
|
},
|
|
8270
8518
|
/* @__PURE__ */ React21.createElement("option", { value: "featured" }, "Featured products"),
|
|
8271
8519
|
/* @__PURE__ */ React21.createElement("option", { value: "price-low-high" }, "Price: low to high"),
|
|
8272
8520
|
/* @__PURE__ */ React21.createElement("option", { value: "price-high-low" }, "Price: high to low"),
|
|
8273
8521
|
/* @__PURE__ */ React21.createElement("option", { value: "newest" }, "Newest arrivals")
|
|
8274
|
-
), /* @__PURE__ */ React21.createElement(ChevronDown, { className: "pointer-events-none absolute right-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400" })), /* @__PURE__ */ React21.createElement("div", { className: "flex items-center rounded-
|
|
8522
|
+
), /* @__PURE__ */ React21.createElement(ChevronDown, { className: "pointer-events-none absolute right-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400" })), /* @__PURE__ */ React21.createElement("div", { className: "flex items-center rounded-full border border-gray-200 bg-gray-100 shadow-sm p-1" }, /* @__PURE__ */ React21.createElement(
|
|
8275
8523
|
"button",
|
|
8276
8524
|
{
|
|
8277
8525
|
type: "button",
|
|
8278
8526
|
onClick: () => setViewMode("grid"),
|
|
8279
|
-
className: `flex items-center gap-2 rounded-
|
|
8527
|
+
className: `flex items-center gap-2 rounded-full px-4 py-2 text-sm font-medium transition ${viewMode === "grid" ? "bg-white text-primary shadow-md" : "text-gray-500 hover:text-gray-700"}`,
|
|
8280
8528
|
"aria-pressed": viewMode === "grid"
|
|
8281
8529
|
},
|
|
8282
|
-
/* @__PURE__ */ React21.createElement(LayoutGrid, { className: "h-4 w-4" })
|
|
8283
|
-
"Grid"
|
|
8530
|
+
/* @__PURE__ */ React21.createElement(LayoutGrid, { className: "h-4 w-4" })
|
|
8284
8531
|
), /* @__PURE__ */ React21.createElement(
|
|
8285
8532
|
"button",
|
|
8286
8533
|
{
|
|
8287
8534
|
type: "button",
|
|
8288
8535
|
onClick: () => setViewMode("list"),
|
|
8289
|
-
className: `flex items-center gap-2 rounded-
|
|
8536
|
+
className: `flex items-center gap-2 rounded-full px-4 py-2 text-sm font-medium transition ${viewMode === "list" ? "bg-white text-primary shadow-md" : "text-gray-500 hover:text-gray-700"}`,
|
|
8290
8537
|
"aria-pressed": viewMode === "list"
|
|
8291
8538
|
},
|
|
8292
|
-
/* @__PURE__ */ React21.createElement(LayoutList, { className: "h-4 w-4" })
|
|
8293
|
-
|
|
8294
|
-
)))), /* @__PURE__ */ React21.createElement("div", { className: "mt-4 md:hidden" }, /* @__PURE__ */ React21.createElement(
|
|
8295
|
-
Button,
|
|
8296
|
-
{
|
|
8297
|
-
variant: "outline",
|
|
8298
|
-
className: "w-full",
|
|
8299
|
-
onClick: () => setShowFilters(true)
|
|
8300
|
-
},
|
|
8301
|
-
/* @__PURE__ */ React21.createElement(SlidersHorizontal, { className: "h-5 w-5" }),
|
|
8302
|
-
"Filters",
|
|
8303
|
-
hasActiveFilters && /* @__PURE__ */ React21.createElement("span", { className: "ml-2 rounded-full bg-primary-600 px-2 py-0.5 text-xs font-semibold text-white" }, activeFilterChips.length)
|
|
8304
|
-
)), hasActiveFilters && /* @__PURE__ */ React21.createElement("div", { className: "mt-6 flex flex-wrap items-center gap-2 border-t border-gray-100 pt-4" }, activeFilterChips.map((chip) => /* @__PURE__ */ React21.createElement(
|
|
8539
|
+
/* @__PURE__ */ React21.createElement(LayoutList, { className: "h-4 w-4" })
|
|
8540
|
+
)))), hasActiveFilters && /* @__PURE__ */ React21.createElement("div", { className: "mt-6 flex flex-wrap items-center gap-2 border-t border-gray-100 pt-4" }, activeFilterChips.map((chip) => /* @__PURE__ */ React21.createElement(
|
|
8305
8541
|
"button",
|
|
8306
8542
|
{
|
|
8307
8543
|
key: chip.key,
|
|
@@ -8340,7 +8576,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
8340
8576
|
onClick: () => router.push(buildPath(`/products/${product._id}`))
|
|
8341
8577
|
},
|
|
8342
8578
|
/* @__PURE__ */ React21.createElement("div", { className: "relative h-48 w-full overflow-hidden rounded-2xl bg-gray-100 md:h-40 md:w-40" }, /* @__PURE__ */ React21.createElement(
|
|
8343
|
-
|
|
8579
|
+
Image4,
|
|
8344
8580
|
{
|
|
8345
8581
|
src: product.productMedia[0]?.file || "/placeholder-product.jpg",
|
|
8346
8582
|
alt: product.name,
|
|
@@ -8356,14 +8592,14 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
8356
8592
|
},
|
|
8357
8593
|
tag
|
|
8358
8594
|
))), /* @__PURE__ */ React21.createElement("h3", { className: "text-xl font-semibold text-gray-900" }, product.name), /* @__PURE__ */ React21.createElement("div", { className: "flex flex-wrap items-center gap-4 text-sm text-gray-500" }, /* @__PURE__ */ React21.createElement("span", { className: "inline-flex items-center gap-2 font-medium text-primary-600" }, /* @__PURE__ */ React21.createElement(ShieldCheck, { className: "h-4 w-4" }), product.inventoryCount > 0 ? "In stock & ready to ship" : "Restocking soon"), /* @__PURE__ */ React21.createElement("span", { className: "inline-flex items-center gap-2" }, /* @__PURE__ */ React21.createElement(Clock, { className: "h-4 w-4 text-primary-500" }), "Added ", new Date(product.createdAt).toLocaleDateString()))),
|
|
8359
|
-
/* @__PURE__ */ React21.createElement("div", { className: "flex w-full flex-col items-end gap-3 md:w-auto" }, /* @__PURE__ */ React21.createElement("div", { className: "text-right" }, /* @__PURE__ */ React21.createElement("p", { className: "text-3xl font-semibold text-gray-900" }, formatPrice(product.finalPrice)), product.
|
|
8360
|
-
|
|
8595
|
+
/* @__PURE__ */ React21.createElement("div", { className: "flex w-full flex-col items-end gap-3 md:w-auto" }, /* @__PURE__ */ React21.createElement("div", { className: "text-right" }, /* @__PURE__ */ React21.createElement("p", { className: "text-3xl font-semibold text-gray-900" }, formatPrice(product.finalPrice)), product.isDiscounted && /* @__PURE__ */ React21.createElement("p", { className: "text-sm text-gray-400 line-through" }, formatPrice(product.priceBeforeDiscount))), /* @__PURE__ */ React21.createElement(
|
|
8596
|
+
"button",
|
|
8361
8597
|
{
|
|
8362
|
-
size: "sm",
|
|
8363
8598
|
onClick: (event) => {
|
|
8364
8599
|
event.stopPropagation();
|
|
8365
8600
|
router.push(buildPath(`/products/${product._id}`));
|
|
8366
|
-
}
|
|
8601
|
+
},
|
|
8602
|
+
className: "w-full font-['Poppins',sans-serif] font-medium text-sm px-3 py-2 rounded-xl bg-secondary text-white hover:opacity-80 hover:shadow-lg transition-all duration-300 flex items-center justify-center gap-1.5 disabled:opacity-50 disabled:cursor-not-allowed"
|
|
8367
8603
|
},
|
|
8368
8604
|
"View product"
|
|
8369
8605
|
))
|
|
@@ -8393,50 +8629,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
8393
8629
|
disabled: page === pagination.totalPages
|
|
8394
8630
|
},
|
|
8395
8631
|
"Next"
|
|
8396
|
-
)))))))
|
|
8397
|
-
motion.div,
|
|
8398
|
-
{
|
|
8399
|
-
initial: { opacity: 0 },
|
|
8400
|
-
animate: { opacity: 1 },
|
|
8401
|
-
exit: { opacity: 0 },
|
|
8402
|
-
className: "fixed inset-0 z-50 bg-black/40 backdrop-blur-sm lg:hidden"
|
|
8403
|
-
},
|
|
8404
|
-
/* @__PURE__ */ React21.createElement(
|
|
8405
|
-
motion.div,
|
|
8406
|
-
{
|
|
8407
|
-
initial: { y: "100%" },
|
|
8408
|
-
animate: { y: 0 },
|
|
8409
|
-
exit: { y: "100%" },
|
|
8410
|
-
transition: { type: "spring", stiffness: 260, damping: 26 },
|
|
8411
|
-
className: "absolute inset-x-0 bottom-0 max-h-[85vh] overflow-y-auto rounded-t-3xl bg-white p-6 shadow-2xl"
|
|
8412
|
-
},
|
|
8413
|
-
/* @__PURE__ */ React21.createElement("div", { className: "mb-6 flex items-center justify-between" }, /* @__PURE__ */ React21.createElement("h3", { className: "text-lg font-semibold text-gray-900" }, "Filters"), /* @__PURE__ */ React21.createElement(
|
|
8414
|
-
"button",
|
|
8415
|
-
{
|
|
8416
|
-
type: "button",
|
|
8417
|
-
onClick: () => setShowFilters(false),
|
|
8418
|
-
className: "rounded-full border border-gray-200 p-2 text-gray-500 hover:text-gray-700"
|
|
8419
|
-
},
|
|
8420
|
-
/* @__PURE__ */ React21.createElement(X, { className: "h-4 w-4" })
|
|
8421
|
-
)),
|
|
8422
|
-
renderFiltersPanel()
|
|
8423
|
-
)
|
|
8424
|
-
)));
|
|
8425
|
-
}
|
|
8426
|
-
function Badge({ children, variant = "primary", size = "md", className = "" }) {
|
|
8427
|
-
const variants = {
|
|
8428
|
-
primary: "bg-primary-100 text-primary-700 border-primary-200",
|
|
8429
|
-
secondary: "bg-secondary-100 text-secondary-700 border-secondary-200",
|
|
8430
|
-
success: "bg-green-100 text-green-700 border-green-200",
|
|
8431
|
-
warning: "bg-yellow-100 text-yellow-700 border-yellow-200",
|
|
8432
|
-
danger: "bg-red-100 text-red-700 border-red-200",
|
|
8433
|
-
gray: "bg-gray-100 text-gray-700 border-gray-200"
|
|
8434
|
-
};
|
|
8435
|
-
const sizes = {
|
|
8436
|
-
sm: "px-2 py-1 text-xs",
|
|
8437
|
-
md: "px-3 py-1 text-sm"
|
|
8438
|
-
};
|
|
8439
|
-
return /* @__PURE__ */ React21.createElement("span", { className: `inline-flex items-center font-medium rounded-full border ${variants[variant]} ${sizes[size]} ${className}` }, children);
|
|
8632
|
+
))))))));
|
|
8440
8633
|
}
|
|
8441
8634
|
var safeFormatDate = (date, format = "long") => {
|
|
8442
8635
|
if (!date) return "N/A";
|
|
@@ -8453,6 +8646,7 @@ function ProductDetailScreen({ productId }) {
|
|
|
8453
8646
|
const { buildPath } = useBasePath();
|
|
8454
8647
|
const { product: productData, isLoading } = useProduct(productId);
|
|
8455
8648
|
const { addToCart } = useCart();
|
|
8649
|
+
const notification = useNotification();
|
|
8456
8650
|
const [selectedVariant, setSelectedVariant] = useState(null);
|
|
8457
8651
|
const [quantity, setQuantity] = useState(1);
|
|
8458
8652
|
const [isAddingToCart, setIsAddingToCart] = useState(false);
|
|
@@ -8460,10 +8654,14 @@ function ProductDetailScreen({ productId }) {
|
|
|
8460
8654
|
const [relatedProducts, setRelatedProducts] = useState([]);
|
|
8461
8655
|
const [initialProductData, setInitialProductData] = useState(null);
|
|
8462
8656
|
const [activeImageIndex, setActiveImageIndex] = useState(0);
|
|
8657
|
+
const [activeTab, setActiveTab] = useState("description");
|
|
8463
8658
|
useEffect(() => {
|
|
8464
8659
|
setActiveImageIndex(0);
|
|
8465
8660
|
}, [selectedVariant]);
|
|
8466
8661
|
const product = useMemo(() => {
|
|
8662
|
+
console.log("productData", productData);
|
|
8663
|
+
console.log("selectedVariant", selectedVariant);
|
|
8664
|
+
console.log("initialProductData", initialProductData);
|
|
8467
8665
|
if (initialProductData && !productData) {
|
|
8468
8666
|
return initialProductData;
|
|
8469
8667
|
}
|
|
@@ -8518,12 +8716,11 @@ function ProductDetailScreen({ productId }) {
|
|
|
8518
8716
|
const variantImages = getVariantImages();
|
|
8519
8717
|
const variantPrice = selectedVariant?.finalPrice || currentVariant?.finalPrice || product?.price || 0;
|
|
8520
8718
|
const variantComparePrice = selectedVariant?.retailPrice || (currentVariant && "retailPrice" in currentVariant ? currentVariant.retailPrice : null) || product?.compareAtPrice;
|
|
8521
|
-
const discount = variantComparePrice && variantPrice && variantComparePrice > variantPrice ? Math.round((variantComparePrice - variantPrice) / variantComparePrice * 100) : 0;
|
|
8522
8719
|
const lastUpdatedLabel = safeFormatDate(
|
|
8523
8720
|
currentVariant && "updatedAt" in currentVariant && currentVariant.updatedAt ? currentVariant.updatedAt : product?.updatedAt
|
|
8524
8721
|
);
|
|
8525
|
-
|
|
8526
|
-
|
|
8722
|
+
currentVariant?.sku || product?.sku || "N/A";
|
|
8723
|
+
currentVariant?.inventoryCount > 0;
|
|
8527
8724
|
useEffect(() => {
|
|
8528
8725
|
if (typeof window === "undefined") return;
|
|
8529
8726
|
const searchParams = new URLSearchParams(window.location.search);
|
|
@@ -8574,12 +8771,16 @@ function ProductDetailScreen({ productId }) {
|
|
|
8574
8771
|
quantity,
|
|
8575
8772
|
selectedVariant.id
|
|
8576
8773
|
);
|
|
8577
|
-
|
|
8578
|
-
|
|
8579
|
-
|
|
8774
|
+
notification.success(
|
|
8775
|
+
"Added to cart",
|
|
8776
|
+
`${quantity} \xD7 ${product.name}${selectedVariant.name ? ` (${selectedVariant.name})` : ""} added to your cart.`
|
|
8777
|
+
);
|
|
8580
8778
|
} catch (error) {
|
|
8581
8779
|
console.error("Failed to add to cart", error);
|
|
8582
|
-
|
|
8780
|
+
notification.error(
|
|
8781
|
+
"Could not add to cart",
|
|
8782
|
+
"Something went wrong while adding this item. Please try again."
|
|
8783
|
+
);
|
|
8583
8784
|
} finally {
|
|
8584
8785
|
setIsAddingToCart(false);
|
|
8585
8786
|
}
|
|
@@ -8595,33 +8796,41 @@ function ProductDetailScreen({ productId }) {
|
|
|
8595
8796
|
try {
|
|
8596
8797
|
if (isFavorited) {
|
|
8597
8798
|
await removeFromWishlist(product.id);
|
|
8598
|
-
|
|
8799
|
+
notification.info(
|
|
8800
|
+
"Removed from saved items",
|
|
8801
|
+
`${product.name} was removed from your saved items.`
|
|
8802
|
+
);
|
|
8599
8803
|
} else {
|
|
8600
8804
|
await addToWishlist(product);
|
|
8601
|
-
|
|
8805
|
+
notification.success(
|
|
8806
|
+
"Saved to favorites",
|
|
8807
|
+
`${product.name} was added to your favorites.`
|
|
8808
|
+
);
|
|
8602
8809
|
}
|
|
8603
8810
|
setIsFavorited(!isFavorited);
|
|
8604
8811
|
} catch (error) {
|
|
8605
8812
|
console.error("Error updating wishlist:", error);
|
|
8606
|
-
|
|
8813
|
+
notification.error(
|
|
8814
|
+
"Could not update favorites",
|
|
8815
|
+
"We could not update your favorites. Please try again."
|
|
8816
|
+
);
|
|
8607
8817
|
}
|
|
8608
8818
|
};
|
|
8609
8819
|
if (isLoading) {
|
|
8610
8820
|
return /* @__PURE__ */ React21.createElement("div", { className: "min-h-screen bg-slate-50" }, /* @__PURE__ */ React21.createElement("div", { className: "container mx-auto px-4 py-16" }, /* @__PURE__ */ React21.createElement("div", { className: "grid gap-10 lg:grid-cols-[minmax(0,2fr)_minmax(0,1fr)]" }, /* @__PURE__ */ React21.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React21.createElement("div", { className: "h-[520px] animate-pulse rounded-3xl bg-slate-200" }), /* @__PURE__ */ React21.createElement("div", { className: "grid grid-cols-3 gap-4" }, Array.from({ length: 3 }).map((_, index) => /* @__PURE__ */ React21.createElement("div", { key: index, className: "h-32 animate-pulse rounded-2xl bg-slate-200" })))), /* @__PURE__ */ React21.createElement("div", { className: "space-y-4 rounded-3xl bg-white p-6 shadow-sm" }, /* @__PURE__ */ React21.createElement("div", { className: "h-8 w-32 animate-pulse rounded-full bg-slate-200" }), /* @__PURE__ */ React21.createElement("div", { className: "h-10 w-48 animate-pulse rounded-full bg-slate-200" }), /* @__PURE__ */ React21.createElement("div", { className: "h-6 w-full animate-pulse rounded-full bg-slate-200" }), /* @__PURE__ */ React21.createElement("div", { className: "h-12 w-full animate-pulse rounded-2xl bg-slate-200" }), /* @__PURE__ */ React21.createElement("div", { className: "h-12 w-full animate-pulse rounded-2xl bg-slate-200" })))));
|
|
8611
8821
|
}
|
|
8612
8822
|
if (!product) {
|
|
8613
|
-
return /* @__PURE__ */ React21.createElement("div", { className: "min-h-screen bg-slate-50" }, /* @__PURE__ */ React21.createElement("div", { className: "container mx-auto px-4 py-16" }, /* @__PURE__ */ React21.createElement("div", { className: "rounded-3xl bg-white p-10 text-center shadow-sm" }, /* @__PURE__ */ React21.createElement(Sparkles, { className: "mx-auto h-10 w-10 text-primary-500" }), /* @__PURE__ */ React21.createElement("h1", { className: "mt-6 text-2xl font-semibold text-gray-900" }, "Product not found"), /* @__PURE__ */ React21.createElement("p", { className: "mt-2 text-gray-600" }, "It may have been removed or is temporarily unavailable. Discover other pharmacy essentials in our catalogue."), /* @__PURE__ */ React21.createElement("div", { className: "mt-6" }, /* @__PURE__ */ React21.createElement(
|
|
8823
|
+
return /* @__PURE__ */ React21.createElement("div", { className: "min-h-screen bg-slate-50" }, /* @__PURE__ */ React21.createElement("div", { className: "container mx-auto px-4 py-16" }, /* @__PURE__ */ React21.createElement("div", { className: "rounded-3xl bg-white p-10 text-center shadow-sm" }, /* @__PURE__ */ React21.createElement(Sparkles, { className: "mx-auto h-10 w-10 text-primary-500" }), /* @__PURE__ */ React21.createElement("h1", { className: "mt-6 text-2xl font-semibold text-gray-900" }, "Product not found"), /* @__PURE__ */ React21.createElement("p", { className: "mt-2 text-gray-600" }, "It may have been removed or is temporarily unavailable. Discover other pharmacy essentials in our catalogue."), /* @__PURE__ */ React21.createElement("div", { className: "mt-6" }, /* @__PURE__ */ React21.createElement(Link7, { href: "/shop", className: "inline-block" }, /* @__PURE__ */ React21.createElement(Button, null, "Browse products"))))));
|
|
8614
8824
|
}
|
|
8615
|
-
return /* @__PURE__ */ React21.createElement("div", { className: "bg-white" }, /* @__PURE__ */ React21.createElement("div", { className: "
|
|
8616
|
-
|
|
8825
|
+
return /* @__PURE__ */ React21.createElement("div", { className: "min-h-screen bg-white" }, /* @__PURE__ */ React21.createElement("div", { className: "bg-gray-50 border-b border-gray-200 py-4" }, /* @__PURE__ */ React21.createElement("div", { className: "max-w-[1400px] mx-auto px-8 md:px-12" }, /* @__PURE__ */ React21.createElement(
|
|
8826
|
+
"button",
|
|
8617
8827
|
{
|
|
8618
|
-
|
|
8619
|
-
className: "
|
|
8620
|
-
onClick: () => router.push(buildPath("/shop"))
|
|
8828
|
+
onClick: () => router.push(buildPath("/shop")),
|
|
8829
|
+
className: "flex items-center gap-2 font-['Poppins',sans-serif] text-[13px] text-muted hover:text-primary transition-colors"
|
|
8621
8830
|
},
|
|
8622
|
-
/* @__PURE__ */ React21.createElement(
|
|
8831
|
+
/* @__PURE__ */ React21.createElement(ChevronLeft, { className: "size-4" }),
|
|
8623
8832
|
"Back to Shop"
|
|
8624
|
-
)), /* @__PURE__ */ React21.createElement("div", { className: "grid gap-10 lg:grid-cols-[minmax(0,50fr)_minmax(0,50fr)]" }, /* @__PURE__ */ React21.createElement("div", { className: "space-y-10" }, /* @__PURE__ */ React21.createElement("section", { className: "rounded-3xl " }, /* @__PURE__ */ React21.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React21.createElement(
|
|
8833
|
+
))), /* @__PURE__ */ React21.createElement("section", { className: "py-12" }, /* @__PURE__ */ React21.createElement("div", { className: "relative pb-20 pt-8" }, /* @__PURE__ */ React21.createElement("div", { className: "container mx-auto px-4" }, /* @__PURE__ */ React21.createElement("div", { className: "grid gap-10 lg:grid-cols-[minmax(0,50fr)_minmax(0,50fr)]" }, /* @__PURE__ */ React21.createElement("div", { className: "space-y-10" }, /* @__PURE__ */ React21.createElement("section", { className: "rounded-3xl " }, /* @__PURE__ */ React21.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React21.createElement(
|
|
8625
8834
|
motion.div,
|
|
8626
8835
|
{
|
|
8627
8836
|
key: selectedVariant?.id || "default",
|
|
@@ -8631,7 +8840,7 @@ function ProductDetailScreen({ productId }) {
|
|
|
8631
8840
|
className: "relative overflow-hidden rounded-3xl bg-slate-100 h-[420px] md:h-[560px]"
|
|
8632
8841
|
},
|
|
8633
8842
|
variantImages.length > 0 && variantImages[activeImageIndex] ? /* @__PURE__ */ React21.createElement(
|
|
8634
|
-
|
|
8843
|
+
Image4,
|
|
8635
8844
|
{
|
|
8636
8845
|
src: variantImages[activeImageIndex].src || variantImages[activeImageIndex].url || variantImages[activeImageIndex].file,
|
|
8637
8846
|
alt: currentVariant.name || product.name,
|
|
@@ -8641,7 +8850,7 @@ function ProductDetailScreen({ productId }) {
|
|
|
8641
8850
|
className: "object-contain"
|
|
8642
8851
|
}
|
|
8643
8852
|
) : product?.productMedia?.[0]?.file ? /* @__PURE__ */ React21.createElement(
|
|
8644
|
-
|
|
8853
|
+
Image4,
|
|
8645
8854
|
{
|
|
8646
8855
|
src: product.productMedia[0].file,
|
|
8647
8856
|
alt: product.name,
|
|
@@ -8651,34 +8860,17 @@ function ProductDetailScreen({ productId }) {
|
|
|
8651
8860
|
className: "object-contain"
|
|
8652
8861
|
}
|
|
8653
8862
|
) : null,
|
|
8654
|
-
|
|
8655
|
-
Badge,
|
|
8656
|
-
{
|
|
8657
|
-
variant: "danger",
|
|
8658
|
-
className: "absolute left-6 top-6 shadow-lg shadow-red-500/20"
|
|
8659
|
-
},
|
|
8660
|
-
"Save ",
|
|
8661
|
-
discount,
|
|
8662
|
-
"%"
|
|
8663
|
-
),
|
|
8664
|
-
!variantInStock && /* @__PURE__ */ React21.createElement(
|
|
8665
|
-
Badge,
|
|
8666
|
-
{
|
|
8667
|
-
variant: "secondary",
|
|
8668
|
-
className: "absolute right-6 top-6 bg-white/90 text-slate-700 shadow-lg border-slate-200"
|
|
8669
|
-
},
|
|
8670
|
-
"Out of Stock"
|
|
8671
|
-
)
|
|
8863
|
+
/* @__PURE__ */ React21.createElement("div", { className: "absolute top-6 left-6 flex flex-col gap-3" }, product.salePrice && /* @__PURE__ */ React21.createElement("div", { className: "bg-[#E67E50] text-white rounded-full px-4 py-2" }, /* @__PURE__ */ React21.createElement("span", { className: "font-['Poppins',sans-serif] font-bold text-[12px] uppercase tracking-wide" }, "Save ", product.discount, "%")))
|
|
8672
8864
|
), variantImages.length > 0 && /* @__PURE__ */ React21.createElement("div", { className: "grid grid-cols-8 gap-2" }, variantImages.map((image, index) => /* @__PURE__ */ React21.createElement(
|
|
8673
8865
|
"button",
|
|
8674
8866
|
{
|
|
8675
8867
|
key: image.src + index,
|
|
8676
8868
|
type: "button",
|
|
8677
8869
|
onClick: () => setActiveImageIndex(index),
|
|
8678
|
-
className: `relative aspect-square overflow-hidden rounded-lg border-2 transition-all ${activeImageIndex === index ? "border-primary
|
|
8870
|
+
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"}`
|
|
8679
8871
|
},
|
|
8680
8872
|
/* @__PURE__ */ React21.createElement(
|
|
8681
|
-
|
|
8873
|
+
Image4,
|
|
8682
8874
|
{
|
|
8683
8875
|
src: image?.src,
|
|
8684
8876
|
alt: image.alt || `Product image ${index + 1}`,
|
|
@@ -8688,7 +8880,13 @@ function ProductDetailScreen({ productId }) {
|
|
|
8688
8880
|
unoptimized: true
|
|
8689
8881
|
}
|
|
8690
8882
|
)
|
|
8691
|
-
)))))), /* @__PURE__ */ React21.createElement("aside", { className: "space-y-6 lg:sticky lg:top-24" }, /* @__PURE__ */ React21.createElement("div", { className: "" },
|
|
8883
|
+
)))))), /* @__PURE__ */ React21.createElement("aside", { className: "space-y-6 lg:sticky lg:top-24" }, /* @__PURE__ */ React21.createElement("div", { className: "mb-4" }, /* @__PURE__ */ React21.createElement("p", { className: "font-['Poppins',sans-serif] text-[12px] text-primary uppercase tracking-wide font-medium mb-2" }, product.brand, " \u2022 ", product.parentCategories?.[0].name), /* @__PURE__ */ React21.createElement("h1", { className: "text-3xl font-['Poppins',sans-serif] font-semibold text-secondary tracking-[-1.5px] mb-3" }, product.name), /* @__PURE__ */ React21.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ React21.createElement("div", { className: "flex items-center gap-1" }, [...Array(5)].map((_, i) => /* @__PURE__ */ React21.createElement(
|
|
8884
|
+
Star,
|
|
8885
|
+
{
|
|
8886
|
+
key: i,
|
|
8887
|
+
className: `size-4 ${i < Math.floor(product.rating) ? "text-[#E67E50] fill-[#E67E50]" : "text-gray-300"}`
|
|
8888
|
+
}
|
|
8889
|
+
))), /* @__PURE__ */ React21.createElement("span", { className: "font-['Poppins',sans-serif] text-[14px] text-muted" }, product.rating, " (", product.reviewCount ? product.reviewCount : 0, " reviews)")), /* @__PURE__ */ React21.createElement("div", { className: "flex items-center gap-3 mb-6 pb-6 border-b-2 border-gray-100" }, /* @__PURE__ */ React21.createElement("span", { className: "font-['Poppins',sans-serif] font-bold text-[40px] text-[#E67E50]" }, selectedVariant ? formatPrice(selectedVariant.finalPrice) : formatPrice(product.finalPrice || product.price || 0)), variantComparePrice && variantComparePrice > variantPrice && /* @__PURE__ */ React21.createElement(React21.Fragment, null, /* @__PURE__ */ React21.createElement("span", { className: "font-['Poppins',sans-serif] text-[24px] text-muted line-through" }, "$", product.price.toFixed(2)), /* @__PURE__ */ React21.createElement("div", { className: "px-3 py-1 rounded-full bg-[#E67E50]/10" }, /* @__PURE__ */ React21.createElement("span", { className: "font-['Poppins',sans-serif] font-semibold text-[13px] text-[#E67E50]" }, "Save $", formatPrice(variantComparePrice))))), selectedVariant && /* @__PURE__ */ React21.createElement("div", { className: "mb-6" }, /* @__PURE__ */ React21.createElement("div", { className: "flex items-center gap-2 mb-2" }, selectedVariant.inventoryStatus === "OUT_OF_STOCK" /* OUTOFSTOCK */ || selectedVariant.inventoryStatus === "LOW_STOCK" /* LOWSTOCK */ ? /* @__PURE__ */ React21.createElement(React21.Fragment, null, /* @__PURE__ */ React21.createElement("div", { className: "size-3 rounded-full bg-red-500" }), /* @__PURE__ */ React21.createElement("span", { className: "font-['Poppins',sans-serif] text-[13px] text-red-600 font-medium" }, "Out of Stock")) : selectedVariant.inventoryCount <= 10 ? /* @__PURE__ */ React21.createElement(React21.Fragment, null, /* @__PURE__ */ React21.createElement("div", { className: "size-3 rounded-full bg-orange-500 animate-pulse" }), /* @__PURE__ */ React21.createElement("span", { className: "font-['Poppins',sans-serif] text-[13px] text-orange-600 font-medium" }, "Only ", selectedVariant.inventoryCount, " left in stock - Order soon!")) : /* @__PURE__ */ React21.createElement(React21.Fragment, null, /* @__PURE__ */ React21.createElement("div", { className: "size-3 rounded-full bg-green-500" }), /* @__PURE__ */ React21.createElement("span", { className: "font-['Poppins',sans-serif] text-[13px] text-green-600 font-medium" }, "In Stock"))), /* @__PURE__ */ React21.createElement("p", { className: "font-['Poppins',sans-serif] text-[12px] text-muted" }, "SKU: ", selectedVariant?.sku)), product.description && /* @__PURE__ */ React21.createElement("p", { className: "font-['Poppins',sans-serif] text-[14px] text-muted leading-[1.7] mb-8" }, /* @__PURE__ */ React21.createElement("div", { dangerouslySetInnerHTML: { __html: product.description } })), product?.productVariants && product.productVariants.length > 0 && /* @__PURE__ */ React21.createElement("div", { className: "mb-6" }, /* @__PURE__ */ React21.createElement("h3", { className: "font-['Poppins',sans-serif] font-semibold text-[14px] text-secondary mb-3" }, "Select Variant"), /* @__PURE__ */ React21.createElement("div", { className: "flex flex-wrap gap-3" }, product.productVariants.map((variant) => {
|
|
8692
8890
|
const isSelected = selectedVariant?.id === variant.id;
|
|
8693
8891
|
const variantImage = variant.productMedia?.[0]?.file || product.productMedia?.[0]?.file || product.images?.[0] || "/placeholder-product.jpg";
|
|
8694
8892
|
return /* @__PURE__ */ React21.createElement(
|
|
@@ -8697,10 +8895,10 @@ function ProductDetailScreen({ productId }) {
|
|
|
8697
8895
|
key: variant.id,
|
|
8698
8896
|
type: "button",
|
|
8699
8897
|
onClick: () => handleVariantSelect(variant),
|
|
8700
|
-
className: `flex
|
|
8898
|
+
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"}`
|
|
8701
8899
|
},
|
|
8702
|
-
/* @__PURE__ */ React21.createElement("div", { className: `relative h-12 w-12 flex-shrink-0 overflow-hidden rounded-full border-2 ${isSelected ? "border-primary
|
|
8703
|
-
|
|
8900
|
+
/* @__PURE__ */ React21.createElement("div", { className: `relative h-12 w-12 flex-shrink-0 overflow-hidden rounded-full border-2 ${isSelected ? "border-primary" : "border-slate-200"}` }, /* @__PURE__ */ React21.createElement(
|
|
8901
|
+
Image4,
|
|
8704
8902
|
{
|
|
8705
8903
|
src: variantImage,
|
|
8706
8904
|
alt: variant.name || "Variant image",
|
|
@@ -8709,60 +8907,53 @@ function ProductDetailScreen({ productId }) {
|
|
|
8709
8907
|
sizes: "48px"
|
|
8710
8908
|
}
|
|
8711
8909
|
)),
|
|
8712
|
-
/* @__PURE__ */ React21.createElement("div", { className: "flex-1" }, /* @__PURE__ */ React21.createElement("p", { className: `text-sm font-medium ${isSelected ? "text-
|
|
8713
|
-
isSelected && /* @__PURE__ */ React21.createElement(Check, { className: "h-5 w-5 text-
|
|
8910
|
+
/* @__PURE__ */ React21.createElement("div", { className: "flex-1" }, /* @__PURE__ */ React21.createElement("p", { className: `text-start text-sm font-medium ${isSelected ? "text-secondary" : "text-slate-900"}` }, variant.name), variant.sku && /* @__PURE__ */ React21.createElement("p", { className: "text-start text-xs text-slate-500 mt-0.5" }, "SKU: ", variant.sku)),
|
|
8911
|
+
isSelected && /* @__PURE__ */ React21.createElement(Check, { className: "h-5 w-5 text-secondary flex-shrink-0" })
|
|
8714
8912
|
);
|
|
8715
|
-
}))), /* @__PURE__ */ React21.createElement("div", { className: "
|
|
8913
|
+
}))), /* @__PURE__ */ React21.createElement("div", { className: "mb-8" }, /* @__PURE__ */ React21.createElement("h3", { className: "font-['Poppins',sans-serif] font-semibold text-[14px] text-secondary mb-3" }, "Quantity"), /* @__PURE__ */ React21.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ React21.createElement("div", { className: "flex items-center gap-4 bg-gray-100 rounded-full px-6 py-3" }, /* @__PURE__ */ React21.createElement(
|
|
8716
8914
|
"button",
|
|
8717
8915
|
{
|
|
8718
8916
|
type: "button",
|
|
8719
8917
|
onClick: () => setQuantity((current) => Math.max(1, current - 1)),
|
|
8720
|
-
className: "
|
|
8721
|
-
"aria-label": "
|
|
8918
|
+
className: "font-['Poppins',sans-serif] font-bold text-[18px] text-secondary hover:text-primary transition-colors",
|
|
8919
|
+
"aria-label": "Increase quantity"
|
|
8722
8920
|
},
|
|
8723
|
-
|
|
8724
|
-
), /* @__PURE__ */ React21.createElement("span", { className: "
|
|
8921
|
+
"-"
|
|
8922
|
+
), /* @__PURE__ */ React21.createElement("span", { className: "font-['Poppins',sans-serif] font-semibold text-[16px] text-secondary min-w-[30px] text-center" }, quantity), /* @__PURE__ */ React21.createElement(
|
|
8725
8923
|
"button",
|
|
8726
8924
|
{
|
|
8727
|
-
|
|
8728
|
-
|
|
8729
|
-
|
|
8730
|
-
return Math.min(maxQty, current + 1);
|
|
8731
|
-
}),
|
|
8732
|
-
className: "px-3 py-2 hover:bg-slate-50",
|
|
8733
|
-
"aria-label": "Increase quantity"
|
|
8925
|
+
onClick: () => setQuantity(Math.min(selectedVariant?.inventoryCount || product.inventoryCount || 999, quantity + 1)),
|
|
8926
|
+
disabled: quantity >= (selectedVariant?.inventoryCount || product.inventoryCount || 0),
|
|
8927
|
+
className: "font-['Poppins',sans-serif] font-bold text-[18px] text-secondary hover:text-primary transition-colors disabled:opacity-50"
|
|
8734
8928
|
},
|
|
8735
|
-
|
|
8736
|
-
)), selectedVariant && /* @__PURE__ */ React21.createElement("span", { className: "text-sm text-slate-500" }, selectedVariant.inventoryCount || product.inventoryCount || 0, " available"))), /* @__PURE__ */ React21.createElement("div", { className: "flex flex-col gap-
|
|
8737
|
-
|
|
8929
|
+
"+"
|
|
8930
|
+
)), selectedVariant && /* @__PURE__ */ React21.createElement("span", { className: "text-sm text-slate-500" }, selectedVariant.inventoryCount || product.inventoryCount || 0, " available"))), /* @__PURE__ */ React21.createElement("div", { className: "flex flex-col sm:flex-row gap-3 mb-8" }, /* @__PURE__ */ React21.createElement(
|
|
8931
|
+
"button",
|
|
8738
8932
|
{
|
|
8739
|
-
|
|
8740
|
-
className: "w-full bg-orange-500 hover:bg-orange-600 text-white py-2.5",
|
|
8933
|
+
className: "flex-1 font-['Poppins',sans-serif] font-medium text-[14px] px-8 py-4 rounded-full transition-all duration-300 flex items-center justify-center gap-3 bg-[#E67E50] text-white hover:bg-[#d66f45] hover:shadow-lg disabled:opacity-50 disabled:cursor-not-allowed",
|
|
8741
8934
|
onClick: handleAddToCart,
|
|
8742
|
-
isLoading: isAddingToCart,
|
|
8743
8935
|
disabled: !selectedVariant || selectedVariant.inventoryStatus === "OUT_OF_STOCK" /* OUTOFSTOCK */
|
|
8744
8936
|
},
|
|
8745
|
-
/* @__PURE__ */ React21.createElement(ShoppingCart, { className: "h-4 w-4" }),
|
|
8746
|
-
!selectedVariant ? "Select a variant" : selectedVariant.inventoryStatus === "OUT_OF_STOCK" /* OUTOFSTOCK */ ? "Out of Stock" : "Add to Cart"
|
|
8937
|
+
isAddingToCart ? /* @__PURE__ */ React21.createElement(React21.Fragment, null, /* @__PURE__ */ React21.createElement("svg", { className: "animate-spin h-5 w-5", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", "aria-hidden": "true" }, /* @__PURE__ */ React21.createElement("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), /* @__PURE__ */ React21.createElement("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })), "Loading...") : /* @__PURE__ */ React21.createElement(React21.Fragment, null, /* @__PURE__ */ React21.createElement(ShoppingCart, { className: "h-4 w-4" }), !selectedVariant ? "Select a variant" : selectedVariant.inventoryStatus === "OUT_OF_STOCK" /* OUTOFSTOCK */ ? "Out of Stock" : "Add to Cart")
|
|
8747
8938
|
), /* @__PURE__ */ React21.createElement(
|
|
8748
|
-
|
|
8939
|
+
"button",
|
|
8749
8940
|
{
|
|
8750
|
-
|
|
8751
|
-
variant: "outline",
|
|
8752
|
-
className: "w-full py-2.5",
|
|
8941
|
+
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",
|
|
8753
8942
|
onClick: handleToggleFavorite
|
|
8754
8943
|
},
|
|
8755
|
-
/* @__PURE__ */ React21.createElement(
|
|
8756
|
-
|
|
8757
|
-
|
|
8758
|
-
|
|
8759
|
-
|
|
8760
|
-
|
|
8761
|
-
|
|
8762
|
-
|
|
8944
|
+
/* @__PURE__ */ React21.createElement(Heart, { className: `h-4 w-4 ${isFavorited ? "fill-red-500 text-red-500" : "text-primary"}` })
|
|
8945
|
+
))), /* @__PURE__ */ React21.createElement("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-4 p-6 bg-gradient-to-br from-[#5B9BD5]/5 to-[#2B4B7C]/5 rounded-[24px]" }, /* @__PURE__ */ React21.createElement("div", { className: "flex items-start gap-3" }, /* @__PURE__ */ React21.createElement("div", { className: "size-10 rounded-full bg-white flex items-center justify-center shrink-0" }, /* @__PURE__ */ React21.createElement(Truck, { className: "size-5 text-primary" })), /* @__PURE__ */ React21.createElement("div", null, /* @__PURE__ */ React21.createElement("p", { className: "font-['Poppins',sans-serif] font-semibold text-[12px] text-secondary mb-1" }, "Free Shipping"), /* @__PURE__ */ React21.createElement("p", { className: "font-['Poppins',sans-serif] text-[11px] text-muted" }, "On all orders"))), /* @__PURE__ */ React21.createElement("div", { className: "flex items-start gap-3" }, /* @__PURE__ */ React21.createElement("div", { className: "size-10 rounded-full bg-white flex items-center justify-center shrink-0" }, /* @__PURE__ */ React21.createElement(RotateCcw, { className: "size-5 text-primary" })), /* @__PURE__ */ React21.createElement("div", null, /* @__PURE__ */ React21.createElement("p", { className: "font-['Poppins',sans-serif] font-semibold text-[12px] text-secondary mb-1" }, "Easy Returns"), /* @__PURE__ */ React21.createElement("p", { className: "font-['Poppins',sans-serif] text-[11px] text-muted" }, "30-day return policy"))), /* @__PURE__ */ React21.createElement("div", { className: "flex items-start gap-3" }, /* @__PURE__ */ React21.createElement("div", { className: "size-10 rounded-full bg-white flex items-center justify-center shrink-0" }, /* @__PURE__ */ React21.createElement(Shield, { className: "size-5 text-primary" })), /* @__PURE__ */ React21.createElement("div", null, /* @__PURE__ */ React21.createElement("p", { className: "font-['Poppins',sans-serif] font-semibold text-[12px] text-secondary mb-1" }, "Secure Checkout"), /* @__PURE__ */ React21.createElement("p", { className: "font-['Poppins',sans-serif] text-[11px] text-muted" }, "Safe & protected"))), /* @__PURE__ */ React21.createElement("div", { className: "flex items-start gap-3" }, /* @__PURE__ */ React21.createElement("div", { className: "size-10 rounded-full bg-white flex items-center justify-center shrink-0" }, /* @__PURE__ */ React21.createElement(Package, { className: "size-5 text-primary" })), /* @__PURE__ */ React21.createElement("div", null, /* @__PURE__ */ React21.createElement("p", { className: "font-['Poppins',sans-serif] font-semibold text-[12px] text-secondary mb-1" }, "Quality Guaranteed"), /* @__PURE__ */ React21.createElement("p", { className: "font-['Poppins',sans-serif] text-[11px] text-muted" }, "Premium materials")))))), /* @__PURE__ */ React21.createElement("div", { className: "mb-16" }, /* @__PURE__ */ React21.createElement("div", { className: "flex items-center gap-2 mb-8 border-b-2 border-gray-100" }, ["description", "reviews"].map((tab) => /* @__PURE__ */ React21.createElement(
|
|
8946
|
+
"button",
|
|
8947
|
+
{
|
|
8948
|
+
key: tab,
|
|
8949
|
+
onClick: () => setActiveTab(tab),
|
|
8950
|
+
className: `font-['Poppins',sans-serif] font-medium text-[14px] px-6 py-4 transition-all ${activeTab === tab ? "text-primary border-b-2 border-primary -mb-0.5" : "text-muted hover:text-primary"}`
|
|
8951
|
+
},
|
|
8952
|
+
tab.charAt(0).toUpperCase() + tab.slice(1)
|
|
8953
|
+
))), /* @__PURE__ */ React21.createElement("div", { className: "bg-white rounded-[24px] p-8 border-2 border-gray-100" }, activeTab === "description" && /* @__PURE__ */ React21.createElement("div", null, /* @__PURE__ */ React21.createElement("h3", { className: "font-['Poppins',sans-serif] font-semibold text-secondary mb-4" }, "Product Description"), /* @__PURE__ */ React21.createElement("p", { className: "font-['Poppins',sans-serif] text-[14px] text-muted leading-[1.8] mb-4" }, /* @__PURE__ */ React21.createElement("div", { dangerouslySetInnerHTML: { __html: product.description } })), /* @__PURE__ */ React21.createElement("div", { className: "mt-6" }, /* @__PURE__ */ React21.createElement("h4", { className: "font-['Poppins',sans-serif] font-semibold text-[13px] text-secondary mb-3" }, "Last updated:"), /* @__PURE__ */ React21.createElement("p", { className: "font-['Poppins',sans-serif] text-[14px] text-muted" }, lastUpdatedLabel)), /* @__PURE__ */ React21.createElement("div", { className: "mt-6" }, /* @__PURE__ */ React21.createElement("h4", { className: "font-['Poppins',sans-serif] font-semibold text-[13px] text-secondary mb-3" }, "Shipped from:"), /* @__PURE__ */ React21.createElement("p", { className: "font-['Poppins',sans-serif] text-[14px] text-muted" }, "Local pharmacy distribution center"))), activeTab === "reviews" && /* @__PURE__ */ React21.createElement("div", { className: "text-center py-8" }, /* @__PURE__ */ React21.createElement(Star, { className: "size-12 text-[#E67E50] mx-auto mb-4" }), /* @__PURE__ */ React21.createElement("h3", { className: "font-['Poppins',sans-serif] font-semibold text-secondary mb-2" }, product.rating, " out of 5 stars"), /* @__PURE__ */ React21.createElement("p", { className: "font-['Poppins',sans-serif] text-[14px] text-muted" }, "Based on ", product.reviewCount, " customer reviews")))), relatedProducts.length > 0 && /* @__PURE__ */ React21.createElement("div", null, /* @__PURE__ */ React21.createElement("h2", { className: "font-['Poppins',sans-serif] font-semibold text-secondary mb-8 text-2xl" }, "You May Also Like"), /* @__PURE__ */ React21.createElement("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6" }, relatedProducts.map((relatedProduct) => /* @__PURE__ */ React21.createElement(
|
|
8763
8954
|
ProductCard,
|
|
8764
8955
|
{
|
|
8765
|
-
key: relatedProduct.id
|
|
8956
|
+
key: relatedProduct.id,
|
|
8766
8957
|
product: relatedProduct,
|
|
8767
8958
|
onClickProduct: (item) => {
|
|
8768
8959
|
router.push(buildPath(`/products/${item._id || item.id}`));
|
|
@@ -8803,70 +8994,71 @@ function CartItem({ item }) {
|
|
|
8803
8994
|
initial: { opacity: 0, y: 20 },
|
|
8804
8995
|
animate: { opacity: 1, y: 0 },
|
|
8805
8996
|
exit: { opacity: 0, x: -100 },
|
|
8806
|
-
className: "
|
|
8997
|
+
className: "bg-white border-2 border-gray-100 rounded-[24px] p-6 hover:border-[#5B9BD5]/30 transition-all duration-300"
|
|
8807
8998
|
},
|
|
8808
|
-
/* @__PURE__ */ React21.createElement(
|
|
8999
|
+
/* @__PURE__ */ React21.createElement("div", { className: "flex gap-4 pr-8" }, /* @__PURE__ */ React21.createElement("div", { className: "w-28 h-28 rounded-[16px] overflow-hidden bg-gray-50 shrink-0" }, /* @__PURE__ */ React21.createElement(
|
|
9000
|
+
Image4,
|
|
9001
|
+
{
|
|
9002
|
+
src: item.productVariantData.productMedia[0]?.file || "/placeholder-product.jpg",
|
|
9003
|
+
alt: item.productVariantData.name,
|
|
9004
|
+
className: "w-full h-full object-cover",
|
|
9005
|
+
height: 112,
|
|
9006
|
+
width: 112
|
|
9007
|
+
}
|
|
9008
|
+
)), /* @__PURE__ */ React21.createElement("div", { className: "flex-1 min-w-0" }, /* @__PURE__ */ React21.createElement("div", { className: "flex items-start justify-between gap-4 mb-3" }, /* @__PURE__ */ React21.createElement("div", { className: "flex-1 min-w-0" }, /* @__PURE__ */ React21.createElement("h3", { className: "font-['Poppins',sans-serif] font-semibold text-[#2B4B7C] mb-2" }, item.productVariantData.name), /* @__PURE__ */ React21.createElement("div", { className: "flex flex-wrap items-center gap-3" }, /* @__PURE__ */ React21.createElement("span", { className: "font-['Poppins',sans-serif] text-[12px] text-[#676c80]" }, "Variant: ", /* @__PURE__ */ React21.createElement("span", { className: "font-medium text-[#2B4B7C]" }, item.productVariantData.name)))), /* @__PURE__ */ React21.createElement(
|
|
8809
9009
|
"button",
|
|
8810
9010
|
{
|
|
8811
9011
|
onClick: handleRemove,
|
|
8812
|
-
className: "
|
|
9012
|
+
className: "p-2 hover:bg-red-50 rounded-full transition-colors group",
|
|
8813
9013
|
"aria-label": "Remove item"
|
|
8814
9014
|
},
|
|
8815
|
-
/* @__PURE__ */ React21.createElement(Trash2, { className: "
|
|
8816
|
-
),
|
|
8817
|
-
/* @__PURE__ */ React21.createElement("div", { className: "flex gap-4 pr-8" }, /* @__PURE__ */ React21.createElement("div", { className: "relative w-20 h-24 rounded-md overflow-hidden flex-shrink-0 bg-gray-100" }, /* @__PURE__ */ React21.createElement(
|
|
8818
|
-
Image3,
|
|
8819
|
-
{
|
|
8820
|
-
src: item.productVariantData.productMedia[0]?.file || "/placeholder-product.jpg",
|
|
8821
|
-
alt: item.productVariantData.name,
|
|
8822
|
-
fill: true,
|
|
8823
|
-
className: "object-cover",
|
|
8824
|
-
sizes: "80px"
|
|
8825
|
-
}
|
|
8826
|
-
)), /* @__PURE__ */ React21.createElement("div", { className: "flex-1 min-w-0" }, /* @__PURE__ */ React21.createElement("h3", { className: "text-base font-bold text-gray-900" }, item.productVariantData.name), attributes.length > 0 && /* @__PURE__ */ React21.createElement("p", { className: "text-sm text-gray-500 mt-1" }, attributes.join(" ")), /* @__PURE__ */ React21.createElement("div", { className: "flex items-center gap-2 mt-3" }, /* @__PURE__ */ React21.createElement(
|
|
9015
|
+
/* @__PURE__ */ React21.createElement(Trash2, { className: "size-5 text-[#676c80] group-hover:text-red-500 transition-colors" })
|
|
9016
|
+
)), /* @__PURE__ */ React21.createElement("div", { className: "flex items-center justify-between gap-4" }, /* @__PURE__ */ React21.createElement("div", { className: "flex items-center gap-3 bg-gray-50 rounded-full px-4 py-2" }, /* @__PURE__ */ React21.createElement(
|
|
8827
9017
|
"button",
|
|
8828
9018
|
{
|
|
8829
9019
|
onClick: () => handleUpdateQuantity(item.quantity - 1),
|
|
8830
9020
|
disabled: isUpdating || item.quantity <= 1,
|
|
8831
|
-
className: "p-1 hover:bg-
|
|
9021
|
+
className: "p-1 hover:bg-white rounded-full transition-colors"
|
|
8832
9022
|
},
|
|
8833
|
-
/* @__PURE__ */ React21.createElement(Minus, { className: "
|
|
8834
|
-
), /* @__PURE__ */ React21.createElement("span", { className: "
|
|
9023
|
+
/* @__PURE__ */ React21.createElement(Minus, { className: "size-4 text-[#2B4B7C]" })
|
|
9024
|
+
), /* @__PURE__ */ React21.createElement("span", { className: "font-['Poppins',sans-serif] font-semibold text-[14px] text-[#2B4B7C] min-w-[20px] text-center" }, item.quantity), /* @__PURE__ */ React21.createElement(
|
|
8835
9025
|
"button",
|
|
8836
9026
|
{
|
|
8837
9027
|
onClick: () => handleUpdateQuantity(item.quantity + 1),
|
|
8838
9028
|
disabled: isUpdating || item.quantity >= (item.productVariantData.inventoryCount || 999),
|
|
8839
|
-
className: "p-1 hover:bg-
|
|
9029
|
+
className: "p-1 hover:bg-white rounded-full transition-colors"
|
|
8840
9030
|
},
|
|
8841
|
-
/* @__PURE__ */ React21.createElement(Plus, { className: "
|
|
8842
|
-
))
|
|
9031
|
+
/* @__PURE__ */ React21.createElement(Plus, { className: "size-4 text-[#2B4B7C]" })
|
|
9032
|
+
)), /* @__PURE__ */ React21.createElement("div", { className: "text-right" }, /* @__PURE__ */ React21.createElement("p", { className: "font-['Poppins',sans-serif] font-bold text-[18px] text-[#E67E50]" }, formatPrice(itemTotal)), /* @__PURE__ */ React21.createElement("p", { className: "font-['Poppins',sans-serif] text-[11px] text-[#676c80]" }, formatPrice(unitPrice), " each")))))
|
|
8843
9033
|
);
|
|
8844
9034
|
}
|
|
8845
9035
|
function CartScreen() {
|
|
8846
9036
|
const router = useRouter();
|
|
8847
9037
|
const { cart, isLoading } = useCart();
|
|
8848
9038
|
const { buildPath } = useBasePath();
|
|
9039
|
+
const { isAuthenticated, user } = useAuth();
|
|
9040
|
+
const notification = useNotification();
|
|
8849
9041
|
if (!cart || cart.cartBody.items.length === 0) {
|
|
8850
|
-
return /* @__PURE__ */ React21.createElement("div", { className: "bg-white" }, /* @__PURE__ */ React21.createElement("div", { className: "min-h-screen bg-white max-w-6xl mx-auto" }, /* @__PURE__ */ React21.createElement("div", { className: "container mx-auto px-4 py-8" }, /* @__PURE__ */ React21.createElement("div", { className: "
|
|
9042
|
+
return /* @__PURE__ */ React21.createElement("div", { className: "bg-white" }, /* @__PURE__ */ React21.createElement("div", { className: "min-h-screen bg-white max-w-6xl mx-auto" }, /* @__PURE__ */ React21.createElement("div", { className: "container mx-auto px-4 py-8" }, /* @__PURE__ */ React21.createElement("div", { className: "flex flex-col items-center justify-center py-20" }, /* @__PURE__ */ React21.createElement(
|
|
8851
9043
|
motion.div,
|
|
8852
9044
|
{
|
|
8853
9045
|
initial: { opacity: 0, y: 24 },
|
|
8854
9046
|
animate: { opacity: 1, y: 0 },
|
|
8855
9047
|
className: "text-center space-y-6 max-w-md"
|
|
8856
9048
|
},
|
|
8857
|
-
/* @__PURE__ */ React21.createElement("div", { className: "flex justify-center" }, /* @__PURE__ */ React21.createElement("div", { className: "rounded-full bg-gray-100 p-6" }, /* @__PURE__ */ React21.createElement(ShoppingBag, { className: "h-12 w-12 text-
|
|
8858
|
-
/* @__PURE__ */ React21.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React21.createElement("h2", { className: "text-2xl font-bold text-
|
|
9049
|
+
/* @__PURE__ */ React21.createElement("div", { className: "flex justify-center" }, /* @__PURE__ */ React21.createElement("div", { className: "rounded-full bg-gray-100 p-6" }, /* @__PURE__ */ React21.createElement(ShoppingBag, { className: "h-12 w-12 text-secondary" }))),
|
|
9050
|
+
/* @__PURE__ */ React21.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React21.createElement("h2", { className: "text-2xl font-bold text-secondary" }, "Your cart is empty"), /* @__PURE__ */ React21.createElement("p", { className: "text-muted" }, "Start adding products to your cart to see them here.")),
|
|
8859
9051
|
/* @__PURE__ */ React21.createElement("div", { className: "flex flex-wrap gap-3 justify-center" }, /* @__PURE__ */ React21.createElement(
|
|
8860
9052
|
"button",
|
|
8861
9053
|
{
|
|
8862
9054
|
type: "button",
|
|
8863
9055
|
onClick: () => router.push(buildPath("/shop")),
|
|
8864
|
-
className: "rounded-
|
|
9056
|
+
className: "rounded-xl border-2 border-primary bg-primary text-white px-6 py-3 text-sm font-medium transition-colors flex items-center justify-center gap-2 hover:opacity-80"
|
|
8865
9057
|
},
|
|
8866
9058
|
"Discover products",
|
|
8867
9059
|
/* @__PURE__ */ React21.createElement(ArrowRight, { className: "h-5 w-5" })
|
|
8868
9060
|
)),
|
|
8869
|
-
/* @__PURE__ */ React21.createElement("div", { className: "mt-8 space-y-3 pt-6 border-t border-gray-200" }, /* @__PURE__ */ React21.createElement("div", { className: "flex items-start gap-3 text-sm text-slate-600" }, /* @__PURE__ */ React21.createElement(CheckCircle2, { className: "h-5 w-5 text-
|
|
9061
|
+
/* @__PURE__ */ React21.createElement("div", { className: "mt-8 space-y-3 pt-6 border-t border-gray-200" }, /* @__PURE__ */ React21.createElement("div", { className: "flex items-start gap-3 text-sm text-slate-600" }, /* @__PURE__ */ React21.createElement(CheckCircle2, { className: "h-5 w-5 text-secondary flex-shrink-0 mt-0.5" }), /* @__PURE__ */ React21.createElement("span", null, "Free shipping on all orders")), /* @__PURE__ */ React21.createElement("div", { className: "flex items-start gap-3 text-sm text-slate-600" }, /* @__PURE__ */ React21.createElement(CheckCircle2, { className: "h-5 w-5 text-secondary flex-shrink-0 mt-0.5" }), /* @__PURE__ */ React21.createElement("span", null, "Easy returns within 30 days")), /* @__PURE__ */ React21.createElement("div", { className: "flex items-start gap-3 text-sm text-slate-600" }, /* @__PURE__ */ React21.createElement(CheckCircle2, { className: "h-5 w-5 text-secondary flex-shrink-0 mt-0.5" }), /* @__PURE__ */ React21.createElement("span", null, "Secure checkout process")))
|
|
8870
9062
|
)))));
|
|
8871
9063
|
}
|
|
8872
9064
|
const subtotal = cart.total;
|
|
@@ -8874,12 +9066,23 @@ function CartScreen() {
|
|
|
8874
9066
|
const tax = 0;
|
|
8875
9067
|
const total = subtotal + shipping + tax;
|
|
8876
9068
|
const itemCount = cart.cartBody.items.length;
|
|
8877
|
-
|
|
9069
|
+
const handleSubmit = async (e) => {
|
|
9070
|
+
if (!isAuthenticated) {
|
|
9071
|
+
notification.error(
|
|
9072
|
+
"Sign-in required",
|
|
9073
|
+
"Please log in to complete your checkout."
|
|
9074
|
+
);
|
|
9075
|
+
setTimeout(() => router.push(buildPath("/login?redirect=/checkout")), 50);
|
|
9076
|
+
return;
|
|
9077
|
+
}
|
|
9078
|
+
router.push(buildPath("/checkout"));
|
|
9079
|
+
};
|
|
9080
|
+
return /* @__PURE__ */ React21.createElement("div", { className: "min-h-screen bg-white" }, /* @__PURE__ */ React21.createElement("div", { className: "max-w-[1400px] mx-auto px-8 md:px-12" }, /* @__PURE__ */ React21.createElement("div", { className: "container mx-auto px-4 py-8" }, /* @__PURE__ */ React21.createElement("div", { className: "mb-12" }, /* @__PURE__ */ React21.createElement("h1", { className: "font-['Poppins',sans-serif] font-semibold text-secondary tracking-[-2px] mb-2 text-4xl" }, "Shopping Cart"), /* @__PURE__ */ React21.createElement("p", { className: "font-['Poppins',sans-serif] text-[16px] text-muted" }, itemCount, " ", itemCount === 1 ? "item" : "items", " in your cart")), /* @__PURE__ */ React21.createElement("div", { className: "grid grid-cols-1 lg:grid-cols-3 gap-8" }, /* @__PURE__ */ React21.createElement(
|
|
8878
9081
|
motion.section,
|
|
8879
9082
|
{
|
|
8880
9083
|
initial: { opacity: 0, y: 24 },
|
|
8881
9084
|
animate: { opacity: 1, y: 0 },
|
|
8882
|
-
className: "space-y-6"
|
|
9085
|
+
className: "space-y-6 lg:col-span-2"
|
|
8883
9086
|
},
|
|
8884
9087
|
isLoading && /* @__PURE__ */ React21.createElement("div", { className: "flex items-center gap-2 rounded-xl border border-slate-200 bg-white px-4 py-3 text-sm text-slate-600" }, /* @__PURE__ */ React21.createElement("span", { className: "inline-block h-4 w-4 animate-spin rounded-full border-2 border-slate-300 border-t-slate-600" }), "Updating cart\u2026"),
|
|
8885
9088
|
/* @__PURE__ */ React21.createElement("div", { className: "space-y-4" }, cart.cartBody.items.map((item) => /* @__PURE__ */ React21.createElement(CartItem, { key: item.productVariantId, item })))
|
|
@@ -8889,13 +9092,13 @@ function CartScreen() {
|
|
|
8889
9092
|
initial: { opacity: 0, y: 24 },
|
|
8890
9093
|
animate: { opacity: 1, y: 0 },
|
|
8891
9094
|
transition: { delay: 0.1 },
|
|
8892
|
-
className: "space-y-6 lg:sticky lg:top-
|
|
9095
|
+
className: "space-y-6 lg:sticky lg:top-24 h-fit lg:col-span-1"
|
|
8893
9096
|
},
|
|
8894
|
-
/* @__PURE__ */ React21.createElement("div", { className: "rounded-
|
|
9097
|
+
/* @__PURE__ */ React21.createElement("div", { className: "bg-gradient-to-br from-[#5B9BD5]/10 to-[#2B4B7C]/10 rounded-[24px] p-8 border-2 border-[#5B9BD5]/20 sticky top-24" }, /* @__PURE__ */ React21.createElement("h2", { className: "font-['Poppins',sans-serif] font-semibold text-secondary mb-6" }, "Order Summary"), /* @__PURE__ */ React21.createElement("div", { className: "space-y-4 mb-6" }, /* @__PURE__ */ React21.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React21.createElement("span", { className: "font-['Poppins',sans-serif] text-[14px] text-muted" }, "Subtotal (", itemCount, " ", itemCount === 1 ? "item" : "items", ")"), /* @__PURE__ */ React21.createElement("span", { className: "font-['Poppins',sans-serif] font-semibold text-[14px] text-secondary" }, formatPrice(subtotal))), /* @__PURE__ */ React21.createElement("div", { className: "flex items-center justify-between text-sm" }, /* @__PURE__ */ React21.createElement("span", { className: "text-gray-600" }, "Shipping"), /* @__PURE__ */ React21.createElement("span", { className: "font-semibold text-green-600" }, "Will be calculated at checkout")), /* @__PURE__ */ React21.createElement("div", { className: "border-t border-gray-200 pt-4 mt-4" }, /* @__PURE__ */ React21.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React21.createElement("span", { className: "text-lg font-bold text-secondary" }, "Total"), /* @__PURE__ */ React21.createElement("span", { className: "text-2xl font-bold text-orange-600" }, formatPrice(total))))), /* @__PURE__ */ React21.createElement("div", { className: "space-y-3" }, /* @__PURE__ */ React21.createElement(
|
|
8895
9098
|
"button",
|
|
8896
9099
|
{
|
|
8897
|
-
type: "
|
|
8898
|
-
onClick:
|
|
9100
|
+
type: "submit",
|
|
9101
|
+
onClick: handleSubmit,
|
|
8899
9102
|
className: "w-full rounded-full border-2 border-primary-500 bg-primary-500 hover:bg-primary-600 text-white px-4 py-3 text-sm font-medium transition-colors flex items-center justify-center gap-2"
|
|
8900
9103
|
},
|
|
8901
9104
|
"Proceed to Checkout",
|
|
@@ -8905,11 +9108,10 @@ function CartScreen() {
|
|
|
8905
9108
|
{
|
|
8906
9109
|
type: "button",
|
|
8907
9110
|
onClick: () => router.push(buildPath("/shop")),
|
|
8908
|
-
className: "w-full rounded-full border-2 border-
|
|
9111
|
+
className: "w-full rounded-full border-2 border-muted bg-white px-4 py-3 text-sm font-medium text-slate-700 hover:bg-gray-50 transition-colors"
|
|
8909
9112
|
},
|
|
8910
9113
|
"Continue Shopping"
|
|
8911
|
-
)), /* @__PURE__ */ React21.createElement("div", { className: "mt-6 space-y-3 pt-6 border-t border-gray-200" }, /* @__PURE__ */ React21.createElement("div", { className: "flex items-start gap-3 text-sm text-slate-600" }, /* @__PURE__ */ React21.createElement(CheckCircle2, { className: "h-5 w-5 text-
|
|
8912
|
-
/* @__PURE__ */ React21.createElement("div", { className: "rounded-3xl border border-primary-100 bg-primary-50/70 p-6 text-sm text-primary-700 shadow-sm" }, /* @__PURE__ */ React21.createElement("p", { className: "font-semibold uppercase tracking-[0.3em]" }, "Need help?"), /* @__PURE__ */ React21.createElement("p", { className: "mt-2 leading-relaxed" }, "Chat with a pharmacist to optimize your regimen or discuss substitutions before you check out."))
|
|
9114
|
+
)), /* @__PURE__ */ React21.createElement("div", { className: "mt-6 space-y-3 pt-6 border-t border-gray-200" }, /* @__PURE__ */ React21.createElement("div", { className: "flex items-start gap-3 text-sm text-slate-600" }, /* @__PURE__ */ React21.createElement(CheckCircle2, { className: "h-5 w-5 text-muted flex-shrink-0 mt-0.5" }), /* @__PURE__ */ React21.createElement("span", null, "Easy returns within 30 days")), /* @__PURE__ */ React21.createElement("div", { className: "flex items-start gap-3 text-sm text-slate-600" }, /* @__PURE__ */ React21.createElement(CheckCircle2, { className: "h-5 w-5 text-muted flex-shrink-0 mt-0.5" }), /* @__PURE__ */ React21.createElement("span", null, "Secure checkout process"))))
|
|
8913
9115
|
)))));
|
|
8914
9116
|
}
|
|
8915
9117
|
function useAddresses() {
|
|
@@ -8970,15 +9172,6 @@ function useAddresses() {
|
|
|
8970
9172
|
markAsDefault
|
|
8971
9173
|
};
|
|
8972
9174
|
}
|
|
8973
|
-
function Card({ className = "", ...props }) {
|
|
8974
|
-
return /* @__PURE__ */ React21.createElement(
|
|
8975
|
-
"div",
|
|
8976
|
-
{
|
|
8977
|
-
className: `rounded-lg border bg-white shadow-sm ${className}`,
|
|
8978
|
-
...props
|
|
8979
|
-
}
|
|
8980
|
-
);
|
|
8981
|
-
}
|
|
8982
9175
|
function Modal({ isOpen, onClose, title, children, size = "md" }) {
|
|
8983
9176
|
useEffect(() => {
|
|
8984
9177
|
if (typeof window === "undefined") return;
|
|
@@ -9035,8 +9228,11 @@ var addressSchema = z.object({
|
|
|
9035
9228
|
country: z.string().min(2, "Country is required"),
|
|
9036
9229
|
phone: z.string().min(10, "Phone number is required")
|
|
9037
9230
|
});
|
|
9231
|
+
|
|
9232
|
+
// src/components/AddressFormModal.tsx
|
|
9038
9233
|
function AddressFormModal({ isOpen, onClose, onAddressAdded, onAddressUpdated, initialAddress }) {
|
|
9039
9234
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
9235
|
+
const notification = useNotification();
|
|
9040
9236
|
const {
|
|
9041
9237
|
register,
|
|
9042
9238
|
handleSubmit,
|
|
@@ -9082,7 +9278,10 @@ function AddressFormModal({ isOpen, onClose, onAddressAdded, onAddressUpdated, i
|
|
|
9082
9278
|
country: data.country,
|
|
9083
9279
|
phone: data.phone
|
|
9084
9280
|
}, initialAddress.id);
|
|
9085
|
-
|
|
9281
|
+
notification.success(
|
|
9282
|
+
"Address updated",
|
|
9283
|
+
"Your address has been updated successfully."
|
|
9284
|
+
);
|
|
9086
9285
|
reset();
|
|
9087
9286
|
onClose();
|
|
9088
9287
|
if (onAddressUpdated) onAddressUpdated(response.data);
|
|
@@ -9098,16 +9297,25 @@ function AddressFormModal({ isOpen, onClose, onAddressAdded, onAddressUpdated, i
|
|
|
9098
9297
|
phone: data.phone
|
|
9099
9298
|
});
|
|
9100
9299
|
if (response.status === 201) {
|
|
9101
|
-
|
|
9300
|
+
notification.success(
|
|
9301
|
+
"Address added",
|
|
9302
|
+
"Your new address has been saved to your account."
|
|
9303
|
+
);
|
|
9102
9304
|
reset();
|
|
9103
9305
|
onClose();
|
|
9104
9306
|
if (onAddressAdded) onAddressAdded(response.data);
|
|
9105
9307
|
} else {
|
|
9106
|
-
|
|
9308
|
+
notification.error(
|
|
9309
|
+
"Could not add address",
|
|
9310
|
+
"We could not save this address. Please try again."
|
|
9311
|
+
);
|
|
9107
9312
|
}
|
|
9108
9313
|
}
|
|
9109
9314
|
} catch (error) {
|
|
9110
|
-
|
|
9315
|
+
notification.error(
|
|
9316
|
+
"Could not save address",
|
|
9317
|
+
"Something went wrong while saving your address. Please try again."
|
|
9318
|
+
);
|
|
9111
9319
|
} finally {
|
|
9112
9320
|
setIsSubmitting(false);
|
|
9113
9321
|
}
|
|
@@ -9184,14 +9392,14 @@ function AddressFormModal({ isOpen, onClose, onAddressAdded, onAddressUpdated, i
|
|
|
9184
9392
|
error: errors.country?.message
|
|
9185
9393
|
}
|
|
9186
9394
|
)), /* @__PURE__ */ React21.createElement("div", { className: "flex justify-end gap-4" }, /* @__PURE__ */ React21.createElement(
|
|
9187
|
-
|
|
9395
|
+
"button",
|
|
9188
9396
|
{
|
|
9189
9397
|
type: "button",
|
|
9190
|
-
|
|
9191
|
-
|
|
9398
|
+
onClick: onClose,
|
|
9399
|
+
className: "flex flex-row items-center gap-2 px-6 py-2 border border-slate-200 rounded-xl text-slate-700 hover:opacity-80 transition-colors text-secondary text-sm"
|
|
9192
9400
|
},
|
|
9193
9401
|
"Cancel"
|
|
9194
|
-
), /* @__PURE__ */ React21.createElement(
|
|
9402
|
+
), /* @__PURE__ */ React21.createElement("button", { type: "submit", disabled: isSubmitting, className: "flex flex-row items-center gap-2 px-6 py-2 border border-slate-200 rounded-xl text-slate-700 hover:opacity-80 transition-colors bg-secondary text-white text-sm" }, isSubmitting ? "Adding Address..." : "Add Address")))
|
|
9195
9403
|
);
|
|
9196
9404
|
}
|
|
9197
9405
|
var checkoutSchema = z.object({
|
|
@@ -9240,6 +9448,7 @@ function CheckoutScreen() {
|
|
|
9240
9448
|
const [isAddressModalOpen, setIsAddressModalOpen] = useState(false);
|
|
9241
9449
|
const [editingAddress, setEditingAddress] = useState(null);
|
|
9242
9450
|
const [shippingPrice, setShippingPrice] = useState(0);
|
|
9451
|
+
const notification = useNotification();
|
|
9243
9452
|
const {
|
|
9244
9453
|
addresses: userAddresses,
|
|
9245
9454
|
defaultAddress
|
|
@@ -9369,7 +9578,10 @@ function CheckoutScreen() {
|
|
|
9369
9578
|
const onSubmit = async (data) => {
|
|
9370
9579
|
setError(null);
|
|
9371
9580
|
if (!isAuthenticated) {
|
|
9372
|
-
|
|
9581
|
+
notification.error(
|
|
9582
|
+
"Sign-in required",
|
|
9583
|
+
"Please log in to complete your checkout."
|
|
9584
|
+
);
|
|
9373
9585
|
setTimeout(() => router.push(buildPath("/login?redirect=/checkout")), 50);
|
|
9374
9586
|
return;
|
|
9375
9587
|
}
|
|
@@ -9421,7 +9633,10 @@ function CheckoutScreen() {
|
|
|
9421
9633
|
}
|
|
9422
9634
|
}
|
|
9423
9635
|
setIsSubmitting(true);
|
|
9424
|
-
|
|
9636
|
+
notification.info(
|
|
9637
|
+
"Submitting order",
|
|
9638
|
+
"We are processing your order and preparing your payment options."
|
|
9639
|
+
);
|
|
9425
9640
|
try {
|
|
9426
9641
|
const items = (cart?.cartBody?.items || []).map((item) => ({
|
|
9427
9642
|
productVariantId: String(item.productVariantId),
|
|
@@ -9453,7 +9668,10 @@ function CheckoutScreen() {
|
|
|
9453
9668
|
);
|
|
9454
9669
|
if (response?.data?.payment && response.data.payment.hostedInvoiceUrl === "INSUFFICIENT_CREDIT") {
|
|
9455
9670
|
setError("You have insufficient credit to complete this order.");
|
|
9456
|
-
|
|
9671
|
+
notification.error(
|
|
9672
|
+
"Insufficient credit",
|
|
9673
|
+
"You do not have enough credit to complete this order."
|
|
9674
|
+
);
|
|
9457
9675
|
return;
|
|
9458
9676
|
}
|
|
9459
9677
|
if (paymentMethod === "Card") {
|
|
@@ -9472,21 +9690,33 @@ function CheckoutScreen() {
|
|
|
9472
9690
|
} else if (!paymentUrl) {
|
|
9473
9691
|
console.error("No payment URL received in response:", response.data);
|
|
9474
9692
|
setError("Failed to initiate payment. Please try again or contact support.");
|
|
9475
|
-
|
|
9693
|
+
notification.error(
|
|
9694
|
+
"Payment setup failed",
|
|
9695
|
+
"We could not start the payment flow. Please try again or contact support."
|
|
9696
|
+
);
|
|
9476
9697
|
return;
|
|
9477
9698
|
}
|
|
9478
|
-
|
|
9699
|
+
notification.success(
|
|
9700
|
+
"Order placed",
|
|
9701
|
+
"Your order has been placed successfully. You will be redirected to payment."
|
|
9702
|
+
);
|
|
9479
9703
|
await clearCart();
|
|
9480
9704
|
router.push(buildPath(`/orders/${response.data?.id}`));
|
|
9481
9705
|
} else {
|
|
9482
|
-
|
|
9706
|
+
notification.success(
|
|
9707
|
+
"Order placed",
|
|
9708
|
+
"Your order has been placed successfully."
|
|
9709
|
+
);
|
|
9483
9710
|
await clearCart();
|
|
9484
9711
|
router.push(buildPath(`/orders/${response.data?.id}`));
|
|
9485
9712
|
}
|
|
9486
9713
|
} catch (err) {
|
|
9487
9714
|
const msg = err?.message || err?.response?.data?.message || "Failed to place order";
|
|
9488
9715
|
setError(msg);
|
|
9489
|
-
|
|
9716
|
+
notification.error(
|
|
9717
|
+
"Could not place order",
|
|
9718
|
+
msg
|
|
9719
|
+
);
|
|
9490
9720
|
} finally {
|
|
9491
9721
|
setIsSubmitting(false);
|
|
9492
9722
|
}
|
|
@@ -9498,14 +9728,15 @@ function CheckoutScreen() {
|
|
|
9498
9728
|
const subtotal = cart.total;
|
|
9499
9729
|
const tax = 0;
|
|
9500
9730
|
const total = subtotal + shippingPrice + tax;
|
|
9501
|
-
return /* @__PURE__ */ React21.createElement("div", { className: "min-h-screen bg-
|
|
9731
|
+
return /* @__PURE__ */ React21.createElement("div", { className: "min-h-screen bg-white pb-16" }, /* @__PURE__ */ React21.createElement("form", { onSubmit: handleSubmit(onSubmit) }, error && /* @__PURE__ */ React21.createElement("div", { className: "mb-4 text-red-600 font-semibold" }, error), /* @__PURE__ */ React21.createElement("div", { className: "pt-12 container mx-auto grid gap-10 px-4 lg:grid-cols-[minmax(0,2fr)_minmax(0,1fr)]" }, /* @__PURE__ */ React21.createElement(
|
|
9502
9732
|
motion.div,
|
|
9503
9733
|
{
|
|
9504
9734
|
initial: { opacity: 0, y: 24 },
|
|
9505
9735
|
animate: { opacity: 1, y: 0 },
|
|
9506
9736
|
className: "space-y-8"
|
|
9507
9737
|
},
|
|
9508
|
-
/* @__PURE__ */ React21.createElement("
|
|
9738
|
+
/* @__PURE__ */ React21.createElement("div", { className: "mb-12" }, /* @__PURE__ */ React21.createElement("h1", { className: "font-['Poppins',sans-serif] font-semibold text-[#2B4B7C] mb-2 text-3xl" }, "Checkout"), /* @__PURE__ */ React21.createElement("p", { className: "font-['Poppins',sans-serif] text-[14px] text-[#676c80] text-md leading-relaxed" }, "Complete your order information below")),
|
|
9739
|
+
/* @__PURE__ */ React21.createElement("section", { className: "bg-white border-2 border-gray-100 rounded-[24px] p-8 text-[#2B4B7C]" }, /* @__PURE__ */ React21.createElement("div", { className: "flex flex-wrap items-center justify-between gap-4" }, /* @__PURE__ */ React21.createElement("div", null, /* @__PURE__ */ React21.createElement("h2", { className: "font-['Poppins',sans-serif] font-semibold text-[#2B4B7C] mb-2 text-2xl" }, "Contact Information"), /* @__PURE__ */ React21.createElement("p", { className: "text-sm text-slate-500" }, "We use temperature-aware packaging and real-time tracking on every shipment.")), /* @__PURE__ */ React21.createElement("span", { className: "inline-flex items-center gap-2 rounded-full bg-primary-50 px-3 py-1 text-xs font-semibold uppercase tracking-wide text-primary-700" }, /* @__PURE__ */ React21.createElement(Truck, { className: "h-4 w-4" }), "Dispatch in 12h")), /* @__PURE__ */ React21.createElement("div", { className: "mt-6 grid grid-cols-1 gap-4 md:grid-cols-2" }, isDelivery && /* @__PURE__ */ React21.createElement("div", { className: "md:col-span-2 space-y-4" }, /* @__PURE__ */ React21.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React21.createElement("label", { className: "block font-semibold" }, "Select Address"), /* @__PURE__ */ React21.createElement(
|
|
9509
9740
|
Button,
|
|
9510
9741
|
{
|
|
9511
9742
|
type: "button",
|
|
@@ -9569,9 +9800,9 @@ function CheckoutScreen() {
|
|
|
9569
9800
|
try {
|
|
9570
9801
|
await removeAddress(addr.id);
|
|
9571
9802
|
if (selectedAddressId === addr.id) setSelectedAddressId(null);
|
|
9572
|
-
|
|
9803
|
+
notification.success("Address deleted");
|
|
9573
9804
|
} catch (e2) {
|
|
9574
|
-
|
|
9805
|
+
notification.error("Failed to delete address");
|
|
9575
9806
|
}
|
|
9576
9807
|
},
|
|
9577
9808
|
className: "inline-flex items-center gap-1 rounded-full border border-red-200 px-2.5 py-0.5 text-xs font-semibold text-red-600 hover:border-red-300 hover:text-red-700"
|
|
@@ -9588,7 +9819,7 @@ function CheckoutScreen() {
|
|
|
9588
9819
|
},
|
|
9589
9820
|
storeAddresses.map((addr) => /* @__PURE__ */ React21.createElement("option", { key: addr.id, value: addr.id }, addr.name, " - ", addr.street1, ", ", addr.city))
|
|
9590
9821
|
)))),
|
|
9591
|
-
isDelivery && selectedAddressId && /* @__PURE__ */ React21.createElement(
|
|
9822
|
+
isDelivery && selectedAddressId && /* @__PURE__ */ React21.createElement("div", { className: "bg-white border-2 border-gray-100 rounded-[24px] p-8 text-[#2B4B7C]" }, /* @__PURE__ */ React21.createElement("div", { className: "flex items-center gap-3 text-xl font-semibold text-gray-900 pb-4 mb-8 border-b" }, /* @__PURE__ */ React21.createElement(Truck, { className: "text-accent w-8 h-8 flex items-center justify-center text-[#2B4B7C]" }), /* @__PURE__ */ React21.createElement("h2", { className: "font-['Poppins',sans-serif] font-semibold text-[#2B4B7C] text-2xl" }, "Shipping Options")), shippingRatesLoading ? /* @__PURE__ */ React21.createElement("div", { className: "flex items-center justify-center py-12" }, /* @__PURE__ */ React21.createElement("div", { className: "animate-spin rounded-full h-8 w-8 border-b-2 border-accent" }), /* @__PURE__ */ React21.createElement("span", { className: "ml-3 text-gray-600" }, "Loading shipping options...")) : shippingRatesError ? /* @__PURE__ */ React21.createElement("div", { className: "text-center py-12" }, /* @__PURE__ */ React21.createElement("div", { className: "w-16 h-16 mx-auto mb-4 bg-red-100 rounded-full flex items-center justify-center" }, /* @__PURE__ */ React21.createElement("svg", { className: "w-8 h-8 text-red-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24" }, /* @__PURE__ */ React21.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" }))), /* @__PURE__ */ React21.createElement("p", { className: "text-red-500 text-lg font-medium" }, "Error loading shipping options"), /* @__PURE__ */ React21.createElement("p", { className: "text-red-400 text-sm mt-1" }, shippingRatesError)) : shippingRates && shippingRates.length > 0 ? /* @__PURE__ */ React21.createElement("div", { className: "space-y-4" }, shippingRates.map((rate) => {
|
|
9592
9823
|
const isSelected = !!selectedShippingRateId && selectedShippingRateId === rate.objectId;
|
|
9593
9824
|
const isTest = rate.test;
|
|
9594
9825
|
const hasAttributes = rate.attributes && rate.attributes.length > 0;
|
|
@@ -9603,7 +9834,7 @@ function CheckoutScreen() {
|
|
|
9603
9834
|
className: `relative p-5 border-2 rounded-xl cursor-pointer transition-all duration-200 hover:shadow-md ${isSelected ? "border-primary-500 bg-primary-50 ring-2 ring-primary-200" : "border-gray-200 hover:border-gray-300"}`
|
|
9604
9835
|
},
|
|
9605
9836
|
/* @__PURE__ */ React21.createElement("div", { className: "flex items-start justify-between" }, /* @__PURE__ */ React21.createElement("div", { className: "flex items-start gap-4 flex-1" }, /* @__PURE__ */ React21.createElement("div", { className: "flex-shrink-0" }, /* @__PURE__ */ React21.createElement(
|
|
9606
|
-
|
|
9837
|
+
Image4,
|
|
9607
9838
|
{
|
|
9608
9839
|
src: rate.providerImage75 || "/placeholder-product.jpg",
|
|
9609
9840
|
alt: rate.provider,
|
|
@@ -9625,16 +9856,8 @@ function CheckoutScreen() {
|
|
|
9625
9856
|
))), /* @__PURE__ */ React21.createElement("div", { className: "space-y-1 text-sm text-gray-600" }, rate.durationTerms && /* @__PURE__ */ React21.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React21.createElement("svg", { className: "w-4 h-4 text-gray-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24" }, /* @__PURE__ */ React21.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" })), /* @__PURE__ */ React21.createElement("span", null, rate.durationTerms)), rate.estimatedDays && /* @__PURE__ */ React21.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React21.createElement("svg", { className: "w-4 h-4 text-gray-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24" }, /* @__PURE__ */ React21.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" })), /* @__PURE__ */ React21.createElement("span", null, "Estimated ", rate.estimatedDays, " day", rate.estimatedDays !== 1 ? "s" : "")), /* @__PURE__ */ React21.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React21.createElement("svg", { className: "w-4 h-4 text-gray-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24" }, /* @__PURE__ */ React21.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M9 5H7a2 2 0 00-2 2v10a2 2 0 002 2h8a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" })), /* @__PURE__ */ React21.createElement("span", null, "Carrier: ", rate.provider)), /* @__PURE__ */ React21.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React21.createElement("svg", { className: "w-4 h-4 text-gray-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24" }, /* @__PURE__ */ React21.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1" })), /* @__PURE__ */ React21.createElement("span", null, "Currency: ", rate.currency))))), /* @__PURE__ */ React21.createElement("div", { className: "flex flex-col items-end" }, /* @__PURE__ */ React21.createElement("div", { className: "text-2xl font-bold text-gray-900" }, formatPrice(parseFloat(rate.amount))), rate.amount !== rate.amountLocal && /* @__PURE__ */ React21.createElement("div", { className: "text-sm text-gray-500" }, rate.amountLocal, " ", rate.currencyLocal))),
|
|
9626
9857
|
isSelected && /* @__PURE__ */ React21.createElement("div", { className: "absolute top-3 right-3" }, /* @__PURE__ */ React21.createElement("div", { className: "w-6 h-6 bg-primary-500 rounded-full flex items-center justify-center" }, /* @__PURE__ */ React21.createElement(Check, { className: "w-4 h-4 text-white" })))
|
|
9627
9858
|
);
|
|
9628
|
-
})) : /* @__PURE__ */ React21.createElement("div", { className: "text-center py-12" }, /* @__PURE__ */ React21.createElement("div", { className: "w-16 h-16 mx-auto mb-4 bg-gray-100 rounded-full flex items-center justify-center" }, /* @__PURE__ */ React21.createElement(Truck, { className: "w-8 h-8 text-gray-400" })), /* @__PURE__ */ React21.createElement("p", { className: "text-gray-500 text-lg font-medium" }, "No shipping options available"), /* @__PURE__ */ React21.createElement("p", { className: "text-gray-400 text-sm mt-1" }, "Please check the shipping address or try a different location.")))
|
|
9629
|
-
|
|
9630
|
-
motion.aside,
|
|
9631
|
-
{
|
|
9632
|
-
initial: { opacity: 0, y: 32 },
|
|
9633
|
-
animate: { opacity: 1, y: 0 },
|
|
9634
|
-
transition: { duration: 0.5, ease: "easeOut", delay: 0.1 },
|
|
9635
|
-
className: "space-y-10 lg:sticky lg:top-24"
|
|
9636
|
-
},
|
|
9637
|
-
/* @__PURE__ */ React21.createElement("div", { className: "rounded-3xl border border-slate-100 bg-white p-6 shadow-xl shadow-primary-50/50 transition hover:shadow-primary-100/60" }, /* @__PURE__ */ React21.createElement("h2", { className: "text-2xl font-semibold text-slate-900" }, "Order Summary"), /* @__PURE__ */ React21.createElement("section", { className: "mt-6 space-y-4" }, /* @__PURE__ */ React21.createElement("h3", { className: "text-xs font-semibold text-slate-700 uppercase tracking-wider" }, "Delivery Method"), /* @__PURE__ */ React21.createElement("div", { className: "grid grid-cols-1 gap-3" }, [
|
|
9859
|
+
})) : /* @__PURE__ */ React21.createElement("div", { className: "text-center py-12" }, /* @__PURE__ */ React21.createElement("div", { className: "w-16 h-16 mx-auto mb-4 bg-gray-100 rounded-full flex items-center justify-center" }, /* @__PURE__ */ React21.createElement(Truck, { className: "w-8 h-8 text-gray-400" })), /* @__PURE__ */ React21.createElement("p", { className: "text-gray-500 text-lg font-medium" }, "No shipping options available"), /* @__PURE__ */ React21.createElement("p", { className: "text-gray-400 text-sm mt-1" }, "Please check the shipping address or try a different location."))),
|
|
9860
|
+
/* @__PURE__ */ React21.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React21.createElement("div", { className: "bg-white border-2 border-gray-100 rounded-[24px] p-8" }, /* @__PURE__ */ React21.createElement("div", { className: "flex items-center gap-3 mb-6" }, /* @__PURE__ */ React21.createElement(Truck, { className: "w-8 h-8 text-[#2B4B7C]" }), /* @__PURE__ */ React21.createElement("h2", { className: "text-2xl font-semibold text-[#2B4B7C]" }, "Delivery Method")), /* @__PURE__ */ React21.createElement("div", { className: "grid grid-cols-1 gap-3" }, [
|
|
9638
9861
|
{
|
|
9639
9862
|
label: "Delivery",
|
|
9640
9863
|
icon: /* @__PURE__ */ React21.createElement(Truck, { className: "w-5 h-5" }),
|
|
@@ -9654,20 +9877,25 @@ function CheckoutScreen() {
|
|
|
9654
9877
|
{
|
|
9655
9878
|
key: option.label,
|
|
9656
9879
|
type: "button",
|
|
9657
|
-
onClick: () =>
|
|
9658
|
-
|
|
9659
|
-
|
|
9880
|
+
onClick: () => {
|
|
9881
|
+
setIsDelivery(option.value);
|
|
9882
|
+
if (option.value) {
|
|
9883
|
+
setSelectedShippingRateId(null);
|
|
9884
|
+
setShippingPrice(0);
|
|
9885
|
+
}
|
|
9886
|
+
},
|
|
9887
|
+
className: `relative flex w-full items-center justify-between rounded-xl border-2 p-4 transition-all duration-200 ${active ? "border-primary-500 bg-primary-50" : "border-gray-200 hover:border-primary-300"}`
|
|
9660
9888
|
},
|
|
9661
9889
|
/* @__PURE__ */ React21.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ React21.createElement(
|
|
9662
9890
|
"div",
|
|
9663
9891
|
{
|
|
9664
|
-
className: `p-2 rounded-lg ${active ? "bg-primary-100 text-primary-600" : "bg-
|
|
9892
|
+
className: `p-2 rounded-lg ${active ? "bg-primary-100 text-primary-600" : "bg-gray-100 text-gray-600"}`
|
|
9665
9893
|
},
|
|
9666
9894
|
option.icon
|
|
9667
|
-
), /* @__PURE__ */ React21.createElement("div", { className: "text-left" }, /* @__PURE__ */ React21.createElement("div", { className: "font-medium text-
|
|
9668
|
-
active && /* @__PURE__ */ React21.createElement("div", { className: "w-5 h-5 rounded-full bg-primary-500 flex items-center justify-center
|
|
9895
|
+
), /* @__PURE__ */ React21.createElement("div", { className: "text-left" }, /* @__PURE__ */ React21.createElement("div", { className: "font-medium text-gray-900" }, option.label), /* @__PURE__ */ React21.createElement("p", { className: "text-sm text-gray-500" }, option.desc))),
|
|
9896
|
+
active && /* @__PURE__ */ React21.createElement("div", { className: "w-5 h-5 rounded-full bg-primary-500 flex items-center justify-center" }, /* @__PURE__ */ React21.createElement(Check, { className: "w-3 h-3 text-white" }))
|
|
9669
9897
|
);
|
|
9670
|
-
}))), /* @__PURE__ */ React21.createElement("
|
|
9898
|
+
}))), /* @__PURE__ */ React21.createElement("div", { className: "bg-white border-2 border-gray-100 rounded-[24px] p-8" }, /* @__PURE__ */ React21.createElement("div", { className: "flex items-center gap-3 mb-6" }, /* @__PURE__ */ React21.createElement(CreditCard, { className: "w-8 h-8 text-[#2B4B7C]" }), /* @__PURE__ */ React21.createElement("h2", { className: "text-2xl font-semibold text-[#2B4B7C]" }, "Payment Method")), /* @__PURE__ */ React21.createElement("div", { className: "grid gap-4 md:grid-cols-3" }, PAYMENT_METHODS.map((pm) => {
|
|
9671
9899
|
const active = paymentMethod === pm.value;
|
|
9672
9900
|
return /* @__PURE__ */ React21.createElement(
|
|
9673
9901
|
"button",
|
|
@@ -9675,47 +9903,46 @@ function CheckoutScreen() {
|
|
|
9675
9903
|
key: pm.value,
|
|
9676
9904
|
type: "button",
|
|
9677
9905
|
onClick: () => setPaymentMethod(pm.value),
|
|
9678
|
-
className: `
|
|
9906
|
+
className: `
|
|
9907
|
+
group relative flex w-full items-center justify-between rounded-xl border-2 p-3
|
|
9908
|
+
transition-all duration-200 ease-out
|
|
9909
|
+
focus:outline-none f
|
|
9910
|
+
${active ? `${pm.activeClass} shadow-md scale-[1.02]` : `${pm.className} border-gray-200 bg-white hover:shadow-sm hover:-translate-y-0.5`}
|
|
9911
|
+
`
|
|
9679
9912
|
},
|
|
9680
9913
|
/* @__PURE__ */ React21.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ React21.createElement(
|
|
9681
9914
|
"div",
|
|
9682
9915
|
{
|
|
9683
|
-
className: `
|
|
9916
|
+
className: `
|
|
9917
|
+
flex items-center justify-center rounded-lg p-2
|
|
9918
|
+
transition-colors duration-200
|
|
9919
|
+
${pm.value === "Card" ? " text-blue-600" : pm.value === "Cash" ? " text-amber-600" : " text-emerald-600"}
|
|
9920
|
+
${active ? "opacity-80" : "group-hover:opacity-90"}
|
|
9921
|
+
`
|
|
9684
9922
|
},
|
|
9685
9923
|
pm.icon
|
|
9686
|
-
), /* @__PURE__ */ React21.createElement("span", { className: "text-sm font-
|
|
9687
|
-
active && /* @__PURE__ */ React21.createElement("div", { className: "
|
|
9924
|
+
), /* @__PURE__ */ React21.createElement("span", { className: "text-sm font-semibold text-gray-900" }, pm.label)),
|
|
9925
|
+
active && /* @__PURE__ */ React21.createElement("div", { className: "flex h-6 w-6 items-center justify-center rounded-full shadow-sm" }, /* @__PURE__ */ React21.createElement(Check, { className: "h-3.5 w-3.5 text-white" }))
|
|
9688
9926
|
);
|
|
9689
|
-
})), /* @__PURE__ */ React21.createElement("p", { className: "text-
|
|
9690
|
-
|
|
9691
|
-
|
|
9692
|
-
|
|
9693
|
-
|
|
9694
|
-
},
|
|
9695
|
-
|
|
9696
|
-
|
|
9697
|
-
|
|
9698
|
-
|
|
9699
|
-
alt: item.productVariantData.name,
|
|
9700
|
-
width: 64,
|
|
9701
|
-
height: 64,
|
|
9702
|
-
className: "object-contain"
|
|
9703
|
-
}
|
|
9704
|
-
)),
|
|
9705
|
-
/* @__PURE__ */ React21.createElement("div", { className: "flex-1" }, /* @__PURE__ */ React21.createElement("p", { className: "text-sm font-semibold text-slate-900" }, item?.productVariantData?.name), /* @__PURE__ */ React21.createElement("p", { className: "text-xs text-slate-500" }, "Qty ", item.quantity)),
|
|
9706
|
-
/* @__PURE__ */ React21.createElement("p", { className: "text-sm font-semibold text-slate-900" }, formatPrice(item.productVariantData.finalPrice * item.quantity))
|
|
9707
|
-
))), /* @__PURE__ */ React21.createElement("div", { className: "mt-6 space-y-3 text-sm text-slate-600" }, /* @__PURE__ */ React21.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React21.createElement("span", null, "Subtotal"), /* @__PURE__ */ React21.createElement("span", { className: "font-semibold text-slate-900" }, formatPrice(subtotal))), isDelivery && /* @__PURE__ */ React21.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React21.createElement("span", null, "Shipping"), /* @__PURE__ */ React21.createElement("span", { className: "font-semibold" }, formatPrice(shippingPrice))), /* @__PURE__ */ React21.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React21.createElement("span", null, "Estimated tax"), /* @__PURE__ */ React21.createElement("span", { className: "font-semibold" }, formatPrice(tax))), /* @__PURE__ */ React21.createElement("div", { className: "rounded-2xl bg-slate-50 p-4" }, /* @__PURE__ */ React21.createElement("div", { className: "flex items-center justify-between text-base font-semibold text-slate-900" }, /* @__PURE__ */ React21.createElement("span", null, "Total Due"), /* @__PURE__ */ React21.createElement("span", null, formatPrice(total))), /* @__PURE__ */ React21.createElement("p", { className: "mt-1 text-xs text-slate-500" }, "Tax is estimated. Final amount confirmed after payment.")))), /* @__PURE__ */ React21.createElement(
|
|
9927
|
+
})), /* @__PURE__ */ React21.createElement("p", { className: "text-sm text-gray-500 mt-4" }, paymentMethod === "Card" && "You will be redirected to a secure payment page.", paymentMethod === "Cash" && "Pay with cash at the time of delivery or pickup.", paymentMethod === "Credit" && "Use your available account credit for this order.")))
|
|
9928
|
+
), /* @__PURE__ */ React21.createElement(
|
|
9929
|
+
motion.aside,
|
|
9930
|
+
{
|
|
9931
|
+
initial: { opacity: 0, y: 32 },
|
|
9932
|
+
animate: { opacity: 1, y: 0 },
|
|
9933
|
+
transition: { duration: 0.5, ease: "easeOut", delay: 0.1 },
|
|
9934
|
+
className: "space-y-10 lg:sticky lg:top-24 lg:col-span-1"
|
|
9935
|
+
},
|
|
9936
|
+
/* @__PURE__ */ React21.createElement("div", { className: "bg-gradient-to-br from-[#5B9BD5]/10 to-[#2B4B7C]/10 rounded-[24px] p-8 border-2 border-[#5B9BD5]/20 sticky top-24" }, /* @__PURE__ */ React21.createElement("h2", { className: "font-['Poppins',sans-serif] font-semibold text-[#2B4B7C] mb-6 text-2xl" }, "Order Summary"), /* @__PURE__ */ React21.createElement("section", { className: "mt-8 pt-6 border-t border-slate-100" }, /* @__PURE__ */ React21.createElement("div", { className: "space-y-4 mb-6" }, cart?.cartBody?.items?.map((item) => /* @__PURE__ */ React21.createElement("div", { key: `${item.productId}-${item.color}-${item.size}`, className: "flex gap-3" }, /* @__PURE__ */ React21.createElement("div", { className: "w-16 h-16 rounded-xl overflow-hidden bg-white shrink-0" }, /* @__PURE__ */ React21.createElement(Image4, { src: item.productVariantData.productMedia?.[0]?.file || "/placeholder-product.jpg", alt: item.productVariantData.name, className: "w-full h-full object-cover", height: 200, width: 200 })), /* @__PURE__ */ React21.createElement("div", { className: "flex-1 min-w-0" }, /* @__PURE__ */ React21.createElement("p", { className: "font-['Poppins',sans-serif] font-medium text-[12px] text-[#2B4B7C] mb-1" }, item?.productVariantData?.name), /* @__PURE__ */ React21.createElement("p", { className: "font-['Poppins',sans-serif] text-[11px] text-[#676c80]" }, item?.productVariantData?.brand, " \u2022 Qty: ", item.quantity), /* @__PURE__ */ React21.createElement("p", { className: "font-['Poppins',sans-serif] font-semibold text-[12px] text-[#E67E50] mt-1" }, formatPrice(item.productVariantData.finalPrice * item.quantity)))))), /* @__PURE__ */ React21.createElement("div", { className: "h-px bg-[#5B9BD5]/20 my-4" }), /* @__PURE__ */ React21.createElement("div", { className: "text-sm text-slate-600 space-y-3 py-4" }, /* @__PURE__ */ React21.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React21.createElement("span", null, "Subtotal"), /* @__PURE__ */ React21.createElement("span", { className: "font-semibold text-slate-900" }, formatPrice(subtotal))), isDelivery && /* @__PURE__ */ React21.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React21.createElement("span", null, "Shipping"), /* @__PURE__ */ React21.createElement("span", { className: "font-semibold" }, formatPrice(shippingPrice))), /* @__PURE__ */ React21.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React21.createElement("span", null, "Estimated tax"), /* @__PURE__ */ React21.createElement("span", { className: "font-semibold" }, formatPrice(tax))), /* @__PURE__ */ React21.createElement("div", { className: "h-px bg-[#5B9BD5]/20 mt-6" }), /* @__PURE__ */ React21.createElement("div", { className: "flex items-center justify-between mb-6" }, /* @__PURE__ */ React21.createElement("span", { className: "font-['Poppins',sans-serif] font-semibold text-[16px] text-[#2B4B7C]" }, "Total"), /* @__PURE__ */ React21.createElement("span", { className: "font-['Poppins',sans-serif] font-bold text-[24px] text-[#E67E50]" }, formatPrice(total)))), /* @__PURE__ */ React21.createElement("div", { className: "bg-white/80 rounded-xl p-4" }, /* @__PURE__ */ React21.createElement("p", { className: "font-['Poppins',sans-serif] text-[11px] text-[#676c80] leading-[1.6]" }, /* @__PURE__ */ React21.createElement("strong", { className: "text-[#2B4B7C]" }, "Payment:"), " We'll contact you to arrange payment upon pickup or delivery. We accept cash, credit cards, and all major payment methods."))), /* @__PURE__ */ React21.createElement(
|
|
9708
9937
|
Button,
|
|
9709
9938
|
{
|
|
9710
9939
|
type: "submit",
|
|
9711
|
-
size: "lg",
|
|
9712
9940
|
isLoading: isSubmitting,
|
|
9713
|
-
className: "
|
|
9941
|
+
className: "font-['Poppins',sans-serif] font-medium text-[14px] px-6 py-2 rounded-full bg-[#E67E50] text-white hover:bg-[#d66f45] hover:shadow-lg transition-all duration-300 mt-4 w-full"
|
|
9714
9942
|
},
|
|
9715
9943
|
/* @__PURE__ */ React21.createElement(CreditCard, { className: "h-5 w-5" }),
|
|
9716
9944
|
isSubmitting ? "Placing order..." : "Place Secure Order"
|
|
9717
|
-
), /* @__PURE__ */ React21.createElement("p", { className: "mt-4 flex items-center justify-center gap-2 text-xs text-slate-500" }, /* @__PURE__ */ React21.createElement(Lock, { className: "h-4 w-4" }), "Fully encrypted checkout \u2014 cancel anytime before shipment."))
|
|
9718
|
-
/* @__PURE__ */ React21.createElement("div", { className: "rounded-3xl border border-primary-100 bg-primary-50/80 p-6 text-sm text-primary-700 shadow-sm hover:shadow-md transition-shadow" }, /* @__PURE__ */ React21.createElement("p", { className: "font-semibold uppercase tracking-[0.3em] text-primary-800" }, "Why Patients Choose Us"), /* @__PURE__ */ React21.createElement("ul", { className: "mt-4 space-y-3 text-primary-700 leading-relaxed" }, /* @__PURE__ */ React21.createElement("li", { className: "flex items-start gap-3" }, /* @__PURE__ */ React21.createElement(PackageCheck, { className: "mt-0.5 h-4 w-4 shrink-0" }), /* @__PURE__ */ React21.createElement("span", null, "Pharmacy-grade verification on every order.")), /* @__PURE__ */ React21.createElement("li", { className: "flex items-start gap-3" }, /* @__PURE__ */ React21.createElement(ShieldCheck, { className: "mt-0.5 h-4 w-4 shrink-0" }), /* @__PURE__ */ React21.createElement("span", null, "Cold-chain logistics for sensitive medications.")), /* @__PURE__ */ React21.createElement("li", { className: "flex items-start gap-3" }, /* @__PURE__ */ React21.createElement(Truck, { className: "mt-0.5 h-4 w-4 shrink-0" }), /* @__PURE__ */ React21.createElement("span", null, "Real-time tracking and SMS updates from prep to delivery."))))
|
|
9945
|
+
), /* @__PURE__ */ React21.createElement("p", { className: "mt-4 flex items-center justify-center gap-2 text-xs text-slate-500" }, /* @__PURE__ */ React21.createElement(Lock, { className: "h-4 w-4" }), "Fully encrypted checkout \u2014 cancel anytime before shipment."))
|
|
9719
9946
|
))), /* @__PURE__ */ React21.createElement(
|
|
9720
9947
|
AddressFormModal,
|
|
9721
9948
|
{
|
|
@@ -9750,9 +9977,12 @@ function LoginScreen() {
|
|
|
9750
9977
|
const { buildPath } = useBasePath();
|
|
9751
9978
|
const searchParams = useSearchParams();
|
|
9752
9979
|
const redirectUrl = searchParams?.get("redirect") || buildPath("/");
|
|
9753
|
-
const { login } = useAuth();
|
|
9980
|
+
const { login, user, isLoading } = useAuth();
|
|
9754
9981
|
const [showPassword, setShowPassword] = useState(false);
|
|
9755
9982
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
9983
|
+
const [status, setStatus] = useState(
|
|
9984
|
+
null
|
|
9985
|
+
);
|
|
9756
9986
|
const {
|
|
9757
9987
|
register,
|
|
9758
9988
|
handleSubmit,
|
|
@@ -9762,36 +9992,25 @@ function LoginScreen() {
|
|
|
9762
9992
|
});
|
|
9763
9993
|
const onSubmit = async (data) => {
|
|
9764
9994
|
setIsSubmitting(true);
|
|
9995
|
+
setStatus(null);
|
|
9765
9996
|
try {
|
|
9766
9997
|
await login(data);
|
|
9767
|
-
|
|
9998
|
+
setStatus({ type: "success", message: "Welcome back!" });
|
|
9768
9999
|
router.push(redirectUrl);
|
|
9769
10000
|
} catch (error) {
|
|
9770
|
-
|
|
10001
|
+
setStatus({
|
|
10002
|
+
type: "error",
|
|
10003
|
+
message: error?.response?.data?.message || "Invalid credentials"
|
|
10004
|
+
});
|
|
9771
10005
|
} finally {
|
|
9772
10006
|
setIsSubmitting(false);
|
|
9773
10007
|
}
|
|
9774
10008
|
};
|
|
9775
|
-
|
|
9776
|
-
|
|
9777
|
-
|
|
9778
|
-
|
|
9779
|
-
|
|
9780
|
-
transition: { duration: 0.4 },
|
|
9781
|
-
className: "relative flex flex-col justify-between bg-gradient-to-br from-slate-700 via-slate-600 to-slate-700 px-10 py-14 text-white"
|
|
9782
|
-
},
|
|
9783
|
-
/* @__PURE__ */ React21.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React21.createElement("span", { className: "inline-flex items-center gap-2 rounded-full bg-white/15 px-3 py-1 text-sm font-semibold uppercase tracking-[0.35em] text-white/70 backdrop-blur" }, /* @__PURE__ */ React21.createElement(HeartPulse, { className: "h-4 w-4" }), "Hey Pharmacist"), /* @__PURE__ */ React21.createElement("h1", { className: "text-4xl font-bold leading-tight lg:text-5xl" }, "Pharmacy-grade care for your household"), /* @__PURE__ */ React21.createElement("p", { className: "max-w-xl text-white/80" }, "Log in to unlock personalized regimens, pharmacist support, and fast delivery on wellness essentials curated just for you.")),
|
|
9784
|
-
/* @__PURE__ */ React21.createElement("div", { className: "grid gap-4 rounded-3xl bg-white/10 p-6 backdrop-blur" }, /* @__PURE__ */ React21.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ React21.createElement(ShieldCheck, { className: "h-5 w-5 text-white" }), /* @__PURE__ */ React21.createElement("p", { className: "text-sm text-white/80" }, "HIPAA-compliant security keeps your health information protected.")), /* @__PURE__ */ React21.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ React21.createElement(Sparkles, { className: "h-5 w-5 text-white" }), /* @__PURE__ */ React21.createElement("p", { className: "text-sm text-white/80" }, "Pharmacists ready to chat in under 10 minutes for medication support."))),
|
|
9785
|
-
/* @__PURE__ */ React21.createElement("div", { className: "flex items-center gap-6 text-sm text-white/80" }, /* @__PURE__ */ React21.createElement("span", null, "Need an account?"), /* @__PURE__ */ React21.createElement(
|
|
9786
|
-
Link8,
|
|
9787
|
-
{
|
|
9788
|
-
href: buildPath("/register"),
|
|
9789
|
-
className: "inline-flex items-center gap-2 rounded-full bg-white/15 px-4 py-2 font-semibold transition hover:bg-white/25"
|
|
9790
|
-
},
|
|
9791
|
-
"Create one now",
|
|
9792
|
-
/* @__PURE__ */ React21.createElement(ArrowRight, { className: "h-4 w-4" })
|
|
9793
|
-
))
|
|
9794
|
-
), /* @__PURE__ */ React21.createElement(
|
|
10009
|
+
if (!isLoading && user) {
|
|
10010
|
+
router.push(buildPath("/account"));
|
|
10011
|
+
return null;
|
|
10012
|
+
}
|
|
10013
|
+
return /* @__PURE__ */ React21.createElement("div", { className: "min-h-screen bg-gradient-to-b from-[#F8FAFC] to-[#EBF4FB]" }, /* @__PURE__ */ React21.createElement("div", { className: "grid min-h-screen overflow-hidden pb-12" }, /* @__PURE__ */ React21.createElement(
|
|
9795
10014
|
motion.section,
|
|
9796
10015
|
{
|
|
9797
10016
|
initial: { opacity: 0, x: 24 },
|
|
@@ -9799,55 +10018,74 @@ function LoginScreen() {
|
|
|
9799
10018
|
transition: { duration: 0.4 },
|
|
9800
10019
|
className: "flex items-center justify-center px-6 py-12 lg:px-16"
|
|
9801
10020
|
},
|
|
9802
|
-
/* @__PURE__ */ React21.createElement("div", { className: "w-full max-w-
|
|
9803
|
-
|
|
9804
|
-
{
|
|
9805
|
-
type: "email",
|
|
9806
|
-
label: "Email address",
|
|
9807
|
-
placeholder: "you@example.com",
|
|
9808
|
-
...register("email"),
|
|
9809
|
-
error: errors.email?.message
|
|
9810
|
-
}
|
|
9811
|
-
)), /* @__PURE__ */ React21.createElement("div", { className: "relative" }, /* @__PURE__ */ React21.createElement(
|
|
9812
|
-
Input,
|
|
9813
|
-
{
|
|
9814
|
-
type: showPassword ? "text" : "password",
|
|
9815
|
-
label: "Password",
|
|
9816
|
-
placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022",
|
|
9817
|
-
...register("password"),
|
|
9818
|
-
error: errors.password?.message
|
|
9819
|
-
}
|
|
9820
|
-
), /* @__PURE__ */ React21.createElement(
|
|
9821
|
-
"button",
|
|
9822
|
-
{
|
|
9823
|
-
type: "button",
|
|
9824
|
-
onClick: () => setShowPassword((prev) => !prev),
|
|
9825
|
-
className: "absolute right-3 top-[42px] text-slate-400 transition hover:text-slate-600"
|
|
9826
|
-
},
|
|
9827
|
-
showPassword ? /* @__PURE__ */ React21.createElement(EyeOff, { className: "h-5 w-5" }) : /* @__PURE__ */ React21.createElement(Eye, { className: "h-5 w-5" })
|
|
9828
|
-
)), /* @__PURE__ */ React21.createElement("div", { className: "flex items-center justify-between text-sm" }, /* @__PURE__ */ React21.createElement("label", { className: "flex items-center gap-2 text-slate-600" }, /* @__PURE__ */ React21.createElement(
|
|
9829
|
-
"input",
|
|
9830
|
-
{
|
|
9831
|
-
type: "checkbox",
|
|
9832
|
-
className: "h-4 w-4 rounded border-slate-300 text-primary-600 focus:ring-primary-500"
|
|
9833
|
-
}
|
|
9834
|
-
), "Remember me"), /* @__PURE__ */ React21.createElement(
|
|
9835
|
-
Link8,
|
|
9836
|
-
{
|
|
9837
|
-
href: buildPath("/forgot-password"),
|
|
9838
|
-
className: "font-medium text-primary-600 transition hover:text-primary-700"
|
|
9839
|
-
},
|
|
9840
|
-
"Forgot password?"
|
|
9841
|
-
)), /* @__PURE__ */ React21.createElement(
|
|
9842
|
-
Button,
|
|
10021
|
+
/* @__PURE__ */ React21.createElement("div", { className: "w-full max-w-lg space-y-10 text-center" }, /* @__PURE__ */ React21.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React21.createElement(Lock, { strokeWidth: 2, className: "h-16 w-16 mx-auto text-white rounded-full bg-secondary m-2 mb-4 px-4" }), /* @__PURE__ */ React21.createElement("h2", { className: "text-4xl text-secondary" }, "Welcome Back"), /* @__PURE__ */ React21.createElement("p", { className: "text-sm text-muted" }, "Sign in to access your patient portal")), /* @__PURE__ */ React21.createElement(
|
|
10022
|
+
"form",
|
|
9843
10023
|
{
|
|
9844
|
-
|
|
9845
|
-
|
|
9846
|
-
|
|
9847
|
-
|
|
10024
|
+
onSubmit: handleSubmit(onSubmit),
|
|
10025
|
+
className: "space-y-6 rounded-3xl border bg-white p-8",
|
|
10026
|
+
style: {
|
|
10027
|
+
boxShadow: "0px 4px 6px -4px #0000001A, 0px 10px 15px -3px #0000001A"
|
|
10028
|
+
}
|
|
9848
10029
|
},
|
|
9849
|
-
|
|
9850
|
-
|
|
10030
|
+
status && /* @__PURE__ */ React21.createElement(
|
|
10031
|
+
"div",
|
|
10032
|
+
{
|
|
10033
|
+
className: `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"}`
|
|
10034
|
+
},
|
|
10035
|
+
/* @__PURE__ */ React21.createElement("span", { className: "mt-[2px] text-base" }, status.type === "success" ? "\u2714" : "!"),
|
|
10036
|
+
/* @__PURE__ */ React21.createElement("span", null, status.message)
|
|
10037
|
+
),
|
|
10038
|
+
/* @__PURE__ */ React21.createElement("div", { className: "text-start text-secondary" }, /* @__PURE__ */ React21.createElement("h2", { className: "text-sm text-secondary mb-3" }, "Email Address ", /* @__PURE__ */ React21.createElement("span", { className: "text-primary-500" }, "*")), /* @__PURE__ */ React21.createElement(
|
|
10039
|
+
Input,
|
|
10040
|
+
{
|
|
10041
|
+
type: "email",
|
|
10042
|
+
placeholder: "you@example.com",
|
|
10043
|
+
...register("email"),
|
|
10044
|
+
error: errors.email?.message,
|
|
10045
|
+
className: "text-secondary"
|
|
10046
|
+
}
|
|
10047
|
+
)),
|
|
10048
|
+
/* @__PURE__ */ React21.createElement("div", { className: "relative text-start text-secondary" }, /* @__PURE__ */ React21.createElement("h2", { className: "text-sm text-secondary mb-3" }, "Password ", /* @__PURE__ */ React21.createElement("span", { className: "text-primary-500" }, "*")), /* @__PURE__ */ React21.createElement(
|
|
10049
|
+
Input,
|
|
10050
|
+
{
|
|
10051
|
+
type: showPassword ? "text" : "password",
|
|
10052
|
+
placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022",
|
|
10053
|
+
...register("password"),
|
|
10054
|
+
error: errors.password?.message
|
|
10055
|
+
}
|
|
10056
|
+
), /* @__PURE__ */ React21.createElement(
|
|
10057
|
+
"button",
|
|
10058
|
+
{
|
|
10059
|
+
type: "button",
|
|
10060
|
+
onClick: () => setShowPassword((prev) => !prev),
|
|
10061
|
+
className: "absolute right-3 top-[42px] text-slate-400 transition hover:text-slate-600"
|
|
10062
|
+
},
|
|
10063
|
+
showPassword ? /* @__PURE__ */ React21.createElement(EyeOff, { className: "h-5 w-5" }) : /* @__PURE__ */ React21.createElement(Eye, { className: "h-5 w-5" })
|
|
10064
|
+
)),
|
|
10065
|
+
/* @__PURE__ */ React21.createElement("div", { className: "flex items-center justify-between text-sm" }, /* @__PURE__ */ React21.createElement("label", { className: "flex items-center gap-2 text-slate-600" }, /* @__PURE__ */ React21.createElement(
|
|
10066
|
+
"input",
|
|
10067
|
+
{
|
|
10068
|
+
type: "checkbox",
|
|
10069
|
+
className: "h-4 w-4 rounded border-slate-300 text-primary-600 focus:ring-primary-500"
|
|
10070
|
+
}
|
|
10071
|
+
), "Remember me"), /* @__PURE__ */ React21.createElement(
|
|
10072
|
+
Link7,
|
|
10073
|
+
{
|
|
10074
|
+
href: buildPath("/forgot-password"),
|
|
10075
|
+
className: "font-medium text-primary transition hover:opacity-80"
|
|
10076
|
+
},
|
|
10077
|
+
"Forgot password?"
|
|
10078
|
+
)),
|
|
10079
|
+
/* @__PURE__ */ React21.createElement(
|
|
10080
|
+
"button",
|
|
10081
|
+
{
|
|
10082
|
+
type: "submit",
|
|
10083
|
+
disabled: isSubmitting,
|
|
10084
|
+
className: "w-full bg-secondary hover:opacity-80 text-white font-medium py-3 px-4 rounded-lg transition-colors disabled:opacity-70 disabled:cursor-not-allowed"
|
|
10085
|
+
},
|
|
10086
|
+
isSubmitting ? "Signing in..." : "Sign in"
|
|
10087
|
+
)
|
|
10088
|
+
), /* @__PURE__ */ React21.createElement("div", { className: "mt-4" }, /* @__PURE__ */ React21.createElement("p", { className: "text-muted" }, "Don't have an account? ", /* @__PURE__ */ React21.createElement(Link7, { href: buildPath("/register"), className: "font-medium text-primary transition hover:opacity-90" }, "Sign up"))))
|
|
9851
10089
|
)));
|
|
9852
10090
|
}
|
|
9853
10091
|
var registerSchema = z.object({
|
|
@@ -9861,11 +10099,6 @@ var registerSchema = z.object({
|
|
|
9861
10099
|
message: "Passwords don't match",
|
|
9862
10100
|
path: ["confirmPassword"]
|
|
9863
10101
|
});
|
|
9864
|
-
var BENEFITS = [
|
|
9865
|
-
"Personalized care plans from licensed pharmacists",
|
|
9866
|
-
"Express delivery with cold-chain handling",
|
|
9867
|
-
"Automatic refills and refill reminders"
|
|
9868
|
-
];
|
|
9869
10102
|
function RegisterScreen() {
|
|
9870
10103
|
const router = useRouter();
|
|
9871
10104
|
const { register: registerUser } = useAuth();
|
|
@@ -9873,6 +10106,7 @@ function RegisterScreen() {
|
|
|
9873
10106
|
const [showPassword, setShowPassword] = useState(false);
|
|
9874
10107
|
const [showConfirmPassword, setShowConfirmPassword] = useState(false);
|
|
9875
10108
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
10109
|
+
const notification = useNotification();
|
|
9876
10110
|
const {
|
|
9877
10111
|
register,
|
|
9878
10112
|
handleSubmit,
|
|
@@ -9890,33 +10124,21 @@ function RegisterScreen() {
|
|
|
9890
10124
|
customerType: "Regular" /* Regular */,
|
|
9891
10125
|
role: "User" /* User */
|
|
9892
10126
|
});
|
|
9893
|
-
|
|
10127
|
+
notification.success(
|
|
10128
|
+
"Account created",
|
|
10129
|
+
"Your Hey Pharmacist account is ready to use."
|
|
10130
|
+
);
|
|
9894
10131
|
router.push(buildPath("/"));
|
|
9895
10132
|
} catch (error) {
|
|
9896
|
-
|
|
10133
|
+
notification.error(
|
|
10134
|
+
"Could not create account",
|
|
10135
|
+
error.response?.data?.message || "Something went wrong while creating your account. Please try again."
|
|
10136
|
+
);
|
|
9897
10137
|
} finally {
|
|
9898
10138
|
setIsSubmitting(false);
|
|
9899
10139
|
}
|
|
9900
10140
|
};
|
|
9901
|
-
return /* @__PURE__ */ React21.createElement("div", { className: "min-h-screen bg-
|
|
9902
|
-
motion.section,
|
|
9903
|
-
{
|
|
9904
|
-
initial: { opacity: 0, x: -24 },
|
|
9905
|
-
animate: { opacity: 1, x: 0 },
|
|
9906
|
-
transition: { duration: 0.4 },
|
|
9907
|
-
className: "flex flex-col justify-between bg-gradient-to-br from-slate-700 via-slate-600 to-slate-700 px-10 py-14 text-white"
|
|
9908
|
-
},
|
|
9909
|
-
/* @__PURE__ */ React21.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React21.createElement("span", { className: "inline-flex items-center gap-2 rounded-full bg-white/15 px-3 py-1 text-sm font-semibold uppercase tracking-[0.35em] text-white/70 backdrop-blur" }, /* @__PURE__ */ React21.createElement(HeartPulse, { className: "h-4 w-4" }), "Join Hey Pharmacist"), /* @__PURE__ */ React21.createElement("h1", { className: "text-4xl font-bold leading-tight lg:text-5xl" }, "Create your wellness account"), /* @__PURE__ */ React21.createElement("p", { className: "max-w-xl text-white/80" }, "Unlock concierge-level pharmacy support, curated product recommendations, and smarter refills designed for busy families.")),
|
|
9910
|
-
/* @__PURE__ */ React21.createElement("div", { className: "space-y-4 rounded-3xl bg-white/10 p-6 backdrop-blur" }, BENEFITS.map((benefit) => /* @__PURE__ */ React21.createElement("div", { key: benefit, className: "flex items-center gap-3" }, /* @__PURE__ */ React21.createElement(CheckCircle2, { className: "h-5 w-5 text-white" }), /* @__PURE__ */ React21.createElement("p", { className: "text-sm text-white/85" }, benefit)))),
|
|
9911
|
-
/* @__PURE__ */ React21.createElement("div", { className: "flex items-center gap-6 text-sm text-white/80" }, /* @__PURE__ */ React21.createElement("span", null, "Already part of the community?"), /* @__PURE__ */ React21.createElement(
|
|
9912
|
-
Link8,
|
|
9913
|
-
{
|
|
9914
|
-
href: buildPath("/login"),
|
|
9915
|
-
className: "inline-flex items-center gap-2 rounded-full bg-white/15 px-4 py-2 font-semibold transition hover:bg-white/25"
|
|
9916
|
-
},
|
|
9917
|
-
"Sign in"
|
|
9918
|
-
))
|
|
9919
|
-
), /* @__PURE__ */ React21.createElement(
|
|
10141
|
+
return /* @__PURE__ */ React21.createElement("div", { className: "min-h-screen bg-gradient-to-b from-[#F8FAFC] to-[#EBF4FB]" }, /* @__PURE__ */ React21.createElement("div", { className: "grid min-h-screen overflow-hidden pb-12" }, /* @__PURE__ */ React21.createElement(
|
|
9920
10142
|
motion.section,
|
|
9921
10143
|
{
|
|
9922
10144
|
initial: { opacity: 0, x: 24 },
|
|
@@ -9924,54 +10146,52 @@ function RegisterScreen() {
|
|
|
9924
10146
|
transition: { duration: 0.4 },
|
|
9925
10147
|
className: "flex items-center justify-center px-6 py-12 lg:px-16"
|
|
9926
10148
|
},
|
|
9927
|
-
/* @__PURE__ */ React21.createElement("div", { className: "w-full max-w-
|
|
10149
|
+
/* @__PURE__ */ React21.createElement("div", { className: "w-full max-w-xl space-y-10 text-center" }, /* @__PURE__ */ React21.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React21.createElement(UserPlus, { strokeWidth: 2, className: "h-16 w-16 mx-auto text-white rounded-full bg-primary m-2 mb-4 px-4" }), /* @__PURE__ */ React21.createElement("h2", { className: "text-4xl text-secondary" }, "Create Your Account"), /* @__PURE__ */ React21.createElement("p", { className: "text-sm text-muted" }, "Join Holmdel Pharmacy Care for convenient healthcare access")), /* @__PURE__ */ React21.createElement(
|
|
9928
10150
|
"form",
|
|
9929
10151
|
{
|
|
9930
10152
|
onSubmit: handleSubmit(onSubmit),
|
|
9931
|
-
className: "space-y-6 rounded-3xl border border-slate-100 bg-white p-8 shadow-lg shadow-primary-50"
|
|
10153
|
+
className: "text-start space-y-6 rounded-3xl border border-slate-100 bg-white p-8 shadow-lg shadow-primary-50",
|
|
10154
|
+
style: {
|
|
10155
|
+
boxShadow: "0px 4px 6px -4px #0000001A, 0px 10px 15px -3px #0000001A"
|
|
10156
|
+
}
|
|
9932
10157
|
},
|
|
9933
|
-
/* @__PURE__ */ React21.createElement("div", { className: "grid gap-4 md:grid-cols-2" }, /* @__PURE__ */ React21.createElement(
|
|
10158
|
+
/* @__PURE__ */ React21.createElement("div", { className: "grid gap-4 md:grid-cols-2 text-start" }, /* @__PURE__ */ React21.createElement("div", null, /* @__PURE__ */ React21.createElement("h2", { className: "text-sm text-secondary mb-3" }, "First name ", /* @__PURE__ */ React21.createElement("span", { className: "text-primary-500" }, "*")), /* @__PURE__ */ React21.createElement(
|
|
9934
10159
|
Input,
|
|
9935
10160
|
{
|
|
9936
|
-
label: "First name",
|
|
9937
10161
|
placeholder: "Alex",
|
|
9938
10162
|
...register("firstName"),
|
|
9939
10163
|
error: errors.firstName?.message
|
|
9940
10164
|
}
|
|
9941
|
-
), /* @__PURE__ */ React21.createElement(
|
|
10165
|
+
)), /* @__PURE__ */ React21.createElement("div", null, /* @__PURE__ */ React21.createElement("h2", { className: "text-sm text-secondary mb-3" }, "Last name ", /* @__PURE__ */ React21.createElement("span", { className: "text-primary-500" }, "*")), /* @__PURE__ */ React21.createElement(
|
|
9942
10166
|
Input,
|
|
9943
10167
|
{
|
|
9944
|
-
label: "Last name",
|
|
9945
10168
|
placeholder: "Morgan",
|
|
9946
10169
|
...register("lastName"),
|
|
9947
10170
|
error: errors.lastName?.message
|
|
9948
10171
|
}
|
|
9949
|
-
)),
|
|
9950
|
-
/* @__PURE__ */ React21.createElement(
|
|
10172
|
+
))),
|
|
10173
|
+
/* @__PURE__ */ React21.createElement("div", null, /* @__PURE__ */ React21.createElement("h2", { className: "text-sm text-secondary mb-3" }, "Email Address ", /* @__PURE__ */ React21.createElement("span", { className: "text-primary-500" }, "*")), /* @__PURE__ */ React21.createElement(
|
|
9951
10174
|
Input,
|
|
9952
10175
|
{
|
|
9953
10176
|
type: "email",
|
|
9954
|
-
label: "Email address",
|
|
9955
10177
|
placeholder: "you@example.com",
|
|
9956
10178
|
...register("email"),
|
|
9957
10179
|
error: errors.email?.message
|
|
9958
10180
|
}
|
|
9959
|
-
),
|
|
9960
|
-
/* @__PURE__ */ React21.createElement(
|
|
10181
|
+
)),
|
|
10182
|
+
/* @__PURE__ */ React21.createElement("div", null, /* @__PURE__ */ React21.createElement("h2", { className: "text-sm text-secondary mb-3" }, "Phone Number"), /* @__PURE__ */ React21.createElement(
|
|
9961
10183
|
Input,
|
|
9962
10184
|
{
|
|
9963
10185
|
type: "tel",
|
|
9964
|
-
label: "Phone number (optional)",
|
|
9965
10186
|
placeholder: "+1 (555) 123-4567",
|
|
9966
10187
|
...register("phone"),
|
|
9967
10188
|
error: errors.phone?.message
|
|
9968
10189
|
}
|
|
9969
|
-
),
|
|
9970
|
-
/* @__PURE__ */ React21.createElement("div", { className: "relative" }, /* @__PURE__ */ React21.createElement(
|
|
10190
|
+
)),
|
|
10191
|
+
/* @__PURE__ */ React21.createElement("div", { className: "relative" }, /* @__PURE__ */ React21.createElement("h2", { className: "text-sm text-secondary mb-3" }, "Password ", /* @__PURE__ */ React21.createElement("span", { className: "text-primary-500" }, "*")), /* @__PURE__ */ React21.createElement(
|
|
9971
10192
|
Input,
|
|
9972
10193
|
{
|
|
9973
10194
|
type: showPassword ? "text" : "password",
|
|
9974
|
-
label: "Password",
|
|
9975
10195
|
placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022",
|
|
9976
10196
|
...register("password"),
|
|
9977
10197
|
error: errors.password?.message
|
|
@@ -9985,11 +10205,10 @@ function RegisterScreen() {
|
|
|
9985
10205
|
},
|
|
9986
10206
|
showPassword ? /* @__PURE__ */ React21.createElement(EyeOff, { className: "h-5 w-5" }) : /* @__PURE__ */ React21.createElement(Eye, { className: "h-5 w-5" })
|
|
9987
10207
|
)),
|
|
9988
|
-
/* @__PURE__ */ React21.createElement("div", { className: "relative" }, /* @__PURE__ */ React21.createElement(
|
|
10208
|
+
/* @__PURE__ */ React21.createElement("div", { className: "relative" }, /* @__PURE__ */ React21.createElement("h2", { className: "text-sm text-secondary mb-3" }, "Confirm Password ", /* @__PURE__ */ React21.createElement("span", { className: "text-primary-500" }, "*")), /* @__PURE__ */ React21.createElement(
|
|
9989
10209
|
Input,
|
|
9990
10210
|
{
|
|
9991
10211
|
type: showConfirmPassword ? "text" : "password",
|
|
9992
|
-
label: "Confirm password",
|
|
9993
10212
|
placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022",
|
|
9994
10213
|
...register("confirmPassword"),
|
|
9995
10214
|
error: errors.confirmPassword?.message
|
|
@@ -10003,77 +10222,54 @@ function RegisterScreen() {
|
|
|
10003
10222
|
},
|
|
10004
10223
|
showConfirmPassword ? /* @__PURE__ */ React21.createElement(EyeOff, { className: "h-5 w-5" }) : /* @__PURE__ */ React21.createElement(Eye, { className: "h-5 w-5" })
|
|
10005
10224
|
)),
|
|
10006
|
-
/* @__PURE__ */ React21.createElement("div", { className: "flex items-start gap-3 rounded-2xl bg-slate-50 p-4 text-sm text-slate-600" }, /* @__PURE__ */ React21.createElement(Shield, { className: "mt-0.5 h-
|
|
10007
|
-
|
|
10225
|
+
/* @__PURE__ */ React21.createElement("div", { className: "flex items-start gap-3 rounded-2xl bg-slate-50 p-4 text-sm text-slate-600" }, /* @__PURE__ */ React21.createElement(Shield, { strokeWidth: 2, className: "mt-0.5 h-8 w-8 text-primary" }), /* @__PURE__ */ React21.createElement("span", null, "By creating an account, you agree to our", " ", /* @__PURE__ */ React21.createElement(Link7, { href: buildPath("/terms"), className: "font-semibold text-primary hover:opacity-70" }, "Terms of Service"), " ", "and", " ", /* @__PURE__ */ React21.createElement(
|
|
10226
|
+
Link7,
|
|
10008
10227
|
{
|
|
10009
10228
|
href: buildPath("/privacy"),
|
|
10010
|
-
className: "font-semibold text-primary
|
|
10229
|
+
className: "font-semibold text-primary hover:opacity-70"
|
|
10011
10230
|
},
|
|
10012
10231
|
"Privacy Policy"
|
|
10013
10232
|
), ". We protect your information with bank-level encryption.")),
|
|
10014
10233
|
/* @__PURE__ */ React21.createElement(
|
|
10015
|
-
|
|
10234
|
+
"button",
|
|
10016
10235
|
{
|
|
10017
10236
|
type: "submit",
|
|
10018
|
-
|
|
10019
|
-
|
|
10020
|
-
className: "w-full"
|
|
10237
|
+
disabled: isSubmitting,
|
|
10238
|
+
className: "w-full bg-secondary hover:opacity-80 text-white font-medium py-3 px-4 rounded-lg transition-colors disabled:opacity-70 disabled:cursor-not-allowed"
|
|
10021
10239
|
},
|
|
10022
|
-
|
|
10023
|
-
"Create my account"
|
|
10240
|
+
isSubmitting ? "Creating account..." : "Create my account"
|
|
10024
10241
|
)
|
|
10025
|
-
), /* @__PURE__ */ React21.createElement("div", { className: "
|
|
10242
|
+
), /* @__PURE__ */ React21.createElement("div", { className: "mt-4" }, /* @__PURE__ */ React21.createElement("p", { className: "text-muted" }, "Already have an account? ", /* @__PURE__ */ React21.createElement(Link7, { href: buildPath("/login"), className: "font-medium text-primary transition hover:opacity-90" }, "Sign in"))))
|
|
10026
10243
|
)));
|
|
10027
10244
|
}
|
|
10028
|
-
var profileSchema = z.object({
|
|
10029
|
-
firstName: z.string().min(2, "First name is required"),
|
|
10030
|
-
lastName: z.string().min(2, "Last name is required"),
|
|
10031
|
-
email: z.string().email("Enter a valid email address"),
|
|
10032
|
-
phone: z.string().optional()
|
|
10033
|
-
});
|
|
10034
10245
|
function ProfileScreen() {
|
|
10035
10246
|
const router = useRouter();
|
|
10036
|
-
const { user,
|
|
10247
|
+
const { user, logout, isLoading } = useAuth();
|
|
10037
10248
|
const { buildPath } = useBasePath();
|
|
10038
|
-
const [
|
|
10039
|
-
const
|
|
10040
|
-
|
|
10041
|
-
|
|
10042
|
-
|
|
10043
|
-
} = useForm({
|
|
10044
|
-
resolver: zodResolver(profileSchema),
|
|
10045
|
-
defaultValues: {
|
|
10046
|
-
firstName: user?.firstname || "",
|
|
10047
|
-
lastName: user?.lastname || "",
|
|
10048
|
-
email: user?.email || "",
|
|
10049
|
-
phone: user?.phoneNumber || ""
|
|
10050
|
-
}
|
|
10051
|
-
});
|
|
10052
|
-
const onSubmit = async (data) => {
|
|
10053
|
-
setIsSubmitting(true);
|
|
10249
|
+
const [isLoggingOut, setIsLoggingOut] = useState(false);
|
|
10250
|
+
const [logoutError, setLogoutError] = useState(null);
|
|
10251
|
+
const handleLogout = async () => {
|
|
10252
|
+
setIsLoggingOut(true);
|
|
10253
|
+
setLogoutError(null);
|
|
10054
10254
|
try {
|
|
10055
|
-
await
|
|
10056
|
-
|
|
10255
|
+
await logout();
|
|
10256
|
+
router.push(buildPath("/"));
|
|
10057
10257
|
} catch (error) {
|
|
10058
|
-
|
|
10258
|
+
setLogoutError(error?.response?.data?.message || "Failed to logout. Please try again.");
|
|
10059
10259
|
} finally {
|
|
10060
|
-
|
|
10260
|
+
setIsLoggingOut(false);
|
|
10061
10261
|
}
|
|
10062
10262
|
};
|
|
10063
|
-
const handleLogout = async () => {
|
|
10064
|
-
await logout();
|
|
10065
|
-
toast.success("Logged out successfully");
|
|
10066
|
-
router.push(buildPath("/"));
|
|
10067
|
-
};
|
|
10068
10263
|
if (!user) {
|
|
10264
|
+
if (isLoading) return null;
|
|
10069
10265
|
router.push(buildPath("/login"));
|
|
10070
10266
|
return null;
|
|
10071
10267
|
}
|
|
10072
10268
|
const quickLinks = [
|
|
10073
10269
|
{
|
|
10074
10270
|
icon: Package,
|
|
10075
|
-
label: "
|
|
10076
|
-
description: "Track shipments and
|
|
10271
|
+
label: "Orders & invoices",
|
|
10272
|
+
description: "Track shipments, invoices, and receipts",
|
|
10077
10273
|
href: buildPath("/orders")
|
|
10078
10274
|
},
|
|
10079
10275
|
{
|
|
@@ -10089,121 +10285,105 @@ function ProfileScreen() {
|
|
|
10089
10285
|
href: buildPath("/account/addresses")
|
|
10090
10286
|
}
|
|
10091
10287
|
];
|
|
10092
|
-
return /* @__PURE__ */ React21.createElement("div", { className: "min-h-screen bg-slate-50" }, /* @__PURE__ */ React21.createElement("
|
|
10288
|
+
return /* @__PURE__ */ React21.createElement("div", { className: "min-h-screen bg-slate-50 text-slate-900" }, /* @__PURE__ */ React21.createElement("div", { className: "relative container mx-auto px-4 pb-16 pt-10" }, /* @__PURE__ */ React21.createElement("div", { className: "rounded-3xl border border-slate-200 bg-white/95 p-8 shadow-xl shadow-primary-50 backdrop-blur" }, /* @__PURE__ */ React21.createElement("div", { className: "mb-6 flex flex-wrap items-center justify-between gap-3" }, /* @__PURE__ */ React21.createElement("div", { className: "text-sm text-slate-500" }, "Stay signed in to keep prescriptions and deliveries synced."), /* @__PURE__ */ React21.createElement("div", { className: "flex items-center gap-3" }, logoutError && /* @__PURE__ */ React21.createElement("div", { className: "flex items-start gap-2 rounded-xl border border-red-200 bg-red-50 px-3 py-2 text-xs text-red-700" }, /* @__PURE__ */ React21.createElement(ShieldCheck, { className: "mt-[1px] h-4 w-4 text-red-500" }), /* @__PURE__ */ React21.createElement("span", null, logoutError)), /* @__PURE__ */ React21.createElement(
|
|
10289
|
+
Button,
|
|
10290
|
+
{
|
|
10291
|
+
type: "button",
|
|
10292
|
+
variant: "outline",
|
|
10293
|
+
size: "sm",
|
|
10294
|
+
className: "border-red-200 text-red-600 hover:bg-red-50",
|
|
10295
|
+
onClick: handleLogout,
|
|
10296
|
+
disabled: isLoggingOut
|
|
10297
|
+
},
|
|
10298
|
+
/* @__PURE__ */ React21.createElement(LogOut, { className: "h-4 w-4" }),
|
|
10299
|
+
isLoggingOut ? "Logging out..." : "Log out"
|
|
10300
|
+
))), /* @__PURE__ */ React21.createElement(
|
|
10093
10301
|
motion.div,
|
|
10094
10302
|
{
|
|
10095
|
-
initial: { opacity: 0, y:
|
|
10303
|
+
initial: { opacity: 0, y: 18 },
|
|
10096
10304
|
animate: { opacity: 1, y: 0 },
|
|
10097
|
-
className: "
|
|
10305
|
+
className: "grid gap-8 md:grid-cols-[minmax(0,1.1fr)_minmax(0,0.9fr)] md:items-center"
|
|
10098
10306
|
},
|
|
10099
|
-
/* @__PURE__ */ React21.createElement("div", { className: "space-y-
|
|
10100
|
-
/* @__PURE__ */ React21.createElement("div", { className: "flex flex-col
|
|
10307
|
+
/* @__PURE__ */ React21.createElement("div", { className: "space-y-4" }, /* @__PURE__ */ React21.createElement("div", { className: "inline-flex items-center gap-2 rounded-full bg-slate-900 text-white px-4 py-1 text-xs font-semibold uppercase tracking-[0.32em]" }, /* @__PURE__ */ React21.createElement(HeartPulse, { className: "h-4 w-4" }), "Account"), /* @__PURE__ */ React21.createElement("div", null, /* @__PURE__ */ React21.createElement("h1", { className: "text-4xl font-semibold md:text-5xl" }, "Welcome back, ", user.firstname, " ", user.lastname), /* @__PURE__ */ React21.createElement("p", { className: "mt-3 max-w-2xl text-base text-slate-600" }, "Keep your identity and delivery details accurate for smoother refills, faster shipping, and timely pharmacist guidance.")), /* @__PURE__ */ React21.createElement("div", { className: "flex flex-wrap gap-3 text-sm text-slate-600" }, /* @__PURE__ */ React21.createElement("span", { className: "inline-flex items-center gap-2 rounded-full border border-slate-200 bg-slate-50 px-3 py-2" }, /* @__PURE__ */ React21.createElement(ShieldCheck, { className: "h-4 w-4 text-primary-600" }), "Secure login enabled"), /* @__PURE__ */ React21.createElement("span", { className: "inline-flex items-center gap-2 rounded-full border border-slate-200 bg-slate-50 px-3 py-2" }, /* @__PURE__ */ React21.createElement(Mail, { className: "h-4 w-4 text-primary-600" }), user.email), /* @__PURE__ */ React21.createElement("span", { className: "inline-flex items-center gap-2 rounded-full border border-slate-200 bg-slate-50 px-3 py-2" }, /* @__PURE__ */ React21.createElement(Phone, { className: "h-4 w-4 text-primary-600" }), user.phoneNumber || "Add phone for urgent updates"))),
|
|
10308
|
+
/* @__PURE__ */ React21.createElement("div", { className: "flex flex-col gap-4 rounded-2xl border border-slate-200 bg-slate-50/70 p-6 shadow-sm" }, /* @__PURE__ */ React21.createElement("div", { className: "flex items-center gap-4" }, /* @__PURE__ */ React21.createElement("div", { className: "flex h-16 w-16 items-center justify-center rounded-2xl bg-white text-2xl font-semibold text-slate-900 shadow-sm" }, getInitials(user?.firstname || "", user?.lastname || "") || ""), /* @__PURE__ */ React21.createElement("div", { className: "space-y-1" }, /* @__PURE__ */ React21.createElement("p", { className: "text-sm text-slate-500" }, "Signed in as"), /* @__PURE__ */ React21.createElement("p", { className: "text-lg font-semibold text-slate-900" }, user.firstname), /* @__PURE__ */ React21.createElement("p", { className: "text-sm text-slate-500" }, user.email))), /* @__PURE__ */ React21.createElement("div", { className: "grid gap-3 sm:grid-cols-2" }, /* @__PURE__ */ React21.createElement(
|
|
10309
|
+
Button,
|
|
10310
|
+
{
|
|
10311
|
+
variant: "outline",
|
|
10312
|
+
size: "md",
|
|
10313
|
+
className: "border-slate-300 text-slate-800 hover:bg-white",
|
|
10314
|
+
onClick: () => router.push(buildPath("/account/edit"))
|
|
10315
|
+
},
|
|
10316
|
+
"Edit profile"
|
|
10317
|
+
), /* @__PURE__ */ React21.createElement(
|
|
10101
10318
|
Button,
|
|
10102
10319
|
{
|
|
10103
10320
|
variant: "ghost",
|
|
10104
|
-
|
|
10321
|
+
size: "md",
|
|
10322
|
+
className: "text-slate-700 hover:bg-white",
|
|
10105
10323
|
onClick: () => router.push(buildPath("/account/change-password"))
|
|
10106
10324
|
},
|
|
10107
10325
|
"Change password"
|
|
10108
|
-
))
|
|
10109
|
-
))
|
|
10326
|
+
)))
|
|
10327
|
+
)), /* @__PURE__ */ React21.createElement("div", { className: "mt-10 grid gap-8 lg:grid-cols-[minmax(0,1.08fr)_minmax(0,0.92fr)] items-stretch" }, /* @__PURE__ */ React21.createElement(
|
|
10110
10328
|
motion.div,
|
|
10111
10329
|
{
|
|
10112
|
-
initial: { opacity: 0, y:
|
|
10330
|
+
initial: { opacity: 0, y: 18 },
|
|
10113
10331
|
animate: { opacity: 1, y: 0 },
|
|
10114
10332
|
className: "space-y-6"
|
|
10115
10333
|
},
|
|
10116
|
-
/* @__PURE__ */ React21.createElement("section", { className: "rounded-3xl border border-slate-
|
|
10117
|
-
Input,
|
|
10118
|
-
{
|
|
10119
|
-
label: "First name",
|
|
10120
|
-
placeholder: "Taylor",
|
|
10121
|
-
...register("firstName"),
|
|
10122
|
-
error: errors.firstName?.message
|
|
10123
|
-
}
|
|
10124
|
-
), /* @__PURE__ */ React21.createElement(
|
|
10125
|
-
Input,
|
|
10126
|
-
{
|
|
10127
|
-
label: "Last name",
|
|
10128
|
-
placeholder: "Reed",
|
|
10129
|
-
...register("lastName"),
|
|
10130
|
-
error: errors.lastName?.message
|
|
10131
|
-
}
|
|
10132
|
-
)), /* @__PURE__ */ React21.createElement("div", { className: "relative" }, /* @__PURE__ */ React21.createElement(
|
|
10133
|
-
Input,
|
|
10134
|
-
{
|
|
10135
|
-
type: "email",
|
|
10136
|
-
label: "Email address",
|
|
10137
|
-
placeholder: "you@example.com",
|
|
10138
|
-
className: "pl-10",
|
|
10139
|
-
...register("email"),
|
|
10140
|
-
error: errors.email?.message
|
|
10141
|
-
}
|
|
10142
|
-
), /* @__PURE__ */ React21.createElement(Mail, { className: "absolute left-3 top-[38px] h-4 w-4 text-slate-400" })), /* @__PURE__ */ React21.createElement("div", { className: "relative" }, /* @__PURE__ */ React21.createElement(
|
|
10143
|
-
Input,
|
|
10144
|
-
{
|
|
10145
|
-
type: "tel",
|
|
10146
|
-
label: "Phone number",
|
|
10147
|
-
placeholder: "+1 (555) 123-4567",
|
|
10148
|
-
className: "pl-10",
|
|
10149
|
-
...register("phone"),
|
|
10150
|
-
error: errors.phone?.message
|
|
10151
|
-
}
|
|
10152
|
-
), /* @__PURE__ */ React21.createElement(Phone, { className: "absolute left-3 top-[38px] h-4 w-4 text-slate-400" })), /* @__PURE__ */ React21.createElement("div", { className: "flex flex-wrap gap-4" }, /* @__PURE__ */ React21.createElement(
|
|
10153
|
-
Button,
|
|
10154
|
-
{
|
|
10155
|
-
type: "submit",
|
|
10156
|
-
size: "lg",
|
|
10157
|
-
isLoading: isSubmitting
|
|
10158
|
-
},
|
|
10159
|
-
"Save changes"
|
|
10160
|
-
), /* @__PURE__ */ React21.createElement(
|
|
10334
|
+
/* @__PURE__ */ React21.createElement("section", { className: "rounded-3xl border border-slate-200 bg-white p-7 shadow-lg shadow-primary-50/40 min-h-[420px] h-full flex flex-col" }, /* @__PURE__ */ React21.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React21.createElement("div", null, /* @__PURE__ */ React21.createElement("p", { className: "text-xs font-semibold uppercase tracking-[0.3em] text-slate-400" }, "Essentials"), /* @__PURE__ */ React21.createElement("h2", { className: "mt-1 text-xl font-semibold text-slate-900" }, "Profile snapshot")), /* @__PURE__ */ React21.createElement(Sparkles, { className: "h-5 w-5 text-primary-500" })), /* @__PURE__ */ React21.createElement("div", { className: "mt-6 grid gap-4 md:grid-cols-2" }, /* @__PURE__ */ React21.createElement("div", { className: "rounded-2xl border border-slate-200 bg-slate-50/70 p-5" }, /* @__PURE__ */ React21.createElement("p", { className: "text-xs font-semibold uppercase tracking-[0.28em] text-slate-500" }, "Contact"), /* @__PURE__ */ React21.createElement("div", { className: "mt-3 space-y-2 text-sm text-slate-600" }, /* @__PURE__ */ React21.createElement("p", { className: "flex items-center gap-2 font-semibold text-slate-900" }, /* @__PURE__ */ React21.createElement(User, { className: "h-4 w-4 text-primary-500" }), user.firstname, " ", user.lastname), /* @__PURE__ */ React21.createElement("p", { className: "flex items-center gap-2" }, /* @__PURE__ */ React21.createElement(Mail, { className: "h-4 w-4 text-primary-500" }), user.email), /* @__PURE__ */ React21.createElement("p", { className: "flex items-center gap-2" }, /* @__PURE__ */ React21.createElement(Phone, { className: "h-4 w-4 text-primary-500" }), user.phoneNumber || "Not provided")), /* @__PURE__ */ React21.createElement(
|
|
10161
10335
|
Button,
|
|
10162
10336
|
{
|
|
10163
|
-
type: "button",
|
|
10164
10337
|
variant: "outline",
|
|
10165
|
-
size: "
|
|
10166
|
-
|
|
10338
|
+
size: "md",
|
|
10339
|
+
className: "mt-4 w-full border-slate-300 text-slate-800 hover:bg-white",
|
|
10340
|
+
onClick: () => router.push(buildPath("/account/edit"))
|
|
10167
10341
|
},
|
|
10168
|
-
"
|
|
10169
|
-
)))),
|
|
10170
|
-
|
|
10171
|
-
Link8,
|
|
10342
|
+
"Update information"
|
|
10343
|
+
)), /* @__PURE__ */ React21.createElement("div", { className: "rounded-2xl border border-slate-200 bg-slate-50/70 p-5" }, /* @__PURE__ */ React21.createElement("p", { className: "text-xs font-semibold uppercase tracking-[0.28em] text-slate-500" }, "Security"), /* @__PURE__ */ React21.createElement("div", { className: "mt-3 space-y-2 text-sm text-slate-600" }, /* @__PURE__ */ React21.createElement("p", { className: "flex items-center gap-2 font-semibold text-slate-900" }, /* @__PURE__ */ React21.createElement(ShieldCheck, { className: "h-4 w-4 text-primary-500" }), "Multi-factor ready"), /* @__PURE__ */ React21.createElement("p", null, "Protect your account with a fresh password and keep notifications on.")), /* @__PURE__ */ React21.createElement(
|
|
10344
|
+
Button,
|
|
10172
10345
|
{
|
|
10173
|
-
|
|
10174
|
-
|
|
10175
|
-
className: "
|
|
10346
|
+
variant: "primary",
|
|
10347
|
+
size: "md",
|
|
10348
|
+
className: "mt-4 w-full",
|
|
10349
|
+
onClick: () => router.push(buildPath("/account/change-password"))
|
|
10176
10350
|
},
|
|
10177
|
-
|
|
10178
|
-
)))
|
|
10351
|
+
"Change password"
|
|
10352
|
+
))))
|
|
10179
10353
|
), /* @__PURE__ */ React21.createElement(
|
|
10180
10354
|
motion.aside,
|
|
10181
10355
|
{
|
|
10182
|
-
initial: { opacity: 0, y:
|
|
10356
|
+
initial: { opacity: 0, y: 18 },
|
|
10183
10357
|
animate: { opacity: 1, y: 0 },
|
|
10184
|
-
transition: { delay: 0.
|
|
10185
|
-
className: "space-y-
|
|
10358
|
+
transition: { delay: 0.05 },
|
|
10359
|
+
className: "space-y-4 h-full"
|
|
10186
10360
|
},
|
|
10187
|
-
/* @__PURE__ */ React21.createElement("
|
|
10188
|
-
|
|
10361
|
+
/* @__PURE__ */ React21.createElement("section", { className: "rounded-3xl border border-slate-200 bg-white p-6 shadow-sm min-h-[420px] h-full flex flex-col" }, /* @__PURE__ */ React21.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React21.createElement("div", null, /* @__PURE__ */ React21.createElement("p", { className: "text-xs font-semibold uppercase tracking-[0.3em] text-slate-400" }, "Quick links"), /* @__PURE__ */ React21.createElement("h3", { className: "mt-1 text-lg font-semibold text-slate-900" }, "Next steps")), /* @__PURE__ */ React21.createElement(Heart, { className: "h-5 w-5 text-primary-500" })), /* @__PURE__ */ React21.createElement("div", { className: "mt-5 grid gap-3" }, quickLinks.map((item) => /* @__PURE__ */ React21.createElement(
|
|
10362
|
+
Link7,
|
|
10189
10363
|
{
|
|
10190
|
-
|
|
10191
|
-
|
|
10192
|
-
|
|
10193
|
-
},
|
|
10194
|
-
"Manage preferences"
|
|
10195
|
-
)),
|
|
10196
|
-
/* @__PURE__ */ React21.createElement("div", { className: "rounded-3xl border border-primary-100 bg-primary-50/70 p-6 text-sm text-primary-700 shadow-sm" }, /* @__PURE__ */ React21.createElement("p", { className: "font-semibold uppercase tracking-[0.3em]" }, "Pharmacist tip"), /* @__PURE__ */ React21.createElement("p", { className: "mt-3 leading-relaxed" }, "Keep your phone number current so pharmacists can reach you quickly with dosage advice or time-sensitive updates about your order.")),
|
|
10197
|
-
/* @__PURE__ */ React21.createElement(
|
|
10198
|
-
"button",
|
|
10199
|
-
{
|
|
10200
|
-
onClick: handleLogout,
|
|
10201
|
-
className: "flex w-full items-center justify-center gap-2 rounded-3xl border border-red-200 bg-red-50 px-4 py-3 text-sm font-semibold text-red-600 transition hover:bg-red-100"
|
|
10364
|
+
key: item.href,
|
|
10365
|
+
href: item.href,
|
|
10366
|
+
className: "group relative flex items-start gap-3 rounded-2xl border border-slate-200 bg-slate-50/70 p-4 transition duration-200 hover:-translate-y-0.5 hover:border-primary-200 hover:bg-white hover:shadow-md"
|
|
10202
10367
|
},
|
|
10203
|
-
/* @__PURE__ */ React21.createElement(
|
|
10204
|
-
"
|
|
10205
|
-
)
|
|
10206
|
-
))))
|
|
10368
|
+
/* @__PURE__ */ React21.createElement("span", { className: "flex h-11 w-11 items-center justify-center rounded-xl bg-white text-primary-600 shadow-sm group-hover:bg-primary-600 group-hover:text-white" }, /* @__PURE__ */ React21.createElement(item.icon, { className: "h-5 w-5" })),
|
|
10369
|
+
/* @__PURE__ */ React21.createElement("div", { className: "flex-1" }, /* @__PURE__ */ React21.createElement("p", { className: "flex items-center gap-2 text-base font-semibold text-slate-900 group-hover:text-primary-700" }, item.label, /* @__PURE__ */ React21.createElement(ArrowRight, { className: "h-4 w-4 opacity-0 transition group-hover:opacity-100" })), /* @__PURE__ */ React21.createElement("p", { className: "text-sm text-slate-500" }, item.description))
|
|
10370
|
+
))))
|
|
10371
|
+
))));
|
|
10372
|
+
}
|
|
10373
|
+
function Badge({ children, variant = "primary", size = "md", className = "" }) {
|
|
10374
|
+
const variants = {
|
|
10375
|
+
primary: "bg-primary-100 text-primary-700 border-primary-200",
|
|
10376
|
+
secondary: "bg-secondary-100 text-secondary-700 border-secondary-200",
|
|
10377
|
+
success: "bg-green-100 text-green-700 border-green-200",
|
|
10378
|
+
warning: "bg-yellow-100 text-yellow-700 border-yellow-200",
|
|
10379
|
+
danger: "bg-red-100 text-red-700 border-red-200",
|
|
10380
|
+
gray: "bg-gray-100 text-gray-700 border-gray-200"
|
|
10381
|
+
};
|
|
10382
|
+
const sizes = {
|
|
10383
|
+
sm: "px-2 py-1 text-xs",
|
|
10384
|
+
md: "px-3 py-1 text-sm"
|
|
10385
|
+
};
|
|
10386
|
+
return /* @__PURE__ */ React21.createElement("span", { className: `inline-flex items-center font-medium rounded-full border ${variants[variant]} ${sizes[size]} ${className}` }, children);
|
|
10207
10387
|
}
|
|
10208
10388
|
function OrderCard({ order }) {
|
|
10209
10389
|
const config = order.orderStatus;
|
|
@@ -10221,7 +10401,7 @@ function OrderCard({ order }) {
|
|
|
10221
10401
|
const itemPrice = item.productVariantData?.finalPrice || 0;
|
|
10222
10402
|
const itemTotal = itemPrice * item.quantity;
|
|
10223
10403
|
return /* @__PURE__ */ React21.createElement("div", { key: item.productVariantId || item._id, className: "flex items-center gap-2 text-sm" }, /* @__PURE__ */ React21.createElement("div", { className: "relative w-12 h-12 rounded bg-gray-100 flex-shrink-0 overflow-hidden" }, /* @__PURE__ */ React21.createElement(
|
|
10224
|
-
|
|
10404
|
+
Image4,
|
|
10225
10405
|
{
|
|
10226
10406
|
src: item?.productVariantData?.productMedia?.[0]?.file || "/placeholder-product.jpg",
|
|
10227
10407
|
alt: item?.productVariantData?.name || "Product image",
|
|
@@ -10561,7 +10741,7 @@ function CurrentOrdersScreen() {
|
|
|
10561
10741
|
},
|
|
10562
10742
|
/* @__PURE__ */ React21.createElement("p", { className: "text-sm font-semibold uppercase tracking-[0.35em] text-white/70" }, "Quick actions"),
|
|
10563
10743
|
/* @__PURE__ */ React21.createElement("div", { className: "mt-4 space-y-3 text-sm text-white/80" }, /* @__PURE__ */ React21.createElement(
|
|
10564
|
-
|
|
10744
|
+
Link7,
|
|
10565
10745
|
{
|
|
10566
10746
|
href: buildPath("/orders"),
|
|
10567
10747
|
className: "flex items-center justify-between rounded-2xl bg-white/10 px-4 py-3 transition hover:bg-white/20"
|
|
@@ -10640,6 +10820,9 @@ function AddressesScreen() {
|
|
|
10640
10820
|
} = useAddresses();
|
|
10641
10821
|
const [isModalOpen, setIsModalOpen] = useState(false);
|
|
10642
10822
|
const [editingAddress, setEditingAddress] = useState(null);
|
|
10823
|
+
const [banner, setBanner] = useState(
|
|
10824
|
+
null
|
|
10825
|
+
);
|
|
10643
10826
|
const {
|
|
10644
10827
|
register,
|
|
10645
10828
|
handleSubmit,
|
|
@@ -10694,10 +10877,10 @@ function AddressesScreen() {
|
|
|
10694
10877
|
if (editingAddress) {
|
|
10695
10878
|
const response = await updateAddress(editingAddress.id, payload);
|
|
10696
10879
|
if (response) {
|
|
10697
|
-
|
|
10880
|
+
setBanner({ type: "success", message: "Address updated successfully" });
|
|
10698
10881
|
closeModal();
|
|
10699
10882
|
} else {
|
|
10700
|
-
|
|
10883
|
+
setBanner({ type: "error", message: "Unable to update address" });
|
|
10701
10884
|
}
|
|
10702
10885
|
} else {
|
|
10703
10886
|
const response = await addAddress({
|
|
@@ -10712,10 +10895,10 @@ function AddressesScreen() {
|
|
|
10712
10895
|
addressType: values.addressType
|
|
10713
10896
|
});
|
|
10714
10897
|
if (response) {
|
|
10715
|
-
|
|
10898
|
+
setBanner({ type: "success", message: "Address added successfully" });
|
|
10716
10899
|
closeModal();
|
|
10717
10900
|
} else {
|
|
10718
|
-
|
|
10901
|
+
setBanner({ type: "error", message: "Failed to add address" });
|
|
10719
10902
|
}
|
|
10720
10903
|
}
|
|
10721
10904
|
};
|
|
@@ -10727,20 +10910,22 @@ You can add it back at any time.`
|
|
|
10727
10910
|
if (!confirmDelete) return;
|
|
10728
10911
|
try {
|
|
10729
10912
|
await removeAddress(address.id);
|
|
10730
|
-
|
|
10913
|
+
setBanner({ type: "success", message: "Address removed successfully" });
|
|
10731
10914
|
} catch (error2) {
|
|
10732
|
-
|
|
10733
|
-
|
|
10915
|
+
setBanner({
|
|
10916
|
+
type: "error",
|
|
10917
|
+
message: error2 instanceof Error ? error2.message : "Failed to remove address. Please try again."
|
|
10734
10918
|
});
|
|
10735
10919
|
}
|
|
10736
10920
|
};
|
|
10737
10921
|
const handleSetDefault = async (address) => {
|
|
10738
10922
|
try {
|
|
10739
10923
|
await markAsDefault(address.id);
|
|
10740
|
-
|
|
10924
|
+
setBanner({ type: "success", message: `${address.name} is now your default address` });
|
|
10741
10925
|
} catch (error2) {
|
|
10742
|
-
|
|
10743
|
-
|
|
10926
|
+
setBanner({
|
|
10927
|
+
type: "error",
|
|
10928
|
+
message: error2 instanceof Error ? error2.message : "Failed to set default address. Try again."
|
|
10744
10929
|
});
|
|
10745
10930
|
}
|
|
10746
10931
|
};
|
|
@@ -10768,27 +10953,32 @@ You can add it back at any time.`
|
|
|
10768
10953
|
}
|
|
10769
10954
|
];
|
|
10770
10955
|
}, [addresses]);
|
|
10771
|
-
return /* @__PURE__ */ React21.createElement("div", { className: "min-h-screen bg-slate-50" }, /* @__PURE__ */ React21.createElement("
|
|
10772
|
-
|
|
10956
|
+
return /* @__PURE__ */ React21.createElement("div", { className: "min-h-screen bg-slate-50 text-slate-900" }, /* @__PURE__ */ React21.createElement("div", { className: "container mx-auto px-4 pb-16 pt-10" }, /* @__PURE__ */ React21.createElement("div", { className: "rounded-3xl border border-slate-200 bg-white/95 p-6 shadow-xl shadow-primary-50" }, /* @__PURE__ */ React21.createElement("div", { className: "flex flex-col gap-4 md:flex-row md:items-center md:justify-between" }, /* @__PURE__ */ React21.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React21.createElement("div", { className: "inline-flex items-center gap-2 rounded-full bg-slate-900 text-white px-4 py-1 text-xs font-semibold uppercase tracking-[0.32em]" }, /* @__PURE__ */ React21.createElement(MapPin, { className: "h-4 w-4" }), "Address book"), /* @__PURE__ */ React21.createElement("h1", { className: "text-3xl font-semibold md:text-4xl" }, "Manage where your care arrives"), /* @__PURE__ */ React21.createElement("p", { className: "max-w-2xl text-sm text-slate-600" }, "Save home, office, or loved ones' addresses and choose a default for faster checkout and delivery."), /* @__PURE__ */ React21.createElement("div", { className: "flex flex-wrap gap-3 text-xs text-slate-500" }, /* @__PURE__ */ React21.createElement("span", { className: "inline-flex items-center gap-2 rounded-full border border-slate-200 bg-slate-50 px-3 py-2" }, /* @__PURE__ */ React21.createElement(Sparkles, { className: "h-4 w-4 text-primary-600" }), "Default: ", defaultAddress ? defaultAddress.name : "Not set"))), /* @__PURE__ */ React21.createElement("div", { className: "flex items-center gap-3" }, banner && /* @__PURE__ */ React21.createElement(
|
|
10957
|
+
"div",
|
|
10773
10958
|
{
|
|
10774
|
-
|
|
10775
|
-
animate: { opacity: 1, y: 0 },
|
|
10776
|
-
className: "space-y-5"
|
|
10959
|
+
className: `flex items-start gap-2 rounded-2xl border px-3 py-2 text-xs ${banner.type === "success" ? "border-green-200 bg-green-50 text-green-700" : "border-red-200 bg-red-50 text-red-700"}`
|
|
10777
10960
|
},
|
|
10778
|
-
/* @__PURE__ */ React21.createElement("span", { className: "
|
|
10779
|
-
/* @__PURE__ */ React21.createElement("
|
|
10780
|
-
/* @__PURE__ */ React21.createElement("p", { className: "max-w-2xl text-white/80 md:text-lg" }, "Add home, office, or loved ones' addresses and toggle a default for lightning-fast checkout and delivery."),
|
|
10781
|
-
/* @__PURE__ */ React21.createElement("div", { className: "flex flex-wrap items-center gap-3 text-sm text-white/75" }, /* @__PURE__ */ React21.createElement("span", { className: "inline-flex items-center gap-2 rounded-full bg-white/10 px-3 py-1" }, /* @__PURE__ */ React21.createElement(Sparkles, { className: "h-4 w-4 text-white" }), "Default address: ", defaultAddress ? defaultAddress.name : "Not set"), /* @__PURE__ */ React21.createElement(Button, { variant: "ghost", className: "text-white hover:bg-white/10", onClick: openCreateModal }, /* @__PURE__ */ React21.createElement(Plus, { className: "h-5 w-5" }), "Add address"))
|
|
10961
|
+
/* @__PURE__ */ React21.createElement("span", { className: "mt-[1px] text-base" }, banner.type === "success" ? "\u2714" : "!"),
|
|
10962
|
+
/* @__PURE__ */ React21.createElement("span", null, banner.message)
|
|
10782
10963
|
), /* @__PURE__ */ React21.createElement(
|
|
10783
|
-
|
|
10964
|
+
Button,
|
|
10784
10965
|
{
|
|
10785
|
-
|
|
10786
|
-
|
|
10787
|
-
|
|
10788
|
-
|
|
10966
|
+
variant: "outline",
|
|
10967
|
+
size: "md",
|
|
10968
|
+
className: "border-slate-300 text-slate-800 hover:bg-white",
|
|
10969
|
+
onClick: openCreateModal
|
|
10789
10970
|
},
|
|
10790
|
-
|
|
10791
|
-
|
|
10971
|
+
/* @__PURE__ */ React21.createElement(Plus, { className: "h-5 w-5" }),
|
|
10972
|
+
"Add address"
|
|
10973
|
+
))), /* @__PURE__ */ React21.createElement("div", { className: "mt-6 grid gap-4 sm:grid-cols-3" }, stats.map((stat) => /* @__PURE__ */ React21.createElement(
|
|
10974
|
+
"div",
|
|
10975
|
+
{
|
|
10976
|
+
key: stat.id,
|
|
10977
|
+
className: "rounded-2xl border border-slate-200 bg-slate-50/70 px-4 py-3 text-sm text-slate-600"
|
|
10978
|
+
},
|
|
10979
|
+
/* @__PURE__ */ React21.createElement("p", { className: "text-xs font-semibold uppercase tracking-[0.28em] text-slate-500" }, stat.label),
|
|
10980
|
+
/* @__PURE__ */ React21.createElement("div", { className: "mt-1 flex items-center justify-between" }, /* @__PURE__ */ React21.createElement("p", { className: "text-slate-800" }, stat.helper), /* @__PURE__ */ React21.createElement("span", { className: "text-xl font-semibold text-slate-900" }, stat.value))
|
|
10981
|
+
)))), /* @__PURE__ */ React21.createElement("div", { className: "mt-10" }, isLoading ? /* @__PURE__ */ React21.createElement("div", { className: "grid gap-4 sm:grid-cols-2 xl:grid-cols-3" }, Array.from({ length: 3 }).map((_, index) => /* @__PURE__ */ React21.createElement(
|
|
10792
10982
|
"div",
|
|
10793
10983
|
{
|
|
10794
10984
|
key: index,
|
|
@@ -10811,7 +11001,7 @@ You can add it back at any time.`
|
|
|
10811
11001
|
key: address.id,
|
|
10812
11002
|
initial: { opacity: 0, y: 24 },
|
|
10813
11003
|
animate: { opacity: 1, y: 0 },
|
|
10814
|
-
className: "group relative flex h-full flex-col rounded-3xl border border-slate-
|
|
11004
|
+
className: "group relative flex h-full flex-col rounded-3xl border border-slate-200 bg-white p-6 shadow-sm transition hover:-translate-y-1 hover:border-primary-200 hover:shadow-lg"
|
|
10815
11005
|
},
|
|
10816
11006
|
address.isDefault && /* @__PURE__ */ React21.createElement("span", { className: "absolute right-6 top-6 inline-flex items-center gap-2 rounded-full bg-amber-100 px-3 py-1 text-xs font-semibold text-amber-700" }, /* @__PURE__ */ React21.createElement(Crown, { className: "h-4 w-4" }), "Default"),
|
|
10817
11007
|
/* @__PURE__ */ React21.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ React21.createElement("span", { className: "rounded-full bg-primary-50 p-3 text-primary-600" }, /* @__PURE__ */ React21.createElement(User, { className: "h-5 w-5" })), /* @__PURE__ */ React21.createElement("div", null, /* @__PURE__ */ React21.createElement("p", { className: "text-base font-semibold text-slate-900" }, address.name), /* @__PURE__ */ React21.createElement("p", { className: "text-xs uppercase tracking-[0.3em] text-slate-400" }, typeCopy.label))),
|
|
@@ -11001,6 +11191,7 @@ function WishlistScreen() {
|
|
|
11001
11191
|
clearWishlist,
|
|
11002
11192
|
refreshWishlist
|
|
11003
11193
|
} = useWishlist();
|
|
11194
|
+
const notification = useNotification();
|
|
11004
11195
|
const wishlistCount = getWishlistCount?.() ?? 0;
|
|
11005
11196
|
const { products: wishlistProducts, isLoading, error } = useWishlistProducts(
|
|
11006
11197
|
wishlistItems
|
|
@@ -11010,9 +11201,12 @@ function WishlistScreen() {
|
|
|
11010
11201
|
const [sortOption, setSortOption] = useState("featured");
|
|
11011
11202
|
useEffect(() => {
|
|
11012
11203
|
if (error) {
|
|
11013
|
-
|
|
11204
|
+
notification.error(
|
|
11205
|
+
"Could not load wishlist",
|
|
11206
|
+
"We had trouble loading your saved products. Please refresh the page or try again shortly."
|
|
11207
|
+
);
|
|
11014
11208
|
}
|
|
11015
|
-
}, [error]);
|
|
11209
|
+
}, [error, notification]);
|
|
11016
11210
|
const handleRemoveFromWishlist = async (productId) => {
|
|
11017
11211
|
try {
|
|
11018
11212
|
await removeFromWishlist(productId);
|
|
@@ -11080,22 +11274,22 @@ function WishlistScreen() {
|
|
|
11080
11274
|
animate: { opacity: 1, y: 0 },
|
|
11081
11275
|
className: "space-y-6"
|
|
11082
11276
|
},
|
|
11083
|
-
!isAuthenticated && /* @__PURE__ */ React21.createElement("div", { className: "flex min-h-[40vh] items-center justify-center" }, /* @__PURE__ */ React21.createElement("div", { className: "max-w-lg text-center space-y-6" }, /* @__PURE__ */ React21.createElement("div", { className: "flex justify-center" }, /* @__PURE__ */ React21.createElement("div", { className: "rounded-full bg-gray-100 p-6" }, /* @__PURE__ */ React21.createElement(Heart, { className: "h-12 w-12 text-
|
|
11277
|
+
!isAuthenticated && /* @__PURE__ */ React21.createElement("div", { className: "flex min-h-[40vh] items-center justify-center" }, /* @__PURE__ */ React21.createElement("div", { className: "max-w-lg text-center space-y-6" }, /* @__PURE__ */ React21.createElement("div", { className: "flex justify-center" }, /* @__PURE__ */ React21.createElement("div", { className: "rounded-full bg-gray-100 p-6" }, /* @__PURE__ */ React21.createElement(Heart, { className: "h-12 w-12 text-secondary" }))), /* @__PURE__ */ React21.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React21.createElement("h2", { className: "text-2xl font-bold text-secondary" }, "Sign in to see your favourites"), /* @__PURE__ */ React21.createElement("p", { className: "text-muted" }, "Create your curated shelf of products and we'll keep them ready whenever you return.")), /* @__PURE__ */ React21.createElement(
|
|
11084
11278
|
"button",
|
|
11085
11279
|
{
|
|
11086
11280
|
type: "button",
|
|
11087
11281
|
onClick: () => router.push(buildPath("/login")),
|
|
11088
|
-
className: "rounded-
|
|
11282
|
+
className: "rounded-xl border-2 border-primary bg-primary text-white px-6 py-3 text-sm font-medium transition-colors hover:opacity-80"
|
|
11089
11283
|
},
|
|
11090
11284
|
"Sign In"
|
|
11091
11285
|
))),
|
|
11092
|
-
isAuthenticated && /* @__PURE__ */ React21.createElement(React21.Fragment, null, /* @__PURE__ */ React21.createElement("div", { className: "mb-6" }, /* @__PURE__ */ React21.createElement("h1", { className: "text-2xl font-bold text-
|
|
11286
|
+
isAuthenticated && /* @__PURE__ */ React21.createElement(React21.Fragment, null, /* @__PURE__ */ React21.createElement("div", { className: "mb-6" }, /* @__PURE__ */ React21.createElement("h1", { className: "text-2xl font-bold text-secondary" }, "Wishlist"), /* @__PURE__ */ React21.createElement("p", { className: "text-sm text-muted mt-1" }, wishlistCount, " ", wishlistCount === 1 ? "item" : "items", " saved", wishlistCount > 0 && ` \u2022 Total value: ${formatPrice(totalValue)}`)), /* @__PURE__ */ React21.createElement("div", { className: "flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between mb-6" }, /* @__PURE__ */ React21.createElement("div", { className: "space-y-1" }, onlyInStock && /* @__PURE__ */ React21.createElement("p", { className: "text-sm text-muted" }, "Showing items ready to ship")), /* @__PURE__ */ React21.createElement("div", { className: "flex flex-wrap items-center gap-3" }, /* @__PURE__ */ React21.createElement("label", { className: "inline-flex cursor-pointer items-center gap-2 rounded-full border border-slate-200 bg-slate-50 px-3 py-1.5 text-sm font-medium text-slate-600 transition hover:border-primary hover:text-secondary" }, /* @__PURE__ */ React21.createElement(
|
|
11093
11287
|
"input",
|
|
11094
11288
|
{
|
|
11095
11289
|
type: "checkbox",
|
|
11096
11290
|
checked: onlyInStock,
|
|
11097
11291
|
onChange: (event) => setOnlyInStock(event.target.checked),
|
|
11098
|
-
className: "h-4 w-4 rounded border-slate-300 text-
|
|
11292
|
+
className: "h-4 w-4 rounded border-slate-300 text-secondary focus:ring-secondary"
|
|
11099
11293
|
}
|
|
11100
11294
|
), "Only show in-stock"), /* @__PURE__ */ React21.createElement("div", { className: "flex items-center gap-2 rounded-full border border-slate-200 bg-slate-50 px-3 py-1.5 text-sm text-slate-600" }, /* @__PURE__ */ React21.createElement("span", null, "Sort"), /* @__PURE__ */ React21.createElement(
|
|
11101
11295
|
"select",
|
|
@@ -11105,24 +11299,22 @@ function WishlistScreen() {
|
|
|
11105
11299
|
className: "bg-transparent text-sm font-medium text-slate-700 outline-none"
|
|
11106
11300
|
},
|
|
11107
11301
|
SORT_OPTIONS.map((option) => /* @__PURE__ */ React21.createElement("option", { key: option.value, value: option.value }, option.label))
|
|
11108
|
-
)), /* @__PURE__ */ React21.createElement("div", { className: "flex overflow-hidden rounded-full border border-slate-200 bg-
|
|
11302
|
+
)), /* @__PURE__ */ React21.createElement("div", { className: "flex overflow-hidden rounded-full border border-slate-200 bg-gray-100 p-1" }, /* @__PURE__ */ React21.createElement(
|
|
11109
11303
|
"button",
|
|
11110
11304
|
{
|
|
11111
11305
|
type: "button",
|
|
11112
11306
|
onClick: () => setViewMode("grid"),
|
|
11113
|
-
className: `flex items-center gap-1 px-3 py-1.5 text-sm font-medium transition ${viewMode === "grid" ? "bg-
|
|
11307
|
+
className: `flex items-center gap-1 px-3 py-1.5 text-sm font-medium transition rounded-full ${viewMode === "grid" ? "bg-white text-primary shadow-md" : "text-slate-600 hover:bg-white"}`
|
|
11114
11308
|
},
|
|
11115
|
-
/* @__PURE__ */ React21.createElement(Grid, { className: "h-4 w-4" })
|
|
11116
|
-
"Grid"
|
|
11309
|
+
/* @__PURE__ */ React21.createElement(Grid, { className: "h-4 w-4" })
|
|
11117
11310
|
), /* @__PURE__ */ React21.createElement(
|
|
11118
11311
|
"button",
|
|
11119
11312
|
{
|
|
11120
11313
|
type: "button",
|
|
11121
11314
|
onClick: () => setViewMode("list"),
|
|
11122
|
-
className: `flex items-center gap-1 px-3 py-1.5 text-sm font-medium transition ${viewMode === "list" ? "bg-
|
|
11315
|
+
className: `flex items-center gap-1 px-3 py-1.5 text-sm font-medium transition rounded-full ${viewMode === "list" ? "bg-white text-primary shadow-md" : "text-slate-600 hover:bg-white"}`
|
|
11123
11316
|
},
|
|
11124
|
-
/* @__PURE__ */ React21.createElement(List, { className: "h-4 w-4" })
|
|
11125
|
-
"List"
|
|
11317
|
+
/* @__PURE__ */ React21.createElement(List, { className: "h-4 w-4" })
|
|
11126
11318
|
)), wishlistCount > 0 && /* @__PURE__ */ React21.createElement(
|
|
11127
11319
|
Button,
|
|
11128
11320
|
{
|
|
@@ -11138,12 +11330,12 @@ function WishlistScreen() {
|
|
|
11138
11330
|
key: index,
|
|
11139
11331
|
className: "h-72 animate-pulse rounded-2xl border border-slate-200 bg-slate-100"
|
|
11140
11332
|
}
|
|
11141
|
-
))), !isLoading && wishlistCount === 0 && /* @__PURE__ */ React21.createElement("div", { className: "flex min-h-[30vh] items-center justify-center" }, /* @__PURE__ */ React21.createElement("div", { className: "text-center space-y-6 max-w-md" }, /* @__PURE__ */ React21.createElement("div", { className: "flex justify-center" }, /* @__PURE__ */ React21.createElement("div", { className: "rounded-full bg-gray-100 p-6" }, /* @__PURE__ */ React21.createElement(Heart, { className: "h-12 w-12 text-
|
|
11333
|
+
))), !isLoading && wishlistCount === 0 && /* @__PURE__ */ React21.createElement("div", { className: "flex min-h-[30vh] items-center justify-center" }, /* @__PURE__ */ React21.createElement("div", { className: "text-center space-y-6 max-w-md" }, /* @__PURE__ */ React21.createElement("div", { className: "flex justify-center" }, /* @__PURE__ */ React21.createElement("div", { className: "rounded-full bg-gray-100 p-6" }, /* @__PURE__ */ React21.createElement(Heart, { className: "h-12 w-12 text-secondary" }))), /* @__PURE__ */ React21.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React21.createElement("h2", { className: "text-2xl font-bold text-secondary" }, "Your wishlist is empty"), /* @__PURE__ */ React21.createElement("p", { className: "text-muted" }, "Start adding products to your wishlist to see them here.")), /* @__PURE__ */ React21.createElement("div", { className: "flex flex-wrap justify-center gap-3" }, /* @__PURE__ */ React21.createElement(
|
|
11142
11334
|
"button",
|
|
11143
11335
|
{
|
|
11144
11336
|
type: "button",
|
|
11145
11337
|
onClick: () => router.push(buildPath("/shop")),
|
|
11146
|
-
className: "rounded-
|
|
11338
|
+
className: "rounded-xl border-2 border-primary bg-primary text-white px-6 py-3 text-sm font-medium transition-colors flex items-center justify-center gap-2 hover:opacity-80"
|
|
11147
11339
|
},
|
|
11148
11340
|
"Discover products"
|
|
11149
11341
|
)))), !isLoading && processedProducts.length > 0 && /* @__PURE__ */ React21.createElement(React21.Fragment, null, viewMode === "grid" ? /* @__PURE__ */ React21.createElement(
|
|
@@ -11184,7 +11376,7 @@ function WishlistScreen() {
|
|
|
11184
11376
|
className: "flex flex-col gap-4 rounded-2xl border border-slate-100 bg-slate-50 p-4 shadow-sm shadow-primary-50 sm:flex-row sm:items-center"
|
|
11185
11377
|
},
|
|
11186
11378
|
/* @__PURE__ */ React21.createElement("div", { className: "relative h-28 w-full overflow-hidden rounded-2xl bg-white sm:w-40" }, /* @__PURE__ */ React21.createElement(
|
|
11187
|
-
|
|
11379
|
+
Image4,
|
|
11188
11380
|
{
|
|
11189
11381
|
fill: true,
|
|
11190
11382
|
src: product.productMedia?.[0]?.file || "/placeholder-product.jpg",
|
|
@@ -11192,7 +11384,7 @@ function WishlistScreen() {
|
|
|
11192
11384
|
className: "h-full w-full object-cover"
|
|
11193
11385
|
}
|
|
11194
11386
|
)),
|
|
11195
|
-
/* @__PURE__ */ React21.createElement("div", { className: "flex flex-1 flex-col gap-2" }, /* @__PURE__ */ React21.createElement("div", { className: "flex flex-wrap items-center justify-between gap-3" }, /* @__PURE__ */ React21.createElement("div", null, /* @__PURE__ */ React21.createElement("h3", { className: "text-lg font-semibold text-
|
|
11387
|
+
/* @__PURE__ */ React21.createElement("div", { className: "flex flex-1 flex-col gap-2" }, /* @__PURE__ */ React21.createElement("div", { className: "flex flex-wrap items-center justify-between gap-3" }, /* @__PURE__ */ React21.createElement("div", null, /* @__PURE__ */ React21.createElement("h3", { className: "text-lg font-semibold text-secondary" }, product.name), /* @__PURE__ */ React21.createElement("p", { className: "text-sm text-muted" }, product.parentCategories?.map((category) => category?.name).join(", ") || "General wellness")), /* @__PURE__ */ React21.createElement("div", { className: "text-right" }, /* @__PURE__ */ React21.createElement("p", { className: "text-lg font-bold text-primary" }, formatPrice(product.finalPrice ?? 0)), product.isDiscounted && /* @__PURE__ */ React21.createElement("p", { className: "text-xs text-emerald-500" }, "You save ", formatPrice(Math.max((product.priceBeforeDiscount ?? 0) - (product.finalPrice ?? 0), 0))))), /* @__PURE__ */ React21.createElement("div", { className: "flex flex-wrap items-center gap-3 text-xs text-slate-500" }, /* @__PURE__ */ React21.createElement("span", { className: `inline-flex items-center gap-1 rounded-full px-2.5 py-1 font-medium ${product.inventoryCount > 0 ? "bg-emerald-100 text-emerald-700" : "bg-rose-100 text-rose-700"}` }, /* @__PURE__ */ React21.createElement(Package, { className: "h-3.5 w-3.5" }), product.inventoryCount > 0 ? "In stock" : "Backordered"), product.totalSold > 0 && /* @__PURE__ */ React21.createElement("span", { className: "inline-flex items-center gap-1 rounded-full bg-slate-200 px-2.5 py-1 font-medium text-slate-700" }, /* @__PURE__ */ React21.createElement(Sparkles, { className: "h-3.5 w-3.5" }), product.totalSold, "+ purchased")), /* @__PURE__ */ React21.createElement("div", { className: "flex flex-wrap gap-2" }, /* @__PURE__ */ React21.createElement(
|
|
11196
11388
|
Button,
|
|
11197
11389
|
{
|
|
11198
11390
|
size: "sm",
|
|
@@ -11205,15 +11397,15 @@ function WishlistScreen() {
|
|
|
11205
11397
|
size: "sm",
|
|
11206
11398
|
variant: "outline",
|
|
11207
11399
|
onClick: () => handleRemoveFromWishlist(product.id),
|
|
11208
|
-
className: "text-
|
|
11400
|
+
className: "text-secondary"
|
|
11209
11401
|
},
|
|
11210
11402
|
"Remove"
|
|
11211
11403
|
)))
|
|
11212
|
-
))))), isAuthenticated && emptyAfterFiltering && /* @__PURE__ */ React21.createElement("div", { className: "flex flex-col items-center justify-center rounded-lg border border-dashed border-gray-200 bg-gray-50 p-12 text-center" }, /* @__PURE__ */ React21.createElement("div", { className: "flex h-16 w-16 items-center justify-center rounded-full bg-gray-200 text-gray-500" }, /* @__PURE__ */ React21.createElement(Package, { className: "h-8 w-8" })), /* @__PURE__ */ React21.createElement("h3", { className: "mt-6 text-xl font-semibold text-
|
|
11404
|
+
))))), isAuthenticated && emptyAfterFiltering && /* @__PURE__ */ React21.createElement("div", { className: "flex flex-col items-center justify-center rounded-lg border border-dashed border-gray-200 bg-gray-50 p-12 text-center" }, /* @__PURE__ */ React21.createElement("div", { className: "flex h-16 w-16 items-center justify-center rounded-full bg-gray-200 text-gray-500" }, /* @__PURE__ */ React21.createElement(Package, { className: "h-8 w-8" })), /* @__PURE__ */ React21.createElement("h3", { className: "mt-6 text-xl font-semibold text-secondary" }, "Nothing matches those filters"), /* @__PURE__ */ React21.createElement("p", { className: "mt-2 max-w-md text-sm text-muted" }, "Try showing out-of-stock items or adjust your sort order to revisit everything you've saved."), /* @__PURE__ */ React21.createElement(
|
|
11213
11405
|
"button",
|
|
11214
11406
|
{
|
|
11215
11407
|
type: "button",
|
|
11216
|
-
className: "mt-6 rounded-
|
|
11408
|
+
className: "mt-6 rounded-xl border-2 border-primary bg-white px-6 py-3 text-sm font-medium text-secondary hover:opacity-80 transition-colors",
|
|
11217
11409
|
onClick: () => setOnlyInStock(false)
|
|
11218
11410
|
},
|
|
11219
11411
|
"Show all saved products"
|
|
@@ -11321,67 +11513,17 @@ function SearchPage() {
|
|
|
11321
11513
|
))), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("h1", { className: "text-2xl font-bold text-gray-900 mb-6" }, searchQuery ? `Search results for "${searchQuery}"` : "Search Products"), isLoading ? /* @__PURE__ */ React.createElement("div", { className: "grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6" }, [...Array(8)].map((_, i) => /* @__PURE__ */ React.createElement("div", { key: i, className: "space-y-3" }, /* @__PURE__ */ React.createElement(Skeleton, { className: "h-48 w-full rounded-lg" }), /* @__PURE__ */ React.createElement(Skeleton, { className: "h-4 w-3/4" }), /* @__PURE__ */ React.createElement(Skeleton, { className: "h-4 w-1/2" })))) : products.length > 0 ? /* @__PURE__ */ React.createElement("div", { className: "grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6" }, products.map((product) => /* @__PURE__ */ React.createElement(
|
|
11322
11514
|
ProductCard,
|
|
11323
11515
|
{
|
|
11516
|
+
key: product.id,
|
|
11324
11517
|
product,
|
|
11325
11518
|
isFavorited: isInWishlist(product.id),
|
|
11326
11519
|
onClickProduct: (p) => router.push(buildPath(`/products/${p.id}`))
|
|
11327
11520
|
}
|
|
11328
|
-
))) : hasSearched ? /* @__PURE__ */ React.createElement("div", { className: "text-center py-12" }, /* @__PURE__ */ React.createElement("div", { className: "text-gray-500 text-lg mb-4" }, 'No products found for "', searchQuery, '"'), /* @__PURE__ */ React.createElement("p", { className: "text-gray-500 mb-6" }, "Try different keywords or check out our", " ", /* @__PURE__ */ React.createElement(
|
|
11329
|
-
}
|
|
11330
|
-
function CategoriesScreen() {
|
|
11331
|
-
const { categories, isLoading } = useCategories();
|
|
11332
|
-
const router = useRouter();
|
|
11333
|
-
const { buildPath } = useBasePath();
|
|
11334
|
-
return /* @__PURE__ */ React21.createElement("div", { className: "min-h-screen bg-slate-50" }, /* @__PURE__ */ React21.createElement("section", { className: "relative overflow-hidden bg-gradient-to-br from-[rgb(var(--header-from))] via-[rgb(var(--header-via))] to-[rgb(var(--header-to))] text-white mb-8" }, /* @__PURE__ */ React21.createElement("div", { className: "absolute inset-0 bg-[radial-gradient(circle_at_top_left,_rgba(255,255,255,0.35),_transparent_60%)]" }), /* @__PURE__ */ React21.createElement("div", { className: "relative container mx-auto px-4 py-16" }, /* @__PURE__ */ React21.createElement(
|
|
11335
|
-
motion.div,
|
|
11336
|
-
{
|
|
11337
|
-
initial: { opacity: 0, y: 24 },
|
|
11338
|
-
animate: { opacity: 1, y: 0 },
|
|
11339
|
-
className: "space-y-6"
|
|
11340
|
-
},
|
|
11341
|
-
/* @__PURE__ */ React21.createElement("span", { className: "inline-flex items-center gap-2 rounded-full bg-white/15 px-3 py-1 text-sm font-semibold uppercase tracking-[0.35em] text-white/70 backdrop-blur" }, /* @__PURE__ */ React21.createElement(Package, { className: "h-4 w-4" }), "Product Categories"),
|
|
11342
|
-
/* @__PURE__ */ React21.createElement("div", { className: "flex flex-col gap-4 md:flex-row md:items-center md:justify-between" }, /* @__PURE__ */ React21.createElement("div", { className: "space-y-4" }, /* @__PURE__ */ React21.createElement("h1", { className: "text-4xl font-bold md:text-5xl" }, "Browse Our Product Range"), /* @__PURE__ */ React21.createElement("p", { className: "max-w-2xl text-white/80 md:text-lg" }, "Explore our comprehensive selection of healthcare products, carefully curated by our pharmacists to meet all your wellness needs.")), /* @__PURE__ */ React21.createElement("div", { className: "rounded-3xl bg-white/15 p-6 backdrop-blur" }, /* @__PURE__ */ React21.createElement("p", { className: "text-sm font-semibold uppercase tracking-[0.35em] text-white/70" }, "Quick tip"), /* @__PURE__ */ React21.createElement("p", { className: "mt-3 text-sm text-white/80" }, "Use the categories below to quickly find the products you're looking for, or use the search function for specific items.")))
|
|
11343
|
-
))), /* @__PURE__ */ React21.createElement("div", { className: "relative -mt-16 pb-16" }, /* @__PURE__ */ React21.createElement("div", { className: "container mx-auto px-4" }, /* @__PURE__ */ React21.createElement(
|
|
11344
|
-
motion.div,
|
|
11345
|
-
{
|
|
11346
|
-
initial: { opacity: 0, y: 24 },
|
|
11347
|
-
animate: { opacity: 1, y: 0 },
|
|
11348
|
-
className: "rounded-3xl border border-slate-100 bg-white p-6 shadow-lg shadow-primary-50"
|
|
11349
|
-
},
|
|
11350
|
-
/* @__PURE__ */ React21.createElement("div", { className: "flex items-center gap-3 text-sm text-slate-500 mb-6" }, /* @__PURE__ */ React21.createElement(Sparkles, { className: "h-4 w-4 text-primary-500" }), /* @__PURE__ */ React21.createElement("span", null, "Browse our complete product catalog organized by categories.")),
|
|
11351
|
-
isLoading ? /* @__PURE__ */ React21.createElement("div", { className: "grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6" }, [...Array(8)].map((_, i) => /* @__PURE__ */ React21.createElement("div", { key: i, className: "animate-pulse" }, /* @__PURE__ */ React21.createElement("div", { className: "bg-gray-200 rounded-lg aspect-square mb-2" }), /* @__PURE__ */ React21.createElement("div", { className: "h-4 bg-gray-200 rounded w-3/4 mb-1" }), /* @__PURE__ */ React21.createElement("div", { className: "h-3 bg-gray-200 rounded w-1/2" })))) : categories.length > 0 ? /* @__PURE__ */ React21.createElement("div", { className: "grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6" }, categories.map((category) => /* @__PURE__ */ React21.createElement(
|
|
11352
|
-
Link8,
|
|
11353
|
-
{
|
|
11354
|
-
key: category.id,
|
|
11355
|
-
href: buildPath(`/shop?category=${category.name}`),
|
|
11356
|
-
className: "group block overflow-hidden rounded-xl border border-gray-100 bg-white p-4 text-center transition hover:shadow-lg hover:border-primary-500"
|
|
11357
|
-
},
|
|
11358
|
-
/* @__PURE__ */ React21.createElement("div", { className: "relative aspect-square w-full overflow-hidden rounded-lg bg-gray-50 mb-3" }, category.image ? /* @__PURE__ */ React21.createElement(
|
|
11359
|
-
Image3,
|
|
11360
|
-
{
|
|
11361
|
-
src: category.image,
|
|
11362
|
-
alt: category.name || "Category Image",
|
|
11363
|
-
fill: true,
|
|
11364
|
-
className: "object-cover transition-transform group-hover:scale-105",
|
|
11365
|
-
sizes: "(max-width: 768px) 50vw, (max-width: 1200px) 33vw, 25vw"
|
|
11366
|
-
}
|
|
11367
|
-
) : /* @__PURE__ */ React21.createElement("div", { className: "flex h-full w-full items-center justify-center bg-gray-100 text-gray-400" }, /* @__PURE__ */ React21.createElement(Package, { className: "h-12 w-12" }))),
|
|
11368
|
-
/* @__PURE__ */ React21.createElement("h3", { className: "text-lg font-semibold text-gray-900 group-hover:text-primary-600 transition-colors" }, category.name),
|
|
11369
|
-
category.productCount > 0 && /* @__PURE__ */ React21.createElement("p", { className: "mt-1 text-sm text-gray-500" }, category.productCount, " ", category.productCount === 1 ? "product" : "products")
|
|
11370
|
-
))) : /* @__PURE__ */ React21.createElement(
|
|
11371
|
-
EmptyState,
|
|
11372
|
-
{
|
|
11373
|
-
title: "No categories found",
|
|
11374
|
-
description: "There are currently no product categories available.",
|
|
11375
|
-
icon: Package,
|
|
11376
|
-
actionLabel: "Shop products",
|
|
11377
|
-
onAction: () => router.push(buildPath("/shop"))
|
|
11378
|
-
}
|
|
11379
|
-
)
|
|
11380
|
-
))));
|
|
11521
|
+
))) : hasSearched ? /* @__PURE__ */ React.createElement("div", { className: "text-center py-12" }, /* @__PURE__ */ React.createElement("div", { className: "text-gray-500 text-lg mb-4" }, 'No products found for "', searchQuery, '"'), /* @__PURE__ */ React.createElement("p", { className: "text-gray-500 mb-6" }, "Try different keywords or check out our", " ", /* @__PURE__ */ React.createElement(Link7, { href: "/shop", className: "text-primary-600 hover:underline ml-1 font-medium" }, "featured products"))) : /* @__PURE__ */ React.createElement("div", { className: "text-center py-12" }, /* @__PURE__ */ React.createElement("p", { className: "text-gray-500" }, "Enter a search term to find products"))));
|
|
11381
11522
|
}
|
|
11382
11523
|
function NewAddressPage() {
|
|
11383
11524
|
const router = useRouter();
|
|
11384
11525
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
11526
|
+
const notification = useNotification();
|
|
11385
11527
|
const {
|
|
11386
11528
|
register,
|
|
11387
11529
|
handleSubmit,
|
|
@@ -11407,7 +11549,10 @@ function NewAddressPage() {
|
|
|
11407
11549
|
country: data.country,
|
|
11408
11550
|
phone: data.phone
|
|
11409
11551
|
});
|
|
11410
|
-
|
|
11552
|
+
notification.success(
|
|
11553
|
+
"Address added",
|
|
11554
|
+
"Your new address has been saved to your account."
|
|
11555
|
+
);
|
|
11411
11556
|
router.back();
|
|
11412
11557
|
} catch (error) {
|
|
11413
11558
|
let errorMessage = "An unexpected error occurred";
|
|
@@ -11422,15 +11567,17 @@ function NewAddressPage() {
|
|
|
11422
11567
|
if (error.message === "Network Error") {
|
|
11423
11568
|
errorMessage = "Unable to connect to the server. Please check your internet connection.";
|
|
11424
11569
|
}
|
|
11425
|
-
|
|
11426
|
-
|
|
11427
|
-
|
|
11428
|
-
|
|
11570
|
+
notification.error(
|
|
11571
|
+
"Unable to save address",
|
|
11572
|
+
errorMessage,
|
|
11573
|
+
5e3
|
|
11574
|
+
);
|
|
11429
11575
|
if (error.response?.status === 422) {
|
|
11430
|
-
|
|
11431
|
-
|
|
11432
|
-
|
|
11433
|
-
|
|
11576
|
+
notification.info(
|
|
11577
|
+
"Address validation failed",
|
|
11578
|
+
"Make sure your address is complete and formatted correctly.",
|
|
11579
|
+
6e3
|
|
11580
|
+
);
|
|
11434
11581
|
}
|
|
11435
11582
|
} finally {
|
|
11436
11583
|
setIsSubmitting(false);
|
|
@@ -11519,31 +11666,42 @@ function NewAddressPage() {
|
|
|
11519
11666
|
}
|
|
11520
11667
|
function Header() {
|
|
11521
11668
|
const { config } = useTheme();
|
|
11522
|
-
const { user, isAuthenticated } = useAuth();
|
|
11669
|
+
const { user, isAuthenticated, logout } = useAuth();
|
|
11523
11670
|
const { cart } = useCart() || { cart: { } };
|
|
11524
11671
|
const { getWishlistCount } = useWishlist();
|
|
11525
11672
|
const wishlistCount = getWishlistCount?.() || 0;
|
|
11526
11673
|
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
|
|
11527
11674
|
const [isSearchOpen, setIsSearchOpen] = useState(false);
|
|
11675
|
+
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
|
|
11676
|
+
const [isLoggingOut, setIsLoggingOut] = useState(false);
|
|
11528
11677
|
const [searchQuery, setSearchQuery] = useState("");
|
|
11529
11678
|
const { buildPath } = useBasePath();
|
|
11679
|
+
const router = useRouter();
|
|
11680
|
+
const handleLogout = async () => {
|
|
11681
|
+
setIsLoggingOut(true);
|
|
11682
|
+
try {
|
|
11683
|
+
await logout();
|
|
11684
|
+
router.push(buildPath("/"));
|
|
11685
|
+
} catch (error) {
|
|
11686
|
+
console.error("Logout failed:", error);
|
|
11687
|
+
} finally {
|
|
11688
|
+
setIsLoggingOut(false);
|
|
11689
|
+
setIsDropdownOpen(false);
|
|
11690
|
+
}
|
|
11691
|
+
};
|
|
11530
11692
|
const navLinks = [
|
|
11531
|
-
{ href: buildPath("/shop"), label: "Shop" }
|
|
11532
|
-
{ href: buildPath("/categories"), label: "Categories" },
|
|
11533
|
-
{ href: buildPath("/orders"), label: "Orders" },
|
|
11534
|
-
{ href: buildPath("/about"), label: "About" },
|
|
11535
|
-
{ href: buildPath("/contact"), label: "Contact" }
|
|
11693
|
+
{ href: buildPath("/shop"), label: "Shop" }
|
|
11536
11694
|
];
|
|
11537
|
-
return /* @__PURE__ */ React21.createElement("header", { className: "sticky top-0 z-
|
|
11538
|
-
|
|
11695
|
+
return /* @__PURE__ */ React21.createElement("header", { className: "sticky top-0 z-10 bg-white/80 backdrop-blur-xl border-b border-gray-200 shadow-sm" }, /* @__PURE__ */ React21.createElement("div", { className: "container mx-auto px-4" }, /* @__PURE__ */ React21.createElement("div", { className: "flex items-center justify-between h-20" }, /* @__PURE__ */ React21.createElement(Link7, { href: buildPath("/"), className: "flex items-center gap-3" }, /* @__PURE__ */ React21.createElement("div", { className: "relative w-12 h-12" }, /* @__PURE__ */ React21.createElement(
|
|
11696
|
+
Image4,
|
|
11539
11697
|
{
|
|
11540
11698
|
src: config.logo,
|
|
11541
11699
|
alt: config.storeName,
|
|
11542
11700
|
fill: true,
|
|
11543
11701
|
className: "object-contain"
|
|
11544
11702
|
}
|
|
11545
|
-
))
|
|
11546
|
-
|
|
11703
|
+
))), /* @__PURE__ */ React21.createElement("nav", { className: "hidden lg:flex items-center gap-8" }, navLinks.map((link) => /* @__PURE__ */ React21.createElement(
|
|
11704
|
+
Link7,
|
|
11547
11705
|
{
|
|
11548
11706
|
key: link.href,
|
|
11549
11707
|
href: link.href,
|
|
@@ -11590,15 +11748,40 @@ function Header() {
|
|
|
11590
11748
|
},
|
|
11591
11749
|
/* @__PURE__ */ React21.createElement(X, { className: "w-4 h-4" })
|
|
11592
11750
|
))
|
|
11593
|
-
))), /* @__PURE__ */ React21.createElement("div", { className: "flex items-center gap-4" }, /* @__PURE__ */ React21.createElement(
|
|
11594
|
-
|
|
11751
|
+
))), /* @__PURE__ */ React21.createElement("div", { className: "flex items-center gap-4" }, /* @__PURE__ */ React21.createElement(Link7, { href: buildPath("/wishlist"), className: "relative p-2 text-gray-700 hover:text-red-500 transition-colors" }, /* @__PURE__ */ React21.createElement(Heart, { className: "w-6 h-6" }), wishlistCount > 0 && /* @__PURE__ */ React21.createElement("span", { 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" }, wishlistCount)), /* @__PURE__ */ React21.createElement(Link7, { href: buildPath("/cart"), className: "relative p-2 text-gray-700 hover:text-primary-600 transition-colors" }, /* @__PURE__ */ React21.createElement(ShoppingCart, { className: "w-6 h-6" }), cart?.cartBody?.items?.length && cart.cartBody?.items?.length > 0 ? /* @__PURE__ */ React21.createElement("span", { 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" }, cart.cartBody?.items?.length) : null), isAuthenticated ? /* @__PURE__ */ React21.createElement("div", { className: "relative" }, /* @__PURE__ */ React21.createElement(
|
|
11752
|
+
"button",
|
|
11753
|
+
{
|
|
11754
|
+
onClick: () => setIsDropdownOpen(!isDropdownOpen),
|
|
11755
|
+
className: "flex items-center gap-2 rounded-full border border-slate-200 bg-white px-3 py-2 hover:bg-slate-50 transition-colors"
|
|
11756
|
+
},
|
|
11757
|
+
/* @__PURE__ */ React21.createElement("div", { className: "flex h-7 w-7 items-center justify-center rounded-full bg-primary-100 text-xs font-semibold text-primary-700" }, getInitials(user?.firstname || "", user?.lastname || "")),
|
|
11758
|
+
/* @__PURE__ */ React21.createElement(ChevronDown, { className: `h-4 w-4 text-slate-400 transition-transform ${isDropdownOpen ? "rotate-180" : ""}` })
|
|
11759
|
+
), isDropdownOpen && /* @__PURE__ */ React21.createElement(React21.Fragment, null, /* @__PURE__ */ React21.createElement(
|
|
11760
|
+
"div",
|
|
11761
|
+
{
|
|
11762
|
+
className: "fixed inset-0 z-10",
|
|
11763
|
+
onClick: () => setIsDropdownOpen(false)
|
|
11764
|
+
}
|
|
11765
|
+
), /* @__PURE__ */ React21.createElement("div", { className: "absolute right-0 top-full mt-2 w-56 rounded-lg border border-slate-200 bg-white shadow-lg z-20" }, /* @__PURE__ */ React21.createElement("div", { className: "p-2" }, /* @__PURE__ */ React21.createElement("div", { className: "px-3 py-2 border-b border-slate-200 mb-1" }, /* @__PURE__ */ React21.createElement("p", { className: "text-sm font-medium text-secondary truncate" }, user?.firstname, " ", user?.lastname), /* @__PURE__ */ React21.createElement("p", { className: "text-xs text-slate-500 truncate" }, user?.email)), /* @__PURE__ */ React21.createElement(
|
|
11766
|
+
Link7,
|
|
11595
11767
|
{
|
|
11596
11768
|
href: buildPath("/account"),
|
|
11597
|
-
|
|
11769
|
+
onClick: () => setIsDropdownOpen(false),
|
|
11770
|
+
className: "flex w-full items-center gap-2 rounded-md px-3 py-2 text-sm text-slate-700 hover:bg-slate-100 transition-colors"
|
|
11598
11771
|
},
|
|
11599
|
-
/* @__PURE__ */ React21.createElement(User, { className: "
|
|
11600
|
-
|
|
11601
|
-
|
|
11772
|
+
/* @__PURE__ */ React21.createElement(User, { className: "h-4 w-4" }),
|
|
11773
|
+
"My Account"
|
|
11774
|
+
), /* @__PURE__ */ React21.createElement("div", { className: "my-1 border-t border-slate-200" }), /* @__PURE__ */ React21.createElement(
|
|
11775
|
+
"button",
|
|
11776
|
+
{
|
|
11777
|
+
onClick: handleLogout,
|
|
11778
|
+
disabled: isLoggingOut,
|
|
11779
|
+
className: "flex w-full items-center gap-2 rounded-md px-3 py-2 text-sm text-red-600 hover:bg-red-50 transition-colors disabled:opacity-50"
|
|
11780
|
+
},
|
|
11781
|
+
/* @__PURE__ */ React21.createElement(LogOut, { className: "h-4 w-4" }),
|
|
11782
|
+
isLoggingOut ? "Signing out..." : "Sign Out"
|
|
11783
|
+
))))) : /* @__PURE__ */ React21.createElement(
|
|
11784
|
+
Link7,
|
|
11602
11785
|
{
|
|
11603
11786
|
href: buildPath("/login"),
|
|
11604
11787
|
className: "hidden sm:block px-4 py-2 bg-primary-600 text-white rounded-lg hover:bg-primary-700 transition-colors font-medium"
|
|
@@ -11620,7 +11803,7 @@ function Header() {
|
|
|
11620
11803
|
className: "lg:hidden overflow-hidden border-t border-gray-200"
|
|
11621
11804
|
},
|
|
11622
11805
|
/* @__PURE__ */ React21.createElement("nav", { className: "flex flex-col gap-1 py-2" }, navLinks.map((link) => /* @__PURE__ */ React21.createElement(
|
|
11623
|
-
|
|
11806
|
+
Link7,
|
|
11624
11807
|
{
|
|
11625
11808
|
key: link.href,
|
|
11626
11809
|
href: link.href,
|
|
@@ -11629,7 +11812,7 @@ function Header() {
|
|
|
11629
11812
|
},
|
|
11630
11813
|
link.label
|
|
11631
11814
|
)), !isAuthenticated && /* @__PURE__ */ React21.createElement(
|
|
11632
|
-
|
|
11815
|
+
Link7,
|
|
11633
11816
|
{
|
|
11634
11817
|
href: buildPath("/login"),
|
|
11635
11818
|
onClick: () => setIsMobileMenuOpen(false),
|
|
@@ -11668,21 +11851,21 @@ function Footer() {
|
|
|
11668
11851
|
]
|
|
11669
11852
|
};
|
|
11670
11853
|
return /* @__PURE__ */ React21.createElement("footer", { className: "bg-gray-900 text-gray-300" }, /* @__PURE__ */ React21.createElement("div", { className: "container mx-auto px-4 py-16" }, /* @__PURE__ */ React21.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-5 gap-12" }, /* @__PURE__ */ React21.createElement("div", { className: "lg:col-span-2" }, /* @__PURE__ */ React21.createElement("h3", { className: "text-2xl font-bold text-white mb-4" }, config.storeName), /* @__PURE__ */ React21.createElement("p", { className: "text-gray-400 mb-6 max-w-md" }, "Your trusted online store for quality products. We deliver excellence with every order."), /* @__PURE__ */ React21.createElement("div", { className: "space-y-3" }, /* @__PURE__ */ React21.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ React21.createElement(Mail, { className: "w-5 h-5 text-primary-500" }), /* @__PURE__ */ React21.createElement("span", null, "support@", config.storeName.toLowerCase().replace(/\s+/g, ""), ".com")), /* @__PURE__ */ React21.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ React21.createElement(Phone, { className: "w-5 h-5 text-primary-500" }), /* @__PURE__ */ React21.createElement("span", null, "+1 (555) 123-4567")), /* @__PURE__ */ React21.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ React21.createElement(MapPin, { className: "w-5 h-5 text-primary-500" }), /* @__PURE__ */ React21.createElement("span", null, "123 Store Street, City, Country")))), /* @__PURE__ */ React21.createElement("div", null, /* @__PURE__ */ React21.createElement("h4", { className: "text-lg font-semibold text-white mb-4" }, "Shop"), /* @__PURE__ */ React21.createElement("ul", { className: "space-y-2" }, footerLinks.shop.map((link) => /* @__PURE__ */ React21.createElement("li", { key: link.href }, /* @__PURE__ */ React21.createElement(
|
|
11671
|
-
|
|
11854
|
+
Link7,
|
|
11672
11855
|
{
|
|
11673
11856
|
href: link.href,
|
|
11674
11857
|
className: "hover:text-primary-500 transition-colors"
|
|
11675
11858
|
},
|
|
11676
11859
|
link.label
|
|
11677
11860
|
))))), /* @__PURE__ */ React21.createElement("div", null, /* @__PURE__ */ React21.createElement("h4", { className: "text-lg font-semibold text-white mb-4" }, "Account"), /* @__PURE__ */ React21.createElement("ul", { className: "space-y-2" }, footerLinks.account.map((link) => /* @__PURE__ */ React21.createElement("li", { key: link.href }, /* @__PURE__ */ React21.createElement(
|
|
11678
|
-
|
|
11861
|
+
Link7,
|
|
11679
11862
|
{
|
|
11680
11863
|
href: link.href,
|
|
11681
11864
|
className: "hover:text-primary-500 transition-colors"
|
|
11682
11865
|
},
|
|
11683
11866
|
link.label
|
|
11684
11867
|
))))), /* @__PURE__ */ React21.createElement("div", null, /* @__PURE__ */ React21.createElement("h4", { className: "text-lg font-semibold text-white mb-4" }, "Support"), /* @__PURE__ */ React21.createElement("ul", { className: "space-y-2" }, footerLinks.support.map((link) => /* @__PURE__ */ React21.createElement("li", { key: link.href }, /* @__PURE__ */ React21.createElement(
|
|
11685
|
-
|
|
11868
|
+
Link7,
|
|
11686
11869
|
{
|
|
11687
11870
|
href: link.href,
|
|
11688
11871
|
className: "hover:text-primary-500 transition-colors"
|
|
@@ -11712,6 +11895,6 @@ function Footer() {
|
|
|
11712
11895
|
)))));
|
|
11713
11896
|
}
|
|
11714
11897
|
|
|
11715
|
-
export { AddressesScreen, AuthProvider, Badge, Button, CartItem, CartProvider, CartScreen,
|
|
11898
|
+
export { AddressesScreen, AuthProvider, Badge, Button, CartItem, CartProvider, CartScreen, CheckoutScreen, CurrentOrdersScreen, EcommerceProvider, EmptyState, Footer, Header, Input, LoginScreen, Modal, NewAddressPage as NewAddressScreen, OrderCard, OrderCardSkeleton, OrdersScreen, ProductCard, ProductCardSkeleton, ProductDetailScreen, ProfileScreen, RegisterScreen, SearchPage as SearchResultsScreen, ShopScreen, Skeleton, ThemeProvider, WishlistProvider, WishlistScreen, formatDate, formatPrice, generateColorShades, getApiConfiguration, getInitials, hexToRgb, initializeApiAdapter, truncate, useAddresses, useAuth, useBasePath, useCart, useCategories, useCurrentOrders, useOrder, useOrders, useProduct, useProducts, useTheme, useWishlist };
|
|
11716
11899
|
//# sourceMappingURL=index.mjs.map
|
|
11717
11900
|
//# sourceMappingURL=index.mjs.map
|