hey-pharmacist-ecommerce 1.1.28 → 1.1.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/dist/index.d.mts +10552 -1370
  2. package/dist/index.d.ts +10552 -1370
  3. package/dist/index.js +4696 -1281
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.mjs +4640 -1283
  6. package/dist/index.mjs.map +1 -1
  7. package/package.json +1 -1
  8. package/src/components/AccountOrdersTab.tsx +1 -1
  9. package/src/components/AccountSettingsTab.tsx +88 -6
  10. package/src/components/CartItem.tsx +1 -1
  11. package/src/components/Header.tsx +8 -2
  12. package/src/components/OrderCard.tsx +4 -4
  13. package/src/components/ProductCard.tsx +59 -42
  14. package/src/components/QuickViewModal.tsx +13 -13
  15. package/src/hooks/useAddresses.ts +4 -1
  16. package/src/hooks/usePaymentMethods.ts +26 -31
  17. package/src/hooks/useProducts.ts +63 -64
  18. package/src/hooks/useStoreCapabilities.ts +87 -0
  19. package/src/hooks/useWishlistProducts.ts +4 -5
  20. package/src/index.ts +6 -0
  21. package/src/lib/Apis/api.ts +0 -1
  22. package/src/lib/Apis/apis/auth-api.ts +37 -36
  23. package/src/lib/Apis/apis/categories-api.ts +97 -0
  24. package/src/lib/Apis/apis/products-api.ts +942 -405
  25. package/src/lib/Apis/apis/shipping-api.ts +105 -0
  26. package/src/lib/Apis/apis/stores-api.ts +356 -0
  27. package/src/lib/Apis/apis/sub-categories-api.ts +97 -0
  28. package/src/lib/Apis/apis/users-api.ts +8 -8
  29. package/src/lib/Apis/models/address-created-request.ts +0 -12
  30. package/src/lib/Apis/models/address.ts +0 -12
  31. package/src/lib/Apis/models/api-key-info-dto.ts +49 -0
  32. package/src/lib/Apis/models/category-populated.ts +0 -12
  33. package/src/lib/Apis/models/category-sub-category-populated.ts +2 -2
  34. package/src/lib/Apis/models/category.ts +0 -18
  35. package/src/lib/Apis/models/{table-cell-dto.ts → change-password-dto.ts} +6 -6
  36. package/src/lib/Apis/models/create-address-dto.ts +0 -12
  37. package/src/lib/Apis/models/create-discount-dto.ts +0 -8
  38. package/src/lib/Apis/models/create-product-dto.ts +30 -23
  39. package/src/lib/Apis/models/create-store-address-dto.ts +0 -12
  40. package/src/lib/Apis/models/create-store-dto-settings.ts +51 -0
  41. package/src/lib/Apis/models/create-store-dto.ts +7 -0
  42. package/src/lib/Apis/models/create-sub-category-dto.ts +6 -0
  43. package/src/lib/Apis/models/create-variant-dto.ts +26 -32
  44. package/src/lib/Apis/models/discount.ts +0 -8
  45. package/src/lib/Apis/models/index.ts +16 -7
  46. package/src/lib/Apis/models/paginated-products-dto.ts +6 -6
  47. package/src/lib/Apis/models/populated-discount.ts +0 -8
  48. package/src/lib/Apis/models/product-summary.ts +69 -0
  49. package/src/lib/Apis/models/product-variant.ts +31 -68
  50. package/src/lib/Apis/models/product.ts +138 -0
  51. package/src/lib/Apis/models/products-insights-dto.ts +12 -0
  52. package/src/lib/Apis/models/reorder-categories-dto.ts +27 -0
  53. package/src/lib/Apis/models/reorder-products-dto.ts +49 -0
  54. package/src/lib/Apis/models/{table-dto.ts → reorder-products-success-response-dto.ts} +8 -9
  55. package/src/lib/Apis/models/reorder-subcategories-dto.ts +33 -0
  56. package/src/lib/Apis/models/{shallow-parent-category-dto.ts → reorder-success-response-dto.ts} +7 -7
  57. package/src/lib/Apis/models/shipment-with-order.ts +18 -0
  58. package/src/lib/Apis/models/shipment.ts +18 -0
  59. package/src/lib/Apis/models/single-product-media.ts +0 -12
  60. package/src/lib/Apis/models/store-api-keys-response-dto.ts +34 -0
  61. package/src/lib/Apis/models/store-capabilities-dto.ts +63 -0
  62. package/src/lib/Apis/models/store-entity.ts +7 -0
  63. package/src/lib/Apis/models/store.ts +7 -0
  64. package/src/lib/Apis/models/sub-category.ts +6 -12
  65. package/src/lib/Apis/models/update-address-dto.ts +0 -12
  66. package/src/lib/Apis/models/update-api-keys-dto.ts +39 -0
  67. package/src/lib/Apis/models/update-discount-dto.ts +0 -8
  68. package/src/lib/Apis/models/update-manual-shipment-status-dto.ts +47 -0
  69. package/src/lib/Apis/models/update-product-dto.ts +30 -19
  70. package/src/lib/Apis/models/update-store-dto.ts +7 -0
  71. package/src/lib/Apis/models/update-sub-category-dto.ts +6 -0
  72. package/src/lib/Apis/models/{update-product-variant-dto.ts → update-variant-dto.ts} +46 -46
  73. package/src/lib/Apis/models/variant-id-inventory-body.ts +27 -0
  74. package/src/lib/api-adapter/config.ts +53 -0
  75. package/src/lib/validations/address.ts +1 -1
  76. package/src/providers/FavoritesProvider.tsx +5 -5
  77. package/src/providers/WishlistProvider.tsx +4 -4
  78. package/src/screens/CartScreen.tsx +1 -1
  79. package/src/screens/ChangePasswordScreen.tsx +2 -6
  80. package/src/screens/CheckoutScreen.tsx +402 -288
  81. package/src/screens/ForgotPasswordScreen.tsx +153 -0
  82. package/src/screens/ProductDetailScreen.tsx +51 -60
  83. package/src/screens/RegisterScreen.tsx +31 -31
  84. package/src/screens/ResetPasswordScreen.tsx +208 -0
  85. package/src/screens/SearchResultsScreen.tsx +264 -26
  86. package/src/screens/ShopScreen.tsx +42 -45
  87. package/src/screens/WishlistScreen.tsx +35 -31
  88. package/src/lib/Apis/apis/product-variants-api.ts +0 -552
  89. package/src/lib/Apis/models/create-single-variant-product-dto.ts +0 -154
  90. package/src/lib/Apis/models/extended-product-dto.ts +0 -206
  91. package/src/lib/Apis/models/frequently-bought-product-dto.ts +0 -71
@@ -6,11 +6,10 @@ import {
6
6
  useMemo,
7
7
  useState,
8
8
  } from 'react';
9
- import { AnimatePresence, motion } from 'framer-motion';
9
+ import { motion } from 'framer-motion';
10
10
  import {
11
11
  ArrowUpDown,
12
12
  ChevronDown,
13
- ChevronUp,
14
13
  Clock,
15
14
  LayoutGrid,
16
15
  LayoutList,
@@ -74,12 +73,12 @@ export function ShopScreen({ initialFilters = {}, categoryName }: ShopScreenProp
74
73
 
75
74
  const { products, isLoading, pagination } = useProducts(filters, page, 20);
76
75
  const { categories, isLoading: isLoadingCategories } = useCategories();
77
-
78
76
  const handleSearch = (e: React.FormEvent) => {
79
77
  e.preventDefault();
80
- if (searchQuery.trim()) {
78
+ const sanitized = searchQuery.trim().replace(/\s+/g, ' ');
79
+ if (sanitized) {
81
80
  setIsSearching(true);
82
- router.push(buildPath(`/search?q=${encodeURIComponent(searchQuery.trim())}`));
81
+ router.push(buildPath(`/search?q=${encodeURIComponent(sanitized)}`));
83
82
  }
84
83
  };
85
84
 
@@ -90,10 +89,13 @@ export function ShopScreen({ initialFilters = {}, categoryName }: ShopScreenProp
90
89
 
91
90
  // Handle search when pressing Enter
92
91
  const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
93
- if (e.key === 'Enter' && searchQuery.trim()) {
92
+ if (e.key === 'Enter') {
94
93
  e.preventDefault();
95
- setIsSearching(true);
96
- router.push(buildPath(`/search?q=${encodeURIComponent(searchQuery.trim())}`));
94
+ const sanitized = searchQuery.trim().replace(/\s+/g, ' ');
95
+ if (sanitized) {
96
+ setIsSearching(true);
97
+ router.push(buildPath(`/search?q=${encodeURIComponent(sanitized)}`));
98
+ }
97
99
  }
98
100
  };
99
101
 
@@ -120,9 +122,10 @@ export function ShopScreen({ initialFilters = {}, categoryName }: ShopScreenProp
120
122
  if (filters.category) updates[filters.category] = true;
121
123
  if (filters.subCategory) {
122
124
  const parent = categories.find((c) =>
123
- c.categorySubCategories?.some((sc) => sc.id === filters.subCategory)
125
+ c.categorySubCategories?.some((sc) => (sc._id ?? sc.id) === filters.subCategory)
124
126
  );
125
- if (parent?.id) updates[parent.id] = true;
127
+ const parentId = parent?._id ?? parent?.id;
128
+ if (parentId) updates[parentId] = true;
126
129
  }
127
130
  if (Object.keys(updates).length) {
128
131
  setExpandedCategories((prev) => ({ ...prev, ...updates }));
@@ -156,7 +159,7 @@ export function ShopScreen({ initialFilters = {}, categoryName }: ShopScreenProp
156
159
  let inStockCount = 0;
157
160
 
158
161
  products.forEach((product) => {
159
- if (product.inventoryCount > 0) inStockCount += 1;
162
+ if (product.summary?.totalInventory > 0) inStockCount += 1;
160
163
  if (new Date(product.createdAt).getTime() >= monthAgo) newArrivals += 1;
161
164
  });
162
165
 
@@ -213,7 +216,7 @@ export function ShopScreen({ initialFilters = {}, categoryName }: ShopScreenProp
213
216
  if (isLoading) return products;
214
217
  let items = [...products];
215
218
  if (filters.tags?.length) {
216
- items = items.filter((p) => Array.isArray(p.tags) && p.tags.some((t) => filters.tags!.includes(t)));
219
+ items = items.filter((p) => Array.isArray(p.tags) && p.tags.some((t: string) => filters.tags!.includes(t)));
217
220
  }
218
221
  if (filters.newArrivals) {
219
222
  const thirtyDaysAgo = Date.now() - 30 * 24 * 60 * 60 * 1000;
@@ -234,9 +237,9 @@ export function ShopScreen({ initialFilters = {}, categoryName }: ShopScreenProp
234
237
 
235
238
  switch (sortOption) {
236
239
  case 'price-low-high':
237
- return items.sort((a, b) => a.finalPrice - b.finalPrice);
240
+ return items.sort((a, b) => (a.variants?.[0]?.finalPrice ?? 0) - (b.variants?.[0]?.finalPrice ?? 0));
238
241
  case 'price-high-low':
239
- return items.sort((a, b) => b.finalPrice - a.finalPrice);
242
+ return items.sort((a, b) => (b.variants?.[0]?.finalPrice ?? 0) - (a.variants?.[0]?.finalPrice ?? 0));
240
243
  case 'newest':
241
244
  return items.sort(
242
245
  (a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()
@@ -262,7 +265,7 @@ export function ShopScreen({ initialFilters = {}, categoryName }: ShopScreenProp
262
265
  const quickSearches = useMemo(() => {
263
266
  const counts = new Map<string, number>();
264
267
  products.forEach((p) => {
265
- (p.tags || []).forEach((t) => counts.set(t, (counts.get(t) || 0) + 1));
268
+ (p.tags || []).forEach((t: string) => counts.set(t, (counts.get(t) || 0) + 1));
266
269
  });
267
270
  return Array.from(counts.entries())
268
271
  .sort((a, b) => b[1] - a[1])
@@ -539,7 +542,7 @@ export function ShopScreen({ initialFilters = {}, categoryName }: ShopScreenProp
539
542
  let subName: string | undefined;
540
543
  let parentName: string | undefined;
541
544
  categories.forEach((cat) => {
542
- const found = cat.categorySubCategories?.find((sc) => sc.id === subCategoryFilter);
545
+ const found = cat.categorySubCategories?.find((sc) => (sc._id ?? sc.id) === subCategoryFilter);
543
546
  if (found) {
544
547
  subName = found.name;
545
548
  parentName = cat.name;
@@ -551,7 +554,7 @@ export function ShopScreen({ initialFilters = {}, categoryName }: ShopScreenProp
551
554
  onRemove: handleRemoveSubCategory,
552
555
  });
553
556
  if (categoryFilter) {
554
- const catObj = categories.find((c) => c.id === categoryFilter);
557
+ const catObj = categories.find((c) => (c._id ?? c.id) === categoryFilter);
555
558
  chips.push({
556
559
  key: 'category',
557
560
  label: `Category: ${catObj?.name ?? parentName ?? categoryFilter}`,
@@ -559,7 +562,7 @@ export function ShopScreen({ initialFilters = {}, categoryName }: ShopScreenProp
559
562
  });
560
563
  }
561
564
  } else if (categoryFilter) {
562
- const category = categories.find((cat) => cat.id === categoryFilter);
565
+ const category = categories.find((cat) => (cat._id ?? cat.id) === categoryFilter);
563
566
  chips.push({
564
567
  key: 'category',
565
568
  label: `Category: ${category?.name ?? categoryFilter}`,
@@ -697,15 +700,16 @@ export function ShopScreen({ initialFilters = {}, categoryName }: ShopScreenProp
697
700
  {expandedFilterSections.category && (
698
701
  <div className="space-y-2">
699
702
  {sortedCategories.map((category) => {
700
- const isCategoryActive = categoryFilter === category.id;
701
- const isExpanded = !!expandedCategories[category.id as string];
703
+ const categoryId = category._id ?? category.id ?? '';
704
+ const isCategoryActive = categoryFilter === categoryId;
705
+ const isExpanded = !!expandedCategories[categoryId];
702
706
  const Icon = getCategoryIconForFilter(category.name ?? '');
703
707
  return (
704
708
  <button
705
- key={category.id}
709
+ key={categoryId}
706
710
  onClick={() => {
707
- if (!isExpanded) toggleCategoryExpand(category.id ?? '');
708
- handleCategoryChange(category.id ?? '');
711
+ if (!isExpanded) toggleCategoryExpand(categoryId);
712
+ handleCategoryChange(categoryId);
709
713
  }}
710
714
  className={`w-full text-left px-4 py-3 rounded-xl font-['Poppins',sans-serif] text-[13px] transition-all flex items-center gap-3 ${isCategoryActive
711
715
  ? 'bg-primary text-white shadow-lg'
@@ -955,15 +959,16 @@ export function ShopScreen({ initialFilters = {}, categoryName }: ShopScreenProp
955
959
 
956
960
  {displayCategories.map((category, index) => {
957
961
  const Icon = getCategoryIcon(category.name ?? '');
958
- const isSelected = categoryFilter === category.id;
962
+ const categoryId = category._id ?? category.id ?? '';
963
+ const isSelected = categoryFilter === categoryId;
959
964
 
960
965
  return (
961
966
  <motion.button
962
- key={category.id}
967
+ key={categoryId}
963
968
  initial={{ opacity: 0, y: 20 }}
964
969
  animate={{ opacity: 1, y: 0 }}
965
970
  transition={{ delay: index * 0.1 }}
966
- onClick={() => handleCategoryChange(category.id ?? '')}
971
+ onClick={() => handleCategoryChange(categoryId)}
967
972
  className={`group relative overflow-hidden rounded-[24px] p-6 min-h-[180px] min-w-[170px] transition-all duration-300 ${isSelected ? 'bg-linear-to-br from-primary to-secondary text-white shadow-xl scale-105'
968
973
  : 'bg-linear-to-br from-gray-50 to-white hover:shadow-lg border-2 border-gray-100 hover:border-primary'
969
974
  }`}
@@ -1106,14 +1111,11 @@ export function ShopScreen({ initialFilters = {}, categoryName }: ShopScreenProp
1106
1111
  ) : (
1107
1112
  <div className="space-y-4">
1108
1113
  {displayedProducts.map((product) => {
1109
- const discount =
1110
- product.priceBeforeDiscount && product.priceBeforeDiscount > product.finalPrice
1111
- ? Math.round(
1112
- ((product.priceBeforeDiscount - product.finalPrice) /
1113
- product.priceBeforeDiscount) *
1114
- 100
1115
- )
1116
- : 0;
1114
+ const firstVariant = product.variants?.[0];
1115
+ const displayFinalPrice = firstVariant?.finalPrice ?? 0;
1116
+ const displayRetailPrice = firstVariant?.retailPrice ?? 0;
1117
+ const displayIsDiscounted = firstVariant?.isDiscounted ?? false;
1118
+ const displayInventoryCount = firstVariant?.inventoryCount ?? 0;
1117
1119
 
1118
1120
  return (
1119
1121
  <motion.div
@@ -1124,7 +1126,7 @@ export function ShopScreen({ initialFilters = {}, categoryName }: ShopScreenProp
1124
1126
  >
1125
1127
  <div className="relative h-48 w-full overflow-hidden rounded-2xl bg-gray-100 md:h-40 md:w-40">
1126
1128
  <Image
1127
- src={product.productMedia[0]?.file || '/placeholder-product.jpg'}
1129
+ src={product.media?.[0]?.file || '/placeholder-product.jpg'}
1128
1130
  alt={product.name}
1129
1131
  fill
1130
1132
  className="object-cover transition duration-500 group-hover:scale-105"
@@ -1133,12 +1135,7 @@ export function ShopScreen({ initialFilters = {}, categoryName }: ShopScreenProp
1133
1135
 
1134
1136
  <div className="flex-1 space-y-3">
1135
1137
  <div className="flex flex-wrap items-center gap-2 text-xs font-semibold uppercase tracking-wide text-primary-600">
1136
- {product.parentCategories.length > 0 && (
1137
- <span className="rounded-full bg-primary-50 px-3 py-1 text-primary-700">
1138
- {product.parentCategories.map((category) => category?.name).join(', ')}
1139
- </span>
1140
- )}
1141
- {product.tags?.slice(0, 3).map((tag) => (
1138
+ {product.tags?.slice(0, 3).map((tag: string) => (
1142
1139
  <span
1143
1140
  key={tag}
1144
1141
  className="rounded-full bg-slate-100 px-3 py-1 text-gray-600"
@@ -1153,7 +1150,7 @@ export function ShopScreen({ initialFilters = {}, categoryName }: ShopScreenProp
1153
1150
  <div className="flex flex-wrap items-center gap-4 text-sm text-gray-500">
1154
1151
  <span className="inline-flex items-center gap-2 font-medium text-primary-600">
1155
1152
  <ShieldCheck className="h-4 w-4" />
1156
- {product.inventoryCount > 0 ? 'In stock & ready to ship' : 'Restocking soon'}
1153
+ {displayInventoryCount > 0 ? 'In stock & ready to ship' : 'Restocking soon'}
1157
1154
  </span>
1158
1155
  <span className="inline-flex items-center gap-2">
1159
1156
  <Clock className="h-4 w-4 text-primary-500" />
@@ -1165,11 +1162,11 @@ export function ShopScreen({ initialFilters = {}, categoryName }: ShopScreenProp
1165
1162
  <div className="flex w-full flex-col items-end gap-3 md:w-auto">
1166
1163
  <div className="text-right">
1167
1164
  <p className="text-3xl font-semibold text-gray-900">
1168
- {formatPrice(product.finalPrice)}
1165
+ {formatPrice(displayFinalPrice)}
1169
1166
  </p>
1170
- {product.isDiscounted && (
1167
+ {displayIsDiscounted && (
1171
1168
  <p className="text-sm text-gray-400 line-through">
1172
- {formatPrice(product.priceBeforeDiscount)}
1169
+ {formatPrice(displayRetailPrice)}
1173
1170
  </p>
1174
1171
  )}
1175
1172
  </div>
@@ -12,6 +12,7 @@ import {
12
12
  ShoppingBag,
13
13
  Sparkles,
14
14
  Trash2,
15
+ Trash
15
16
  } from 'lucide-react';
16
17
  import { useRouter } from 'next/navigation';
17
18
  import { ProductCard } from '@/components/ProductCard';
@@ -21,7 +22,7 @@ import { useAuth } from '@/providers/AuthProvider';
21
22
  import { useWishlistProducts } from '@/hooks/useWishlistProducts';
22
23
  import Image from 'next/image';
23
24
  import { formatPrice } from '@/lib/utils/format';
24
- import { ExtendedProductDTO } from '@/lib/Apis';
25
+ import { Product } from '@/lib/Apis';
25
26
  import { useBasePath } from '@/providers/BasePathProvider';
26
27
  import { useNotification } from '@/providers/NotificationProvider';
27
28
 
@@ -95,23 +96,26 @@ export default function WishlistScreen() {
95
96
  };
96
97
 
97
98
  const totalValue = useMemo(
98
- () => wishlistProducts.reduce((sum, product) => sum + (product.finalPrice ?? 0), 0),
99
+ () => wishlistProducts.reduce((sum, product) => sum + (product.summary?.minPrice ?? 0), 0),
99
100
  [wishlistProducts]
100
101
  );
101
102
 
102
103
  const totalSavings = useMemo(
103
104
  () =>
104
105
  wishlistProducts.reduce((sum, product) => {
105
- const before = product.priceBeforeDiscount ?? product.finalPrice ?? 0;
106
- const after = product.finalPrice ?? 0;
107
- const savings = Math.max(before - after, 0);
108
- return sum + savings;
106
+ // Calculate savings if product has discount
107
+ if (product.summary?.hasDiscount) {
108
+ const maxPrice = product.summary?.maxPrice ?? 0;
109
+ const minPrice = product.summary?.minPrice ?? 0;
110
+ return sum + (maxPrice - minPrice);
111
+ }
112
+ return sum;
109
113
  }, 0),
110
114
  [wishlistProducts]
111
115
  );
112
116
 
113
117
  const inStockCount = useMemo(
114
- () => wishlistProducts.filter((product) => (product.inventoryCount ?? 0) > 0).length,
118
+ () => wishlistProducts.filter((product) => (product.summary?.totalInventory ?? 0) > 0).length,
115
119
  [wishlistProducts]
116
120
  );
117
121
 
@@ -119,25 +123,25 @@ export default function WishlistScreen() {
119
123
  let list = [...wishlistProducts];
120
124
 
121
125
  if (onlyInStock) {
122
- list = list.filter((product) => (product.inventoryCount ?? 0) > 0);
126
+ list = list.filter((product) => (product.summary?.totalInventory ?? 0) > 0);
123
127
  }
124
128
 
125
129
  switch (sortOption) {
126
130
  case 'price-low':
127
- list.sort((a, b) => (a.finalPrice ?? 0) - (b.finalPrice ?? 0));
131
+ list.sort((a, b) => (a.summary?.minPrice ?? 0) - (b.summary?.minPrice ?? 0));
128
132
  break;
129
133
  case 'price-high':
130
- list.sort((a, b) => (b.finalPrice ?? 0) - (a.finalPrice ?? 0));
134
+ list.sort((a, b) => (b.summary?.maxPrice ?? 0) - (a.summary?.maxPrice ?? 0));
131
135
  break;
132
136
  case 'name':
133
137
  list.sort((a, b) => (a.name || '').localeCompare(b.name || ''));
134
138
  break;
135
139
  case 'availability':
136
- list.sort((a, b) => (b.inventoryCount ?? 0) - (a.inventoryCount ?? 0));
140
+ list.sort((a, b) => (b.summary?.totalInventory ?? 0) - (a.summary?.totalInventory ?? 0));
137
141
  break;
138
142
  case 'featured':
139
143
  default:
140
- list.sort((a, b) => (b.totalSold ?? 0) - (a.totalSold ?? 0));
144
+ list.sort((a, b) => (b.summary?.totalSold ?? 0) - (a.summary?.totalSold ?? 0));
141
145
  break;
142
146
  }
143
147
 
@@ -318,9 +322,9 @@ export default function WishlistScreen() {
318
322
  transition={{ duration: 0.2 }}
319
323
  >
320
324
  <ProductCard
321
- product={product as ExtendedProductDTO}
322
- onClickProduct={(p) => router.push(buildPath(`/products/${p.id}`))}
323
- onFavorite={() => handleRemoveFromWishlist(product.id)}
325
+ product={product as Product}
326
+ onClickProduct={(p) => router.push(buildPath(`/products/${p._id}`))}
327
+ onFavorite={() => handleRemoveFromWishlist(product._id || product.id || '')}
324
328
  isFavorited
325
329
  />
326
330
  </motion.div>
@@ -343,7 +347,7 @@ export default function WishlistScreen() {
343
347
  <div className="relative h-28 w-full overflow-hidden rounded-2xl bg-white sm:w-40">
344
348
  <Image
345
349
  fill
346
- src={product.productMedia?.[0]?.file || '/placeholder-product.jpg'}
350
+ src={product.media?.[0]?.file || '/placeholder-product.jpg'}
347
351
  alt={product.name || 'Wishlist item'}
348
352
  className="h-full w-full object-cover"
349
353
  />
@@ -355,47 +359,47 @@ export default function WishlistScreen() {
355
359
  {product.name}
356
360
  </h3>
357
361
  <p className="text-sm text-muted">
358
- {product.parentCategories?.map((category) => category?.name).join(', ') || 'General wellness'}
362
+ General wellness
359
363
  </p>
360
364
  </div>
361
365
  <div className="text-right">
362
366
  <p className="text-lg font-bold text-primary">
363
- {formatPrice(product.finalPrice ?? 0)}
367
+ {formatPrice(product.summary?.minPrice ?? 0)}
364
368
  </p>
365
- {product.isDiscounted && (
369
+ {product.summary?.hasDiscount && (
366
370
  <p className="text-xs text-emerald-500">
367
- You save {formatPrice(Math.max((product.priceBeforeDiscount ?? 0) - (product.finalPrice ?? 0), 0))}
371
+ You save {formatPrice(Math.max((product.summary?.maxPrice ?? 0) - (product.summary?.minPrice ?? 0), 0))}
368
372
  </p>
369
373
  )}
370
374
  </div>
371
375
  </div>
372
376
  <div className="flex flex-wrap items-center gap-3 text-xs text-slate-500">
373
- <span className={`inline-flex items-center gap-1 rounded-full px-2.5 py-1 font-medium ${product.inventoryCount > 0 ? 'bg-emerald-100 text-emerald-700' : 'bg-rose-100 text-rose-700'}`}>
377
+ <span className={`inline-flex items-center gap-1 rounded-full px-2.5 py-1 font-medium ${(product.summary?.totalInventory ?? 0) > 0 ? 'bg-emerald-100 text-emerald-700' : 'bg-rose-100 text-rose-700'}`}>
374
378
  <Package className="h-3.5 w-3.5" />
375
- {product.inventoryCount > 0 ? 'In stock' : 'Backordered'}
379
+ {(product.summary?.totalInventory ?? 0) > 0 ? 'In stock' : 'Backordered'}
376
380
  </span>
377
- {product.totalSold > 0 && (
381
+ {(product.summary?.totalSold ?? 0) > 0 && (
378
382
  <span className="inline-flex items-center gap-1 rounded-full bg-slate-200 px-2.5 py-1 font-medium text-slate-700">
379
383
  <Sparkles className="h-3.5 w-3.5" />
380
- {product.totalSold}+ purchased
384
+ {product.summary?.totalSold}+ purchased
381
385
  </span>
382
386
  )}
383
387
  </div>
384
388
  <div className="flex flex-wrap gap-2">
385
389
  <Button
386
390
  size="sm"
387
- onClick={() => router.push(buildPath(`/products/${product.id}`))}
391
+ onClick={() => router.push(buildPath(`/products/${product._id}`))}
392
+ className='bg-primary/90 text-white hover:bg-primary/70'
388
393
  >
389
394
  View details
390
395
  </Button>
391
- <Button
392
- size="sm"
393
- variant="outline-solid"
394
- onClick={() => handleRemoveFromWishlist(product.id)}
395
- className="text-secondary"
396
+ <button
397
+ onClick={() => handleRemoveFromWishlist(product._id || product.id || '')}
398
+ className='text-red-500 hover:text-red-600 hover:bg-red-50 transition-colors cursor-pointer border border-red-500 rounded-full px-4 py-1 text-sm flex-row'
396
399
  >
400
+ {/* <Trash className="h-4 w-4" /> */}
397
401
  Remove
398
- </Button>
402
+ </button>
399
403
  </div>
400
404
  </div>
401
405
  </motion.div>