@pradip1995/segment-powerhouse-shop 0.1.1

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 ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@pradip1995/segment-powerhouse-shop",
3
+ "version": "0.1.1",
4
+ "license": "MIT",
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
8
+ "sideEffects": [
9
+ "./src/shop.css"
10
+ ],
11
+ "files": [
12
+ "src"
13
+ ],
14
+ "exports": {
15
+ ".": "./src/index.ts",
16
+ "./manifest": "./src/manifest.ts"
17
+ },
18
+ "peerDependencies": {
19
+ "@medusajs/types": "^2.0.0",
20
+ "@pradip1995/plugin-sdk": "^0.2.0",
21
+ "next": ">=15",
22
+ "react": ">=19",
23
+ "react-dom": ">=19"
24
+ },
25
+ "dependencies": {
26
+ "@pradip1995/commerce-core": "^4.0.0",
27
+ "@pradip1995/segment-primitives": "^0.4.0"
28
+ },
29
+ "devDependencies": {
30
+ "@medusajs/types": "^2.0.0",
31
+ "@pradip1995/plugin-sdk": "^0.2.0",
32
+ "@types/react": "^19",
33
+ "react": "19.0.3",
34
+ "typescript": "^5.7.2"
35
+ },
36
+ "scripts": {
37
+ "typecheck": "tsc --noEmit",
38
+ "lint": "tsc --noEmit"
39
+ }
40
+ }
package/src/index.ts ADDED
@@ -0,0 +1,2 @@
1
+ export { default } from "./segment"
2
+ export { default as manifest } from "./manifest"
@@ -0,0 +1,10 @@
1
+ import type { SegmentManifest } from "@pradip1995/plugin-sdk"
2
+
3
+ const manifest: SegmentManifest = {
4
+ id: "powerhouse-shop",
5
+ type: "segment",
6
+ version: "0.1.0",
7
+ compatibleFramework: ["^1.0.0"],
8
+ dataKey: "store",
9
+ }
10
+ export default manifest
@@ -0,0 +1,132 @@
1
+ "use client"
2
+
3
+ import { useState, type MouseEvent } from "react"
4
+ import { useRouter } from "next/navigation"
5
+ import { addToCart } from "@pradip1995/commerce-core/client/actions/cart"
6
+ import LocalizedLink from "@pradip1995/segment-primitives/localized-link"
7
+ import { formatPrice } from "@pradip1995/segment-primitives/format-price"
8
+ import { isNextRedirect } from "@pradip1995/segment-primitives/is-next-redirect"
9
+ import type { HttpTypes } from "@medusajs/types"
10
+
11
+ function stripHtml(value?: string | null) {
12
+ if (!value) return ""
13
+ return value.replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim()
14
+ }
15
+
16
+ function snippet(value?: string | null, length = 140) {
17
+ const text = stripHtml(value)
18
+ if (text.length <= length) return text
19
+ return `${text.slice(0, length).trim()}...`
20
+ }
21
+
22
+ export default function ShopProductCard({
23
+ product,
24
+ countryCode,
25
+ }: {
26
+ product: HttpTypes.StoreProduct
27
+ countryCode: string
28
+ }) {
29
+ const router = useRouter()
30
+ const [adding, setAdding] = useState(false)
31
+ const variants = product.variants ?? []
32
+ const variant = variants[0]
33
+ const price = variant?.calculated_price?.calculated_amount
34
+ const originalPrice = variant?.calculated_price?.original_amount
35
+ const currency = variant?.calculated_price?.currency_code || "inr"
36
+ const onSale = originalPrice != null && price != null && originalPrice > price
37
+ const saved = onSale && originalPrice != null && price != null ? originalPrice - price : null
38
+ const inventory = variant?.inventory_quantity
39
+ const inStock =
40
+ variant?.manage_inventory === false ||
41
+ variant?.allow_backorder === true ||
42
+ (inventory ?? 0) > 0
43
+ const lowStock = inventory != null && inventory > 0 && inventory <= 5
44
+ const href = `/products/${product.handle}`
45
+ const hasOptions = variants.length > 1
46
+ const copy = snippet(product.description)
47
+
48
+ const handleAdd = async (event: MouseEvent) => {
49
+ event.preventDefault()
50
+ event.stopPropagation()
51
+ if (!variant?.id || adding || !inStock || hasOptions) return
52
+ setAdding(true)
53
+ try {
54
+ await addToCart({
55
+ variantId: variant.id,
56
+ quantity: 1,
57
+ countryCode,
58
+ })
59
+ window.dispatchEvent(new CustomEvent("cart:item-added", { detail: { message: "Added to cart" } }))
60
+ router.refresh()
61
+ } catch (err) {
62
+ if (isNextRedirect(err)) throw err
63
+ const message = err instanceof Error ? err.message : "Could not add to cart"
64
+ window.dispatchEvent(new CustomEvent("cart:item-added", { detail: { message, variant: "error" } }))
65
+ } finally {
66
+ setAdding(false)
67
+ }
68
+ }
69
+
70
+ return (
71
+ <article className={`powerhouse-shop__card${onSale ? " is-sale" : ""}`}>
72
+ <LocalizedLink href={href} countryCode={countryCode} className="powerhouse-shop__media" tabIndex={-1}>
73
+ {product.thumbnail?.trim() ? (
74
+ <img src={product.thumbnail.trim()} alt={product.title || ""} />
75
+ ) : (
76
+ <div className="powerhouse-shop__placeholder" />
77
+ )}
78
+ {onSale && saved != null ? (
79
+ <span className="powerhouse-shop__badge">Save {formatPrice(saved, currency)}</span>
80
+ ) : null}
81
+ {!inStock ? <span className="powerhouse-shop__sold">Sold out</span> : null}
82
+ </LocalizedLink>
83
+
84
+ <div className="powerhouse-shop__info">
85
+ <h2 className="powerhouse-shop__name">
86
+ <LocalizedLink href={href} countryCode={countryCode}>
87
+ {product.title}
88
+ </LocalizedLink>
89
+ </h2>
90
+
91
+ {lowStock ? (
92
+ <p className="powerhouse-shop__stock">Only {inventory} left!</p>
93
+ ) : inStock ? (
94
+ <p className="powerhouse-shop__stock is-ok">in stock</p>
95
+ ) : (
96
+ <p className="powerhouse-shop__stock is-out">Out of stock</p>
97
+ )}
98
+
99
+ {copy ? <p className="powerhouse-shop__excerpt">{copy}</p> : null}
100
+
101
+ {price != null ? (
102
+ <div className="powerhouse-shop__price">
103
+ {onSale && originalPrice != null ? (
104
+ <span className="powerhouse-shop__compare">{formatPrice(originalPrice, currency)}</span>
105
+ ) : null}
106
+ <span className="powerhouse-shop__current">{formatPrice(price, currency)}</span>
107
+ </div>
108
+ ) : null}
109
+
110
+ <div className="powerhouse-shop__actions">
111
+ <LocalizedLink href={href} countryCode={countryCode} className="powerhouse-shop__quickshop">
112
+ Quick shop
113
+ </LocalizedLink>
114
+ {hasOptions ? (
115
+ <LocalizedLink href={href} countryCode={countryCode} className="powerhouse-shop__atc">
116
+ Choose options
117
+ </LocalizedLink>
118
+ ) : (
119
+ <button
120
+ type="button"
121
+ className="powerhouse-shop__atc"
122
+ onClick={handleAdd}
123
+ disabled={adding || !variant?.id || !inStock}
124
+ >
125
+ {adding ? "Adding…" : !inStock ? "Sold out" : "Add to cart"}
126
+ </button>
127
+ )}
128
+ </div>
129
+ </div>
130
+ </article>
131
+ )
132
+ }
@@ -0,0 +1 @@
1
+ export { default } from "./shop"