@pradip1995/segment-powerhouse-carousel 0.1.3 → 0.1.5
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/package.json +1 -1
- package/src/carousel.css +7 -1
- package/src/product-card.tsx +37 -7
- package/src/wishlist-button.tsx +11 -3
package/package.json
CHANGED
package/src/carousel.css
CHANGED
|
@@ -291,9 +291,15 @@
|
|
|
291
291
|
background: #f1eeae;
|
|
292
292
|
border: 1px solid #f2f682;
|
|
293
293
|
color: #1d1d1d;
|
|
294
|
+
cursor: pointer;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
.powerhouse-carousel__quickshop:disabled {
|
|
298
|
+
opacity: 0.55;
|
|
299
|
+
cursor: not-allowed;
|
|
294
300
|
}
|
|
295
301
|
|
|
296
|
-
.powerhouse-carousel__quickshop:hover {
|
|
302
|
+
.powerhouse-carousel__quickshop:hover:not(:disabled) {
|
|
297
303
|
background: #f4f1be;
|
|
298
304
|
}
|
|
299
305
|
|
package/src/product-card.tsx
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { useState } from "react"
|
|
4
4
|
import { useRouter } from "next/navigation"
|
|
5
|
-
import { addToCart } from "@pradip1995/commerce-core/client/actions/cart"
|
|
5
|
+
import { addToCart, buyNow } from "@pradip1995/commerce-core/client/actions/cart"
|
|
6
6
|
import LocalizedLink from "@pradip1995/segment-primitives/localized-link"
|
|
7
7
|
import { formatPrice } from "@pradip1995/segment-primitives/format-price"
|
|
8
8
|
import { isNextRedirect } from "@pradip1995/segment-primitives/is-next-redirect"
|
|
@@ -19,6 +19,7 @@ type Props = {
|
|
|
19
19
|
export default function ProductCard({ product, region, countryCode, wishlistProductIds }: Props) {
|
|
20
20
|
const router = useRouter()
|
|
21
21
|
const [adding, setAdding] = useState(false)
|
|
22
|
+
const [buying, setBuying] = useState(false)
|
|
22
23
|
const variant = product.variants?.[0]
|
|
23
24
|
const price = variant?.calculated_price?.calculated_amount
|
|
24
25
|
const originalPrice = variant?.calculated_price?.original_amount
|
|
@@ -32,17 +33,19 @@ export default function ProductCard({ product, region, countryCode, wishlistProd
|
|
|
32
33
|
(inventory ?? 0) > 0
|
|
33
34
|
const href = `/products/${product.handle}`
|
|
34
35
|
const hasOptions = (product.variants?.length ?? 0) > 1
|
|
36
|
+
const busy = adding || buying
|
|
37
|
+
const code = countryCode.toLowerCase()
|
|
35
38
|
|
|
36
39
|
const handleAdd = async (event: React.MouseEvent) => {
|
|
37
40
|
event.preventDefault()
|
|
38
41
|
event.stopPropagation()
|
|
39
|
-
if (!variant?.id ||
|
|
42
|
+
if (!variant?.id || busy || !inStock || hasOptions) return
|
|
40
43
|
setAdding(true)
|
|
41
44
|
try {
|
|
42
45
|
await addToCart({
|
|
43
46
|
variantId: variant.id,
|
|
44
47
|
quantity: 1,
|
|
45
|
-
countryCode:
|
|
48
|
+
countryCode: code,
|
|
46
49
|
})
|
|
47
50
|
window.dispatchEvent(new CustomEvent("cart:item-added", { detail: { message: "Added to cart" } }))
|
|
48
51
|
router.refresh()
|
|
@@ -55,6 +58,26 @@ export default function ProductCard({ product, region, countryCode, wishlistProd
|
|
|
55
58
|
}
|
|
56
59
|
}
|
|
57
60
|
|
|
61
|
+
const handleBuyNow = async (event: React.MouseEvent) => {
|
|
62
|
+
event.preventDefault()
|
|
63
|
+
event.stopPropagation()
|
|
64
|
+
if (!variant?.id || busy || !inStock) return
|
|
65
|
+
setBuying(true)
|
|
66
|
+
try {
|
|
67
|
+
await buyNow({
|
|
68
|
+
variantId: variant.id,
|
|
69
|
+
quantity: 1,
|
|
70
|
+
countryCode: code,
|
|
71
|
+
})
|
|
72
|
+
router.refresh()
|
|
73
|
+
} catch (err) {
|
|
74
|
+
if (isNextRedirect(err)) throw err
|
|
75
|
+
const message = err instanceof Error ? err.message : "Buy now failed"
|
|
76
|
+
window.dispatchEvent(new CustomEvent("cart:item-added", { detail: { message, variant: "error" } }))
|
|
77
|
+
setBuying(false)
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
58
81
|
return (
|
|
59
82
|
<article className={`powerhouse-carousel__card${onSale ? " is-sale" : ""}`}>
|
|
60
83
|
<div className="powerhouse-carousel__media-wrap">
|
|
@@ -101,9 +124,16 @@ export default function ProductCard({ product, region, countryCode, wishlistProd
|
|
|
101
124
|
)}
|
|
102
125
|
|
|
103
126
|
<div className="powerhouse-carousel__actions">
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
127
|
+
{inStock ? (
|
|
128
|
+
<button
|
|
129
|
+
type="button"
|
|
130
|
+
className="powerhouse-carousel__quickshop"
|
|
131
|
+
onClick={handleBuyNow}
|
|
132
|
+
disabled={busy || !variant?.id}
|
|
133
|
+
>
|
|
134
|
+
{buying ? "Processing…" : "Buy now"}
|
|
135
|
+
</button>
|
|
136
|
+
) : null}
|
|
107
137
|
{hasOptions ? (
|
|
108
138
|
<LocalizedLink href={href} countryCode={countryCode} className="powerhouse-carousel__atc">
|
|
109
139
|
Choose options
|
|
@@ -113,7 +143,7 @@ export default function ProductCard({ product, region, countryCode, wishlistProd
|
|
|
113
143
|
type="button"
|
|
114
144
|
className="powerhouse-carousel__atc"
|
|
115
145
|
onClick={handleAdd}
|
|
116
|
-
disabled={
|
|
146
|
+
disabled={busy || !variant?.id || !inStock}
|
|
117
147
|
>
|
|
118
148
|
{adding ? "Adding…" : !inStock ? "Sold out" : "Add to cart"}
|
|
119
149
|
</button>
|
package/src/wishlist-button.tsx
CHANGED
|
@@ -7,7 +7,10 @@ import {
|
|
|
7
7
|
getWishlistProductIds,
|
|
8
8
|
removeFromWishlist,
|
|
9
9
|
} from "@pradip1995/commerce-core/client/actions/wishlist"
|
|
10
|
-
import LoginRequiredModal
|
|
10
|
+
import LoginRequiredModal, {
|
|
11
|
+
isAuthRequiredError,
|
|
12
|
+
promptLoginForWishlist,
|
|
13
|
+
} from "@pradip1995/segment-login-popup/required"
|
|
11
14
|
|
|
12
15
|
type WishlistButtonProps = {
|
|
13
16
|
productId?: string | null
|
|
@@ -60,8 +63,13 @@ export default function WishlistButton({
|
|
|
60
63
|
return
|
|
61
64
|
}
|
|
62
65
|
|
|
63
|
-
if (result.error
|
|
64
|
-
setLoginRequired(true)
|
|
66
|
+
if (isAuthRequiredError(result.error)) {
|
|
67
|
+
promptLoginForWishlist(() => setLoginRequired(true))
|
|
68
|
+
}
|
|
69
|
+
} catch (error) {
|
|
70
|
+
const message = error instanceof Error ? error.message : ""
|
|
71
|
+
if (isAuthRequiredError(message) || !message) {
|
|
72
|
+
promptLoginForWishlist(() => setLoginRequired(true))
|
|
65
73
|
}
|
|
66
74
|
} finally {
|
|
67
75
|
setLoading(false)
|