@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 +21 -0
- package/README.md +94 -0
- package/dist/index.cjs +548 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.esm.js +533 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.iife.js +549 -0
- package/dist/index.iife.js.map +1 -0
- package/dist/index.umd.js +550 -0
- package/dist/index.umd.js.map +1 -0
- package/dist/styles.css +1 -0
- package/package.json +86 -0
- package/types/index.d.ts +71 -0
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
|