hey-pharmacist-ecommerce 1.1.11 → 1.1.12
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 +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +548 -396
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +549 -397
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/CartItem.tsx +63 -42
- package/src/components/ProductCard.tsx +131 -55
- package/src/lib/types/index.ts +1 -0
- package/src/providers/CartProvider.tsx +47 -3
- package/src/screens/CartScreen.tsx +146 -231
- package/src/screens/CheckoutScreen.tsx +30 -61
- package/src/screens/LoginScreen.tsx +1 -1
- package/src/screens/ProductDetailScreen.tsx +355 -362
- package/src/screens/RegisterScreen.tsx +1 -1
- package/src/screens/ShopScreen.tsx +439 -268
- package/src/screens/WishlistScreen.tsx +80 -76
package/dist/index.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import globalAxios4 from 'axios';
|
|
|
4
4
|
import { Toaster, toast } from 'sonner';
|
|
5
5
|
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
6
6
|
import { motion, AnimatePresence } from 'framer-motion';
|
|
7
|
-
import { Heart, Sparkles, ShieldCheck, TrendingUp, Search, ArrowUpDown, ChevronDown, LayoutGrid, LayoutList, SlidersHorizontal, X, Clock, Package, ArrowLeft,
|
|
7
|
+
import { Heart, ShoppingCart, Sparkles, ShieldCheck, TrendingUp, Star, Search, ShoppingBag, ArrowUpDown, ChevronDown, LayoutGrid, LayoutList, SlidersHorizontal, X, Clock, Package, ArrowLeft, Check, Minus, Plus, Trash2, ArrowRight, CheckCircle2, Truck, Edit3, MapPin, CreditCard, Lock, PackageCheck, HeartPulse, EyeOff, Eye, Shield, UserPlus, Mail, Phone, LogOut, Calendar, CalendarDays, Filter, ChevronLeft, ChevronRight, ArrowUpRight, Warehouse, BellRing, Crown, User, Grid, List, Menu, Facebook, Twitter, Instagram, ChevronUp, Shirt, Pill, Box, Globe, Home } from 'lucide-react';
|
|
8
8
|
import Image3 from 'next/image';
|
|
9
9
|
import { useRouter, useSearchParams } from 'next/navigation';
|
|
10
10
|
import dynamic from 'next/dynamic';
|
|
@@ -6789,7 +6789,24 @@ function CartProvider({ children }) {
|
|
|
6789
6789
|
const addToCart = async (productId, quantity = 1, variantId) => {
|
|
6790
6790
|
setIsLoading(true);
|
|
6791
6791
|
try {
|
|
6792
|
-
const
|
|
6792
|
+
const currentItems = cart?.cartBody?.items || [];
|
|
6793
|
+
const targetVariantId = variantId || productId;
|
|
6794
|
+
const existingItemIndex = currentItems.findIndex(
|
|
6795
|
+
(item) => item.productVariantId === targetVariantId
|
|
6796
|
+
);
|
|
6797
|
+
const items = [...currentItems];
|
|
6798
|
+
if (existingItemIndex >= 0) {
|
|
6799
|
+
items[existingItemIndex] = {
|
|
6800
|
+
...items[existingItemIndex],
|
|
6801
|
+
quantity: (items[existingItemIndex].quantity || 0) + quantity
|
|
6802
|
+
};
|
|
6803
|
+
} else {
|
|
6804
|
+
items.push({
|
|
6805
|
+
productVariantId: targetVariantId,
|
|
6806
|
+
quantity
|
|
6807
|
+
});
|
|
6808
|
+
}
|
|
6809
|
+
const response = await new CartApi(getApiConfiguration()).handleUserCart({ items });
|
|
6793
6810
|
setCart(response.data);
|
|
6794
6811
|
toast.success("Added to cart!");
|
|
6795
6812
|
} catch (error) {
|
|
@@ -6802,7 +6819,17 @@ function CartProvider({ children }) {
|
|
|
6802
6819
|
const updateQuantity = async (productId, quantity) => {
|
|
6803
6820
|
setIsLoading(true);
|
|
6804
6821
|
try {
|
|
6805
|
-
const
|
|
6822
|
+
const currentItems = cart?.cartBody?.items || [];
|
|
6823
|
+
const items = currentItems.map((item) => {
|
|
6824
|
+
if (item.productVariantId === productId) {
|
|
6825
|
+
return {
|
|
6826
|
+
...item,
|
|
6827
|
+
quantity
|
|
6828
|
+
};
|
|
6829
|
+
}
|
|
6830
|
+
return item;
|
|
6831
|
+
});
|
|
6832
|
+
const response = await new CartApi(getApiConfiguration()).handleUserCart({ items });
|
|
6806
6833
|
setCart(response.data);
|
|
6807
6834
|
} catch (error) {
|
|
6808
6835
|
toast.error(error.response?.data?.message || "Failed to update cart");
|
|
@@ -6814,7 +6841,9 @@ function CartProvider({ children }) {
|
|
|
6814
6841
|
const removeFromCart = async (productId) => {
|
|
6815
6842
|
setIsLoading(true);
|
|
6816
6843
|
try {
|
|
6817
|
-
const
|
|
6844
|
+
const currentItems = cart?.cartBody?.items || [];
|
|
6845
|
+
const items = currentItems.filter((item) => item.productVariantId !== productId);
|
|
6846
|
+
const response = await new CartApi(getApiConfiguration()).handleUserCart({ items });
|
|
6818
6847
|
setCart(response.data);
|
|
6819
6848
|
} catch (error) {
|
|
6820
6849
|
toast.error(error.response?.data?.message || "Failed to remove from cart");
|
|
@@ -7080,8 +7109,11 @@ function ProductCard({
|
|
|
7080
7109
|
const { buildPath } = useBasePath();
|
|
7081
7110
|
const [isFavorite, setIsFavorite] = useState(isFavorited);
|
|
7082
7111
|
const { addToWishlist, removeFromWishlist, isInWishlist } = useWishlist();
|
|
7112
|
+
const { addToCart, isLoading: isAddingToCart } = useCart();
|
|
7083
7113
|
const [isHovered, setIsHovered] = useState(false);
|
|
7084
7114
|
const [isImageLoaded, setIsImageLoaded] = useState(false);
|
|
7115
|
+
const [selectedVariantImage, setSelectedVariantImage] = useState(null);
|
|
7116
|
+
const [selectedVariantId, setSelectedVariantId] = useState(null);
|
|
7085
7117
|
const handleImageLoad = useCallback(() => {
|
|
7086
7118
|
setIsImageLoaded(true);
|
|
7087
7119
|
}, []);
|
|
@@ -7112,22 +7144,51 @@ function ProductCard({
|
|
|
7112
7144
|
useEffect(() => {
|
|
7113
7145
|
setIsFavorite(isInWishlist(product?._id || "") || isFavorited);
|
|
7114
7146
|
}, [isFavorited, isInWishlist, product?._id]);
|
|
7147
|
+
useEffect(() => {
|
|
7148
|
+
setSelectedVariantImage(null);
|
|
7149
|
+
setSelectedVariantId(null);
|
|
7150
|
+
setIsImageLoaded(false);
|
|
7151
|
+
}, [product._id]);
|
|
7115
7152
|
const handleKeyDown = (e) => {
|
|
7116
7153
|
if (e.key === "Enter" || e.key === " ") {
|
|
7117
7154
|
e.preventDefault();
|
|
7118
7155
|
handleCardClick(e);
|
|
7119
7156
|
}
|
|
7120
7157
|
};
|
|
7121
|
-
useMemo(() => {
|
|
7158
|
+
const variantImages = useMemo(() => {
|
|
7159
|
+
if (!product.productVariants || product.productVariants.length === 0) {
|
|
7160
|
+
return [];
|
|
7161
|
+
}
|
|
7162
|
+
return product.productVariants.filter((variant) => variant.productMedia && variant.productMedia.length > 0).map((variant) => ({
|
|
7163
|
+
variantId: variant.id || variant._id,
|
|
7164
|
+
variantName: variant.name,
|
|
7165
|
+
image: variant.productMedia[0].file,
|
|
7166
|
+
color: variant.attribute?.color || variant.attribute?.Color || null
|
|
7167
|
+
}));
|
|
7168
|
+
}, [product.productVariants]);
|
|
7169
|
+
const selectedVariant = useMemo(() => {
|
|
7170
|
+
if (!selectedVariantId || !product.productVariants) return null;
|
|
7171
|
+
return product.productVariants.find(
|
|
7172
|
+
(variant) => (variant.id || variant._id) === selectedVariantId
|
|
7173
|
+
);
|
|
7174
|
+
}, [selectedVariantId, product.productVariants]);
|
|
7175
|
+
const displayName = useMemo(() => {
|
|
7176
|
+
return selectedVariant?.name || product.name;
|
|
7177
|
+
}, [selectedVariant, product.name]);
|
|
7178
|
+
const imageSource = useMemo(() => {
|
|
7179
|
+
const src = selectedVariantImage || product.productMedia?.[0]?.file || "/placeholder-product.jpg";
|
|
7122
7180
|
return {
|
|
7123
|
-
src
|
|
7181
|
+
src,
|
|
7124
7182
|
alt: product.name || "Product image"
|
|
7125
7183
|
};
|
|
7126
|
-
}, [product.productMedia, product.name]);
|
|
7184
|
+
}, [product.productMedia, product.name, selectedVariantImage]);
|
|
7185
|
+
useEffect(() => {
|
|
7186
|
+
setIsImageLoaded(false);
|
|
7187
|
+
}, [imageSource.src]);
|
|
7127
7188
|
return /* @__PURE__ */ React21.createElement(
|
|
7128
7189
|
motion.article,
|
|
7129
7190
|
{
|
|
7130
|
-
className: "relative group bg-white rounded-xl overflow-hidden shadow-sm hover:shadow-md transition-all duration-300 border border-gray-100 hover:border-gray-200 flex
|
|
7191
|
+
className: "relative group bg-white rounded-xl overflow-hidden shadow-sm hover:shadow-md transition-all duration-300 border border-gray-100 hover:border-gray-200 flex flex-col",
|
|
7131
7192
|
whileHover: { y: -4 },
|
|
7132
7193
|
onMouseEnter: () => setIsHovered(true),
|
|
7133
7194
|
onMouseLeave: () => setIsHovered(false),
|
|
@@ -7137,7 +7198,7 @@ function ProductCard({
|
|
|
7137
7198
|
onClick: handleCardClick,
|
|
7138
7199
|
onKeyDown: handleKeyDown
|
|
7139
7200
|
},
|
|
7140
|
-
/* @__PURE__ */ React21.createElement("div", { className: "relative
|
|
7201
|
+
/* @__PURE__ */ React21.createElement("div", { className: "relative aspect-square w-full overflow-hidden bg-gray-50" }, /* @__PURE__ */ React21.createElement(AnimatePresence, null, !isImageLoaded && /* @__PURE__ */ React21.createElement(
|
|
7141
7202
|
motion.div,
|
|
7142
7203
|
{
|
|
7143
7204
|
className: "absolute inset-0 bg-gray-200 animate-pulse",
|
|
@@ -7145,16 +7206,18 @@ function ProductCard({
|
|
|
7145
7206
|
exit: { opacity: 0 },
|
|
7146
7207
|
transition: { duration: 0.2 }
|
|
7147
7208
|
}
|
|
7148
|
-
)),
|
|
7209
|
+
)), /* @__PURE__ */ React21.createElement(
|
|
7149
7210
|
Image3,
|
|
7150
7211
|
{
|
|
7151
|
-
src:
|
|
7152
|
-
alt:
|
|
7212
|
+
src: imageSource.src,
|
|
7213
|
+
alt: imageSource.alt,
|
|
7153
7214
|
fill: true,
|
|
7154
7215
|
className: `h-full w-full object-cover object-center transition-opacity duration-300 ${product.inventoryCount === 0 ? "opacity-60" : ""} ${isImageLoaded ? "opacity-100" : "opacity-0"}`,
|
|
7155
7216
|
sizes: "(max-width: 640px) 100vw, (max-width: 768px) 50vw, 33vw",
|
|
7156
7217
|
priority: false,
|
|
7157
|
-
onLoad: handleImageLoad
|
|
7218
|
+
onLoad: handleImageLoad,
|
|
7219
|
+
onError: () => setIsImageLoaded(true),
|
|
7220
|
+
key: imageSource.src
|
|
7158
7221
|
}
|
|
7159
7222
|
), /* @__PURE__ */ React21.createElement("div", { className: "absolute top-3 left-3 flex flex-col gap-2 z-10" }, product.isDiscounted && /* @__PURE__ */ React21.createElement(
|
|
7160
7223
|
motion.span,
|
|
@@ -7179,51 +7242,80 @@ function ProductCard({
|
|
|
7179
7242
|
{
|
|
7180
7243
|
type: "button",
|
|
7181
7244
|
onClick: handleFavorite,
|
|
7182
|
-
className:
|
|
7245
|
+
className: "absolute top-2 right-2 p-2 rounded-full z-10 transition-colors bg-white shadow-md hover:shadow-lg text-primary-600 hover:text-red-500",
|
|
7183
7246
|
whileHover: { scale: 1.1 },
|
|
7184
7247
|
whileTap: { scale: 0.95 },
|
|
7185
7248
|
"aria-label": isFavorite ? "Remove from wishlist" : "Add to wishlist"
|
|
7186
7249
|
},
|
|
7187
|
-
/* @__PURE__ */ React21.createElement(Heart, { className: `w-5 h-5 ${isFavorite ? "fill-
|
|
7250
|
+
/* @__PURE__ */ React21.createElement(Heart, { className: `w-5 h-5 ${isFavorite ? "fill-red-500 text-red-500" : ""}` })
|
|
7188
7251
|
)),
|
|
7189
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")),
|
|
7190
|
-
|
|
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(
|
|
7191
7254
|
"button",
|
|
7192
7255
|
{
|
|
7256
|
+
key: variant.variantId || index,
|
|
7193
7257
|
type: "button",
|
|
7194
|
-
onClick:
|
|
7195
|
-
|
|
7196
|
-
|
|
7258
|
+
onClick: (e) => {
|
|
7259
|
+
e.stopPropagation();
|
|
7260
|
+
if (selectedVariantId === variant.variantId) {
|
|
7261
|
+
setSelectedVariantImage(null);
|
|
7262
|
+
setSelectedVariantId(null);
|
|
7263
|
+
} else {
|
|
7264
|
+
setSelectedVariantImage(variant.image);
|
|
7265
|
+
setSelectedVariantId(variant.variantId || null);
|
|
7266
|
+
}
|
|
7267
|
+
setIsImageLoaded(false);
|
|
7268
|
+
},
|
|
7269
|
+
className: `relative w-8 h-8 rounded-full overflow-hidden border-2 transition-all ${selectedVariantId === variant.variantId ? "border-primary-500 ring-2 ring-primary-200" : "border-gray-200 hover:border-primary-300"}`,
|
|
7270
|
+
"aria-label": `Select ${variant.color || "variant"} color`
|
|
7197
7271
|
},
|
|
7198
|
-
/* @__PURE__ */ React21.createElement(
|
|
7199
|
-
|
|
7200
|
-
|
|
7272
|
+
/* @__PURE__ */ React21.createElement(
|
|
7273
|
+
Image3,
|
|
7274
|
+
{
|
|
7275
|
+
src: variant.image,
|
|
7276
|
+
alt: variant.color || `Variant ${index + 1}`,
|
|
7277
|
+
fill: true,
|
|
7278
|
+
className: "object-cover",
|
|
7279
|
+
sizes: "32px"
|
|
7280
|
+
}
|
|
7281
|
+
)
|
|
7282
|
+
)))),
|
|
7201
7283
|
/* @__PURE__ */ React21.createElement("div", { className: "mt-auto p-4 pt-0" }, /* @__PURE__ */ React21.createElement(
|
|
7202
7284
|
"button",
|
|
7203
7285
|
{
|
|
7204
7286
|
type: "button",
|
|
7205
|
-
onClick: (e) => {
|
|
7287
|
+
onClick: async (e) => {
|
|
7206
7288
|
e.stopPropagation();
|
|
7207
|
-
|
|
7289
|
+
if (!selectedVariantId && variantImages.length > 0) {
|
|
7290
|
+
toast.error("Please select a variant");
|
|
7291
|
+
return;
|
|
7292
|
+
}
|
|
7293
|
+
try {
|
|
7294
|
+
await addToCart(
|
|
7295
|
+
product._id || product.id,
|
|
7296
|
+
1,
|
|
7297
|
+
selectedVariantId || void 0
|
|
7298
|
+
);
|
|
7299
|
+
} catch (error) {
|
|
7300
|
+
console.error("Failed to add to cart", error);
|
|
7301
|
+
}
|
|
7208
7302
|
},
|
|
7209
|
-
|
|
7303
|
+
disabled: isAddingToCart || variantImages.length > 0 && !selectedVariantId,
|
|
7304
|
+
className: "w-full flex items-center justify-center gap-2 rounded-full px-3 py-2.5 text-sm font-medium bg-primary-400 hover:bg-primary-500 text-white transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
|
|
7210
7305
|
},
|
|
7211
|
-
"
|
|
7212
|
-
|
|
7306
|
+
/* @__PURE__ */ React21.createElement(ShoppingCart, { className: "h-4 w-4" }),
|
|
7307
|
+
"Add to Cart"
|
|
7308
|
+
), /* @__PURE__ */ React21.createElement(
|
|
7213
7309
|
"button",
|
|
7214
7310
|
{
|
|
7215
7311
|
type: "button",
|
|
7216
|
-
onClick:
|
|
7217
|
-
|
|
7218
|
-
|
|
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"
|
|
7219
7317
|
},
|
|
7220
|
-
|
|
7221
|
-
Heart,
|
|
7222
|
-
{
|
|
7223
|
-
className: `mr-2 h-4 w-4 ${isFavorite ? "fill-red-500 text-red-500" : "text-primary-600"}`
|
|
7224
|
-
}
|
|
7225
|
-
),
|
|
7226
|
-
isFavorite ? "Saved" : "Save for later"
|
|
7318
|
+
"View More"
|
|
7227
7319
|
))
|
|
7228
7320
|
);
|
|
7229
7321
|
}
|
|
@@ -7435,8 +7527,12 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7435
7527
|
max: ""
|
|
7436
7528
|
});
|
|
7437
7529
|
const [expandedCategories, setExpandedCategories] = useState({});
|
|
7530
|
+
const [expandedFilterSections, setExpandedFilterSections] = useState({
|
|
7531
|
+
category: true
|
|
7532
|
+
// Category section starts expanded
|
|
7533
|
+
});
|
|
7438
7534
|
const { products, isLoading, pagination } = useProducts(filters, page, 20);
|
|
7439
|
-
const { categories } = useCategories();
|
|
7535
|
+
const { categories, isLoading: isLoadingCategories } = useCategories();
|
|
7440
7536
|
const handleSearch = (e) => {
|
|
7441
7537
|
e.preventDefault();
|
|
7442
7538
|
if (searchQuery.trim()) {
|
|
@@ -7506,7 +7602,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7506
7602
|
});
|
|
7507
7603
|
return { newArrivals: newArrivals2, inStockCount };
|
|
7508
7604
|
}, [products]);
|
|
7509
|
-
|
|
7605
|
+
useMemo(
|
|
7510
7606
|
() => [
|
|
7511
7607
|
{
|
|
7512
7608
|
id: "new",
|
|
@@ -7549,8 +7645,11 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7549
7645
|
const thirtyDaysAgo = Date.now() - 30 * 24 * 60 * 60 * 1e3;
|
|
7550
7646
|
items = items.filter((p) => new Date(p.createdAt).getTime() >= thirtyDaysAgo);
|
|
7551
7647
|
}
|
|
7648
|
+
if (filters.brand) {
|
|
7649
|
+
items = items.filter((p) => p.brand && p.brand.trim().toLowerCase() === filters.brand.toLowerCase());
|
|
7650
|
+
}
|
|
7552
7651
|
return items;
|
|
7553
|
-
}, [isLoading, products, filters.tags, filters.newArrivals]);
|
|
7652
|
+
}, [isLoading, products, filters.tags, filters.newArrivals, filters.brand]);
|
|
7554
7653
|
const sortedProducts = useMemo(() => {
|
|
7555
7654
|
if (isLoading) {
|
|
7556
7655
|
return filteredProducts;
|
|
@@ -7570,14 +7669,23 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7570
7669
|
}
|
|
7571
7670
|
}, [isLoading, filteredProducts, sortOption]);
|
|
7572
7671
|
const displayedProducts = sortedProducts;
|
|
7573
|
-
const
|
|
7672
|
+
const availableBrands = useMemo(() => {
|
|
7673
|
+
const brandSet = /* @__PURE__ */ new Set();
|
|
7674
|
+
products.forEach((product) => {
|
|
7675
|
+
if (product.brand && product.brand.trim()) {
|
|
7676
|
+
brandSet.add(product.brand.trim());
|
|
7677
|
+
}
|
|
7678
|
+
});
|
|
7679
|
+
return Array.from(brandSet).sort();
|
|
7680
|
+
}, [products]);
|
|
7681
|
+
useMemo(() => {
|
|
7574
7682
|
const counts = /* @__PURE__ */ new Map();
|
|
7575
7683
|
products.forEach((p) => {
|
|
7576
7684
|
(p.tags || []).forEach((t) => counts.set(t, (counts.get(t) || 0) + 1));
|
|
7577
7685
|
});
|
|
7578
7686
|
return Array.from(counts.entries()).sort((a, b) => b[1] - a[1]).slice(0, 4).map(([tag]) => tag);
|
|
7579
7687
|
}, [products]);
|
|
7580
|
-
|
|
7688
|
+
useCallback((term) => {
|
|
7581
7689
|
setSearchQuery("");
|
|
7582
7690
|
setFilters((current) => ({
|
|
7583
7691
|
...current,
|
|
@@ -7633,6 +7741,13 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7633
7741
|
});
|
|
7634
7742
|
setPage(1);
|
|
7635
7743
|
}, []);
|
|
7744
|
+
const handleClearCategory = useCallback(() => {
|
|
7745
|
+
setFilters((current) => {
|
|
7746
|
+
const { category, subCategory, ...rest } = current;
|
|
7747
|
+
return rest;
|
|
7748
|
+
});
|
|
7749
|
+
setPage(1);
|
|
7750
|
+
}, []);
|
|
7636
7751
|
const handleClearFilters = useCallback(() => {
|
|
7637
7752
|
setFilters({});
|
|
7638
7753
|
setSearchQuery("");
|
|
@@ -7695,6 +7810,23 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7695
7810
|
});
|
|
7696
7811
|
setPage(1);
|
|
7697
7812
|
}, []);
|
|
7813
|
+
const handleBrandChange = useCallback((brand) => {
|
|
7814
|
+
setFilters((current) => {
|
|
7815
|
+
if (current.brand === brand) {
|
|
7816
|
+
const { brand: _, ...rest } = current;
|
|
7817
|
+
return rest;
|
|
7818
|
+
}
|
|
7819
|
+
return { ...current, brand };
|
|
7820
|
+
});
|
|
7821
|
+
setPage(1);
|
|
7822
|
+
}, []);
|
|
7823
|
+
const handleRemoveBrand = useCallback(() => {
|
|
7824
|
+
setFilters((current) => {
|
|
7825
|
+
const { brand, ...rest } = current;
|
|
7826
|
+
return rest;
|
|
7827
|
+
});
|
|
7828
|
+
setPage(1);
|
|
7829
|
+
}, []);
|
|
7698
7830
|
const handlePriceRangeSelect = useCallback(
|
|
7699
7831
|
(value) => {
|
|
7700
7832
|
const range = priceRanges.find((item) => item.value === value);
|
|
@@ -7769,7 +7901,8 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7769
7901
|
minPrice,
|
|
7770
7902
|
maxPrice,
|
|
7771
7903
|
tags,
|
|
7772
|
-
newArrivals
|
|
7904
|
+
newArrivals,
|
|
7905
|
+
brand: brandFilter
|
|
7773
7906
|
} = filters;
|
|
7774
7907
|
const activeFilterChips = useMemo(() => {
|
|
7775
7908
|
const chips = [];
|
|
@@ -7843,6 +7976,13 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7843
7976
|
onRemove: handleToggleNewArrivals
|
|
7844
7977
|
});
|
|
7845
7978
|
}
|
|
7979
|
+
if (brandFilter) {
|
|
7980
|
+
chips.push({
|
|
7981
|
+
key: "brand",
|
|
7982
|
+
label: `Brand: ${brandFilter}`,
|
|
7983
|
+
onRemove: handleRemoveBrand
|
|
7984
|
+
});
|
|
7985
|
+
}
|
|
7846
7986
|
return chips;
|
|
7847
7987
|
}, [
|
|
7848
7988
|
categories,
|
|
@@ -7854,53 +7994,87 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7854
7994
|
handleRemovePrice,
|
|
7855
7995
|
handleRemoveSearch,
|
|
7856
7996
|
handleRemoveTag,
|
|
7997
|
+
handleRemoveBrand,
|
|
7857
7998
|
inStockOnly,
|
|
7858
7999
|
maxPrice,
|
|
7859
8000
|
minPrice,
|
|
7860
8001
|
searchFilter,
|
|
7861
8002
|
tags,
|
|
7862
|
-
newArrivals
|
|
8003
|
+
newArrivals,
|
|
8004
|
+
brandFilter
|
|
7863
8005
|
]);
|
|
7864
8006
|
const hasActiveFilters = activeFilterChips.length > 0;
|
|
7865
8007
|
const isCustomPriceDirty = customPrice.min.trim() !== "" || customPrice.max.trim() !== "";
|
|
7866
|
-
const
|
|
8008
|
+
const toggleFilterSection = useCallback((section) => {
|
|
8009
|
+
setExpandedFilterSections((prev) => ({
|
|
8010
|
+
...prev,
|
|
8011
|
+
[section]: !prev[section]
|
|
8012
|
+
}));
|
|
8013
|
+
}, []);
|
|
8014
|
+
const getCategoryIconForFilter = (categoryName2) => {
|
|
8015
|
+
const name = categoryName2.toLowerCase();
|
|
8016
|
+
if (name.includes("scrub") || name.includes("uniform")) return Shirt;
|
|
8017
|
+
if (name.includes("vitamin") || name.includes("supplement")) return Pill;
|
|
8018
|
+
if (name.includes("medicine") || name.includes("medication")) return Box;
|
|
8019
|
+
if (name.includes("care") || name.includes("personal")) return Heart;
|
|
8020
|
+
return Package;
|
|
8021
|
+
};
|
|
8022
|
+
const renderFiltersPanel = () => /* @__PURE__ */ React21.createElement(React21.Fragment, null, /* @__PURE__ */ React21.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React21.createElement("h3", { className: "text-lg font-bold text-slate-900" }, "Filters"), /* @__PURE__ */ React21.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React21.createElement("label", { className: "text-sm font-medium text-slate-600" }, "Search Products"), /* @__PURE__ */ React21.createElement("div", { className: "relative" }, /* @__PURE__ */ React21.createElement(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-slate-400" }), /* @__PURE__ */ React21.createElement(
|
|
8023
|
+
"input",
|
|
8024
|
+
{
|
|
8025
|
+
type: "text",
|
|
8026
|
+
placeholder: "Search...",
|
|
8027
|
+
value: searchQuery,
|
|
8028
|
+
onChange: handleInputChange,
|
|
8029
|
+
className: "w-full rounded-lg border border-slate-200 bg-white pl-10 pr-4 py-2 text-sm text-slate-900 placeholder-slate-400 focus:border-primary-500 focus:outline-none focus:ring-2 focus:ring-primary-500/20"
|
|
8030
|
+
}
|
|
8031
|
+
))), /* @__PURE__ */ React21.createElement("div", { className: "space-y-3" }, /* @__PURE__ */ React21.createElement(
|
|
7867
8032
|
"button",
|
|
7868
8033
|
{
|
|
7869
8034
|
type: "button",
|
|
7870
|
-
onClick:
|
|
7871
|
-
className: "text-sm font-
|
|
8035
|
+
onClick: () => toggleFilterSection("category"),
|
|
8036
|
+
className: "flex w-full items-center justify-between text-sm font-medium text-slate-600"
|
|
7872
8037
|
},
|
|
7873
|
-
"
|
|
7874
|
-
|
|
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"}`
|
|
8046
|
+
},
|
|
8047
|
+
/* @__PURE__ */ React21.createElement("div", { className: `flex h-6 w-6 items-center justify-center rounded ${!categoryFilter ? "bg-white/20" : "bg-slate-100"}` }, !categoryFilter ? /* @__PURE__ */ React21.createElement(Check, { className: "h-4 w-4 text-white" }) : /* @__PURE__ */ React21.createElement(ShoppingBag, { className: "h-4 w-4 text-slate-600" })),
|
|
8048
|
+
/* @__PURE__ */ React21.createElement("span", null, "All Products")
|
|
8049
|
+
), sortedCategories.map((category) => {
|
|
7875
8050
|
const isCategoryActive = categoryFilter === category.id;
|
|
7876
8051
|
const isExpanded = !!expandedCategories[category.id];
|
|
7877
|
-
|
|
7878
|
-
|
|
8052
|
+
const Icon = getCategoryIconForFilter(category.name ?? "");
|
|
8053
|
+
return /* @__PURE__ */ React21.createElement("div", { key: category.id, className: "space-y-1" }, /* @__PURE__ */ React21.createElement(
|
|
8054
|
+
"button",
|
|
7879
8055
|
{
|
|
7880
|
-
|
|
7881
|
-
tabIndex: 0,
|
|
8056
|
+
type: "button",
|
|
7882
8057
|
onClick: () => {
|
|
7883
8058
|
if (!isExpanded) toggleCategoryExpand(category.id ?? "");
|
|
7884
8059
|
handleCategoryChange(category.id ?? "");
|
|
7885
8060
|
},
|
|
7886
|
-
className: `flex w-full items-center
|
|
8061
|
+
className: `flex w-full items-center gap-3 rounded-lg px-3 py-2.5 text-sm font-medium transition ${isCategoryActive ? "bg-primary-600 text-white" : "bg-white text-slate-700 border border-slate-200 hover:border-primary-300"}`
|
|
7887
8062
|
},
|
|
7888
|
-
/* @__PURE__ */ React21.createElement("
|
|
7889
|
-
/* @__PURE__ */ React21.createElement(
|
|
8063
|
+
/* @__PURE__ */ React21.createElement("div", { className: `flex h-6 w-6 items-center justify-center rounded ${isCategoryActive ? "bg-white/20" : "bg-slate-100"}` }, /* @__PURE__ */ React21.createElement(Icon, { className: `h-4 w-4 ${isCategoryActive ? "text-white" : "text-slate-600"}` })),
|
|
8064
|
+
/* @__PURE__ */ React21.createElement("span", { className: "flex-1 text-left" }, category.name),
|
|
8065
|
+
Array.isArray(category.categorySubCategories) && category.categorySubCategories.length > 0 && /* @__PURE__ */ React21.createElement(
|
|
7890
8066
|
"button",
|
|
7891
8067
|
{
|
|
7892
8068
|
type: "button",
|
|
7893
8069
|
onClick: (e) => {
|
|
7894
|
-
e.preventDefault();
|
|
7895
8070
|
e.stopPropagation();
|
|
7896
8071
|
toggleCategoryExpand(category.id ?? "");
|
|
7897
8072
|
},
|
|
7898
|
-
className: "
|
|
7899
|
-
"aria-label": isExpanded ? "Collapse" : "Expand"
|
|
8073
|
+
className: "p-1"
|
|
7900
8074
|
},
|
|
7901
|
-
/* @__PURE__ */ React21.createElement(ChevronDown, { className: `h-4 w-4 transition-transform ${isExpanded ? "rotate-180 text-
|
|
8075
|
+
/* @__PURE__ */ React21.createElement(ChevronDown, { className: `h-4 w-4 transition-transform ${isExpanded ? "rotate-180" : ""} ${isCategoryActive ? "text-white" : "text-slate-400"}` })
|
|
7902
8076
|
)
|
|
7903
|
-
), isExpanded && Array.isArray(category.categorySubCategories) && category.categorySubCategories.length > 0 && /* @__PURE__ */ React21.createElement("div", { className: "
|
|
8077
|
+
), isExpanded && Array.isArray(category.categorySubCategories) && category.categorySubCategories.length > 0 && /* @__PURE__ */ React21.createElement("div", { className: "ml-9 space-y-1" }, category.categorySubCategories.map((sub) => {
|
|
7904
8078
|
const isSubActive = subCategoryFilter === sub.id;
|
|
7905
8079
|
return /* @__PURE__ */ React21.createElement(
|
|
7906
8080
|
"button",
|
|
@@ -7908,12 +8082,61 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7908
8082
|
key: sub.id,
|
|
7909
8083
|
type: "button",
|
|
7910
8084
|
onClick: () => handleSubCategoryChange(category.id ?? "", sub.id),
|
|
7911
|
-
className: `block w-full px-
|
|
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"}`
|
|
7912
8086
|
},
|
|
7913
8087
|
sub.name
|
|
7914
8088
|
);
|
|
7915
|
-
})))
|
|
7916
|
-
})))
|
|
8089
|
+
})));
|
|
8090
|
+
}))), /* @__PURE__ */ React21.createElement("div", { className: "space-y-3" }, /* @__PURE__ */ React21.createElement(
|
|
8091
|
+
"button",
|
|
8092
|
+
{
|
|
8093
|
+
type: "button",
|
|
8094
|
+
onClick: () => toggleFilterSection("brand"),
|
|
8095
|
+
className: "flex w-full items-center justify-between text-sm font-medium text-slate-600"
|
|
8096
|
+
},
|
|
8097
|
+
/* @__PURE__ */ React21.createElement("span", null, "Brand"),
|
|
8098
|
+
expandedFilterSections.brand ? /* @__PURE__ */ React21.createElement(ChevronUp, { className: "h-4 w-4" }) : /* @__PURE__ */ React21.createElement(ChevronDown, { className: "h-4 w-4" })
|
|
8099
|
+
), expandedFilterSections.brand && /* @__PURE__ */ React21.createElement("div", { className: "space-y-1.5 max-h-64 overflow-y-auto" }, availableBrands.length === 0 ? /* @__PURE__ */ React21.createElement("div", { className: "text-xs text-slate-500" }, "No brands available") : availableBrands.map((brand) => {
|
|
8100
|
+
const isSelected = brandFilter === brand;
|
|
8101
|
+
return /* @__PURE__ */ React21.createElement(
|
|
8102
|
+
"button",
|
|
8103
|
+
{
|
|
8104
|
+
key: brand,
|
|
8105
|
+
type: "button",
|
|
8106
|
+
onClick: () => handleBrandChange(brand),
|
|
8107
|
+
className: `flex w-full items-center justify-between rounded-md border px-2.5 py-1.5 text-xs font-medium transition ${isSelected ? "border-primary-500 bg-primary-50 text-primary-700" : "border-slate-200 bg-white text-slate-600 hover:border-primary-300"}`
|
|
8108
|
+
},
|
|
8109
|
+
/* @__PURE__ */ React21.createElement("span", { className: "truncate" }, brand),
|
|
8110
|
+
isSelected && /* @__PURE__ */ React21.createElement(Check, { className: "h-3 w-3 text-primary-600 flex-shrink-0 ml-2" })
|
|
8111
|
+
);
|
|
8112
|
+
}))), /* @__PURE__ */ React21.createElement("div", { className: "space-y-3" }, /* @__PURE__ */ React21.createElement(
|
|
8113
|
+
"button",
|
|
8114
|
+
{
|
|
8115
|
+
type: "button",
|
|
8116
|
+
onClick: () => toggleFilterSection("availability"),
|
|
8117
|
+
className: "flex w-full items-center justify-between text-sm font-medium text-slate-600"
|
|
8118
|
+
},
|
|
8119
|
+
/* @__PURE__ */ React21.createElement("span", null, "Availability"),
|
|
8120
|
+
expandedFilterSections.availability ? /* @__PURE__ */ React21.createElement(ChevronUp, { className: "h-4 w-4" }) : /* @__PURE__ */ React21.createElement(ChevronDown, { className: "h-4 w-4" })
|
|
8121
|
+
), expandedFilterSections.availability && /* @__PURE__ */ React21.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React21.createElement(
|
|
8122
|
+
"button",
|
|
8123
|
+
{
|
|
8124
|
+
type: "button",
|
|
8125
|
+
onClick: handleToggleStock,
|
|
8126
|
+
className: `flex w-full items-center justify-between rounded-lg border px-3 py-2.5 text-sm font-medium transition ${inStockOnly ? "border-primary-500 bg-primary-50 text-primary-700" : "border-slate-200 bg-white text-slate-600 hover:border-primary-300"}`
|
|
8127
|
+
},
|
|
8128
|
+
/* @__PURE__ */ React21.createElement("span", null, "In stock only"),
|
|
8129
|
+
inStockOnly && /* @__PURE__ */ React21.createElement(Check, { className: "h-4 w-4 text-primary-600" })
|
|
8130
|
+
))), /* @__PURE__ */ React21.createElement("div", { className: "space-y-3" }, /* @__PURE__ */ React21.createElement(
|
|
8131
|
+
"button",
|
|
8132
|
+
{
|
|
8133
|
+
type: "button",
|
|
8134
|
+
onClick: () => toggleFilterSection("price"),
|
|
8135
|
+
className: "flex w-full items-center justify-between text-sm font-medium text-slate-600"
|
|
8136
|
+
},
|
|
8137
|
+
/* @__PURE__ */ React21.createElement("span", null, "Price Range"),
|
|
8138
|
+
expandedFilterSections.price ? /* @__PURE__ */ React21.createElement(ChevronUp, { className: "h-4 w-4" }) : /* @__PURE__ */ React21.createElement(ChevronDown, { className: "h-4 w-4" })
|
|
8139
|
+
), expandedFilterSections.price && /* @__PURE__ */ React21.createElement("div", { className: "space-y-3" }, /* @__PURE__ */ React21.createElement("div", { className: "flex flex-wrap gap-2" }, priceRanges.map((range) => {
|
|
7917
8140
|
const isActive = selectedPriceRange === range.value;
|
|
7918
8141
|
return /* @__PURE__ */ React21.createElement(
|
|
7919
8142
|
"button",
|
|
@@ -7921,27 +8144,29 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7921
8144
|
type: "button",
|
|
7922
8145
|
key: range.value,
|
|
7923
8146
|
onClick: () => handlePriceRangeSelect(range.value),
|
|
7924
|
-
className: `rounded-
|
|
8147
|
+
className: `rounded-lg border px-3 py-1.5 text-sm font-medium transition ${isActive ? "border-primary-600 bg-primary-600 text-white" : "border-slate-200 bg-white text-slate-600 hover:border-primary-300"}`
|
|
7925
8148
|
},
|
|
7926
8149
|
range.label
|
|
7927
8150
|
);
|
|
7928
|
-
})), /* @__PURE__ */ React21.createElement("div", { className: "grid grid-cols-2 gap-
|
|
8151
|
+
})), /* @__PURE__ */ React21.createElement("div", { className: "grid grid-cols-2 gap-2" }, /* @__PURE__ */ React21.createElement(
|
|
7929
8152
|
Input,
|
|
7930
8153
|
{
|
|
7931
8154
|
type: "number",
|
|
7932
8155
|
min: "0",
|
|
7933
|
-
placeholder: "
|
|
8156
|
+
placeholder: "Min",
|
|
7934
8157
|
value: customPrice.min,
|
|
7935
|
-
onChange: (event) => setCustomPrice((current) => ({ ...current, min: event.target.value }))
|
|
8158
|
+
onChange: (event) => setCustomPrice((current) => ({ ...current, min: event.target.value })),
|
|
8159
|
+
className: "text-sm"
|
|
7936
8160
|
}
|
|
7937
8161
|
), /* @__PURE__ */ React21.createElement(
|
|
7938
8162
|
Input,
|
|
7939
8163
|
{
|
|
7940
8164
|
type: "number",
|
|
7941
8165
|
min: "0",
|
|
7942
|
-
placeholder: "
|
|
8166
|
+
placeholder: "Max",
|
|
7943
8167
|
value: customPrice.max,
|
|
7944
|
-
onChange: (event) => setCustomPrice((current) => ({ ...current, max: event.target.value }))
|
|
8168
|
+
onChange: (event) => setCustomPrice((current) => ({ ...current, max: event.target.value })),
|
|
8169
|
+
className: "text-sm"
|
|
7945
8170
|
}
|
|
7946
8171
|
)), /* @__PURE__ */ React21.createElement(
|
|
7947
8172
|
"button",
|
|
@@ -7949,118 +8174,91 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
7949
8174
|
type: "button",
|
|
7950
8175
|
onClick: applyCustomPrice,
|
|
7951
8176
|
disabled: !isCustomPriceDirty,
|
|
7952
|
-
className: "w-full rounded-
|
|
8177
|
+
className: "w-full rounded-lg border border-primary-500 bg-primary-500/10 px-4 py-2 text-sm font-medium text-primary-700 transition hover:bg-primary-500/20 disabled:cursor-not-allowed disabled:border-slate-200 disabled:text-slate-400"
|
|
7953
8178
|
},
|
|
7954
|
-
"Apply
|
|
7955
|
-
))
|
|
7956
|
-
|
|
7957
|
-
|
|
7958
|
-
|
|
7959
|
-
|
|
7960
|
-
|
|
7961
|
-
|
|
7962
|
-
|
|
7963
|
-
|
|
7964
|
-
|
|
7965
|
-
|
|
7966
|
-
|
|
7967
|
-
|
|
7968
|
-
onClick: handleToggleNewArrivals,
|
|
7969
|
-
className: `mt-2 flex w-full items-center justify-between rounded-xl border px-4 py-3 text-sm font-medium transition ${newArrivals ? "border-secondary-500 bg-secondary-50 text-secondary-700" : "border-gray-200 bg-white text-gray-600 hover:border-secondary-300 hover:text-secondary-600"}`
|
|
7970
|
-
},
|
|
7971
|
-
/* @__PURE__ */ React21.createElement("span", null, "New arrivals (last 30 days)"),
|
|
7972
|
-
/* @__PURE__ */ React21.createElement(Sparkles, { className: "h-4 w-4 text-secondary-500" })
|
|
7973
|
-
))));
|
|
7974
|
-
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" }, /* @__PURE__ */ React21.createElement(
|
|
7975
|
-
"div",
|
|
7976
|
-
{
|
|
7977
|
-
className: "absolute inset-0 bg-[radial-gradient(circle_at_top_left,_rgba(255,255,255,0.35),_transparent_60%)]",
|
|
7978
|
-
"aria-hidden": "true"
|
|
7979
|
-
}
|
|
7980
|
-
), /* @__PURE__ */ React21.createElement("div", { className: "absolute inset-0 bg-[radial-gradient(circle_at_bottom_right,_rgba(94,234,212,0.35),_transparent_55%)] opacity-60" }), /* @__PURE__ */ React21.createElement("div", { className: "relative container mx-auto px-4 py-24" }, /* @__PURE__ */ React21.createElement(
|
|
8179
|
+
"Apply"
|
|
8180
|
+
)))));
|
|
8181
|
+
const displayCategories = useMemo(() => {
|
|
8182
|
+
return topCategories.slice(0, 5);
|
|
8183
|
+
}, [topCategories]);
|
|
8184
|
+
const getCategoryIcon = (categoryName2) => {
|
|
8185
|
+
const name = categoryName2.toLowerCase();
|
|
8186
|
+
if (name.includes("scrub") || name.includes("uniform")) return Shirt;
|
|
8187
|
+
if (name.includes("vitamin") || name.includes("supplement")) return Pill;
|
|
8188
|
+
if (name.includes("medicine") || name.includes("medication")) return Box;
|
|
8189
|
+
if (name.includes("care") || name.includes("personal")) return Heart;
|
|
8190
|
+
return Package;
|
|
8191
|
+
};
|
|
8192
|
+
return /* @__PURE__ */ React21.createElement("div", { className: "min-h-screen bg-[#F9FAFB]" }, /* @__PURE__ */ React21.createElement("section", { className: "relative overflow-hidden bg-[#E6EBF0] py-16 md:py-24" }, /* @__PURE__ */ React21.createElement("div", { className: "container mx-auto px-4" }, /* @__PURE__ */ React21.createElement(
|
|
7981
8193
|
motion.div,
|
|
7982
8194
|
{
|
|
7983
8195
|
initial: { opacity: 0, y: 24 },
|
|
7984
8196
|
animate: { opacity: 1, y: 0 },
|
|
7985
|
-
className: "max-w-
|
|
8197
|
+
className: "max-w-4xl mx-auto space-y-6 text-center"
|
|
7986
8198
|
},
|
|
7987
|
-
/* @__PURE__ */ React21.createElement("
|
|
7988
|
-
/* @__PURE__ */ React21.createElement("h1", { className: "text-4xl font-bold leading-tight
|
|
7989
|
-
/* @__PURE__ */ React21.createElement("p", { className: "text-
|
|
8199
|
+
/* @__PURE__ */ React21.createElement("div", { className: "flex items-center justify-center gap-2 mb-4" }, /* @__PURE__ */ React21.createElement(Star, { className: "h-5 w-5 text-orange-500 fill-orange-500" }), /* @__PURE__ */ React21.createElement("span", { className: "text-sm font-semibold uppercase tracking-wider text-orange-500" }, "COMPLETE PHARMACY SHOP")),
|
|
8200
|
+
/* @__PURE__ */ React21.createElement("h1", { className: "text-3xl md:text-4xl font-bold text-slate-900 leading-tight" }, "Medical Supplies & Wellness Products"),
|
|
8201
|
+
/* @__PURE__ */ React21.createElement("p", { className: "text-base md:text-lg text-slate-600 max-w-2xl mx-auto" }, "From professional scrubs to vitamins, medicines to personal care - everything you need for health and wellness."),
|
|
7990
8202
|
/* @__PURE__ */ React21.createElement(
|
|
7991
8203
|
"form",
|
|
7992
8204
|
{
|
|
7993
8205
|
onSubmit: handleSearch,
|
|
7994
|
-
className: "
|
|
8206
|
+
className: "max-w-2xl mx-auto mt-8"
|
|
7995
8207
|
},
|
|
7996
|
-
/* @__PURE__ */ React21.createElement("div", { className: "relative w-full" }, /* @__PURE__ */ React21.createElement(
|
|
8208
|
+
/* @__PURE__ */ React21.createElement("div", { className: "relative w-full" }, /* @__PURE__ */ React21.createElement(Search, { className: "absolute left-5 top-1/2 -translate-y-1/2 h-5 w-5 text-slate-400 pointer-events-none" }), /* @__PURE__ */ React21.createElement(
|
|
7997
8209
|
"input",
|
|
7998
8210
|
{
|
|
7999
8211
|
type: "search",
|
|
8000
|
-
placeholder: "Search for products,
|
|
8212
|
+
placeholder: "Search for products, brands, or categories...",
|
|
8001
8213
|
value: searchQuery,
|
|
8002
8214
|
onChange: handleInputChange,
|
|
8003
8215
|
onKeyDown: handleKeyDown,
|
|
8004
|
-
className: "flex h-
|
|
8216
|
+
className: "flex h-16 w-full rounded-full border-0 bg-white px-5 pl-14 pr-5 text-base text-slate-900 placeholder-slate-400 shadow-lg focus:outline-none focus:ring-2 focus:ring-primary-500/30 disabled:opacity-50",
|
|
8005
8217
|
disabled: isSearching
|
|
8006
8218
|
}
|
|
8007
|
-
), /* @__PURE__ */ React21.createElement(
|
|
8008
|
-
"button",
|
|
8009
|
-
{
|
|
8010
|
-
type: "submit",
|
|
8011
|
-
className: "absolute right-2 top-1/2 -translate-y-1/2 rounded-xl bg-white/20 p-3 text-white transition hover:bg-white/30 disabled:opacity-50",
|
|
8012
|
-
disabled: !searchQuery.trim() || isSearching
|
|
8013
|
-
},
|
|
8014
|
-
isSearching ? /* @__PURE__ */ React21.createElement("div", { className: "h-5 w-5 animate-spin rounded-full border-2 border-white border-t-transparent" }) : /* @__PURE__ */ React21.createElement(Search, { className: "h-5 w-5" })
|
|
8015
8219
|
))
|
|
8016
8220
|
)
|
|
8017
|
-
), /* @__PURE__ */ React21.createElement(
|
|
8018
|
-
|
|
8019
|
-
{
|
|
8020
|
-
|
|
8021
|
-
animate: { opacity: 1, y: 0 },
|
|
8022
|
-
transition: { delay: 0.15 },
|
|
8023
|
-
className: "mt-12 flex flex-col gap-6 rounded-3xl border border-white/20 bg-white/10 p-6 backdrop-blur md:flex-row md:items-center md:justify-between"
|
|
8024
|
-
},
|
|
8025
|
-
/* @__PURE__ */ React21.createElement("div", { className: "space-y-3" }, /* @__PURE__ */ React21.createElement("p", { className: "text-sm font-semibold uppercase tracking-[0.3em] text-white/60" }, "Explore popular searches"), /* @__PURE__ */ React21.createElement("div", { className: "flex flex-wrap gap-2" }, quickSearches.map((term) => /* @__PURE__ */ React21.createElement(
|
|
8026
|
-
"button",
|
|
8027
|
-
{
|
|
8028
|
-
key: term,
|
|
8029
|
-
type: "button",
|
|
8030
|
-
onClick: () => handleQuickSearch(term),
|
|
8031
|
-
className: "rounded-full border border-white/30 bg-white/10 px-4 py-2 text-sm font-medium text-white transition hover:border-white/50 hover:bg-white/20"
|
|
8032
|
-
},
|
|
8033
|
-
term
|
|
8034
|
-
)))),
|
|
8035
|
-
topCategories.length > 0 && /* @__PURE__ */ React21.createElement("div", { className: "space-y-3 md:text-right" }, /* @__PURE__ */ React21.createElement("p", { className: "text-sm font-semibold uppercase tracking-[0.3em] text-white/60" }, "Trending categories"), /* @__PURE__ */ React21.createElement("div", { className: "flex flex-wrap justify-start gap-2 md:justify-end" }, topCategories.map((category) => /* @__PURE__ */ React21.createElement(
|
|
8036
|
-
"button",
|
|
8221
|
+
))), /* @__PURE__ */ React21.createElement("section", { className: "bg-white py-8 " }, /* @__PURE__ */ React21.createElement("div", { className: "container mx-auto px-4" }, /* @__PURE__ */ React21.createElement("h2", { className: "text-2xl md:text-3xl font-bold text-slate-900 mb-8" }, "Shop by Category"), /* @__PURE__ */ React21.createElement("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-5 gap-6" }, isLoadingCategories ? (
|
|
8222
|
+
// Skeleton loaders
|
|
8223
|
+
/* @__PURE__ */ React21.createElement(React21.Fragment, null, Array.from({ length: 6 }).map((_, index) => /* @__PURE__ */ React21.createElement(
|
|
8224
|
+
"div",
|
|
8037
8225
|
{
|
|
8038
|
-
key:
|
|
8039
|
-
|
|
8040
|
-
onClick: () => handleCategoryChange(category.id ?? ""),
|
|
8041
|
-
className: "rounded-full bg-white/15 px-3 py-1.5 text-sm font-medium text-white transition hover:bg-white/25"
|
|
8226
|
+
key: index,
|
|
8227
|
+
className: "rounded-xl border border-slate-200 bg-white p-8"
|
|
8042
8228
|
},
|
|
8043
|
-
|
|
8044
|
-
|
|
8045
|
-
|
|
8046
|
-
|
|
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) => {
|
|
8245
|
+
const Icon = getCategoryIcon(category.name ?? "");
|
|
8246
|
+
const isSelected = categoryFilter === category.id;
|
|
8047
8247
|
return /* @__PURE__ */ React21.createElement(
|
|
8048
|
-
motion.
|
|
8248
|
+
motion.button,
|
|
8049
8249
|
{
|
|
8050
|
-
key:
|
|
8250
|
+
key: category.id,
|
|
8051
8251
|
initial: { opacity: 0, y: 20 },
|
|
8052
8252
|
animate: { opacity: 1, y: 0 },
|
|
8053
|
-
transition: { delay:
|
|
8054
|
-
|
|
8055
|
-
|
|
8056
|
-
role: card.id === "new" ? "button" : void 0,
|
|
8057
|
-
"aria-pressed": card.id === "new" ? newArrivals ? "true" : "false" : void 0,
|
|
8058
|
-
title: card.id === "new" ? newArrivals ? "Filter active: showing products from the last 30 days" : "Click to filter products from the last 30 days" : void 0
|
|
8253
|
+
transition: { delay: index * 0.1 },
|
|
8254
|
+
onClick: () => handleCategoryChange(category.id ?? ""),
|
|
8255
|
+
className: `group rounded-xl p-8 text-left transition ${isSelected ? "bg-gradient-to-b from-primary-500 to-primary-300 text-white shadow-lg" : "border border-slate-200 bg-white hover:border-primary-300 hover:shadow-md"}`
|
|
8059
8256
|
},
|
|
8060
|
-
/* @__PURE__ */ React21.createElement(
|
|
8061
|
-
/* @__PURE__ */ React21.createElement("
|
|
8257
|
+
/* @__PURE__ */ React21.createElement(Icon, { className: `h-10 w-10 mb-4 ${isSelected ? "text-white" : "text-primary-500"}` }),
|
|
8258
|
+
/* @__PURE__ */ React21.createElement("h3", { className: `text-xl font-bold mb-2 transition-colors ${isSelected ? "text-white" : "text-slate-900 group-hover:text-primary-600"}` }, category.name),
|
|
8259
|
+
/* @__PURE__ */ React21.createElement("p", { className: `text-sm ${isSelected ? "text-white/90" : "text-slate-500"}` }, category.name?.toLowerCase().includes("scrub") ? "Professional uniforms" : category.name?.toLowerCase().includes("vitamin") ? "Health supplements" : category.name?.toLowerCase().includes("medicine") ? "OTC medications" : category.name?.toLowerCase().includes("care") ? "Daily essentials" : "Shop now")
|
|
8062
8260
|
);
|
|
8063
|
-
})))), /* @__PURE__ */ React21.createElement("div", { className: "relative z-10
|
|
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(
|
|
8064
8262
|
"select",
|
|
8065
8263
|
{
|
|
8066
8264
|
value: sortOption,
|
|
@@ -8121,7 +8319,7 @@ function ShopScreen({ initialFilters = {}, categoryName }) {
|
|
|
8121
8319
|
className: "text-sm font-semibold text-gray-500 hover:text-gray-700"
|
|
8122
8320
|
},
|
|
8123
8321
|
"Reset all"
|
|
8124
|
-
))), /* @__PURE__ */ React21.createElement("div",
|
|
8322
|
+
))), /* @__PURE__ */ React21.createElement("div", null, /* @__PURE__ */ React21.createElement("div", { className: "mt-6" }, isLoading ? /* @__PURE__ */ React21.createElement("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5" }, Array.from({ length: 6 }).map((_, index) => /* @__PURE__ */ React21.createElement(ProductCardSkeleton, { key: index }))) : displayedProducts.length > 0 ? viewMode === "grid" ? /* @__PURE__ */ React21.createElement("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5" }, displayedProducts.map((product) => /* @__PURE__ */ React21.createElement("div", { key: product.id, className: "h-full" }, /* @__PURE__ */ React21.createElement(
|
|
8125
8323
|
ProductCard,
|
|
8126
8324
|
{
|
|
8127
8325
|
product,
|
|
@@ -8293,6 +8491,16 @@ function ProductDetailScreen({ productId }) {
|
|
|
8293
8491
|
url: media.file
|
|
8294
8492
|
}));
|
|
8295
8493
|
}
|
|
8494
|
+
if (product?.productMedia?.length) {
|
|
8495
|
+
return product.productMedia.map((media) => ({
|
|
8496
|
+
src: media.file,
|
|
8497
|
+
width: 800,
|
|
8498
|
+
height: 1e3,
|
|
8499
|
+
alt: product?.name || "Product image",
|
|
8500
|
+
...media,
|
|
8501
|
+
url: media.file
|
|
8502
|
+
}));
|
|
8503
|
+
}
|
|
8296
8504
|
if (product?.images?.length) {
|
|
8297
8505
|
return product.images.map((image) => ({
|
|
8298
8506
|
src: image,
|
|
@@ -8355,6 +8563,7 @@ function ProductDetailScreen({ productId }) {
|
|
|
8355
8563
|
}, [product?.id]);
|
|
8356
8564
|
const handleVariantSelect = async (variant) => {
|
|
8357
8565
|
setSelectedVariant(variant);
|
|
8566
|
+
setActiveImageIndex(0);
|
|
8358
8567
|
};
|
|
8359
8568
|
const handleAddToCart = async () => {
|
|
8360
8569
|
if (!product || !selectedVariant) return;
|
|
@@ -8403,76 +8612,45 @@ function ProductDetailScreen({ productId }) {
|
|
|
8403
8612
|
if (!product) {
|
|
8404
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(Link8, { href: "/shop", className: "inline-block" }, /* @__PURE__ */ React21.createElement(Button, null, "Browse products"))))));
|
|
8405
8614
|
}
|
|
8406
|
-
|
|
8407
|
-
const highlightCards = [
|
|
8408
|
-
{
|
|
8409
|
-
icon: ShieldCheck,
|
|
8410
|
-
title: "Pharmacy grade assurance",
|
|
8411
|
-
description: "Sourced from trusted suppliers and reviewed by licensed professionals."
|
|
8412
|
-
},
|
|
8413
|
-
{
|
|
8414
|
-
icon: Truck,
|
|
8415
|
-
title: "Fast, cold-chain ready shipping",
|
|
8416
|
-
description: "Carefully packed and dispatched within 24 hours on business days."
|
|
8417
|
-
},
|
|
8418
|
-
{
|
|
8419
|
-
icon: Award,
|
|
8420
|
-
title: "Loved by patients",
|
|
8421
|
-
description: "Average rating 4.8/5 with over 120 verified customer experiences."
|
|
8422
|
-
}
|
|
8423
|
-
];
|
|
8424
|
-
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(
|
|
8425
|
-
"div",
|
|
8426
|
-
{
|
|
8427
|
-
className: "absolute inset-0 bg-[radial-gradient(circle_at_top_left,_rgba(255,255,255,0.35),_transparent_60%)]",
|
|
8428
|
-
"aria-hidden": "true"
|
|
8429
|
-
}
|
|
8430
|
-
), /* @__PURE__ */ React21.createElement("div", { className: "absolute inset-0 bg-[radial-gradient(circle_at_bottom_right,_rgba(255,255,255,0.25),_transparent_55%)] opacity-70" }), /* @__PURE__ */ React21.createElement("div", { className: "relative container mx-auto px-4 py-16" }, /* @__PURE__ */ React21.createElement("div", { className: "flex flex-col gap-6" }, /* @__PURE__ */ React21.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React21.createElement(
|
|
8615
|
+
return /* @__PURE__ */ React21.createElement("div", { className: "bg-white" }, /* @__PURE__ */ React21.createElement("div", { className: "min-h-screen bg-white max-w-7xl mx-auto" }, /* @__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: "mb-6" }, /* @__PURE__ */ React21.createElement(
|
|
8431
8616
|
Button,
|
|
8432
8617
|
{
|
|
8433
8618
|
variant: "ghost",
|
|
8434
|
-
className: "text-
|
|
8619
|
+
className: "text-slate-600 hover:text-slate-900 hover:bg-slate-100",
|
|
8435
8620
|
onClick: () => router.push(buildPath("/shop"))
|
|
8436
8621
|
},
|
|
8437
|
-
/* @__PURE__ */ React21.createElement(ArrowLeft, { className: "h-
|
|
8438
|
-
"
|
|
8439
|
-
), /* @__PURE__ */ React21.createElement("div", { className: "
|
|
8622
|
+
/* @__PURE__ */ React21.createElement(ArrowLeft, { className: "h-4 w-4 mr-2" }),
|
|
8623
|
+
"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(
|
|
8440
8625
|
motion.div,
|
|
8441
8626
|
{
|
|
8442
|
-
|
|
8443
|
-
animate: { opacity: 1, y: 0 },
|
|
8444
|
-
className: "max-w-3xl space-y-4"
|
|
8445
|
-
},
|
|
8446
|
-
product.category && /* @__PURE__ */ React21.createElement(
|
|
8447
|
-
Badge,
|
|
8448
|
-
{
|
|
8449
|
-
variant: "secondary",
|
|
8450
|
-
className: "bg-white/15 text-white backdrop-blur-sm"
|
|
8451
|
-
},
|
|
8452
|
-
product.category
|
|
8453
|
-
),
|
|
8454
|
-
/* @__PURE__ */ React21.createElement("h1", { className: "text-4xl font-bold leading-tight md:text-5xl" }, product.name),
|
|
8455
|
-
/* @__PURE__ */ React21.createElement("div", { className: "flex flex-wrap items-center gap-3 text-sm text-white/80" }, /* @__PURE__ */ React21.createElement("span", { className: "inline-flex items-center gap-2 rounded-full bg-white/10 px-3 py-1 font-medium text-white" }, /* @__PURE__ */ React21.createElement(Sparkles, { className: "h-4 w-4" }), "Ready to ship today"), /* @__PURE__ */ React21.createElement("span", { className: "inline-flex items-center gap-2 rounded-full bg-white/10 px-3 py-1 font-medium text-white" }, /* @__PURE__ */ React21.createElement(Shield, { className: "h-4 w-4" }), "30-day happiness guarantee"))
|
|
8456
|
-
)))), /* @__PURE__ */ React21.createElement("div", { className: "relative -mt-16 pb-20" }, /* @__PURE__ */ React21.createElement("div", { className: "container mx-auto px-4" }, /* @__PURE__ */ React21.createElement("div", { className: "grid gap-10 lg:grid-cols-[minmax(0,2fr)_minmax(0,1fr)]" }, /* @__PURE__ */ React21.createElement("div", { className: "space-y-10" }, /* @__PURE__ */ React21.createElement("section", { className: "rounded-3xl border border-white bg-white/70 p-6 shadow-xl shadow-primary-100/40 backdrop-blur" }, /* @__PURE__ */ React21.createElement("div", { className: "grid gap-6 lg:grid-cols-[minmax(0,1fr)_220px]" }, /* @__PURE__ */ React21.createElement(
|
|
8457
|
-
motion.div,
|
|
8458
|
-
{
|
|
8459
|
-
key: variantImages[activeImageIndex],
|
|
8627
|
+
key: selectedVariant?.id || "default",
|
|
8460
8628
|
initial: { opacity: 0.4, scale: 0.98 },
|
|
8461
8629
|
animate: { opacity: 1, scale: 1 },
|
|
8462
8630
|
transition: { duration: 0.35 },
|
|
8463
8631
|
className: "relative overflow-hidden rounded-3xl bg-slate-100 h-[420px] md:h-[560px]"
|
|
8464
8632
|
},
|
|
8465
|
-
/* @__PURE__ */ React21.createElement(
|
|
8633
|
+
variantImages.length > 0 && variantImages[activeImageIndex] ? /* @__PURE__ */ React21.createElement(
|
|
8466
8634
|
Image3,
|
|
8467
8635
|
{
|
|
8468
|
-
src: variantImages[activeImageIndex],
|
|
8636
|
+
src: variantImages[activeImageIndex].src || variantImages[activeImageIndex].url || variantImages[activeImageIndex].file,
|
|
8469
8637
|
alt: currentVariant.name || product.name,
|
|
8470
8638
|
fill: true,
|
|
8471
8639
|
priority: true,
|
|
8472
8640
|
sizes: "(max-width: 1024px) 100vw, 800px",
|
|
8473
8641
|
className: "object-contain"
|
|
8474
8642
|
}
|
|
8475
|
-
)
|
|
8643
|
+
) : product?.productMedia?.[0]?.file ? /* @__PURE__ */ React21.createElement(
|
|
8644
|
+
Image3,
|
|
8645
|
+
{
|
|
8646
|
+
src: product.productMedia[0].file,
|
|
8647
|
+
alt: product.name,
|
|
8648
|
+
fill: true,
|
|
8649
|
+
priority: true,
|
|
8650
|
+
sizes: "(max-width: 1024px) 100vw, 800px",
|
|
8651
|
+
className: "object-contain"
|
|
8652
|
+
}
|
|
8653
|
+
) : null,
|
|
8476
8654
|
discount > 0 && /* @__PURE__ */ React21.createElement(
|
|
8477
8655
|
Badge,
|
|
8478
8656
|
{
|
|
@@ -8491,90 +8669,106 @@ function ProductDetailScreen({ productId }) {
|
|
|
8491
8669
|
},
|
|
8492
8670
|
"Out of Stock"
|
|
8493
8671
|
)
|
|
8494
|
-
),
|
|
8495
|
-
"button",
|
|
8496
|
-
{
|
|
8497
|
-
key: variant.id,
|
|
8498
|
-
type: "button",
|
|
8499
|
-
onClick: () => handleVariantSelect(variant),
|
|
8500
|
-
className: `rounded-full px-4 py-2 text-sm font-medium transition ${selectedVariant?.id === variant.id ? "bg-primary-600 text-white" : "bg-slate-100 text-slate-700 hover:bg-slate-200"}`
|
|
8501
|
-
},
|
|
8502
|
-
variant.name
|
|
8503
|
-
)))), /* @__PURE__ */ React21.createElement("div", { className: "grid grid-cols-3 gap-3" }, variantImages.map((image, index) => /* @__PURE__ */ React21.createElement(
|
|
8672
|
+
), variantImages.length > 0 && /* @__PURE__ */ React21.createElement("div", { className: "grid grid-cols-8 gap-2" }, variantImages.map((image, index) => /* @__PURE__ */ React21.createElement(
|
|
8504
8673
|
"button",
|
|
8505
8674
|
{
|
|
8506
8675
|
key: image.src + index,
|
|
8507
8676
|
type: "button",
|
|
8508
8677
|
onClick: () => setActiveImageIndex(index),
|
|
8509
|
-
className: `relative aspect-square overflow-hidden rounded-
|
|
8678
|
+
className: `relative aspect-square overflow-hidden rounded-lg border-2 transition-all ${activeImageIndex === index ? "border-primary-500 ring-2 ring-primary-200 ring-offset-2 shadow-md" : "border-slate-200 hover:border-primary-300"}`
|
|
8510
8679
|
},
|
|
8511
8680
|
/* @__PURE__ */ React21.createElement(
|
|
8512
8681
|
Image3,
|
|
8513
8682
|
{
|
|
8514
|
-
src: image
|
|
8683
|
+
src: image?.src,
|
|
8515
8684
|
alt: image.alt || `Product image ${index + 1}`,
|
|
8516
8685
|
className: "h-full w-full object-cover object-center",
|
|
8517
|
-
width:
|
|
8518
|
-
height:
|
|
8686
|
+
width: 80,
|
|
8687
|
+
height: 80,
|
|
8519
8688
|
unoptimized: true
|
|
8520
8689
|
}
|
|
8521
8690
|
)
|
|
8522
|
-
)))))), /* @__PURE__ */ React21.createElement("
|
|
8523
|
-
const
|
|
8691
|
+
)))))), /* @__PURE__ */ React21.createElement("aside", { className: "space-y-6 lg:sticky lg:top-24" }, /* @__PURE__ */ React21.createElement("div", { className: "" }, product.parentCategories && product.parentCategories.length > 0 && /* @__PURE__ */ React21.createElement("div", { className: "mb-4 text-sm text-slate-600" }, product.parentCategories.map((cat, index) => /* @__PURE__ */ React21.createElement("span", { key: cat.id || index }, cat.name, index < product.parentCategories.length - 1 && " \u2022 ")), product.parentSubCategories && product.parentSubCategories.length > 0 && /* @__PURE__ */ React21.createElement(React21.Fragment, null, " \u2022 ", product.parentSubCategories.map((subCat, index) => /* @__PURE__ */ React21.createElement("span", { key: subCat.id || index }, subCat.name, index < product.parentSubCategories.length - 1 && " \u2022 ")))), /* @__PURE__ */ React21.createElement("h1", { className: "text-2xl font-bold text-slate-900 mb-6" }, product.name), product?.productVariants && product.productVariants.length > 0 && /* @__PURE__ */ React21.createElement("div", { className: "mb-6" }, /* @__PURE__ */ React21.createElement("label", { className: "block text-sm font-medium text-slate-700 mb-3" }, "Select Variant"), /* @__PURE__ */ React21.createElement("div", { className: "space-y-3" }, product.productVariants.map((variant) => {
|
|
8692
|
+
const isSelected = selectedVariant?.id === variant.id;
|
|
8693
|
+
const variantImage = variant.productMedia?.[0]?.file || product.productMedia?.[0]?.file || product.images?.[0] || "/placeholder-product.jpg";
|
|
8524
8694
|
return /* @__PURE__ */ React21.createElement(
|
|
8525
|
-
"
|
|
8695
|
+
"button",
|
|
8526
8696
|
{
|
|
8527
|
-
key:
|
|
8528
|
-
|
|
8697
|
+
key: variant.id,
|
|
8698
|
+
type: "button",
|
|
8699
|
+
onClick: () => handleVariantSelect(variant),
|
|
8700
|
+
className: `flex w-full items-center gap-3 rounded-lg border-2 px-4 py-3 text-left transition ${isSelected ? "border-primary-500 bg-primary-50" : "border-slate-200 bg-white hover:border-primary-300"}`
|
|
8529
8701
|
},
|
|
8530
|
-
/* @__PURE__ */ React21.createElement("div", { className:
|
|
8531
|
-
|
|
8702
|
+
/* @__PURE__ */ React21.createElement("div", { className: `relative h-12 w-12 flex-shrink-0 overflow-hidden rounded-full border-2 ${isSelected ? "border-primary-500" : "border-slate-200"}` }, /* @__PURE__ */ React21.createElement(
|
|
8703
|
+
Image3,
|
|
8704
|
+
{
|
|
8705
|
+
src: variantImage,
|
|
8706
|
+
alt: variant.name || "Variant image",
|
|
8707
|
+
fill: true,
|
|
8708
|
+
className: "object-cover",
|
|
8709
|
+
sizes: "48px"
|
|
8710
|
+
}
|
|
8711
|
+
)),
|
|
8712
|
+
/* @__PURE__ */ React21.createElement("div", { className: "flex-1" }, /* @__PURE__ */ React21.createElement("p", { className: `text-sm font-medium ${isSelected ? "text-primary-700" : "text-slate-900"}` }, variant.name), variant.sku && /* @__PURE__ */ React21.createElement("p", { className: "text-xs text-slate-500 mt-0.5" }, "SKU: ", variant.sku)),
|
|
8713
|
+
isSelected && /* @__PURE__ */ React21.createElement(Check, { className: "h-5 w-5 text-primary-600 flex-shrink-0" })
|
|
8532
8714
|
);
|
|
8533
|
-
}))
|
|
8715
|
+
}))), /* @__PURE__ */ React21.createElement("div", { className: "flex items-baseline gap-3 mb-6" }, /* @__PURE__ */ React21.createElement("p", { className: "text-3xl font-bold text-orange-600" }, selectedVariant ? formatPrice(selectedVariant.finalPrice) : formatPrice(product.finalPrice || product.price || 0)), variantComparePrice && variantComparePrice > variantPrice && /* @__PURE__ */ React21.createElement("p", { className: "text-base text-slate-400 line-through" }, formatPrice(variantComparePrice)), discount > 0 && /* @__PURE__ */ React21.createElement(Badge, { variant: "danger", size: "sm" }, "-", discount, "%")), selectedVariant && /* @__PURE__ */ React21.createElement("div", { className: "mb-4 text-sm" }, selectedVariant.inventoryStatus === "OUT_OF_STOCK" /* OUTOFSTOCK */ || selectedVariant.inventoryStatus === "LOW_STOCK" /* LOWSTOCK */ ? /* @__PURE__ */ React21.createElement("div", { className: "text-red-600 font-medium" }, "Out of Stock") : /* @__PURE__ */ React21.createElement("div", { className: "text-orange-600 font-medium" }, "Only ", selectedVariant.inventoryCount || product.inventoryCount || 0, " left in stock - Order soon!")), variantSku !== "N/A" && /* @__PURE__ */ React21.createElement("div", { className: "mb-4 text-sm text-slate-600" }, /* @__PURE__ */ React21.createElement("span", { className: "font-medium" }, "SKU:"), " ", variantSku), product.description && /* @__PURE__ */ React21.createElement("p", { className: "mb-6 text-sm text-slate-600" }, product.description.replace(/<[^>]*>/g, "").substring(0, 150), product.description.length > 150 && "..."), /* @__PURE__ */ React21.createElement("div", { className: "mb-6" }, /* @__PURE__ */ React21.createElement("label", { className: "block text-sm font-medium text-slate-700 mb-2" }, "Quantity"), /* @__PURE__ */ React21.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ React21.createElement("div", { className: "flex items-center rounded-lg border border-slate-200 bg-white" }, /* @__PURE__ */ React21.createElement(
|
|
8534
8716
|
"button",
|
|
8535
8717
|
{
|
|
8536
8718
|
type: "button",
|
|
8537
8719
|
onClick: () => setQuantity((current) => Math.max(1, current - 1)),
|
|
8538
|
-
className: "
|
|
8720
|
+
className: "px-3 py-2 hover:bg-slate-50",
|
|
8539
8721
|
"aria-label": "Decrease quantity"
|
|
8540
8722
|
},
|
|
8541
|
-
/* @__PURE__ */ React21.createElement(Minus, { className: "h-4 w-4" })
|
|
8542
|
-
), /* @__PURE__ */ React21.createElement("span", { className: "w-12 text-center text-sm font-semibold text-slate-
|
|
8723
|
+
/* @__PURE__ */ React21.createElement(Minus, { className: "h-4 w-4 text-slate-600" })
|
|
8724
|
+
), /* @__PURE__ */ React21.createElement("span", { className: "w-12 text-center text-sm font-semibold text-slate-900" }, quantity), /* @__PURE__ */ React21.createElement(
|
|
8543
8725
|
"button",
|
|
8544
8726
|
{
|
|
8545
8727
|
type: "button",
|
|
8546
|
-
onClick: () => setQuantity((current) =>
|
|
8547
|
-
|
|
8728
|
+
onClick: () => setQuantity((current) => {
|
|
8729
|
+
const maxQty = selectedVariant?.inventoryCount || product.inventoryCount || 999;
|
|
8730
|
+
return Math.min(maxQty, current + 1);
|
|
8731
|
+
}),
|
|
8732
|
+
className: "px-3 py-2 hover:bg-slate-50",
|
|
8548
8733
|
"aria-label": "Increase quantity"
|
|
8549
8734
|
},
|
|
8550
|
-
/* @__PURE__ */ React21.createElement(Plus, { className: "h-4 w-4" })
|
|
8551
|
-
))
|
|
8735
|
+
/* @__PURE__ */ React21.createElement(Plus, { className: "h-4 w-4 text-slate-600" })
|
|
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-4" }, /* @__PURE__ */ React21.createElement(
|
|
8552
8737
|
Button,
|
|
8553
8738
|
{
|
|
8554
|
-
size: "
|
|
8555
|
-
className: "w-full",
|
|
8739
|
+
size: "md",
|
|
8740
|
+
className: "w-full bg-orange-500 hover:bg-orange-600 text-white py-2.5",
|
|
8556
8741
|
onClick: handleAddToCart,
|
|
8557
8742
|
isLoading: isAddingToCart,
|
|
8558
8743
|
disabled: !selectedVariant || selectedVariant.inventoryStatus === "OUT_OF_STOCK" /* OUTOFSTOCK */
|
|
8559
8744
|
},
|
|
8560
|
-
/* @__PURE__ */ React21.createElement(ShoppingCart, { className: "h-
|
|
8561
|
-
!selectedVariant ? "Select a variant" : selectedVariant.inventoryStatus === "OUT_OF_STOCK" /* OUTOFSTOCK */ ? "Out of Stock" :
|
|
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"
|
|
8562
8747
|
), /* @__PURE__ */ React21.createElement(
|
|
8563
8748
|
Button,
|
|
8564
8749
|
{
|
|
8565
|
-
size: "
|
|
8750
|
+
size: "md",
|
|
8566
8751
|
variant: "outline",
|
|
8567
|
-
className: "w-full",
|
|
8752
|
+
className: "w-full py-2.5",
|
|
8568
8753
|
onClick: handleToggleFavorite
|
|
8569
8754
|
},
|
|
8570
8755
|
/* @__PURE__ */ React21.createElement(
|
|
8571
8756
|
Heart,
|
|
8572
8757
|
{
|
|
8573
|
-
className: `h-
|
|
8758
|
+
className: `h-4 w-4 mr-2 ${isFavorited ? "fill-red-500 text-red-500" : "text-slate-500"}`
|
|
8574
8759
|
}
|
|
8575
8760
|
),
|
|
8576
8761
|
isFavorited ? "Saved" : "Save for later"
|
|
8577
|
-
))), /* @__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.25em]" }, "Need advice?"), /* @__PURE__ */ React21.createElement("p", { className: "mt-2 leading-relaxed" }, "Chat with a pharmacist in real time before completing your purchase. We will help you choose supporting supplements and answer dosing questions.")))), relatedProducts.length > 0 && /* @__PURE__ */ React21.createElement("section", { className: "mt-20" }, /* @__PURE__ */ React21.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React21.createElement("div", null, /* @__PURE__ */ React21.createElement("h2", { className: "text-2xl font-semibold text-slate-900" }, "You may also like"), /* @__PURE__ */ React21.createElement("p", { className: "mt-1 text-sm text-slate-500" }, "Hand-picked recommendations that pair nicely with this product.")), /* @__PURE__ */ React21.createElement(Link8, { href: "/shop", className: "hidden md:inline-flex" }, /* @__PURE__ */ React21.createElement(Button, { variant: "ghost", className: "text-primary-600" }, "View all products"))), /* @__PURE__ */ React21.createElement("div", { className: "mt-6 grid gap-
|
|
8762
|
+
))), /* @__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.25em]" }, "Need advice?"), /* @__PURE__ */ React21.createElement("p", { className: "mt-2 leading-relaxed" }, "Chat with a pharmacist in real time before completing your purchase. We will help you choose supporting supplements and answer dosing questions.")))), /* @__PURE__ */ React21.createElement("section", { className: "mt-10" }, /* @__PURE__ */ React21.createElement("div", { className: "rounded-3xl border border-slate-100 bg-white p-8 shadow-sm" }, /* @__PURE__ */ React21.createElement("div", { className: "flex flex-wrap items-center gap-4 pb-6" }, /* @__PURE__ */ React21.createElement("div", { className: "flex items-center gap-1 text-amber-500" }, Array.from({ length: 5 }).map((_, index) => /* @__PURE__ */ React21.createElement(Star, { key: index, className: "h-4 w-4 fill-current" }))), /* @__PURE__ */ React21.createElement("span", { className: "text-sm font-medium text-slate-500" }, "Rated 4.8 \u2022 Patients love the results")), /* @__PURE__ */ React21.createElement("div", { className: "space-y-8" }, product.description && /* @__PURE__ */ React21.createElement("div", { className: "space-y-3" }, /* @__PURE__ */ React21.createElement("h3", { className: "text-lg font-semibold text-slate-900" }, "Description"), /* @__PURE__ */ React21.createElement("p", { className: "text-base leading-relaxed text-slate-600", dangerouslySetInnerHTML: { __html: product.description } }))))), /* @__PURE__ */ React21.createElement("div", { className: "rounded-2xl border border-slate-200 bg-slate-50/60 p-5 mt-10" }, /* @__PURE__ */ React21.createElement("p", { className: "text- font-semibold uppercase tracking-[0.3em] text-slate-500" }, "Product details"), /* @__PURE__ */ React21.createElement("div", { className: "mt-3 space-y-2 text-sm text-slate-600" }, /* @__PURE__ */ React21.createElement("p", null, /* @__PURE__ */ React21.createElement("span", { className: "font-medium text-slate-700" }, "Variant:"), " ", currentVariant.name), /* @__PURE__ */ React21.createElement("p", null, /* @__PURE__ */ React21.createElement("span", { className: "font-medium text-slate-700" }, "SKU:"), " ", variantSku), /* @__PURE__ */ React21.createElement("p", null, /* @__PURE__ */ React21.createElement("span", { className: "font-medium text-slate-700" }, "Status:"), " ", /* @__PURE__ */ React21.createElement("span", { className: variantInStock ? "text-green-600" : "text-amber-600" }, variantInStock ? "In Stock" : "Out of Stock")), /* @__PURE__ */ React21.createElement("p", null, /* @__PURE__ */ React21.createElement("span", { className: "font-medium text-slate-700" }, "Last updated:"), " ", lastUpdatedLabel), /* @__PURE__ */ React21.createElement("p", null, /* @__PURE__ */ React21.createElement("span", { className: "font-medium text-slate-700" }, "Ships from:"), " Local pharmacy distribution center"))), relatedProducts.length > 0 && /* @__PURE__ */ React21.createElement("section", { className: "mt-20" }, /* @__PURE__ */ React21.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React21.createElement("div", null, /* @__PURE__ */ React21.createElement("h2", { className: "text-2xl font-semibold text-slate-900" }, "You may also like"), /* @__PURE__ */ React21.createElement("p", { className: "mt-1 text-sm text-slate-500" }, "Hand-picked recommendations that pair nicely with this product.")), /* @__PURE__ */ React21.createElement(Link8, { href: buildPath("/shop"), className: "hidden md:inline-flex" }, /* @__PURE__ */ React21.createElement(Button, { variant: "ghost", className: "text-primary-600" }, "View all products"))), /* @__PURE__ */ React21.createElement("div", { className: "mt-6 grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5" }, relatedProducts?.map((relatedProduct) => /* @__PURE__ */ React21.createElement(
|
|
8763
|
+
ProductCard,
|
|
8764
|
+
{
|
|
8765
|
+
key: relatedProduct.id || relatedProduct._id,
|
|
8766
|
+
product: relatedProduct,
|
|
8767
|
+
onClickProduct: (item) => {
|
|
8768
|
+
router.push(buildPath(`/products/${item._id || item.id}`));
|
|
8769
|
+
}
|
|
8770
|
+
}
|
|
8771
|
+
))))))));
|
|
8578
8772
|
}
|
|
8579
8773
|
function CartItem({ item }) {
|
|
8580
8774
|
const { updateQuantity, removeFromCart } = useCart();
|
|
@@ -8592,6 +8786,16 @@ function CartItem({ item }) {
|
|
|
8592
8786
|
await removeFromCart(item.productVariantId);
|
|
8593
8787
|
};
|
|
8594
8788
|
const itemTotal = item.productVariantData.finalPrice * item.quantity;
|
|
8789
|
+
const unitPrice = item.productVariantData.finalPrice;
|
|
8790
|
+
const attributes = [];
|
|
8791
|
+
if (item.productVariantData.attribute) {
|
|
8792
|
+
if (item.productVariantData.attribute.color) {
|
|
8793
|
+
attributes.push(`Color: ${item.productVariantData.attribute.color}`);
|
|
8794
|
+
}
|
|
8795
|
+
if (item.productVariantData.attribute.size) {
|
|
8796
|
+
attributes.push(`Size: ${item.productVariantData.attribute.size}`);
|
|
8797
|
+
}
|
|
8798
|
+
}
|
|
8595
8799
|
return /* @__PURE__ */ React21.createElement(
|
|
8596
8800
|
motion.div,
|
|
8597
8801
|
{
|
|
@@ -8599,43 +8803,43 @@ function CartItem({ item }) {
|
|
|
8599
8803
|
initial: { opacity: 0, y: 20 },
|
|
8600
8804
|
animate: { opacity: 1, y: 0 },
|
|
8601
8805
|
exit: { opacity: 0, x: -100 },
|
|
8602
|
-
className: "
|
|
8806
|
+
className: "relative bg-white rounded-lg shadow-sm border border-gray-200 p-4"
|
|
8603
8807
|
},
|
|
8604
|
-
/* @__PURE__ */ React21.createElement(
|
|
8808
|
+
/* @__PURE__ */ React21.createElement(
|
|
8809
|
+
"button",
|
|
8810
|
+
{
|
|
8811
|
+
onClick: handleRemove,
|
|
8812
|
+
className: "absolute top-4 right-4 p-1 text-gray-400 hover:text-red-600 transition-colors",
|
|
8813
|
+
"aria-label": "Remove item"
|
|
8814
|
+
},
|
|
8815
|
+
/* @__PURE__ */ React21.createElement(Trash2, { className: "w-5 h-5" })
|
|
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(
|
|
8605
8818
|
Image3,
|
|
8606
8819
|
{
|
|
8607
8820
|
src: item.productVariantData.productMedia[0]?.file || "/placeholder-product.jpg",
|
|
8608
8821
|
alt: item.productVariantData.name,
|
|
8609
8822
|
fill: true,
|
|
8610
|
-
className: "object-cover"
|
|
8823
|
+
className: "object-cover",
|
|
8824
|
+
sizes: "80px"
|
|
8611
8825
|
}
|
|
8612
|
-
)),
|
|
8613
|
-
/* @__PURE__ */ React21.createElement("div", { className: "flex-1 min-w-0" }, /* @__PURE__ */ React21.createElement("h3", { className: "text-lg font-semibold text-gray-900 truncate" }, item.productVariantData.name), /* @__PURE__ */ React21.createElement("p", { className: "text-sm text-gray-500 mt-1" }, formatPrice(item.productVariantData.finalPrice), " each"), /* @__PURE__ */ React21.createElement("div", { className: "flex items-center gap-3 mt-3" }, /* @__PURE__ */ React21.createElement("div", { className: "flex items-center border-2 border-gray-200 rounded-lg" }, /* @__PURE__ */ React21.createElement(
|
|
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(
|
|
8614
8827
|
"button",
|
|
8615
8828
|
{
|
|
8616
8829
|
onClick: () => handleUpdateQuantity(item.quantity - 1),
|
|
8617
|
-
disabled: isUpdating || item.quantity <=
|
|
8618
|
-
className: "p-
|
|
8830
|
+
disabled: isUpdating || item.quantity <= 1,
|
|
8831
|
+
className: "p-1 hover:bg-gray-100 disabled:opacity-50 disabled:cursor-not-allowed transition-colors rounded"
|
|
8619
8832
|
},
|
|
8620
|
-
/* @__PURE__ */ React21.createElement(Minus, { className: "w-4 h-4" })
|
|
8621
|
-
), /* @__PURE__ */ React21.createElement("span", { className: "px-
|
|
8833
|
+
/* @__PURE__ */ React21.createElement(Minus, { className: "w-4 h-4 text-gray-600" })
|
|
8834
|
+
), /* @__PURE__ */ React21.createElement("span", { className: "px-3 font-medium min-w-[2rem] text-center text-gray-900" }, isUpdating ? /* @__PURE__ */ React21.createElement("span", { className: "inline-block h-4 w-4 align-middle animate-spin rounded-full border-2 border-gray-300 border-t-gray-600" }) : item.quantity), /* @__PURE__ */ React21.createElement(
|
|
8622
8835
|
"button",
|
|
8623
8836
|
{
|
|
8624
8837
|
onClick: () => handleUpdateQuantity(item.quantity + 1),
|
|
8625
|
-
disabled: isUpdating || item.quantity >= item.productVariantData.inventoryCount,
|
|
8626
|
-
className: "p-
|
|
8627
|
-
},
|
|
8628
|
-
/* @__PURE__ */ React21.createElement(Plus, { className: "w-4 h-4" })
|
|
8629
|
-
)), /* @__PURE__ */ React21.createElement(
|
|
8630
|
-
"button",
|
|
8631
|
-
{
|
|
8632
|
-
onClick: handleRemove,
|
|
8633
|
-
className: "p-2 text-red-600 hover:bg-red-50 rounded-lg transition-colors",
|
|
8634
|
-
"aria-label": "Remove item"
|
|
8838
|
+
disabled: isUpdating || item.quantity >= (item.productVariantData.inventoryCount || 999),
|
|
8839
|
+
className: "p-1 hover:bg-gray-100 disabled:opacity-50 disabled:cursor-not-allowed transition-colors rounded"
|
|
8635
8840
|
},
|
|
8636
|
-
/* @__PURE__ */ React21.createElement(
|
|
8637
|
-
))),
|
|
8638
|
-
/* @__PURE__ */ React21.createElement("div", { className: "text-right" }, /* @__PURE__ */ React21.createElement("p", { className: "text-xl font-bold text-gray-900" }, formatPrice(itemTotal)))
|
|
8841
|
+
/* @__PURE__ */ React21.createElement(Plus, { className: "w-4 h-4 text-gray-600" })
|
|
8842
|
+
))), /* @__PURE__ */ React21.createElement("div", { className: "text-right flex-shrink-0" }, /* @__PURE__ */ React21.createElement("p", { className: "text-lg font-bold text-orange-600" }, formatPrice(itemTotal)), /* @__PURE__ */ React21.createElement("p", { className: "text-sm text-gray-500 mt-1" }, formatPrice(unitPrice), " each")))
|
|
8639
8843
|
);
|
|
8640
8844
|
}
|
|
8641
8845
|
function CartScreen() {
|
|
@@ -8643,137 +8847,68 @@ function CartScreen() {
|
|
|
8643
8847
|
const { cart, isLoading } = useCart();
|
|
8644
8848
|
const { buildPath } = useBasePath();
|
|
8645
8849
|
if (!cart || cart.cartBody.items.length === 0) {
|
|
8646
|
-
|
|
8647
|
-
{
|
|
8648
|
-
icon: ShieldCheck,
|
|
8649
|
-
title: "Pharmacist approved",
|
|
8650
|
-
description: "Every product passes pharmacist review and cold-chain handling standards."
|
|
8651
|
-
},
|
|
8652
|
-
{
|
|
8653
|
-
icon: BadgePercent,
|
|
8654
|
-
title: "Bundle savings",
|
|
8655
|
-
description: "Unlock tiered discounts when you combine vitamins, OTC, and wellness kits."
|
|
8656
|
-
},
|
|
8657
|
-
{
|
|
8658
|
-
icon: HeartPulse,
|
|
8659
|
-
title: "Personalized guidance",
|
|
8660
|
-
description: "Follow curated collections tailored to your health goals and routines."
|
|
8661
|
-
}
|
|
8662
|
-
];
|
|
8663
|
-
return /* @__PURE__ */ React21.createElement("div", { className: "relative min-h-screen overflow-hidden bg-slate-950" }, /* @__PURE__ */ React21.createElement("div", { className: "absolute inset-0 bg-gradient-to-br from-[rgb(var(--header-from))] via-[rgb(var(--header-via))] to-[rgb(var(--header-to))]" }), /* @__PURE__ */ React21.createElement("div", { className: "absolute inset-0" }, /* @__PURE__ */ React21.createElement("div", { className: "pointer-events-none absolute -top-24 -left-20 h-96 w-96 rounded-full bg-white/20 blur-3xl opacity-60" }), /* @__PURE__ */ React21.createElement("div", { className: "pointer-events-none absolute bottom-0 right-0 h-[28rem] w-[28rem] rounded-full bg-secondary-500/40 blur-[220px] opacity-70" })), /* @__PURE__ */ React21.createElement("div", { className: "relative z-10 flex min-h-screen items-center px-6 py-20" }, /* @__PURE__ */ React21.createElement("div", { className: "mx-auto grid w-full max-w-6xl gap-12 lg:grid-cols-[minmax(0,1.25fr)_minmax(0,1fr)] lg:items-center" }, /* @__PURE__ */ React21.createElement(
|
|
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: "mb-6" }, /* @__PURE__ */ React21.createElement("h1", { className: "text-2xl font-bold text-slate-900" }, "Shopping Cart"), /* @__PURE__ */ React21.createElement("p", { className: "text-sm text-gray-500 mt-1" }, "0 items in your cart")), /* @__PURE__ */ React21.createElement("div", { className: "flex flex-col items-center justify-center py-20" }, /* @__PURE__ */ React21.createElement(
|
|
8664
8851
|
motion.div,
|
|
8665
8852
|
{
|
|
8666
8853
|
initial: { opacity: 0, y: 24 },
|
|
8667
8854
|
animate: { opacity: 1, y: 0 },
|
|
8668
|
-
|
|
8669
|
-
className: "space-y-8 text-white"
|
|
8855
|
+
className: "text-center space-y-6 max-w-md"
|
|
8670
8856
|
},
|
|
8671
|
-
/* @__PURE__ */ React21.createElement("
|
|
8672
|
-
/* @__PURE__ */ React21.createElement("div", { className: "space-y-
|
|
8673
|
-
/* @__PURE__ */ React21.createElement("div", { className: "flex flex-wrap gap-
|
|
8674
|
-
Button,
|
|
8675
|
-
{
|
|
8676
|
-
size: "lg",
|
|
8677
|
-
className: "bg-white text-primary-700 shadow-xl shadow-white/30 hover:bg-white/90 hover:text-primary-700",
|
|
8678
|
-
onClick: () => router.push(buildPath("/shop"))
|
|
8679
|
-
},
|
|
8680
|
-
"Discover products",
|
|
8681
|
-
/* @__PURE__ */ React21.createElement(ArrowRight, { className: "h-5 w-5" })
|
|
8682
|
-
), /* @__PURE__ */ React21.createElement(
|
|
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-gray-400" }))),
|
|
8858
|
+
/* @__PURE__ */ React21.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React21.createElement("h2", { className: "text-2xl font-bold text-slate-900" }, "Your cart is empty"), /* @__PURE__ */ React21.createElement("p", { className: "text-gray-500" }, "Start adding products to your cart to see them here.")),
|
|
8859
|
+
/* @__PURE__ */ React21.createElement("div", { className: "flex flex-wrap gap-3 justify-center" }, /* @__PURE__ */ React21.createElement(
|
|
8683
8860
|
"button",
|
|
8684
8861
|
{
|
|
8685
8862
|
type: "button",
|
|
8686
|
-
onClick: () => router.push(buildPath("/
|
|
8687
|
-
className: "
|
|
8688
|
-
},
|
|
8689
|
-
"Browse categories",
|
|
8690
|
-
/* @__PURE__ */ React21.createElement(ArrowRight, { className: "h-4 w-4" })
|
|
8691
|
-
)),
|
|
8692
|
-
/* @__PURE__ */ React21.createElement("div", { className: "grid gap-4 sm:grid-cols-2" }, highlights.map(({ icon: Icon, title, description }) => /* @__PURE__ */ React21.createElement(
|
|
8693
|
-
"div",
|
|
8694
|
-
{
|
|
8695
|
-
key: title,
|
|
8696
|
-
className: "rounded-2xl border border-white/15 bg-white/10 p-5 backdrop-blur transition hover:border-white/25 hover:bg-white/15"
|
|
8863
|
+
onClick: () => router.push(buildPath("/shop")),
|
|
8864
|
+
className: "rounded-full border-2 border-primary-500 bg-primary-500 hover:bg-primary-600 text-white px-6 py-3 text-sm font-medium transition-colors flex items-center justify-center gap-2"
|
|
8697
8865
|
},
|
|
8698
|
-
|
|
8699
|
-
/* @__PURE__ */ React21.createElement("p", { className: "mt-3 text-sm font-semibold text-white" }, title),
|
|
8700
|
-
/* @__PURE__ */ React21.createElement("p", { className: "mt-1 text-xs text-white/70" }, description)
|
|
8701
|
-
)))
|
|
8702
|
-
), /* @__PURE__ */ React21.createElement(
|
|
8703
|
-
motion.div,
|
|
8704
|
-
{
|
|
8705
|
-
initial: { opacity: 0, y: 24 },
|
|
8706
|
-
animate: { opacity: 1, y: 0 },
|
|
8707
|
-
transition: { delay: 0.1, duration: 0.4 },
|
|
8708
|
-
className: "rounded-[32px] border border-white/10 bg-white/10 p-10 backdrop-blur-2xl shadow-[0_40px_120px_-45px_rgba(12,5,40,0.6)]"
|
|
8709
|
-
},
|
|
8710
|
-
/* @__PURE__ */ React21.createElement("div", { className: "flex h-16 w-16 items-center justify-center rounded-2xl bg-white/20" }, /* @__PURE__ */ React21.createElement(ShoppingBag, { className: "h-8 w-8 text-white" })),
|
|
8711
|
-
/* @__PURE__ */ React21.createElement("h2", { className: "mt-6 text-3xl font-semibold text-white" }, "Still building your bag?"),
|
|
8712
|
-
/* @__PURE__ */ React21.createElement("p", { className: "mt-3 text-sm text-white/80" }, "Add supplements, wellness tools, and everyday pharmacy favorites to personalize your routine. We'll keep them chilled, curated, and ready for doorstep delivery."),
|
|
8713
|
-
/* @__PURE__ */ React21.createElement("ul", { className: "mt-6 space-y-3 text-sm text-white/80" }, /* @__PURE__ */ React21.createElement("li", { className: "flex items-center gap-2 rounded-xl bg-white/10 px-4 py-3" }, /* @__PURE__ */ React21.createElement(ShieldCheck, { className: "h-5 w-5 text-white" }), "Pharmacist oversight on every order"), /* @__PURE__ */ React21.createElement("li", { className: "flex items-center gap-2 rounded-xl bg-white/10 px-4 py-3" }, /* @__PURE__ */ React21.createElement(BadgePercent, { className: "h-5 w-5 text-white" }), "Member-only savings unlock at checkout"), /* @__PURE__ */ React21.createElement("li", { className: "flex items-center gap-2 rounded-xl bg-white/10 px-4 py-3" }, /* @__PURE__ */ React21.createElement(HeartPulse, { className: "h-5 w-5 text-white" }), "Personalized care plans for each purchase")),
|
|
8714
|
-
/* @__PURE__ */ React21.createElement(
|
|
8715
|
-
Button,
|
|
8716
|
-
{
|
|
8717
|
-
size: "lg",
|
|
8718
|
-
variant: "outline",
|
|
8719
|
-
className: "mt-8 w-full border-white/40 text-white hover:border-white hover:bg-white/10",
|
|
8720
|
-
onClick: () => router.push(buildPath("/shop"))
|
|
8721
|
-
},
|
|
8722
|
-
"Start building my cart",
|
|
8866
|
+
"Discover products",
|
|
8723
8867
|
/* @__PURE__ */ React21.createElement(ArrowRight, { className: "h-5 w-5" })
|
|
8724
|
-
)
|
|
8725
|
-
|
|
8868
|
+
)),
|
|
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-primary-600 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-primary-600 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-primary-600 flex-shrink-0 mt-0.5" }), /* @__PURE__ */ React21.createElement("span", null, "Secure checkout process")))
|
|
8870
|
+
)))));
|
|
8726
8871
|
}
|
|
8727
8872
|
const subtotal = cart.total;
|
|
8728
8873
|
const shipping = 0;
|
|
8729
8874
|
const tax = 0;
|
|
8730
8875
|
const total = subtotal + shipping + tax;
|
|
8731
|
-
|
|
8732
|
-
|
|
8733
|
-
{
|
|
8734
|
-
initial: { opacity: 0, y: 24 },
|
|
8735
|
-
animate: { opacity: 1, y: 0 },
|
|
8736
|
-
className: "flex flex-col gap-6 md:flex-row md:items-center md:justify-between"
|
|
8737
|
-
},
|
|
8738
|
-
/* @__PURE__ */ React21.createElement("div", { className: "max-w-2xl space-y-4" }, /* @__PURE__ */ React21.createElement("span", { className: "inline-flex items-center gap-2 rounded-full bg-white/15 px-3 py-1 text-sm font-semibold tracking-wide text-white/80 backdrop-blur" }, /* @__PURE__ */ React21.createElement(HeartPulse, { className: "h-4 w-4" }), "Wellness essentials, ready when you are"), /* @__PURE__ */ React21.createElement("h1", { className: "text-4xl font-bold md:text-5xl" }, "Your curated cart"), /* @__PURE__ */ React21.createElement("p", { className: "text-white/75 md:text-lg" }, "Review your selections, unlock exclusive perks, and check out with pharmacist-backed confidence.")),
|
|
8739
|
-
/* @__PURE__ */ React21.createElement("div", { className: "rounded-3xl bg-white/15 p-6 backdrop-blur-md" }, /* @__PURE__ */ React21.createElement("p", { className: "text-sm font-semibold uppercase tracking-[0.35em] text-white/70" }, "Cart summary"), /* @__PURE__ */ React21.createElement("p", { className: "mt-4 text-4xl font-semibold" }, formatPrice(total)), /* @__PURE__ */ React21.createElement("p", { className: "text-sm text-white/70" }, "Taxes and shipping calculated below"))
|
|
8740
|
-
))), /* @__PURE__ */ React21.createElement("div", { className: "relative -mt-16 pb-20" }, /* @__PURE__ */ React21.createElement("div", { className: "container mx-auto px-4" }, /* @__PURE__ */ React21.createElement("div", { className: "grid gap-10 lg:grid-cols-[minmax(0,2fr)_minmax(0,1fr)]" }, /* @__PURE__ */ React21.createElement(
|
|
8876
|
+
const itemCount = cart.cartBody.items.length;
|
|
8877
|
+
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: "mb-6" }, /* @__PURE__ */ React21.createElement("h1", { className: "text-2xl font-bold text-slate-900" }, "Shopping Cart"), /* @__PURE__ */ React21.createElement("p", { className: "text-sm text-gray-500 mt-1" }, itemCount, " ", itemCount === 1 ? "item" : "items", " in your cart")), /* @__PURE__ */ React21.createElement("div", { className: "grid gap-8 lg:grid-cols-[1.5fr_1fr]" }, /* @__PURE__ */ React21.createElement(
|
|
8741
8878
|
motion.section,
|
|
8742
8879
|
{
|
|
8743
8880
|
initial: { opacity: 0, y: 24 },
|
|
8744
8881
|
animate: { opacity: 1, y: 0 },
|
|
8745
|
-
|
|
8746
|
-
className: "space-y-6 rounded-3xl border border-slate-100 bg-white p-6 shadow-lg shadow-primary-50"
|
|
8882
|
+
className: "space-y-6"
|
|
8747
8883
|
},
|
|
8748
|
-
/* @__PURE__ */ React21.createElement("div", { className: "flex
|
|
8749
|
-
|
|
8750
|
-
/* @__PURE__ */ React21.createElement("div", { className: "space-y-5" }, cart.cartBody.items.map((item) => /* @__PURE__ */ React21.createElement(CartItem, { key: item.productVariantId, item })))
|
|
8884
|
+
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
|
+
/* @__PURE__ */ React21.createElement("div", { className: "space-y-4" }, cart.cartBody.items.map((item) => /* @__PURE__ */ React21.createElement(CartItem, { key: item.productVariantId, item })))
|
|
8751
8886
|
), /* @__PURE__ */ React21.createElement(
|
|
8752
8887
|
motion.aside,
|
|
8753
8888
|
{
|
|
8754
8889
|
initial: { opacity: 0, y: 24 },
|
|
8755
8890
|
animate: { opacity: 1, y: 0 },
|
|
8756
8891
|
transition: { delay: 0.1 },
|
|
8757
|
-
className: "space-y-6 lg:sticky lg:top-
|
|
8892
|
+
className: "space-y-6 lg:sticky lg:top-8 h-fit"
|
|
8758
8893
|
},
|
|
8759
|
-
/* @__PURE__ */ React21.createElement("div", { className: "rounded-
|
|
8760
|
-
|
|
8894
|
+
/* @__PURE__ */ React21.createElement("div", { className: "rounded-xl border-2 border-primary-200 bg-white p-6 shadow-md" }, /* @__PURE__ */ React21.createElement("h2", { className: "text-xl font-bold text-slate-900 mb-6" }, "Order Summary"), /* @__PURE__ */ React21.createElement("div", { className: "space-y-4 mb-6" }, /* @__PURE__ */ React21.createElement("div", { className: "flex items-center justify-between text-sm" }, /* @__PURE__ */ React21.createElement("span", { className: "text-gray-600" }, "Subtotal (", itemCount, " ", itemCount === 1 ? "item" : "items", ")"), /* @__PURE__ */ React21.createElement("span", { className: "font-semibold text-slate-900" }, 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-slate-900" }, "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
|
+
"button",
|
|
8761
8896
|
{
|
|
8762
|
-
|
|
8763
|
-
|
|
8764
|
-
|
|
8897
|
+
type: "button",
|
|
8898
|
+
onClick: () => router.push(buildPath("/checkout")),
|
|
8899
|
+
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"
|
|
8765
8900
|
},
|
|
8766
|
-
"
|
|
8901
|
+
"Proceed to Checkout",
|
|
8767
8902
|
/* @__PURE__ */ React21.createElement(ArrowRight, { className: "h-5 w-5" })
|
|
8768
8903
|
), /* @__PURE__ */ React21.createElement(
|
|
8769
8904
|
"button",
|
|
8770
8905
|
{
|
|
8771
8906
|
type: "button",
|
|
8772
8907
|
onClick: () => router.push(buildPath("/shop")),
|
|
8773
|
-
className: "
|
|
8908
|
+
className: "w-full rounded-full border-2 border-primary-300 bg-white px-4 py-3 text-sm font-medium text-slate-700 hover:bg-gray-50 transition-colors"
|
|
8774
8909
|
},
|
|
8775
|
-
"Continue
|
|
8776
|
-
)),
|
|
8910
|
+
"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-primary-600 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-primary-600 flex-shrink-0 mt-0.5" }), /* @__PURE__ */ React21.createElement("span", null, "Secure checkout process")))),
|
|
8777
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."))
|
|
8778
8913
|
)))));
|
|
8779
8914
|
}
|
|
@@ -9172,9 +9307,12 @@ function CheckoutScreen() {
|
|
|
9172
9307
|
}
|
|
9173
9308
|
const rates = response.data.rates || [];
|
|
9174
9309
|
if (rates.length > 0) {
|
|
9310
|
+
const sortedRates = [...rates].sort((a, b) => parseFloat(a.amount) - parseFloat(b.amount));
|
|
9311
|
+
const cheapestRate = sortedRates[0];
|
|
9175
9312
|
setShippingRates(rates);
|
|
9176
9313
|
setShippingRatesError(null);
|
|
9177
|
-
setSelectedShippingRateId(
|
|
9314
|
+
setSelectedShippingRateId(cheapestRate.objectId);
|
|
9315
|
+
setShippingPrice(parseFloat(cheapestRate.amount));
|
|
9178
9316
|
return;
|
|
9179
9317
|
}
|
|
9180
9318
|
const messages = response.data.messages || [];
|
|
@@ -9228,11 +9366,6 @@ function CheckoutScreen() {
|
|
|
9228
9366
|
setSelectedStoreAddressId(null);
|
|
9229
9367
|
}
|
|
9230
9368
|
}, [isDelivery]);
|
|
9231
|
-
const checkoutSteps = [
|
|
9232
|
-
{ id: 1, label: "Cart", status: "complete" },
|
|
9233
|
-
{ id: 2, label: "Details", status: "current" },
|
|
9234
|
-
{ id: 3, label: "Payment", status: "upcoming" }
|
|
9235
|
-
];
|
|
9236
9369
|
const onSubmit = async (data) => {
|
|
9237
9370
|
setError(null);
|
|
9238
9371
|
if (!isAuthenticated) {
|
|
@@ -9326,8 +9459,20 @@ function CheckoutScreen() {
|
|
|
9326
9459
|
if (paymentMethod === "Card") {
|
|
9327
9460
|
const paymentUrl = response?.data?.payment?.hostedInvoiceUrl;
|
|
9328
9461
|
if (paymentUrl && paymentUrl !== "INSUFFICIENT_CREDIT") {
|
|
9329
|
-
window.open(
|
|
9330
|
-
|
|
9462
|
+
const newWindow = window.open("", "_blank");
|
|
9463
|
+
if (newWindow) {
|
|
9464
|
+
newWindow.location.href = paymentUrl;
|
|
9465
|
+
await clearCart();
|
|
9466
|
+
return;
|
|
9467
|
+
} else {
|
|
9468
|
+
window.location.href = paymentUrl;
|
|
9469
|
+
await clearCart();
|
|
9470
|
+
return;
|
|
9471
|
+
}
|
|
9472
|
+
} else if (!paymentUrl) {
|
|
9473
|
+
console.error("No payment URL received in response:", response.data);
|
|
9474
|
+
setError("Failed to initiate payment. Please try again or contact support.");
|
|
9475
|
+
toast.error("Failed to initiate payment");
|
|
9331
9476
|
return;
|
|
9332
9477
|
}
|
|
9333
9478
|
toast.success("Order placed successfully!");
|
|
@@ -9353,26 +9498,7 @@ function CheckoutScreen() {
|
|
|
9353
9498
|
const subtotal = cart.total;
|
|
9354
9499
|
const tax = 0;
|
|
9355
9500
|
const total = subtotal + shippingPrice + tax;
|
|
9356
|
-
return /* @__PURE__ */ React21.createElement("div", { className: "min-h-screen bg-slate-50" }, /* @__PURE__ */ React21.createElement("
|
|
9357
|
-
motion.div,
|
|
9358
|
-
{
|
|
9359
|
-
initial: { opacity: 0, y: 24 },
|
|
9360
|
-
animate: { opacity: 1, y: 0 },
|
|
9361
|
-
className: "space-y-6"
|
|
9362
|
-
},
|
|
9363
|
-
/* @__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(ShieldCheck, { className: "h-4 w-4" }), "Secure checkout"),
|
|
9364
|
-
/* @__PURE__ */ React21.createElement("h1", { className: "text-4xl font-bold md:text-5xl" }, "Provide delivery details"),
|
|
9365
|
-
/* @__PURE__ */ React21.createElement("p", { className: "text-white/75 md:text-lg" }, "Our pharmacists handle every package with care. Share your shipping and billing information so we can dispatch your order within the next 12 hours."),
|
|
9366
|
-
/* @__PURE__ */ React21.createElement("div", { className: "flex flex-wrap gap-3" }, checkoutSteps.map((step) => /* @__PURE__ */ React21.createElement(
|
|
9367
|
-
"div",
|
|
9368
|
-
{
|
|
9369
|
-
key: step.id,
|
|
9370
|
-
className: `flex items-center gap-3 rounded-2xl px-4 py-2 text-sm font-semibold ${step.status === "complete" ? "bg-white/20 text-white" : step.status === "current" ? "bg-white text-primary-700" : "bg-white/10 text-white/60"}`
|
|
9371
|
-
},
|
|
9372
|
-
/* @__PURE__ */ React21.createElement("span", { className: "flex h-7 w-7 items-center justify-center rounded-full bg-white/20 text-xs font-bold" }, step.id),
|
|
9373
|
-
step.label
|
|
9374
|
-
)))
|
|
9375
|
-
)))), /* @__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(
|
|
9501
|
+
return /* @__PURE__ */ React21.createElement("div", { className: "min-h-screen bg-slate-50 mb-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(
|
|
9376
9502
|
motion.div,
|
|
9377
9503
|
{
|
|
9378
9504
|
initial: { opacity: 0, y: 24 },
|
|
@@ -9470,9 +9596,10 @@ function CheckoutScreen() {
|
|
|
9470
9596
|
"div",
|
|
9471
9597
|
{
|
|
9472
9598
|
key: rate.objectId,
|
|
9473
|
-
onClick: () =>
|
|
9474
|
-
|
|
9475
|
-
|
|
9599
|
+
onClick: () => {
|
|
9600
|
+
setSelectedShippingRateId(rate.objectId);
|
|
9601
|
+
setShippingPrice(parseFloat(rate.amount));
|
|
9602
|
+
},
|
|
9476
9603
|
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"}`
|
|
9477
9604
|
},
|
|
9478
9605
|
/* @__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(
|
|
@@ -9559,7 +9686,7 @@ function CheckoutScreen() {
|
|
|
9559
9686
|
), /* @__PURE__ */ React21.createElement("span", { className: "text-sm font-medium text-slate-900" }, pm.label)),
|
|
9560
9687
|
active && /* @__PURE__ */ React21.createElement("div", { className: "w-4 h-4 rounded-full bg-primary-500 flex items-center justify-center text-white shadow-sm" }, /* @__PURE__ */ React21.createElement(Check, { className: "w-2.5 h-2.5" }))
|
|
9561
9688
|
);
|
|
9562
|
-
})), /* @__PURE__ */ React21.createElement("p", { className: "text-xs text-slate-500 mt-2 pl-1 leading-relaxed" }, 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.")), /* @__PURE__ */ React21.createElement("section", { className: "mt-8 pt-6 border-t border-slate-100" }, /* @__PURE__ */ React21.createElement("div", { className: "max-h-60 space-y-4 overflow-y-auto pr-2 scrollbar-thin scrollbar-thumb-slate-200 hover:scrollbar-thumb-slate-300" }, cart?.cartBody?.items?.map((item) => /* @__PURE__ */ React21.createElement(
|
|
9689
|
+
})), /* @__PURE__ */ React21.createElement("p", { className: "text-xs text-slate-500 mt-2 pl-1 leading-relaxed" }, 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.")), /* @__PURE__ */ React21.createElement("section", { className: "mt-8 pt-6 border-t border-slate-100" }, /* @__PURE__ */ React21.createElement("h3", { className: "text-xs font-semibold text-slate-700 uppercase tracking-wider" }, "Cart Summary"), /* @__PURE__ */ React21.createElement("div", { className: "max-h-60 space-y-4 overflow-y-auto pr-2 scrollbar-thin scrollbar-thumb-slate-200 hover:scrollbar-thumb-slate-300" }, cart?.cartBody?.items?.map((item) => /* @__PURE__ */ React21.createElement(
|
|
9563
9690
|
"div",
|
|
9564
9691
|
{
|
|
9565
9692
|
key: item.productId,
|
|
@@ -9651,7 +9778,7 @@ function LoginScreen() {
|
|
|
9651
9778
|
initial: { opacity: 0, x: -24 },
|
|
9652
9779
|
animate: { opacity: 1, x: 0 },
|
|
9653
9780
|
transition: { duration: 0.4 },
|
|
9654
|
-
className: "relative flex flex-col justify-between bg-gradient-to-br from-
|
|
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"
|
|
9655
9782
|
},
|
|
9656
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.")),
|
|
9657
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."))),
|
|
@@ -9777,7 +9904,7 @@ function RegisterScreen() {
|
|
|
9777
9904
|
initial: { opacity: 0, x: -24 },
|
|
9778
9905
|
animate: { opacity: 1, x: 0 },
|
|
9779
9906
|
transition: { duration: 0.4 },
|
|
9780
|
-
className: "flex flex-col justify-between bg-gradient-to-br from-
|
|
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"
|
|
9781
9908
|
},
|
|
9782
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.")),
|
|
9783
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)))),
|
|
@@ -10977,14 +11104,23 @@ function WishlistScreen() {
|
|
|
10977
11104
|
return list;
|
|
10978
11105
|
}, [wishlistProducts, onlyInStock, sortOption]);
|
|
10979
11106
|
const emptyAfterFiltering = !isLoading && wishlistProducts.length > 0 && processedProducts.length === 0;
|
|
10980
|
-
return /* @__PURE__ */ React21.createElement("div", { className: "
|
|
11107
|
+
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(
|
|
10981
11108
|
motion.div,
|
|
10982
11109
|
{
|
|
10983
11110
|
initial: { opacity: 0, y: 24 },
|
|
10984
11111
|
animate: { opacity: 1, y: 0 },
|
|
10985
|
-
className: "
|
|
11112
|
+
className: "space-y-6"
|
|
10986
11113
|
},
|
|
10987
|
-
|
|
11114
|
+
!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-gray-400" }))), /* @__PURE__ */ React21.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React21.createElement("h2", { className: "text-2xl font-bold text-slate-900" }, "Sign in to see your favourites"), /* @__PURE__ */ React21.createElement("p", { className: "text-gray-500" }, "Create your curated shelf of products and we'll keep them ready whenever you return.")), /* @__PURE__ */ React21.createElement(
|
|
11115
|
+
"button",
|
|
11116
|
+
{
|
|
11117
|
+
type: "button",
|
|
11118
|
+
onClick: () => router.push(buildPath("/login")),
|
|
11119
|
+
className: "rounded-full border-2 border-primary-500 bg-primary-500 hover:bg-primary-600 text-white px-6 py-3 text-sm font-medium transition-colors"
|
|
11120
|
+
},
|
|
11121
|
+
"Sign In"
|
|
11122
|
+
))),
|
|
11123
|
+
isAuthenticated && /* @__PURE__ */ React21.createElement(React21.Fragment, null, /* @__PURE__ */ React21.createElement("div", { className: "mb-6" }, /* @__PURE__ */ React21.createElement("h1", { className: "text-2xl font-bold text-slate-900" }, "Wishlist"), /* @__PURE__ */ React21.createElement("p", { className: "text-sm text-gray-500 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-gray-500" }, "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-200 hover:text-primary-600" }, /* @__PURE__ */ React21.createElement(
|
|
10988
11124
|
"input",
|
|
10989
11125
|
{
|
|
10990
11126
|
type: "checkbox",
|
|
@@ -11033,7 +11169,15 @@ function WishlistScreen() {
|
|
|
11033
11169
|
key: index,
|
|
11034
11170
|
className: "h-72 animate-pulse rounded-2xl border border-slate-200 bg-slate-100"
|
|
11035
11171
|
}
|
|
11036
|
-
))), !isLoading && wishlistCount === 0 && /* @__PURE__ */ React21.createElement("div", { className: "flex min-h-[30vh] items-center justify-center" }, /* @__PURE__ */ React21.createElement("div", { className: "
|
|
11172
|
+
))), !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-gray-400" }))), /* @__PURE__ */ React21.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React21.createElement("h2", { className: "text-2xl font-bold text-slate-900" }, "Your wishlist is empty"), /* @__PURE__ */ React21.createElement("p", { className: "text-gray-500" }, "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(
|
|
11173
|
+
"button",
|
|
11174
|
+
{
|
|
11175
|
+
type: "button",
|
|
11176
|
+
onClick: () => router.push(buildPath("/shop")),
|
|
11177
|
+
className: "rounded-full border-2 border-primary-500 bg-primary-500 hover:bg-primary-600 text-white px-6 py-3 text-sm font-medium transition-colors flex items-center justify-center gap-2"
|
|
11178
|
+
},
|
|
11179
|
+
"Discover products"
|
|
11180
|
+
)))), !isLoading && processedProducts.length > 0 && /* @__PURE__ */ React21.createElement(React21.Fragment, null, viewMode === "grid" ? /* @__PURE__ */ React21.createElement(
|
|
11037
11181
|
motion.div,
|
|
11038
11182
|
{
|
|
11039
11183
|
layout: true,
|
|
@@ -11096,7 +11240,15 @@ function WishlistScreen() {
|
|
|
11096
11240
|
},
|
|
11097
11241
|
"Remove"
|
|
11098
11242
|
)))
|
|
11099
|
-
))))), isAuthenticated && emptyAfterFiltering && /* @__PURE__ */ React21.createElement("div", { className: "flex flex-col items-center justify-center rounded-
|
|
11243
|
+
))))), 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-slate-900" }, "Nothing matches those filters"), /* @__PURE__ */ React21.createElement("p", { className: "mt-2 max-w-md text-sm text-gray-500" }, "Try showing out-of-stock items or adjust your sort order to revisit everything you've saved."), /* @__PURE__ */ React21.createElement(
|
|
11244
|
+
"button",
|
|
11245
|
+
{
|
|
11246
|
+
type: "button",
|
|
11247
|
+
className: "mt-6 rounded-full border-2 border-primary-300 bg-white px-6 py-3 text-sm font-medium text-slate-700 hover:bg-gray-50 transition-colors",
|
|
11248
|
+
onClick: () => setOnlyInStock(false)
|
|
11249
|
+
},
|
|
11250
|
+
"Show all saved products"
|
|
11251
|
+
)))
|
|
11100
11252
|
))));
|
|
11101
11253
|
}
|
|
11102
11254
|
function SearchPage() {
|