@quantabit/membership-sdk 1.0.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 QuantaBit Team
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,94 @@
1
+ # @quantabit/membership-sdk
2
+
3
+ > QuantaBit Membership SDK - Membership card management and points-based benefit redemption
4
+
5
+ ## ๐Ÿ“ฆ Installation
6
+
7
+ ```bash
8
+ npm install @quantabit/membership-sdk
9
+ # or
10
+ yarn add @quantabit/membership-sdk
11
+ ```
12
+
13
+ ## ๐Ÿš€ Quick Start
14
+
15
+ ### Using Components
16
+
17
+ ```jsx
18
+ import { MembershipCard, useMembershipCard } from "@quantabit/membership-sdk";
19
+
20
+ function MyMembership() {
21
+ const { card, loading } = useMembershipCard();
22
+
23
+ if (loading) return <div>Loading...</div>;
24
+ return <MembershipCard card={card} />;
25
+ }
26
+ ```
27
+
28
+ ### API Client
29
+
30
+ ```javascript
31
+ import { membershipApi, CardType } from "@quantabit/membership-sdk";
32
+
33
+ // Get my membership card
34
+ const card = await membershipApi.getMyCard();
35
+
36
+ // Get all available cards
37
+ const cards = await membershipApi.getCards();
38
+
39
+ // Redeem membership with points
40
+ await membershipApi.redeemWithPoints(CardType.GOLD, 5000);
41
+
42
+ // Extend membership
43
+ await membershipApi.extendCard("card_123", 3); // 3 months
44
+
45
+ // Get card benefits
46
+ const benefits = await membershipApi.getBenefits(CardType.GOLD);
47
+
48
+ // Use a benefit
49
+ await membershipApi.useBenefit("benefit_123");
50
+ ```
51
+
52
+ ## ๐Ÿ“š Components
53
+
54
+ | Component | Description |
55
+ | ---------------- | ---------------------------------------------------- |
56
+ | `MembershipCard` | Gradient membership card with type, name, and expiry |
57
+
58
+ ## ๐Ÿช Hooks
59
+
60
+ | Hook | Description |
61
+ | ------------------- | ----------------------------------- |
62
+ | `useMembershipCard` | Load current user's membership card |
63
+
64
+ ## ๐Ÿ“– Type Definitions
65
+
66
+ ```javascript
67
+ import { CardType, CardStatus } from "@quantabit/membership-sdk";
68
+
69
+ // Card types
70
+ CardType.BASIC; // Basic
71
+ CardType.SILVER; // Silver
72
+ CardType.GOLD; // Gold
73
+ CardType.PLATINUM; // Platinum
74
+
75
+ // Card status
76
+ CardStatus.ACTIVE; // Active
77
+ CardStatus.EXPIRED; // Expired
78
+ CardStatus.FROZEN; // Frozen
79
+ ```
80
+
81
+ ## ๐Ÿ“„ License
82
+
83
+ MIT License
84
+
85
+
86
+
87
+ ---
88
+
89
+ ## ๐ŸŒ Brand & Links
90
+ - Official Mainnet: [QuantaBit Chain](https://qbitchain.io/)
91
+ - Developer Platform: [Developer Platform](https://developer.quantabit.io/)
92
+ - Open Platform: [Open Platform](https://open.quantabit.io/)
93
+ - Payment Platform: [Pay Platform](https://pay.qbitwallet.io/)
94
+ - Feedback: [Feedback](https://xwin.live/qbit)
package/dist/index.cjs ADDED
@@ -0,0 +1,548 @@
1
+ 'use client';
2
+ 'use strict';
3
+
4
+ var sdkConfig = require('@quantabit/sdk-config');
5
+ var React = require('react');
6
+
7
+ /**
8
+ * Membership SDK - API ๅฎขๆˆท็ซฏ
9
+ * ไผšๅ‘˜ๅก็ณป็ปŸๅŽ็ซฏๆŽฅๅฃๅฐ่ฃ…
10
+ *
11
+ * ไฝฟ็”จ BaseApiClient ๅŸบ็ฑป๏ผŒ็ปงๆ‰ฟ็ปŸไธ€็š„้…็ฝฎใ€่ฎค่ฏใ€้”™่ฏฏๅค„็†
12
+ */
13
+
14
+
15
+ /**
16
+ * ไผšๅ‘˜ๅก API ๅฎขๆˆท็ซฏ
17
+ */
18
+ class MembershipApiClient extends sdkConfig.BaseApiClient {
19
+ constructor(config = {}) {
20
+ super('/membership', config);
21
+ }
22
+
23
+ // ============ ไผšๅ‘˜ๅกๆŸฅ่ฏข ============
24
+
25
+ /**
26
+ * ่Žทๅ–ๅฝ“ๅ‰็”จๆˆท็š„ไผšๅ‘˜ๅก
27
+ */
28
+ async getMyCard() {
29
+ return this.get('/card');
30
+ }
31
+
32
+ /**
33
+ * ่Žทๅ–ๆ‰€ๆœ‰ไผšๅ‘˜ๅก็ฑปๅž‹
34
+ */
35
+ async getCards() {
36
+ return this.get('/cards');
37
+ }
38
+
39
+ /**
40
+ * ่Žทๅ–ไผšๅ‘˜ๅก่ฏฆๆƒ…
41
+ * @param {string} cardId - ไผšๅ‘˜ๅก ID
42
+ */
43
+ async getCardDetail(cardId) {
44
+ return this.get(`/cards/${cardId}`);
45
+ }
46
+
47
+ // ============ ไผšๅ‘˜ๅกๆ“ไฝœ ============
48
+
49
+ /**
50
+ * ไฝฟ็”จ็งฏๅˆ†ๅ…‘ๆขไผšๅ‘˜ๅก
51
+ * @param {string} cardType - ๅก็‰‡็ฑปๅž‹ (basic/silver/gold/platinum)
52
+ * @param {number} points - ็งฏๅˆ†ๆ•ฐ้‡
53
+ */
54
+ async redeemWithPoints(cardType, points) {
55
+ return this.post('/redeem', {
56
+ cardType,
57
+ points
58
+ });
59
+ }
60
+
61
+ /**
62
+ * ๅปถ้•ฟไผšๅ‘˜ๅกๆœ‰ๆ•ˆๆœŸ
63
+ * @param {string} cardId - ไผšๅ‘˜ๅก ID
64
+ * @param {number} months - ๅปถ้•ฟๆœˆๆ•ฐ
65
+ */
66
+ async extendCard(cardId, months) {
67
+ return this.post(`/cards/${cardId}/extend`, {
68
+ months
69
+ });
70
+ }
71
+
72
+ /**
73
+ * ๅ‡็บงไผšๅ‘˜ๅก
74
+ * @param {string} cardId - ไผšๅ‘˜ๅก ID
75
+ * @param {string} targetType - ็›ฎๆ ‡ๅก็‰‡็ฑปๅž‹
76
+ */
77
+ async upgradeCard(cardId, targetType) {
78
+ return this.post(`/cards/${cardId}/upgrade`, {
79
+ target_type: targetType
80
+ });
81
+ }
82
+
83
+ // ============ ๆƒ็›Š็ฎก็† ============
84
+
85
+ /**
86
+ * ่Žทๅ–ๅก็‰‡ๆƒ็›Šๅˆ—่กจ
87
+ * @param {string} cardType - ๅก็‰‡็ฑปๅž‹
88
+ */
89
+ async getBenefits(cardType) {
90
+ return this.get(`/cards/${cardType}/benefits`);
91
+ }
92
+
93
+ /**
94
+ * ไฝฟ็”จๆƒ็›Š
95
+ * @param {string} benefitId - ๆƒ็›Š ID
96
+ */
97
+ async useBenefit(benefitId) {
98
+ return this.post(`/benefits/${benefitId}/use`);
99
+ }
100
+
101
+ /**
102
+ * ่Žทๅ–ๆƒ็›Šไฝฟ็”จ่ฎฐๅฝ•
103
+ * @param {Object} params - ๆŸฅ่ฏขๅ‚ๆ•ฐ
104
+ */
105
+ async getBenefitHistory(params = {}) {
106
+ return this.get('/benefits/history', params);
107
+ }
108
+ }
109
+
110
+ // ๅˆ›ๅปบ้ป˜่ฎคๅฎžไพ‹
111
+ const membershipApi = new MembershipApiClient();
112
+
113
+ /**
114
+ * Membership SDK - React Hooks
115
+ * ไผšๅ‘˜ๅก React ้’ฉๅญ
116
+ */
117
+
118
+
119
+ /**
120
+ * ่Žทๅ–ๅฝ“ๅ‰็”จๆˆท็š„ไผšๅ‘˜ๅกไฟกๆฏ
121
+ */
122
+ function useMembershipCard() {
123
+ const [card, setCard] = React.useState(null);
124
+ const [loading, setLoading] = React.useState(true);
125
+ const [error, setError] = React.useState(null);
126
+ const fetchCard = React.useCallback(async () => {
127
+ setLoading(true);
128
+ setError(null);
129
+ try {
130
+ const result = await membershipApi.getMyCard();
131
+ setCard(result.data || result);
132
+ } catch (err) {
133
+ setError(err.message);
134
+ } finally {
135
+ setLoading(false);
136
+ }
137
+ }, []);
138
+ React.useEffect(() => {
139
+ fetchCard();
140
+ }, [fetchCard]);
141
+ return {
142
+ card,
143
+ loading,
144
+ error,
145
+ refresh: fetchCard
146
+ };
147
+ }
148
+
149
+ /**
150
+ * ่Žทๅ–ๆ‰€ๆœ‰ๅฏ็”จ็š„ไผšๅ‘˜ๅก็ฑปๅž‹
151
+ */
152
+ function useMembershipCards() {
153
+ const [cards, setCards] = React.useState([]);
154
+ const [loading, setLoading] = React.useState(true);
155
+ const [error, setError] = React.useState(null);
156
+ const fetchCards = React.useCallback(async () => {
157
+ setLoading(true);
158
+ try {
159
+ const result = await membershipApi.getCards();
160
+ setCards(result.data || []);
161
+ } catch (err) {
162
+ setError(err.message);
163
+ } finally {
164
+ setLoading(false);
165
+ }
166
+ }, []);
167
+ React.useEffect(() => {
168
+ fetchCards();
169
+ }, [fetchCards]);
170
+ return {
171
+ cards,
172
+ loading,
173
+ error,
174
+ refresh: fetchCards
175
+ };
176
+ }
177
+
178
+ /**
179
+ * ไผšๅ‘˜ๅกๆƒ็›Š็ฎก็†
180
+ * @param {string} cardType - ๅก็‰‡็ฑปๅž‹
181
+ */
182
+ function useBenefits(cardType) {
183
+ const [benefits, setBenefits] = React.useState([]);
184
+ const [loading, setLoading] = React.useState(false);
185
+ const [error, setError] = React.useState(null);
186
+ const fetchBenefits = React.useCallback(async () => {
187
+ if (!cardType) return;
188
+ setLoading(true);
189
+ try {
190
+ const result = await membershipApi.getBenefits(cardType);
191
+ setBenefits(result.data || []);
192
+ } catch (err) {
193
+ setError(err.message);
194
+ } finally {
195
+ setLoading(false);
196
+ }
197
+ }, [cardType]);
198
+ const useBenefit = React.useCallback(async benefitId => {
199
+ const result = await membershipApi.useBenefit(benefitId);
200
+ await fetchBenefits();
201
+ return result;
202
+ }, [fetchBenefits]);
203
+ React.useEffect(() => {
204
+ fetchBenefits();
205
+ }, [fetchBenefits]);
206
+ return {
207
+ benefits,
208
+ loading,
209
+ error,
210
+ useBenefit,
211
+ refresh: fetchBenefits
212
+ };
213
+ }
214
+
215
+ /**
216
+ * Membership SDK - ๅ›ฝ้™…ๅŒ–
217
+ * ไผšๅ‘˜ๅก็ณป็ปŸๅคš่ฏญ่จ€ๆ”ฏๆŒ
218
+ */
219
+
220
+ const SUPPORTED_LANGUAGES = ['en', 'zh', 'ja', 'ko'];
221
+ const messages = {
222
+ zh: {
223
+ membershipCard: 'ไผšๅ‘˜ๅก',
224
+ cardType: {
225
+ basic: 'ๅŸบ็ก€ไผšๅ‘˜',
226
+ silver: '้“ถๅกไผšๅ‘˜',
227
+ gold: '้‡‘ๅกไผšๅ‘˜',
228
+ platinum: '้“‚้‡‘ไผšๅ‘˜'
229
+ },
230
+ validUntil: 'ๆœ‰ๆ•ˆๆœŸ่‡ณ',
231
+ points: '็งฏๅˆ†',
232
+ use: 'ไฝฟ็”จ',
233
+ noBenefits: 'ๆš‚ๆ— ๅฏ็”จๆƒ็›Š',
234
+ redeem: 'ๅ…‘ๆข',
235
+ upgrade: 'ๅ‡็บง',
236
+ extend: '็ปญๆœŸ',
237
+ benefits: 'ไผšๅ‘˜ๆƒ็›Š',
238
+ history: 'ไฝฟ็”จ่ฎฐๅฝ•',
239
+ loading: 'ๅŠ ่ฝฝไธญ...',
240
+ expired: 'ๅทฒ่ฟ‡ๆœŸ',
241
+ active: 'ๆœ‰ๆ•ˆ',
242
+ frozen: 'ๅทฒๅ†ป็ป“'
243
+ },
244
+ en: {
245
+ membershipCard: 'Membership Card',
246
+ cardType: {
247
+ basic: 'Basic',
248
+ silver: 'Silver',
249
+ gold: 'Gold',
250
+ platinum: 'Platinum'
251
+ },
252
+ validUntil: 'Valid until',
253
+ points: 'Points',
254
+ use: 'Use',
255
+ noBenefits: 'No benefits available',
256
+ redeem: 'Redeem',
257
+ upgrade: 'Upgrade',
258
+ extend: 'Extend',
259
+ benefits: 'Benefits',
260
+ history: 'History',
261
+ loading: 'Loading...',
262
+ expired: 'Expired',
263
+ active: 'Active',
264
+ frozen: 'Frozen'
265
+ },
266
+ ja: {
267
+ membershipCard: 'ใƒกใƒณใƒใƒผใ‚ทใƒƒใƒ—ใ‚ซใƒผใƒ‰',
268
+ cardType: {
269
+ basic: 'ใƒ™ใƒผใ‚ทใƒƒใ‚ฏ',
270
+ silver: 'ใ‚ทใƒซใƒใƒผ',
271
+ gold: 'ใ‚ดใƒผใƒซใƒ‰',
272
+ platinum: 'ใƒ—ใƒฉใƒใƒŠ'
273
+ },
274
+ validUntil: 'ๆœ‰ๅŠนๆœŸ้™',
275
+ points: 'ใƒใ‚คใƒณใƒˆ',
276
+ use: 'ไฝฟ็”จ',
277
+ noBenefits: 'ๅˆฉ็”จๅฏ่ƒฝใช็‰นๅ…ธใฏใ‚ใ‚Šใพใ›ใ‚“',
278
+ redeem: 'ไบคๆ›',
279
+ upgrade: 'ใ‚ขใƒƒใƒ—ใ‚ฐใƒฌใƒผใƒ‰',
280
+ extend: 'ๅปถ้•ท',
281
+ benefits: '็‰นๅ…ธ',
282
+ history: 'ๅฑฅๆญด',
283
+ loading: '่ชญใฟ่พผใฟไธญ...',
284
+ expired: 'ๆœŸ้™ๅˆ‡ใ‚Œ',
285
+ active: 'ๆœ‰ๅŠน',
286
+ frozen: 'ๅ‡็ต'
287
+ },
288
+ ko: {
289
+ membershipCard: '๋ฉค๋ฒ„์‹ญ ์นด๋“œ',
290
+ cardType: {
291
+ basic: '๊ธฐ๋ณธ',
292
+ silver: '์‹ค๋ฒ„',
293
+ gold: '๊ณจ๋“œ',
294
+ platinum: 'ํ”Œ๋ž˜ํ‹ฐ๋„˜'
295
+ },
296
+ validUntil: '์œ ํšจ ๊ธฐํ•œ',
297
+ points: 'ํฌ์ธํŠธ',
298
+ use: '์‚ฌ์šฉ',
299
+ noBenefits: '์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ํ˜œํƒ์ด ์—†์Šต๋‹ˆ๋‹ค',
300
+ redeem: '๊ตํ™˜',
301
+ upgrade: '์—…๊ทธ๋ ˆ์ด๋“œ',
302
+ extend: '์—ฐ์žฅ',
303
+ benefits: 'ํ˜œํƒ',
304
+ history: '๊ธฐ๋ก',
305
+ loading: '๋กœ๋”ฉ ์ค‘...',
306
+ expired: '๋งŒ๋ฃŒ',
307
+ active: 'ํ™œ์„ฑ',
308
+ frozen: '๋™๊ฒฐ'
309
+ }
310
+ };
311
+
312
+ // ๅฝ“ๅ‰่ฏญ่จ€
313
+ let currentLanguage = 'zh';
314
+
315
+ /**
316
+ * ่ฎพ็ฝฎ่ฏญ่จ€
317
+ * @param {string} lang - ่ฏญ่จ€ไปฃ็ 
318
+ */
319
+ function setLanguage(lang) {
320
+ if (SUPPORTED_LANGUAGES.includes(lang)) {
321
+ currentLanguage = lang;
322
+ }
323
+ }
324
+
325
+ /**
326
+ * ่Žทๅ–ๅฝ“ๅ‰่ฏญ่จ€
327
+ * @returns {string}
328
+ */
329
+ function getLanguage() {
330
+ return currentLanguage;
331
+ }
332
+
333
+ /**
334
+ * ็ฟป่ฏ‘ๅ‡ฝๆ•ฐ
335
+ * @param {string} key - ็ฟป่ฏ‘้”ฎ๏ผŒๆ”ฏๆŒ็‚นๅท่ทฏๅพ„๏ผˆๅฆ‚ 'cardType.gold'๏ผ‰
336
+ * @param {Object} params - ๆ’ๅ€ผๅ‚ๆ•ฐ
337
+ * @returns {string}
338
+ */
339
+ function t(key, params = {}) {
340
+ const lang = messages[currentLanguage] || messages.zh;
341
+
342
+ // ๆ”ฏๆŒ็‚นๅท่ทฏๅพ„่ฎฟ้—ฎ
343
+ const keys = key.split('.');
344
+ let value = lang;
345
+ for (const k of keys) {
346
+ value = value?.[k];
347
+ if (value === undefined) break;
348
+ }
349
+ if (typeof value !== 'string') {
350
+ // ๅ›ž้€€ๅˆฐไธญๆ–‡
351
+ value = lang;
352
+ for (const k of keys) {
353
+ value = value?.[k];
354
+ if (value === undefined) break;
355
+ }
356
+ }
357
+ if (typeof value !== 'string') return key;
358
+
359
+ // ็ฎ€ๅ•ๆ’ๅ€ผๆ›ฟๆข
360
+ return value.replace(/\{(\w+)\}/g, (_, k) => params[k] ?? '');
361
+ }
362
+
363
+ // ็›‘ๅฌๅ…จๅฑ€่ฏญ่จ€ๅ˜ๆ›ดไบ‹ไปถ
364
+ if (typeof window !== 'undefined') {
365
+ window.addEventListener('qbit-did:language-change', e => {
366
+ if (e.detail?.language) {
367
+ setLanguage(e.detail.language);
368
+ }
369
+ });
370
+ }
371
+
372
+ /**
373
+ * Membership SDK - ไผšๅ‘˜ๅก็ป„ไปถ
374
+ * ๆ”ฏๆŒ i18n ๅ›ฝ้™…ๅŒ–
375
+ */
376
+
377
+
378
+ /**
379
+ * ไผšๅ‘˜ๅก็ฑปๅž‹ๅฏนๅบ”็š„ๆธๅ˜่‰ฒ้…็ฝฎ
380
+ */
381
+ const CARD_GRADIENTS = {
382
+ basic: {
383
+ from: '#6b7280',
384
+ to: '#4b5563',
385
+ label: '๐Ÿชช'
386
+ },
387
+ silver: {
388
+ from: '#94a3b8',
389
+ to: '#64748b',
390
+ label: '๐Ÿฅˆ'
391
+ },
392
+ gold: {
393
+ from: '#f59e0b',
394
+ to: '#d97706',
395
+ label: '๐Ÿฅ‡'
396
+ },
397
+ platinum: {
398
+ from: '#a855f7',
399
+ to: '#7c3aed',
400
+ label: '๐Ÿ’Ž'
401
+ }
402
+ };
403
+
404
+ /**
405
+ * ไผšๅ‘˜ๅกๅฑ•็คบ็ป„ไปถ
406
+ * @param {Object} props
407
+ * @param {Object} props.card - ไผšๅ‘˜ๅกๆ•ฐๆฎ
408
+ * @param {Function} props.onClick - ็‚นๅ‡ปๅ›ž่ฐƒ
409
+ */
410
+ function MembershipCard({
411
+ card,
412
+ onClick
413
+ }) {
414
+ if (!card) return null;
415
+ const gradient = CARD_GRADIENTS[card.type] || CARD_GRADIENTS.basic;
416
+ return /*#__PURE__*/React.createElement("div", {
417
+ className: "eco-membership-card",
418
+ style: {
419
+ background: `linear-gradient(135deg, ${gradient.from}, ${gradient.to})`,
420
+ borderRadius: '16px',
421
+ padding: '24px',
422
+ color: '#fff',
423
+ cursor: onClick ? 'pointer' : 'default',
424
+ position: 'relative',
425
+ overflow: 'hidden',
426
+ minHeight: '180px'
427
+ },
428
+ onClick: () => onClick?.(card)
429
+ }, /*#__PURE__*/React.createElement("div", {
430
+ style: {
431
+ position: 'absolute',
432
+ top: '16px',
433
+ right: '20px',
434
+ fontSize: '32px',
435
+ opacity: 0.3
436
+ }
437
+ }, gradient.label), /*#__PURE__*/React.createElement("div", {
438
+ style: {
439
+ fontSize: '12px',
440
+ letterSpacing: '2px',
441
+ textTransform: 'uppercase',
442
+ opacity: 0.8
443
+ }
444
+ }, t('membershipCard')), /*#__PURE__*/React.createElement("div", {
445
+ style: {
446
+ fontSize: '20px',
447
+ fontWeight: 'bold',
448
+ marginTop: '8px',
449
+ textTransform: 'uppercase'
450
+ }
451
+ }, t(`cardType.${card.type}`) || card.type), /*#__PURE__*/React.createElement("div", {
452
+ style: {
453
+ marginTop: '24px',
454
+ fontSize: '16px'
455
+ }
456
+ }, card.userName), /*#__PURE__*/React.createElement("div", {
457
+ style: {
458
+ display: 'flex',
459
+ justifyContent: 'space-between',
460
+ marginTop: '16px',
461
+ fontSize: '12px',
462
+ opacity: 0.8
463
+ }
464
+ }, /*#__PURE__*/React.createElement("span", null, t('validUntil'), ": ", card.expiryDate), /*#__PURE__*/React.createElement("span", null, card.points, " ", t('points'))));
465
+ }
466
+
467
+ /**
468
+ * ไผšๅ‘˜ๆƒ็›Šๅˆ—่กจ็ป„ไปถ
469
+ * @param {Object} props
470
+ * @param {Array} props.benefits - ๆƒ็›Šๅˆ—่กจ
471
+ * @param {Function} props.onUseBenefit - ไฝฟ็”จๆƒ็›Šๅ›ž่ฐƒ
472
+ */
473
+ function BenefitList({
474
+ benefits = [],
475
+ onUseBenefit
476
+ }) {
477
+ if (!benefits.length) {
478
+ return /*#__PURE__*/React.createElement("div", {
479
+ className: "eco-empty"
480
+ }, t('noBenefits'));
481
+ }
482
+ return /*#__PURE__*/React.createElement("div", {
483
+ className: "eco-benefit-list"
484
+ }, benefits.map(benefit => /*#__PURE__*/React.createElement("div", {
485
+ key: benefit.id,
486
+ className: "eco-benefit-item",
487
+ style: {
488
+ display: 'flex',
489
+ justifyContent: 'space-between',
490
+ alignItems: 'center',
491
+ padding: '12px 16px',
492
+ borderBottom: '1px solid #f0f0f0'
493
+ }
494
+ }, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
495
+ style: {
496
+ fontWeight: 500
497
+ }
498
+ }, benefit.name), /*#__PURE__*/React.createElement("div", {
499
+ style: {
500
+ fontSize: '12px',
501
+ color: '#999'
502
+ }
503
+ }, benefit.description)), benefit.available && /*#__PURE__*/React.createElement("button", {
504
+ className: "eco-btn eco-btn-sm",
505
+ onClick: () => onUseBenefit?.(benefit.id)
506
+ }, t('use')))));
507
+ }
508
+
509
+ /**
510
+ * @quantabit/membership-sdk
511
+ *
512
+ * QuantaBit Membership SDK
513
+ *
514
+ * Provides reusable membership card features:
515
+ * - Membership card display & management
516
+ * - Points-based card redemption
517
+ * - Card upgrade & extension
518
+ * - Benefit management & usage
519
+ */
520
+
521
+ // ============ Types ============
522
+ const CardType = {
523
+ BASIC: 'basic',
524
+ SILVER: 'silver',
525
+ GOLD: 'gold',
526
+ PLATINUM: 'platinum'
527
+ };
528
+ const CardStatus = {
529
+ ACTIVE: 'active',
530
+ EXPIRED: 'expired',
531
+ FROZEN: 'frozen'
532
+ };
533
+
534
+ exports.BenefitList = BenefitList;
535
+ exports.CardStatus = CardStatus;
536
+ exports.CardType = CardType;
537
+ exports.MembershipApiClient = MembershipApiClient;
538
+ exports.MembershipCard = MembershipCard;
539
+ exports.SUPPORTED_LANGUAGES = SUPPORTED_LANGUAGES;
540
+ exports.getLanguage = getLanguage;
541
+ exports.membershipApi = membershipApi;
542
+ exports.messages = messages;
543
+ exports.setLanguage = setLanguage;
544
+ exports.t = t;
545
+ exports.useBenefits = useBenefits;
546
+ exports.useMembershipCard = useMembershipCard;
547
+ exports.useMembershipCards = useMembershipCards;
548
+ //# sourceMappingURL=index.cjs.map