@cshah18/sdk 4.15.0 → 4.16.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/dist/cobuy-sdk.esm.js +84 -8
- package/dist/cobuy-sdk.esm.js.map +1 -1
- package/dist/cobuy-sdk.umd.js +84 -8
- package/dist/cobuy-sdk.umd.js.map +1 -1
- package/dist/types/core/api-client.d.ts +7 -1
- package/dist/types/core/endpoints.d.ts +1 -0
- package/dist/types/ui/lobby/lobby-modal.d.ts +5 -0
- package/package.json +1 -1
package/dist/cobuy-sdk.umd.js
CHANGED
|
@@ -2294,6 +2294,11 @@ var CoBuySDK = (function (exports) {
|
|
|
2294
2294
|
this.updateData(updatePayload);
|
|
2295
2295
|
// Also update team card to reflect new member count
|
|
2296
2296
|
this.updateTeamCard(participants, max);
|
|
2297
|
+
// If group just became complete and we need offline codes for THIS user, fetch them
|
|
2298
|
+
if (isComplete && !this.data.offlineRedemption) {
|
|
2299
|
+
this.logger.info("[Socket] Group fulfilled - fetching current user's offline codes");
|
|
2300
|
+
this.fetchCurrentUserOfflineCodesIfNeeded();
|
|
2301
|
+
}
|
|
2297
2302
|
};
|
|
2298
2303
|
this.logger = new Logger(debug);
|
|
2299
2304
|
this.apiClient = apiClient;
|
|
@@ -4537,6 +4542,33 @@ var CoBuySDK = (function (exports) {
|
|
|
4537
4542
|
window.removeEventListener("group:created", this.handleSocketGroupUpdate);
|
|
4538
4543
|
this.socketListenerRegistered = false;
|
|
4539
4544
|
}
|
|
4545
|
+
/**
|
|
4546
|
+
* Fetch current user's offline redemption codes when group becomes fulfilled
|
|
4547
|
+
* This ensures we show the current user's codes, not someone else's
|
|
4548
|
+
*/
|
|
4549
|
+
async fetchCurrentUserOfflineCodesIfNeeded() {
|
|
4550
|
+
var _a;
|
|
4551
|
+
if (!this.apiClient || !this.currentGroupId) {
|
|
4552
|
+
return;
|
|
4553
|
+
}
|
|
4554
|
+
try {
|
|
4555
|
+
this.logger.info("[Offline] Fetching current user's offline codes");
|
|
4556
|
+
const response = await this.apiClient.getGroupOfflineRedemption(this.currentGroupId);
|
|
4557
|
+
if (response.success && ((_a = response.data) === null || _a === void 0 ? void 0 : _a.offline_redemption)) {
|
|
4558
|
+
const offlineRedemption = response.data.offline_redemption;
|
|
4559
|
+
if (isValidOfflineRedemption(offlineRedemption)) {
|
|
4560
|
+
this.logger.info("[Offline] Successfully fetched current user's offline codes");
|
|
4561
|
+
this.updateData({ offlineRedemption });
|
|
4562
|
+
}
|
|
4563
|
+
}
|
|
4564
|
+
else {
|
|
4565
|
+
this.logger.warn("[Offline] Failed to fetch offline codes", response.error);
|
|
4566
|
+
}
|
|
4567
|
+
}
|
|
4568
|
+
catch (error) {
|
|
4569
|
+
this.logger.error("[Offline] Error fetching offline codes", error);
|
|
4570
|
+
}
|
|
4571
|
+
}
|
|
4540
4572
|
/**
|
|
4541
4573
|
* Create activity item from socket event data
|
|
4542
4574
|
*/
|
|
@@ -5218,6 +5250,7 @@ var CoBuySDK = (function (exports) {
|
|
|
5218
5250
|
}
|
|
5219
5251
|
/** Fetch latest group data and re-render containers */
|
|
5220
5252
|
async refreshGroupDataFromRealtime() {
|
|
5253
|
+
var _a;
|
|
5221
5254
|
// Debounce rapid refreshes to prevent loops and reduce API load
|
|
5222
5255
|
const now = Date.now();
|
|
5223
5256
|
if (now - this.lastGroupDataRefreshTime < this.GROUP_REFRESH_DEBOUNCE) {
|
|
@@ -5234,19 +5267,24 @@ var CoBuySDK = (function (exports) {
|
|
|
5234
5267
|
const groupData = await this.fetchPrimaryGroup(this.currentProductId);
|
|
5235
5268
|
this.currentGroupData = groupData;
|
|
5236
5269
|
this.currentGroupId = (groupData === null || groupData === void 0 ? void 0 : groupData.id) || this.currentGroupId;
|
|
5270
|
+
// If backend returned member-scoped offline redemption, this session is a member.
|
|
5271
|
+
const hasMemberOfflineRedemption = !!(groupData === null || groupData === void 0 ? void 0 : groupData.offline_redemption) && isValidOfflineRedemption(groupData.offline_redemption);
|
|
5272
|
+
if (hasMemberOfflineRedemption && !this.currentSessionId) {
|
|
5273
|
+
this.currentSessionId = ((_a = this.apiClient) === null || _a === void 0 ? void 0 : _a.getSessionId()) || null;
|
|
5274
|
+
}
|
|
5237
5275
|
// If backend signals completion via counts, reflect it — but only for actual members.
|
|
5238
5276
|
// Observers may see a full group returned by fetchPrimaryGroup; they should NOT enter
|
|
5239
5277
|
// the checkout flow. currentSessionId is the membership signal (non-null = joined).
|
|
5240
5278
|
if (groupData) {
|
|
5241
5279
|
const participants = Number(groupData.participants_count || 0);
|
|
5242
5280
|
const max = Number(groupData.max_participants || 0);
|
|
5243
|
-
|
|
5281
|
+
const isMember = !!this.currentSessionId || hasMemberOfflineRedemption;
|
|
5282
|
+
if (max > 0 && participants >= max && isMember) {
|
|
5244
5283
|
this.groupFulfilled = true;
|
|
5245
5284
|
// The primary group API returns offline_redemption for members of fulfilled groups.
|
|
5246
5285
|
// Extract it here so renderFulfilledSummary shows the "Redeem In-store" link
|
|
5247
5286
|
// (matching the UI users see on a full page reload).
|
|
5248
|
-
if (
|
|
5249
|
-
isValidOfflineRedemption(groupData.offline_redemption)) {
|
|
5287
|
+
if (hasMemberOfflineRedemption) {
|
|
5250
5288
|
this.offlineRedemption = groupData.offline_redemption;
|
|
5251
5289
|
}
|
|
5252
5290
|
if (groupData.campaign_redemption_method) {
|
|
@@ -6649,7 +6687,7 @@ var CoBuySDK = (function (exports) {
|
|
|
6649
6687
|
* Handle CTA button click with analytics and modal opening
|
|
6650
6688
|
*/
|
|
6651
6689
|
async handleCTAClick(productId) {
|
|
6652
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
6690
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
|
|
6653
6691
|
this.logger.info(`CTA clicked for product: ${productId}`);
|
|
6654
6692
|
// Track analytics event asynchronously (fire-and-forget)
|
|
6655
6693
|
if (this.analyticsClient) {
|
|
@@ -6769,6 +6807,8 @@ var CoBuySDK = (function (exports) {
|
|
|
6769
6807
|
}
|
|
6770
6808
|
}
|
|
6771
6809
|
this.logger.info("Successfully joined group", groupJoinData);
|
|
6810
|
+
// Mark this widget session as an active member for subsequent socket fulfillment handling.
|
|
6811
|
+
this.currentSessionId = ((_j = this.apiClient) === null || _j === void 0 ? void 0 : _j.getSessionId()) || this.currentSessionId;
|
|
6772
6812
|
if (this.analyticsClient && groupJoinData) {
|
|
6773
6813
|
this.analyticsClient
|
|
6774
6814
|
.trackJoinSuccess(productId, groupJoinData.group.id)
|
|
@@ -6780,7 +6820,7 @@ var CoBuySDK = (function (exports) {
|
|
|
6780
6820
|
isValidOfflineRedemption(groupJoinData.offline_redemption)
|
|
6781
6821
|
? groupJoinData.offline_redemption
|
|
6782
6822
|
: null;
|
|
6783
|
-
const joinedGroupId = (
|
|
6823
|
+
const joinedGroupId = (_k = groupJoinData === null || groupJoinData === void 0 ? void 0 : groupJoinData.group) === null || _k === void 0 ? void 0 : _k.id;
|
|
6784
6824
|
// Trigger invite tracking before opening lobby (global for product)
|
|
6785
6825
|
if (joinedGroupId) {
|
|
6786
6826
|
try {
|
|
@@ -6812,7 +6852,7 @@ var CoBuySDK = (function (exports) {
|
|
|
6812
6852
|
}
|
|
6813
6853
|
if (this.analyticsClient) {
|
|
6814
6854
|
this.analyticsClient
|
|
6815
|
-
.trackJoinFailure(productId, (
|
|
6855
|
+
.trackJoinFailure(productId, (_l = this.currentGroupId) !== null && _l !== void 0 ? _l : undefined, "EXCEPTION", error instanceof Error ? error.message : String(error))
|
|
6816
6856
|
.catch((e) => this.logger.warn("Analytics tracking failed", e));
|
|
6817
6857
|
}
|
|
6818
6858
|
this.setButtonLoadingState(false);
|
|
@@ -6829,7 +6869,7 @@ var CoBuySDK = (function (exports) {
|
|
|
6829
6869
|
const progress = Math.round((groupJoinData.group.participants_count / groupJoinData.group.max_participants) * 100);
|
|
6830
6870
|
// Format discount based on reward type
|
|
6831
6871
|
let discountText = "";
|
|
6832
|
-
if ((
|
|
6872
|
+
if ((_o = (_m = this.currentRewardData) === null || _m === void 0 ? void 0 : _m.reward) === null || _o === void 0 ? void 0 : _o.value) {
|
|
6833
6873
|
const rewardType = this.currentRewardData.reward.type;
|
|
6834
6874
|
const rewardValue = this.currentRewardData.reward.value;
|
|
6835
6875
|
if (rewardType === "percentage" || rewardType === "cashback") {
|
|
@@ -6869,7 +6909,7 @@ var CoBuySDK = (function (exports) {
|
|
|
6869
6909
|
shareMessage: shareMessageFromInvite,
|
|
6870
6910
|
isLocked: !isGroupFulfilled,
|
|
6871
6911
|
offlineRedemption: offlineRedemptionFromJoin,
|
|
6872
|
-
redemptionMethod: (
|
|
6912
|
+
redemptionMethod: (_p = groupJoinData.group.campaign_redemption_method) !== null && _p !== void 0 ? _p : this.campaignRedemptionMethod,
|
|
6873
6913
|
onShare: this.analyticsClient
|
|
6874
6914
|
? () => {
|
|
6875
6915
|
this.analyticsClient.trackShareClick(productId, groupJoinData.group.id, "other").catch((e) => this.logger.warn("Analytics tracking failed", e));
|
|
@@ -7047,6 +7087,7 @@ var CoBuySDK = (function (exports) {
|
|
|
7047
7087
|
GROUP_CREATE_AND_JOIN: "/v1/sdk/groups/new/join",
|
|
7048
7088
|
PRODUCT_ACTIVE_GROUPS: "/v1/sdk/products/:productId/groups/active",
|
|
7049
7089
|
GROUP_INVITE: "/v1/sdk/groups/:groupId/invite",
|
|
7090
|
+
GROUP_OFFLINE_REDEMPTION: "/v1/sdk/groups/:groupId/offline-redemption",
|
|
7050
7091
|
GROUP_CHECKOUT_PREPARE: "/v1/sdk/groups/:groupId/checkout/prepare",
|
|
7051
7092
|
GROUP_CHECKOUT_VALIDATE: "/v1/sdk/groups/:groupId/checkout/validate",
|
|
7052
7093
|
GROUP_CHECKOUT_CONFIRM: "/v1/sdk/groups/:groupId/checkout/confirm",
|
|
@@ -8159,6 +8200,29 @@ var CoBuySDK = (function (exports) {
|
|
|
8159
8200
|
},
|
|
8160
8201
|
};
|
|
8161
8202
|
}
|
|
8203
|
+
/**
|
|
8204
|
+
* Fetch current session member's offline redemption codes for a group.
|
|
8205
|
+
*/
|
|
8206
|
+
async getGroupOfflineRedemption(groupId) {
|
|
8207
|
+
const endpoint = buildApiUrl("", API_ENDPOINTS.GROUP_OFFLINE_REDEMPTION, {
|
|
8208
|
+
groupId,
|
|
8209
|
+
});
|
|
8210
|
+
const response = await this.get(endpoint);
|
|
8211
|
+
if (response.success) {
|
|
8212
|
+
const payload = response.data;
|
|
8213
|
+
return {
|
|
8214
|
+
success: true,
|
|
8215
|
+
data: (payload === null || payload === void 0 ? void 0 : payload.data) || {},
|
|
8216
|
+
};
|
|
8217
|
+
}
|
|
8218
|
+
return {
|
|
8219
|
+
success: false,
|
|
8220
|
+
error: response.error || {
|
|
8221
|
+
message: "Failed to fetch offline redemption",
|
|
8222
|
+
code: "OFFLINE_REDEMPTION_FETCH_ERROR",
|
|
8223
|
+
},
|
|
8224
|
+
};
|
|
8225
|
+
}
|
|
8162
8226
|
async recoverOrJoinGroup(productId, contact) {
|
|
8163
8227
|
var _a;
|
|
8164
8228
|
const endpoint = buildApiUrl("", API_ENDPOINTS.PRODUCT_RECOVER_OR_JOIN_GROUP, {
|
|
@@ -14438,6 +14502,18 @@ var CoBuySDK = (function (exports) {
|
|
|
14438
14502
|
if ((_a = config.events) === null || _a === void 0 ? void 0 : _a.onModalClose) {
|
|
14439
14503
|
config.events.onModalClose(options.productId);
|
|
14440
14504
|
}
|
|
14505
|
+
// Sync widget state after lobby closes so fulfilled CTAs/group view
|
|
14506
|
+
// reflect socket-driven changes without requiring a page reload.
|
|
14507
|
+
const refreshPromises = [];
|
|
14508
|
+
this.widgets.forEach((w) => {
|
|
14509
|
+
const pid = typeof w.getProductId === "function"
|
|
14510
|
+
? w.getProductId()
|
|
14511
|
+
: null;
|
|
14512
|
+
if (pid === options.productId && typeof w.requestRefresh === "function") {
|
|
14513
|
+
refreshPromises.push(w.requestRefresh());
|
|
14514
|
+
}
|
|
14515
|
+
});
|
|
14516
|
+
void Promise.all(refreshPromises.map((p) => p.then(() => undefined).catch(() => undefined)));
|
|
14441
14517
|
},
|
|
14442
14518
|
onCopyLink: options.onCopyLink,
|
|
14443
14519
|
onShare: options.onShare,
|