hey-pharmacist-ecommerce 1.1.17 → 1.1.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +35 -15
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +35 -15
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/ProductCard.tsx +28 -8
- package/src/components/QuickViewModal.tsx +11 -7
- package/src/screens/CartScreen.tsx +1 -1
- package/src/screens/CheckoutScreen.tsx +2 -2
- package/src/screens/ProductDetailScreen.tsx +8 -8
- package/src/screens/ShopScreen.tsx +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hey-pharmacist-ecommerce",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.18",
|
|
4
4
|
"description": "Production-ready, multi-tenant e‑commerce UI + API adapter for Next.js with auth, carts, checkout, orders, theming, and pharmacist-focused UX.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -141,6 +141,26 @@ export function ProductCard({
|
|
|
141
141
|
return selectedVariant?.name || product.name;
|
|
142
142
|
}, [selectedVariant, product.name]);
|
|
143
143
|
|
|
144
|
+
const displayFinalPrice = useMemo(() => {
|
|
145
|
+
return selectedVariant?.finalPrice ?? product.finalPrice;
|
|
146
|
+
}, [selectedVariant, product.finalPrice]);
|
|
147
|
+
|
|
148
|
+
const displayPriceBeforeDiscount = useMemo(() => {
|
|
149
|
+
return selectedVariant?.retailPrice ?? product.priceBeforeDiscount;
|
|
150
|
+
}, [selectedVariant, product.priceBeforeDiscount]);
|
|
151
|
+
|
|
152
|
+
const displayIsDiscounted = useMemo(() => {
|
|
153
|
+
return selectedVariant ? selectedVariant.isDiscounted : product.isDiscounted;
|
|
154
|
+
}, [selectedVariant, product.isDiscounted]);
|
|
155
|
+
|
|
156
|
+
const displayDiscountAmount = useMemo(() => {
|
|
157
|
+
return selectedVariant ? selectedVariant.discountAmount : product.discountAmount;
|
|
158
|
+
}, [selectedVariant, product.discountAmount]);
|
|
159
|
+
|
|
160
|
+
const displayInventoryCount = useMemo(() => {
|
|
161
|
+
return selectedVariant ? selectedVariant.inventoryCount : product.inventoryCount;
|
|
162
|
+
}, [selectedVariant, product.inventoryCount]);
|
|
163
|
+
|
|
144
164
|
const imageSource = useMemo(() => {
|
|
145
165
|
const src = selectedVariantImage || product.productMedia?.[0]?.file || '/placeholder-product.jpg';
|
|
146
166
|
return {
|
|
@@ -194,7 +214,7 @@ export function ProductCard({
|
|
|
194
214
|
<Eye className="size-4 text-[#2B4B7C]" />
|
|
195
215
|
</button>
|
|
196
216
|
|
|
197
|
-
{
|
|
217
|
+
{displayInventoryCount === 0 && (
|
|
198
218
|
<div className="absolute inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center">
|
|
199
219
|
<div className="bg-white rounded-full px-4 py-2">
|
|
200
220
|
<span className="font-['Poppins',sans-serif] font-bold text-[11px] text-[#2B4B7C] uppercase">
|
|
@@ -210,9 +230,9 @@ export function ProductCard({
|
|
|
210
230
|
<div className="p-0 flex-1 flex flex-col">
|
|
211
231
|
{/* ALL Status Badges */}
|
|
212
232
|
<div className="flex items-center gap-1 mb-2 flex-wrap">
|
|
213
|
-
{
|
|
233
|
+
{displayIsDiscounted && (
|
|
214
234
|
<span className="bg-[#E67E50] text-white rounded-full px-2 py-0.5 flex items-center gap-1">
|
|
215
|
-
<span className="font-['Poppins',sans-serif] font-bold text-[8px] uppercase">-{
|
|
235
|
+
<span className="font-['Poppins',sans-serif] font-bold text-[8px] uppercase">-{displayDiscountAmount}%</span>
|
|
216
236
|
</span>
|
|
217
237
|
)}
|
|
218
238
|
{/* {product.dealOfWeek && (
|
|
@@ -264,11 +284,11 @@ export function ProductCard({
|
|
|
264
284
|
{/* Price */}
|
|
265
285
|
<div className="flex items-center gap-1.5 mb-3">
|
|
266
286
|
<span className="font-['Poppins',sans-serif] font-bold text-md text-primary-600">
|
|
267
|
-
${
|
|
287
|
+
${displayFinalPrice.toFixed(2)}
|
|
268
288
|
</span>
|
|
269
|
-
{
|
|
289
|
+
{displayIsDiscounted && (
|
|
270
290
|
<span className="font-['Poppins',sans-serif] text-sm text-[#676c80] line-through">
|
|
271
|
-
${formatPrice(
|
|
291
|
+
${formatPrice(displayPriceBeforeDiscount)}
|
|
272
292
|
</span>
|
|
273
293
|
)}
|
|
274
294
|
</div>
|
|
@@ -331,11 +351,11 @@ export function ProductCard({
|
|
|
331
351
|
console.error('Failed to add to cart', error);
|
|
332
352
|
}
|
|
333
353
|
}}
|
|
334
|
-
disabled={isAddingToCart || (variantImages.length > 0 && !selectedVariantId)}
|
|
354
|
+
disabled={isAddingToCart || (variantImages.length > 0 && !selectedVariantId) || displayInventoryCount === 0}
|
|
335
355
|
className="w-full font-['Poppins',sans-serif] font-medium text-[11px] px-3 py-2 rounded-full bg-[#5B9BD5] text-white hover:bg-[#4a8ac4] hover:shadow-lg transition-all duration-300 flex items-center justify-center gap-1.5 disabled:opacity-50 disabled:cursor-not-allowed"
|
|
336
356
|
>
|
|
337
357
|
<ShoppingCart className="h-4 w-4" />
|
|
338
|
-
{
|
|
358
|
+
{displayInventoryCount === 0 ? 'Out of Stock' : 'Add to Cart'}
|
|
339
359
|
</button>
|
|
340
360
|
</div>
|
|
341
361
|
|
|
@@ -29,7 +29,11 @@ export function QuickViewModal({ product, onClose, onNavigateToProduct }: QuickV
|
|
|
29
29
|
};
|
|
30
30
|
const selectedVariant = product.productVariants[selectedVariantIndex];
|
|
31
31
|
const selectedSize = selectedVariant.productMedia[selectedSizeIndex];
|
|
32
|
-
const displayPrice =
|
|
32
|
+
const displayPrice = selectedVariant.finalPrice;
|
|
33
|
+
const displayOriginalPrice = selectedVariant.retailPrice;
|
|
34
|
+
const isDiscounted = selectedVariant.isDiscounted;
|
|
35
|
+
const discountAmount = selectedVariant.discountAmount;
|
|
36
|
+
const displayName = selectedVariant.name || product.name;
|
|
33
37
|
|
|
34
38
|
const handleAddToCart = async () => {
|
|
35
39
|
if (!product || !selectedVariant) return;
|
|
@@ -74,7 +78,7 @@ export function QuickViewModal({ product, onClose, onNavigateToProduct }: QuickV
|
|
|
74
78
|
{product.brand} • {product.parentCategories[0].name}
|
|
75
79
|
</p>
|
|
76
80
|
<h2 className="font-['Poppins',sans-serif] font-semibold text-secondary tracking-[-1px]">
|
|
77
|
-
{
|
|
81
|
+
{displayName}
|
|
78
82
|
</h2>
|
|
79
83
|
|
|
80
84
|
{/* Rating */}
|
|
@@ -115,10 +119,10 @@ export function QuickViewModal({ product, onClose, onNavigateToProduct }: QuickV
|
|
|
115
119
|
/>
|
|
116
120
|
{/* Badges */}
|
|
117
121
|
<div className="absolute top-4 left-4 flex flex-col gap-2">
|
|
118
|
-
{
|
|
122
|
+
{isDiscounted && (
|
|
119
123
|
<div className="bg-accent text-white rounded-full px-3 py-1.5">
|
|
120
124
|
<span className="font-['Poppins',sans-serif] font-bold text-[11px] uppercase">
|
|
121
|
-
-{
|
|
125
|
+
-{discountAmount}%
|
|
122
126
|
</span>
|
|
123
127
|
</div>
|
|
124
128
|
)}
|
|
@@ -159,9 +163,9 @@ export function QuickViewModal({ product, onClose, onNavigateToProduct }: QuickV
|
|
|
159
163
|
<span className="font-['Poppins',sans-serif] font-bold text-[32px] text-accent">
|
|
160
164
|
${displayPrice.toFixed(2)}
|
|
161
165
|
</span>
|
|
162
|
-
{
|
|
166
|
+
{isDiscounted && (
|
|
163
167
|
<span className="font-['Poppins',sans-serif] text-[20px] text-muted line-through">
|
|
164
|
-
${
|
|
168
|
+
${displayOriginalPrice.toFixed(2)}
|
|
165
169
|
</span>
|
|
166
170
|
)}
|
|
167
171
|
</div>
|
|
@@ -173,7 +177,7 @@ export function QuickViewModal({ product, onClose, onNavigateToProduct }: QuickV
|
|
|
173
177
|
Out of Stock
|
|
174
178
|
</span>
|
|
175
179
|
) : selectedVariant.inventoryCount <= 10 ? (
|
|
176
|
-
<span className="font-['Poppins',sans-serif] text-[12px] text-
|
|
180
|
+
<span className="font-['Poppins',sans-serif] text-[12px] text-primary font-medium flex items-center gap-1">
|
|
177
181
|
<Package className="size-3" />
|
|
178
182
|
Only {selectedVariant.inventoryCount} left in stock
|
|
179
183
|
</span>
|
|
@@ -167,7 +167,7 @@ export function CartScreen() {
|
|
|
167
167
|
<div className="border-t border-gray-200 pt-4 mt-4">
|
|
168
168
|
<div className="flex items-center justify-between">
|
|
169
169
|
<span className="text-lg font-bold text-secondary">Total</span>
|
|
170
|
-
<span className="text-2xl font-bold text-
|
|
170
|
+
<span className="text-2xl font-bold text-primary">{formatPrice(total)}</span>
|
|
171
171
|
</div>
|
|
172
172
|
</div>
|
|
173
173
|
</div>
|
|
@@ -668,7 +668,7 @@ export function CheckoutScreen() {
|
|
|
668
668
|
{rate.provider} {rate.servicelevel?.name}
|
|
669
669
|
</h3>
|
|
670
670
|
{isTest && (
|
|
671
|
-
<span className="px-2 py-1 text-xs font-medium bg-
|
|
671
|
+
<span className="px-2 py-1 text-xs font-medium bg-primary-100 text-primary-800 rounded-full">
|
|
672
672
|
TEST
|
|
673
673
|
</span>
|
|
674
674
|
)}
|
|
@@ -974,7 +974,7 @@ export function CheckoutScreen() {
|
|
|
974
974
|
|
|
975
975
|
<div className="bg-white/80 rounded-xl p-4">
|
|
976
976
|
<p className="font-['Poppins',sans-serif] text-[11px] text-[#676c80] leading-[1.6]">
|
|
977
|
-
<strong className="text-[#2B4B7C]">Payment:</strong> We
|
|
977
|
+
<strong className="text-[#2B4B7C]">Payment:</strong> We'll contact you to arrange payment upon pickup or delivery. We accept cash, credit cards, and all major payment methods.
|
|
978
978
|
</p>
|
|
979
979
|
</div>
|
|
980
980
|
</section>
|
|
@@ -381,10 +381,10 @@ export function ProductDetailScreen({ productId }: ProductDetailScreenProps) {
|
|
|
381
381
|
) : null}
|
|
382
382
|
|
|
383
383
|
<div className="absolute top-6 left-6 flex flex-col gap-3">
|
|
384
|
-
{
|
|
384
|
+
{discount > 0 && (
|
|
385
385
|
<div className="bg-[#E67E50] text-white rounded-full px-4 py-2">
|
|
386
386
|
<span className="font-['Poppins',sans-serif] font-bold text-[12px] uppercase tracking-wide">
|
|
387
|
-
Save {
|
|
387
|
+
Save {discount}%
|
|
388
388
|
</span>
|
|
389
389
|
</div>
|
|
390
390
|
)}
|
|
@@ -442,7 +442,7 @@ export function ProductDetailScreen({ productId }: ProductDetailScreenProps) {
|
|
|
442
442
|
{product.brand} • {product.parentCategories?.[0].name}
|
|
443
443
|
</p>
|
|
444
444
|
<h1 className="text-3xl font-['Poppins',sans-serif] font-semibold text-secondary tracking-[-1.5px] mb-3">
|
|
445
|
-
{product.name}
|
|
445
|
+
{selectedVariant?.name || product.name}
|
|
446
446
|
</h1>
|
|
447
447
|
{/* Rating */}
|
|
448
448
|
<div className="flex items-center gap-3">
|
|
@@ -465,16 +465,16 @@ export function ProductDetailScreen({ productId }: ProductDetailScreenProps) {
|
|
|
465
465
|
|
|
466
466
|
<div className="flex items-center gap-3 mb-6 pb-6 border-b-2 border-gray-100">
|
|
467
467
|
<span className="font-['Poppins',sans-serif] font-bold text-[40px] text-[#E67E50]">
|
|
468
|
-
{
|
|
468
|
+
${variantPrice.toFixed(2)}
|
|
469
469
|
</span>
|
|
470
470
|
{variantComparePrice && variantComparePrice > variantPrice && (
|
|
471
471
|
<>
|
|
472
472
|
<span className="font-['Poppins',sans-serif] text-[24px] text-muted line-through">
|
|
473
|
-
${
|
|
473
|
+
${variantComparePrice.toFixed(2)}
|
|
474
474
|
</span>
|
|
475
475
|
<div className="px-3 py-1 rounded-full bg-[#E67E50]/10">
|
|
476
476
|
<span className="font-['Poppins',sans-serif] font-semibold text-[13px] text-[#E67E50]">
|
|
477
|
-
Save ${formatPrice(variantComparePrice)}
|
|
477
|
+
Save ${formatPrice(variantComparePrice - variantPrice)}
|
|
478
478
|
</span>
|
|
479
479
|
</div>
|
|
480
480
|
</>
|
|
@@ -495,8 +495,8 @@ export function ProductDetailScreen({ productId }: ProductDetailScreenProps) {
|
|
|
495
495
|
</>
|
|
496
496
|
) : selectedVariant.inventoryCount <= 10 ? (
|
|
497
497
|
<>
|
|
498
|
-
<div className="size-3 rounded-full bg-
|
|
499
|
-
<span className="font-['Poppins',sans-serif] text-[13px] text-
|
|
498
|
+
<div className="size-3 rounded-full bg-primary animate-pulse" />
|
|
499
|
+
<span className="font-['Poppins',sans-serif] text-[13px] text-primary font-medium">
|
|
500
500
|
Only {selectedVariant.inventoryCount} left in stock - Order soon!
|
|
501
501
|
</span>
|
|
502
502
|
</>
|
|
@@ -881,8 +881,8 @@ export function ShopScreen({ initialFilters = {}, categoryName }: ShopScreenProp
|
|
|
881
881
|
>
|
|
882
882
|
{/* Orange icon and badge */}
|
|
883
883
|
<div className="flex items-center justify-center gap-2 mb-4">
|
|
884
|
-
<Star className="h-5 w-5 text-
|
|
885
|
-
<span className="text-sm font-semibold uppercase tracking-wider text-
|
|
884
|
+
<Star className="h-5 w-5 text-primary fill-primary" />
|
|
885
|
+
<span className="text-sm font-semibold uppercase tracking-wider text-primary">
|
|
886
886
|
COMPLETE PHARMACY SHOP
|
|
887
887
|
</span>
|
|
888
888
|
</div>
|