@pradip1995/segment-jewelry-checkout-summary 0.1.1 → 0.1.3

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pradip1995/segment-jewelry-checkout-summary",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "license": "MIT",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -23,7 +23,7 @@
23
23
  "next": ">=15"
24
24
  },
25
25
  "dependencies": {
26
- "@pradip1995/segment-jewelry-checkout-form": "^0.1.1",
26
+ "@pradip1995/segment-jewelry-checkout-form": "^0.1.6",
27
27
  "@pradip1995/segment-primitives": "^0.4.0",
28
28
  "@pradip1995/segment-tokens": "^0.3.7",
29
29
  "@medusajs/types": "^2.8.0"
@@ -36,6 +36,7 @@
36
36
  },
37
37
  "scripts": {
38
38
  "typecheck": "tsc --noEmit",
39
- "lint": "tsc --noEmit"
39
+ "lint": "tsc --noEmit",
40
+ "test": "node --experimental-strip-types --test src/*.test.ts"
40
41
  }
41
42
  }
@@ -1,13 +1,244 @@
1
1
  .jewelry-checkout-summary {
2
- height: 100%;
2
+ --checkout-ink: #1a1224;
3
+ --checkout-muted: #6b6573;
4
+ --checkout-accent: #3b1f4e;
5
+ --checkout-line: rgba(59, 31, 78, 0.12);
6
+ --checkout-soft: #faf6f1;
7
+ display: flex;
8
+ flex-direction: column;
9
+ gap: 1.15rem;
10
+ padding: 1.35rem 1.25rem 1.4rem;
11
+ border: 1px solid var(--checkout-line);
12
+ border-radius: 1rem;
13
+ background: #ffffff;
14
+ box-shadow: 0 12px 40px rgba(59, 31, 78, 0.08);
15
+ }
16
+
17
+ @media (min-width: 1024px) {
18
+ .jewelry-checkout-summary {
19
+ padding: 1.5rem 1.4rem 1.55rem;
20
+ }
21
+ }
22
+
23
+ .jewelry-checkout-summary__header {
24
+ display: flex;
25
+ align-items: baseline;
26
+ justify-content: space-between;
27
+ gap: 0.75rem;
28
+ padding-bottom: 0.85rem;
29
+ border-bottom: 1px solid var(--checkout-line);
30
+ }
31
+
32
+ .jewelry-checkout-summary__title {
33
+ margin: 0;
34
+ font-family: var(--font-heading, Georgia, serif);
35
+ font-size: 1.35rem;
36
+ font-weight: 600;
37
+ letter-spacing: 0;
38
+ color: var(--checkout-ink);
39
+ }
40
+
41
+ .jewelry-checkout-summary__count {
42
+ margin: 0;
43
+ padding: 0.2rem 0.65rem;
44
+ border-radius: 999px;
45
+ background: #f4eff8;
46
+ color: var(--checkout-accent);
47
+ font-size: 0.75rem;
48
+ font-weight: 700;
49
+ letter-spacing: 0.04em;
50
+ white-space: nowrap;
3
51
  }
4
52
 
5
53
  .jewelry-checkout-summary__delivery {
54
+ display: flex;
55
+ align-items: flex-start;
56
+ gap: 0.65rem;
57
+ padding: 0.75rem 0.85rem;
58
+ border-radius: 0.75rem;
59
+ background: var(--checkout-soft);
60
+ color: var(--checkout-ink);
61
+ }
62
+
63
+ .jewelry-checkout-summary__delivery-icon {
64
+ display: inline-flex;
65
+ width: 1.15rem;
66
+ height: 1.15rem;
67
+ margin-top: 0.1rem;
68
+ flex-shrink: 0;
69
+ color: var(--checkout-accent);
70
+ }
71
+
72
+ .jewelry-checkout-summary__delivery-icon svg {
73
+ width: 100%;
74
+ height: 100%;
75
+ }
76
+
77
+ .jewelry-checkout-summary__delivery-text {
78
+ margin: 0;
79
+ font-size: 0.8125rem;
80
+ line-height: 1.45;
81
+ }
82
+
83
+ .jewelry-checkout-summary__delivery-text strong {
84
+ font-weight: 700;
85
+ }
86
+
87
+ .jewelry-checkout-summary__coupon {
88
+ padding-bottom: 0.15rem;
89
+ }
90
+
91
+ .jewelry-checkout-summary__items {
92
+ display: flex;
93
+ flex-direction: column;
94
+ gap: 0.9rem;
95
+ margin: 0;
96
+ padding: 0;
97
+ list-style: none;
98
+ max-height: 18rem;
99
+ overflow-y: auto;
100
+ }
101
+
102
+ .jewelry-checkout-summary__item {
103
+ display: grid;
104
+ grid-template-columns: 4.5rem minmax(0, 1fr) auto;
105
+ gap: 0.75rem;
106
+ align-items: flex-start;
107
+ }
108
+
109
+ .jewelry-checkout-summary__thumb {
110
+ position: relative;
111
+ width: 4.5rem;
112
+ height: 4.5rem;
113
+ overflow: hidden;
114
+ border-radius: 0.7rem;
115
+ background: var(--checkout-soft);
116
+ border: 1px solid var(--checkout-line);
117
+ }
118
+
119
+ .jewelry-checkout-summary__thumb-empty {
120
+ width: 100%;
121
+ height: 100%;
122
+ background: linear-gradient(135deg, #faf6f1 0%, #f4eff8 100%);
123
+ }
124
+
125
+ .jewelry-checkout-summary__qty-badge {
126
+ position: absolute;
127
+ top: -0.35rem;
128
+ right: -0.35rem;
129
+ min-width: 1.25rem;
130
+ height: 1.25rem;
131
+ padding: 0 0.3rem;
132
+ border-radius: 999px;
133
+ background: var(--checkout-accent);
134
+ color: #ffffff;
135
+ font-size: 0.6875rem;
136
+ font-weight: 700;
137
+ line-height: 1.25rem;
138
+ text-align: center;
139
+ box-shadow: 0 0 0 2px #ffffff;
140
+ }
141
+
142
+ .jewelry-checkout-summary__meta {
143
+ min-width: 0;
144
+ display: flex;
145
+ flex-direction: column;
146
+ gap: 0.2rem;
147
+ padding-top: 0.1rem;
148
+ }
149
+
150
+ .jewelry-checkout-summary__item-title {
151
+ margin: 0;
152
+ font-family: var(--font-heading, Georgia, serif);
153
+ font-size: 0.9375rem;
154
+ font-weight: 600;
155
+ line-height: 1.3;
156
+ color: var(--checkout-ink);
157
+ display: -webkit-box;
158
+ -webkit-line-clamp: 2;
159
+ -webkit-box-orient: vertical;
160
+ overflow: hidden;
161
+ }
162
+
163
+ .jewelry-checkout-summary__item-variant {
164
+ margin: 0;
165
+ font-size: 0.6875rem;
166
+ font-weight: 600;
167
+ letter-spacing: 0.06em;
168
+ text-transform: uppercase;
169
+ color: var(--checkout-muted);
170
+ }
171
+
172
+ .jewelry-checkout-summary__item-qty {
173
+ margin: 0.15rem 0 0;
174
+ font-size: 0.75rem;
175
+ color: var(--checkout-muted);
176
+ }
177
+
178
+ .jewelry-checkout-summary__item-total {
179
+ margin: 0;
180
+ padding-top: 0.15rem;
181
+ font-size: 0.875rem;
182
+ font-weight: 700;
183
+ color: var(--checkout-ink);
184
+ white-space: nowrap;
185
+ }
186
+
187
+ .jewelry-checkout-summary__totals {
188
+ display: flex;
189
+ flex-direction: column;
190
+ gap: 0.55rem;
191
+ margin: 0;
192
+ padding: 0.95rem 1rem;
6
193
  border-radius: 0.75rem;
194
+ background: var(--checkout-soft);
195
+ }
196
+
197
+ .jewelry-checkout-summary__total-row {
198
+ display: flex;
199
+ align-items: center;
200
+ justify-content: space-between;
201
+ gap: 0.75rem;
202
+ margin: 0;
203
+ font-size: 0.8125rem;
204
+ color: var(--checkout-muted);
205
+ }
206
+
207
+ .jewelry-checkout-summary__total-row dd {
208
+ margin: 0;
209
+ color: var(--checkout-ink);
210
+ font-weight: 600;
211
+ }
212
+
213
+ .jewelry-checkout-summary__total-row--discount,
214
+ .jewelry-checkout-summary__total-row--discount dd {
215
+ color: #1f7a4d;
216
+ }
217
+
218
+ .jewelry-checkout-summary__total-row--grand {
219
+ padding-top: 0.6rem;
220
+ margin-top: 0.15rem;
221
+ border-top: 1px solid rgba(59, 31, 78, 0.1);
222
+ font-size: 0.9375rem;
223
+ color: var(--checkout-ink);
224
+ }
225
+
226
+ .jewelry-checkout-summary__total-row--grand dt,
227
+ .jewelry-checkout-summary__total-row--grand dd {
228
+ font-weight: 700;
229
+ color: var(--checkout-accent);
230
+ }
231
+
232
+ .jewelry-checkout-summary__total-row--grand dd {
233
+ font-size: 1.125rem;
234
+ }
235
+
236
+ .jewelry-checkout-summary__empty {
237
+ margin: 0;
238
+ font-size: 0.875rem;
239
+ color: var(--checkout-muted);
7
240
  }
8
241
 
9
242
  .jewelry-checkout-summary__payment {
10
- margin-top: 1.5rem;
11
- padding-top: 1.25rem;
12
- border-top: 1px solid var(--color-border-subtle, rgba(59, 31, 78, 0.12));
243
+ padding-top: 0.15rem;
13
244
  }
package/src/segment.tsx CHANGED
@@ -5,6 +5,7 @@ import CouponApply from "@pradip1995/segment-primitives/coupon-apply"
5
5
  import { useShiprocketDeliveryEstimate } from "@pradip1995/commerce-core/hooks/use-shiprocket-delivery-estimate"
6
6
  import { resolveDeliveryEstimateView } from "@pradip1995/commerce-core/util/shiprocket"
7
7
  import PaymentBlock from "@pradip1995/segment-jewelry-checkout-form/payment-block"
8
+ import { checkoutItemCount } from "@pradip1995/segment-jewelry-checkout-form/checkout-line"
8
9
  import type { HttpTypes } from "@medusajs/types"
9
10
  import "./jewelry-checkout-summary.css"
10
11
 
@@ -22,6 +23,7 @@ export default function JewelryCheckoutSummary({
22
23
  }) {
23
24
  const currency = cart?.currency_code || "inr"
24
25
  const items = cart?.items || []
26
+ const itemCount = checkoutItemCount(items)
25
27
  const postalCode = cart?.shipping_address?.postal_code
26
28
  const firstItem = cart?.items?.[0]
27
29
 
@@ -40,14 +42,32 @@ export default function JewelryCheckoutSummary({
40
42
  )
41
43
 
42
44
  return (
43
- <aside className="jewelry-checkout-summary checkout-page__sidebar card-surface rounded-lg p-6 h-fit">
44
- <h2 className="checkout-page__panel-title section-heading text-lg mb-4">{summaryTitle}</h2>
45
+ <aside className="jewelry-checkout-summary">
46
+ <header className="jewelry-checkout-summary__header">
47
+ <h2 className="jewelry-checkout-summary__title">{summaryTitle}</h2>
48
+ {itemCount > 0 ? (
49
+ <p className="jewelry-checkout-summary__count">
50
+ {itemCount} {itemCount === 1 ? "item" : "items"}
51
+ </p>
52
+ ) : null}
53
+ </header>
45
54
 
46
55
  {postalCode && postalCode.length === 6 ? (
47
- <div className="jewelry-checkout-summary__delivery checkout-page__delivery-panel mb-6">
48
- <p className="checkout-page__delivery-msg text-sm text-body">
56
+ <div className="jewelry-checkout-summary__delivery">
57
+ <span className="jewelry-checkout-summary__delivery-icon" aria-hidden>
58
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6">
59
+ <path
60
+ strokeLinecap="round"
61
+ strokeLinejoin="round"
62
+ d="M3 7h11v10H3V7zm11 3h4l3 3v4h-7V10z"
63
+ />
64
+ <circle cx="7" cy="18.5" r="1.5" />
65
+ <circle cx="17" cy="18.5" r="1.5" />
66
+ </svg>
67
+ </span>
68
+ <p className="jewelry-checkout-summary__delivery-text">
49
69
  {deliveryView.kind === "loading" ? (
50
- <span className="checkout-page__delivery-msg--loading">Calculating delivery…</span>
70
+ <span>Calculating delivery…</span>
51
71
  ) : deliveryView.kind === "date" ? (
52
72
  <>
53
73
  Estimated delivery by <strong>{deliveryView.label}</strong>
@@ -59,53 +79,43 @@ export default function JewelryCheckoutSummary({
59
79
  </div>
60
80
  ) : null}
61
81
 
62
- {cart?.items?.length ? <CouponApply cart={cart} className="mb-6" /> : null}
82
+ {cart?.items?.length ? (
83
+ <div className="jewelry-checkout-summary__coupon">
84
+ <CouponApply cart={cart} />
85
+ </div>
86
+ ) : null}
63
87
 
64
88
  {items.length > 0 ? (
65
- <>
66
- <ul className="space-y-3 mb-6 max-h-64 overflow-y-auto">
67
- {items.map((item) => (
68
- <li key={item.id} className="flex justify-between gap-3 text-sm">
69
- <span className="text-body truncate">
70
- {item.title} × {item.quantity}
71
- </span>
72
- <span className="text-heading shrink-0 font-medium">
73
- {formatPrice(item.total, currency)}
74
- </span>
75
- </li>
76
- ))}
77
- </ul>
78
- <dl className="space-y-2 text-sm border-t border-cart-border pt-4">
79
- <div className="flex justify-between">
80
- <dt className="text-muted">Subtotal</dt>
81
- <dd>{formatPrice(cart?.subtotal, currency)}</dd>
89
+ <dl className="jewelry-checkout-summary__totals">
90
+ <div className="jewelry-checkout-summary__total-row">
91
+ <dt>Subtotal</dt>
92
+ <dd>{formatPrice(cart?.subtotal, currency)}</dd>
93
+ </div>
94
+ {cart?.shipping_total != null ? (
95
+ <div className="jewelry-checkout-summary__total-row">
96
+ <dt>Shipping</dt>
97
+ <dd>
98
+ {cart.shipping_total > 0
99
+ ? formatPrice(cart.shipping_total, currency)
100
+ : cart.shipping_address?.postal_code
101
+ ? "Free"
102
+ : "—"}
103
+ </dd>
82
104
  </div>
83
- {cart?.shipping_total != null && (
84
- <div className="flex justify-between">
85
- <dt className="text-muted">Shipping</dt>
86
- <dd>
87
- {cart.shipping_total > 0
88
- ? formatPrice(cart.shipping_total, currency)
89
- : cart.shipping_address?.postal_code
90
- ? "Free"
91
- : "—"}
92
- </dd>
93
- </div>
94
- )}
95
- {(cart?.discount_total ?? 0) > 0 && (
96
- <div className="flex justify-between text-green-700">
97
- <dt>Discount</dt>
98
- <dd>-{formatPrice(cart?.discount_total, currency)}</dd>
99
- </div>
100
- )}
101
- <div className="flex justify-between font-semibold pt-2">
102
- <dt>Total</dt>
103
- <dd className="text-brand-accent text-lg">{formatPrice(cart?.total, currency)}</dd>
105
+ ) : null}
106
+ {(cart?.discount_total ?? 0) > 0 ? (
107
+ <div className="jewelry-checkout-summary__total-row jewelry-checkout-summary__total-row--discount">
108
+ <dt>Discount</dt>
109
+ <dd>-{formatPrice(cart?.discount_total, currency)}</dd>
104
110
  </div>
105
- </dl>
106
- </>
111
+ ) : null}
112
+ <div className="jewelry-checkout-summary__total-row jewelry-checkout-summary__total-row--grand">
113
+ <dt>Total</dt>
114
+ <dd>{formatPrice(cart?.total, currency)}</dd>
115
+ </div>
116
+ </dl>
107
117
  ) : (
108
- <p className="text-muted text-sm">No cart data available.</p>
118
+ <p className="jewelry-checkout-summary__empty">No cart data available.</p>
109
119
  )}
110
120
 
111
121
  {items.length > 0 ? (