@cshah18/sdk 1.0.0 → 2.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/README.md +21 -0
- package/dist/cobuy-sdk.esm.js +8581 -697
- package/dist/cobuy-sdk.esm.js.map +1 -1
- package/dist/cobuy-sdk.umd.js +8589 -699
- package/dist/cobuy-sdk.umd.js.map +1 -1
- package/dist/types/core/api-client.d.ts +74 -5
- package/dist/types/core/auth-strategy.d.ts +55 -0
- package/dist/types/core/cobuy.d.ts +42 -1
- package/dist/types/core/endpoints.d.ts +7 -23
- package/dist/types/core/socket-client.d.ts +126 -0
- package/dist/types/core/socket.d.ts +51 -0
- package/dist/types/core/types.d.ts +301 -5
- package/dist/types/index.d.ts +2 -0
- package/dist/types/ui/group-list/group-list-modal.d.ts +61 -0
- package/dist/types/ui/lobby/lobby-modal.d.ts +257 -0
- package/dist/types/ui/widget/widget-root.d.ts +62 -22
- package/package.json +12 -2
|
@@ -52,14 +52,63 @@ export interface CoBuyThemeOptions {
|
|
|
52
52
|
*/
|
|
53
53
|
animationStyle?: AnimationStyle;
|
|
54
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* Authentication mode for SDK initialization
|
|
57
|
+
* - "public": Use merchant key (no-backend sites, read-only endpoints)
|
|
58
|
+
* - "token": Use short-lived session token (backend-integrated sites, full access)
|
|
59
|
+
*/
|
|
60
|
+
export type AuthMode = "public" | "token";
|
|
61
|
+
/**
|
|
62
|
+
* Authentication callbacks for token mode
|
|
63
|
+
*/
|
|
64
|
+
export interface AuthCallbacks {
|
|
65
|
+
/**
|
|
66
|
+
* Called when authentication fails (401/403)
|
|
67
|
+
* Use this to handle auth errors in your application
|
|
68
|
+
*/
|
|
69
|
+
onAuthError?: (error: Error) => void;
|
|
70
|
+
/**
|
|
71
|
+
* Called when token expires or needs refresh
|
|
72
|
+
* Use this to fetch a new token from your backend
|
|
73
|
+
*/
|
|
74
|
+
onTokenExpired?: () => void | Promise<void>;
|
|
75
|
+
}
|
|
55
76
|
/**
|
|
56
77
|
* Options for initializing the CoBuy SDK
|
|
57
78
|
*/
|
|
58
79
|
export interface CoBuyInitOptions {
|
|
80
|
+
/**
|
|
81
|
+
* Authentication mode (default: "public")
|
|
82
|
+
* - "public": For no-backend sites (uses merchantKey)
|
|
83
|
+
* - "token": For backend-integrated sites (uses sessionToken)
|
|
84
|
+
*/
|
|
85
|
+
authMode?: AuthMode;
|
|
59
86
|
/**
|
|
60
87
|
* Unique merchant key provided by CoBuy
|
|
88
|
+
* Required for authMode="public"
|
|
89
|
+
* Not used in authMode="token"
|
|
61
90
|
*/
|
|
62
|
-
merchantKey
|
|
91
|
+
merchantKey?: string;
|
|
92
|
+
/**
|
|
93
|
+
* Session token for authenticated requests
|
|
94
|
+
* Required for authMode="token"
|
|
95
|
+
* Can be a string or async function that returns a token
|
|
96
|
+
* Token should be short-lived (5-15 minutes) and fetched from your backend
|
|
97
|
+
*
|
|
98
|
+
* Example:
|
|
99
|
+
* ```ts
|
|
100
|
+
* sessionToken: async () => {
|
|
101
|
+
* const response = await fetch('/api/cobuy-token');
|
|
102
|
+
* const { token } = await response.json();
|
|
103
|
+
* return token;
|
|
104
|
+
* }
|
|
105
|
+
* ```
|
|
106
|
+
*/
|
|
107
|
+
sessionToken?: string | (() => string | Promise<string>);
|
|
108
|
+
/**
|
|
109
|
+
* Authentication callbacks for handling errors and token refresh
|
|
110
|
+
*/
|
|
111
|
+
auth?: AuthCallbacks;
|
|
63
112
|
/**
|
|
64
113
|
* Environment to connect to (default: "production")
|
|
65
114
|
*/
|
|
@@ -97,6 +146,44 @@ export interface CheckoutData {
|
|
|
97
146
|
groupId: string;
|
|
98
147
|
productId: string;
|
|
99
148
|
}
|
|
149
|
+
/**
|
|
150
|
+
* Socket payload emitted when a group reaches fulfillment
|
|
151
|
+
*/
|
|
152
|
+
export interface GroupFulfilledEvent {
|
|
153
|
+
groupId: string;
|
|
154
|
+
productId: string;
|
|
155
|
+
participants: number;
|
|
156
|
+
reward: Reward;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Socket payload emitted when a new group is created
|
|
160
|
+
*/
|
|
161
|
+
export interface GroupCreatedEvent {
|
|
162
|
+
groupId: string;
|
|
163
|
+
productId: string;
|
|
164
|
+
createdAt: string;
|
|
165
|
+
participantCount?: number;
|
|
166
|
+
maxParticipants?: number;
|
|
167
|
+
groupNumber?: string;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Socket payload emitted when a member joins a group
|
|
171
|
+
*/
|
|
172
|
+
export interface GroupMemberJoinedEvent {
|
|
173
|
+
groupId: string;
|
|
174
|
+
productId: string;
|
|
175
|
+
memberId: string;
|
|
176
|
+
memberCount: number;
|
|
177
|
+
maxParticipants?: number;
|
|
178
|
+
timestamp?: string;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Payload emitted when shopper opts to continue to checkout
|
|
182
|
+
*/
|
|
183
|
+
export interface CheckoutRequestedEvent {
|
|
184
|
+
groupId: string;
|
|
185
|
+
productId: string;
|
|
186
|
+
}
|
|
100
187
|
/**
|
|
101
188
|
* Widget event callbacks for lifecycle events
|
|
102
189
|
*/
|
|
@@ -125,6 +212,22 @@ export interface WidgetEvents {
|
|
|
125
212
|
* Called when modal closes
|
|
126
213
|
*/
|
|
127
214
|
onModalClose?: (_productId: string) => void;
|
|
215
|
+
/**
|
|
216
|
+
* Called when the backend notifies that a group has been fulfilled
|
|
217
|
+
*/
|
|
218
|
+
onGroupFulfilled?: (_event: GroupFulfilledEvent) => void;
|
|
219
|
+
/**
|
|
220
|
+
* Called when the backend notifies that a group was created
|
|
221
|
+
*/
|
|
222
|
+
onGroupCreated?: (_event: GroupCreatedEvent) => void;
|
|
223
|
+
/**
|
|
224
|
+
* Called when the backend notifies that a member joined a group
|
|
225
|
+
*/
|
|
226
|
+
onGroupMemberJoined?: (_event: GroupMemberJoinedEvent) => void;
|
|
227
|
+
/**
|
|
228
|
+
* Called when shopper clicks continue to checkout from the fulfilled state
|
|
229
|
+
*/
|
|
230
|
+
onCheckoutRequested?: (_event: CheckoutRequestedEvent) => void;
|
|
128
231
|
}
|
|
129
232
|
/**
|
|
130
233
|
* Modal configuration options
|
|
@@ -134,10 +237,61 @@ export interface ModalOptions {
|
|
|
134
237
|
* Product ID to show in the modal
|
|
135
238
|
*/
|
|
136
239
|
productId: string;
|
|
240
|
+
/**
|
|
241
|
+
* Group ID for the lobby
|
|
242
|
+
*/
|
|
243
|
+
groupId?: string;
|
|
137
244
|
/**
|
|
138
245
|
* Optional custom title for the modal
|
|
139
246
|
*/
|
|
140
247
|
title?: string;
|
|
248
|
+
/**
|
|
249
|
+
* Group number (e.g., "1000")
|
|
250
|
+
*/
|
|
251
|
+
groupNumber?: string;
|
|
252
|
+
/**
|
|
253
|
+
* Lobby status
|
|
254
|
+
*/
|
|
255
|
+
status?: "active" | "complete";
|
|
256
|
+
/**
|
|
257
|
+
* Group progress percentage (0-100)
|
|
258
|
+
*/
|
|
259
|
+
progress?: number;
|
|
260
|
+
/**
|
|
261
|
+
* Current number of members in the group
|
|
262
|
+
*/
|
|
263
|
+
currentMembers?: number;
|
|
264
|
+
/**
|
|
265
|
+
* Total members needed for the group
|
|
266
|
+
*/
|
|
267
|
+
totalMembers?: number;
|
|
268
|
+
/**
|
|
269
|
+
* Time left in seconds
|
|
270
|
+
*/
|
|
271
|
+
timeLeft?: number;
|
|
272
|
+
/**
|
|
273
|
+
* Discount text (e.g., "20% OFF")
|
|
274
|
+
*/
|
|
275
|
+
discount?: string;
|
|
276
|
+
/**
|
|
277
|
+
* Group link URL
|
|
278
|
+
*/
|
|
279
|
+
groupLink?: string;
|
|
280
|
+
/**
|
|
281
|
+
* Whether the offer is locked
|
|
282
|
+
*/
|
|
283
|
+
isLocked?: boolean;
|
|
284
|
+
/**
|
|
285
|
+
* Activity items to display
|
|
286
|
+
*/
|
|
287
|
+
activities?: Array<{
|
|
288
|
+
emoji: string;
|
|
289
|
+
username: string;
|
|
290
|
+
location: string;
|
|
291
|
+
action: string;
|
|
292
|
+
timeAgo: string;
|
|
293
|
+
color: "pink" | "purple" | "blue" | "green" | "orange";
|
|
294
|
+
}>;
|
|
141
295
|
/**
|
|
142
296
|
* Optional callback when modal opens
|
|
143
297
|
*/
|
|
@@ -145,12 +299,38 @@ export interface ModalOptions {
|
|
|
145
299
|
/**
|
|
146
300
|
* Optional callback when modal closes
|
|
147
301
|
*/
|
|
148
|
-
onClose?: (
|
|
302
|
+
onClose?: () => void;
|
|
303
|
+
/**
|
|
304
|
+
* Optional callback when user copies the group link
|
|
305
|
+
*/
|
|
306
|
+
onCopyLink?: (_link: string) => void;
|
|
307
|
+
/**
|
|
308
|
+
* Optional callback when user shares
|
|
309
|
+
*/
|
|
310
|
+
onShare?: () => void;
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Contact information for user identification
|
|
314
|
+
* Supports email or phone number as contact types
|
|
315
|
+
* Used for enriching anonymous sessions with user contact data
|
|
316
|
+
*/
|
|
317
|
+
export interface Contact {
|
|
318
|
+
/**
|
|
319
|
+
* Type of contact information
|
|
320
|
+
* - "email": User's email address
|
|
321
|
+
* - "phone": User's phone number
|
|
322
|
+
*/
|
|
323
|
+
type: "email" | "phone";
|
|
324
|
+
/**
|
|
325
|
+
* The contact value (email address or phone number)
|
|
326
|
+
* Must be a valid email or phone format
|
|
327
|
+
*/
|
|
328
|
+
value: string;
|
|
149
329
|
}
|
|
150
330
|
/**
|
|
151
331
|
* Reward type enumeration
|
|
152
332
|
*/
|
|
153
|
-
export type RewardType = "percentage" | "fixed" | "points" | "cashback";
|
|
333
|
+
export type RewardType = "percentage" | "fixed" | "points" | "cashback" | "flat";
|
|
154
334
|
/**
|
|
155
335
|
* Reward status enumeration
|
|
156
336
|
*/
|
|
@@ -185,6 +365,60 @@ export interface ProductRewardData {
|
|
|
185
365
|
reward: Reward;
|
|
186
366
|
eligibility: RewardEligibility;
|
|
187
367
|
}
|
|
368
|
+
/**
|
|
369
|
+
* Primary group information for a product (SCRUM-284)
|
|
370
|
+
*/
|
|
371
|
+
export interface ProductPrimaryGroupData {
|
|
372
|
+
group: ProductPrimaryGroupData | PromiseLike<ProductPrimaryGroupData | null> | null;
|
|
373
|
+
id: string;
|
|
374
|
+
group_name: string;
|
|
375
|
+
description: string | null;
|
|
376
|
+
campaign_creative_id: string | null;
|
|
377
|
+
campaign_creative_name: string | null;
|
|
378
|
+
campaign_id: string | null;
|
|
379
|
+
campaign_name: string | null;
|
|
380
|
+
campaign_status: string | null;
|
|
381
|
+
participants_count: number;
|
|
382
|
+
max_participants: number;
|
|
383
|
+
status: string;
|
|
384
|
+
expiry_at: string;
|
|
385
|
+
timeLeftSeconds: number;
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Group join response data
|
|
389
|
+
*/
|
|
390
|
+
export interface GroupJoinResponseData {
|
|
391
|
+
group: {
|
|
392
|
+
id: string;
|
|
393
|
+
group_name: string;
|
|
394
|
+
participants_count: number;
|
|
395
|
+
max_participants: number;
|
|
396
|
+
status: string;
|
|
397
|
+
expiry_at: string;
|
|
398
|
+
timeLeftSeconds: number;
|
|
399
|
+
};
|
|
400
|
+
membership: {
|
|
401
|
+
id: string;
|
|
402
|
+
session_id: string;
|
|
403
|
+
created_at: string;
|
|
404
|
+
};
|
|
405
|
+
isPrimary: boolean;
|
|
406
|
+
product_id: string;
|
|
407
|
+
}
|
|
408
|
+
export type ShareChannel = "whatsapp" | "facebook" | "email" | "sms" | "copy_link" | "tiktok" | "x" | "other";
|
|
409
|
+
export interface GroupInviteResponseData {
|
|
410
|
+
invite_url?: string;
|
|
411
|
+
invite_token?: string;
|
|
412
|
+
share_message?: string;
|
|
413
|
+
group?: {
|
|
414
|
+
id: string;
|
|
415
|
+
name?: string;
|
|
416
|
+
current_count?: number;
|
|
417
|
+
slots_remaining?: number;
|
|
418
|
+
expires_at?: string;
|
|
419
|
+
};
|
|
420
|
+
[key: string]: unknown;
|
|
421
|
+
}
|
|
188
422
|
/**
|
|
189
423
|
* Options for rendering the CoBuy widget
|
|
190
424
|
*/
|
|
@@ -218,6 +452,45 @@ export interface RenderWidgetOptions {
|
|
|
218
452
|
* Callback triggered when widget closes
|
|
219
453
|
*/
|
|
220
454
|
onClose?: () => void;
|
|
455
|
+
/**
|
|
456
|
+
* Optional layout order for widget sections.
|
|
457
|
+
* Controls the rendering order of 'group' (participation info),
|
|
458
|
+
* 'reward' (reward text), and 'cta' (action button).
|
|
459
|
+
* Defaults to ["group", "reward", "cta"].
|
|
460
|
+
*/
|
|
461
|
+
layout?: Array<"group" | "reward" | "cta">;
|
|
462
|
+
/**
|
|
463
|
+
* Optional separate container for group participation info.
|
|
464
|
+
* If provided, group info will render here instead of inside the main widget.
|
|
465
|
+
* Can be a selector string or HTMLElement.
|
|
466
|
+
*/
|
|
467
|
+
groupContainer?: string | HTMLElement;
|
|
468
|
+
/**
|
|
469
|
+
* Optional separate container for reward text.
|
|
470
|
+
* If provided, reward text will render here instead of inside the main widget.
|
|
471
|
+
* Can be a selector string or HTMLElement.
|
|
472
|
+
*/
|
|
473
|
+
rewardContainer?: string | HTMLElement;
|
|
474
|
+
/**
|
|
475
|
+
* Optional customization for the "View all Groups" link.
|
|
476
|
+
* - container: render the link in a separate element (like reward/group containers)
|
|
477
|
+
* - text / classes / styles: adjust copy, font, color, underline, alignment, etc.
|
|
478
|
+
*/
|
|
479
|
+
viewAllLink?: {
|
|
480
|
+
container?: string | HTMLElement;
|
|
481
|
+
text?: string;
|
|
482
|
+
align?: "left" | "center" | "right";
|
|
483
|
+
className?: string;
|
|
484
|
+
linkClassName?: string;
|
|
485
|
+
underline?: boolean;
|
|
486
|
+
color?: string;
|
|
487
|
+
fontSize?: string;
|
|
488
|
+
fontWeight?: string | number;
|
|
489
|
+
fontFamily?: string;
|
|
490
|
+
textDecoration?: string;
|
|
491
|
+
style?: Partial<Record<string, string | number>>;
|
|
492
|
+
linkStyle?: Partial<Record<string, string | number>>;
|
|
493
|
+
};
|
|
221
494
|
}
|
|
222
495
|
/**
|
|
223
496
|
* Public CoBuy SDK interface
|
|
@@ -231,17 +504,30 @@ export interface CoBuySDK {
|
|
|
231
504
|
* Render the CoBuy widget into a DOM container
|
|
232
505
|
*/
|
|
233
506
|
renderWidget(_options: RenderWidgetOptions): void;
|
|
507
|
+
/**
|
|
508
|
+
* Set or update contact information for the current session
|
|
509
|
+
* Allows merchants to enrich an anonymous session with user contact data
|
|
510
|
+
* @param _contact Contact information (email or phone)
|
|
511
|
+
*/
|
|
512
|
+
setContact(_contact: Contact): Promise<void>;
|
|
234
513
|
/**
|
|
235
514
|
* SDK version
|
|
236
515
|
*/
|
|
237
516
|
readonly version: string;
|
|
517
|
+
/**
|
|
518
|
+
* Optional cleanup for long-lived pages (closes sockets, etc.)
|
|
519
|
+
*/
|
|
520
|
+
destroy?(): void;
|
|
238
521
|
}
|
|
239
522
|
/**
|
|
240
523
|
* Internal configuration object used throughout the SDK
|
|
241
524
|
* This extends the public CoBuyInitOptions with computed values
|
|
242
525
|
*/
|
|
243
526
|
export interface InternalConfig {
|
|
244
|
-
|
|
527
|
+
authMode: AuthMode;
|
|
528
|
+
merchantKey?: string;
|
|
529
|
+
sessionToken?: string | (() => string | Promise<string>);
|
|
530
|
+
auth?: AuthCallbacks;
|
|
245
531
|
env: CoBuyEnvironment;
|
|
246
532
|
apiBaseUrl: string;
|
|
247
533
|
theme: CoBuyThemeOptions;
|
|
@@ -278,7 +564,17 @@ export interface ApiResponse<T = unknown> {
|
|
|
278
564
|
*/
|
|
279
565
|
export interface ApiClientConfig {
|
|
280
566
|
baseUrl: string;
|
|
281
|
-
|
|
567
|
+
authStrategy: AuthStrategy;
|
|
568
|
+
sessionId: string;
|
|
282
569
|
debug?: boolean;
|
|
283
570
|
timeout?: number;
|
|
284
571
|
}
|
|
572
|
+
/**
|
|
573
|
+
* Authentication strategy interface (imported from auth-strategy.ts)
|
|
574
|
+
* Re-exported here for convenience
|
|
575
|
+
*/
|
|
576
|
+
export interface AuthStrategy {
|
|
577
|
+
getHeaders(): Record<string, string>;
|
|
578
|
+
refreshIfNeeded(): Promise<boolean>;
|
|
579
|
+
onAuthError(error: Error): void;
|
|
580
|
+
}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -2,6 +2,8 @@ import { CoBuy } from "./core/cobuy";
|
|
|
2
2
|
import type { CoBuySDK } from "./core/types";
|
|
3
3
|
export type { CoBuySDK };
|
|
4
4
|
export * from "./core/types";
|
|
5
|
+
export type { AuthStrategy } from "./core/auth-strategy";
|
|
6
|
+
export { PublicKeyAuth, TokenAuth } from "./core/auth-strategy";
|
|
5
7
|
declare const instance: CoBuy;
|
|
6
8
|
declare global {
|
|
7
9
|
interface Window {
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { ApiClient } from "../../core/api-client";
|
|
2
|
+
import { ProductPrimaryGroupData, GroupJoinResponseData } from "../../core/types";
|
|
3
|
+
export interface GroupListItem {
|
|
4
|
+
groupId: string;
|
|
5
|
+
timeLabel: string;
|
|
6
|
+
timeLeftSeconds?: number;
|
|
7
|
+
joined: number;
|
|
8
|
+
total: number;
|
|
9
|
+
isMember: boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface ApiGroupData extends ProductPrimaryGroupData {
|
|
12
|
+
is_member: boolean;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* GroupListModal - Renders the "View all Groups" popup with optional API integration.
|
|
16
|
+
*/
|
|
17
|
+
export declare class GroupListModal {
|
|
18
|
+
private overlayEl;
|
|
19
|
+
private logger;
|
|
20
|
+
private groups;
|
|
21
|
+
private liveCount;
|
|
22
|
+
private apiClient;
|
|
23
|
+
private isLoading;
|
|
24
|
+
private startButton;
|
|
25
|
+
private countdownIntervals;
|
|
26
|
+
private currentJoinedGroupId;
|
|
27
|
+
private currentProductId;
|
|
28
|
+
private currentSessionId;
|
|
29
|
+
private onGroupJoined;
|
|
30
|
+
private onViewProgress;
|
|
31
|
+
private readonly escapeHandler;
|
|
32
|
+
constructor(groups?: GroupListItem[], liveCount?: number, debug?: boolean, apiClient?: ApiClient | null);
|
|
33
|
+
/** Set callback for when a group is joined successfully */
|
|
34
|
+
setOnGroupJoined(callback: (joinData: GroupJoinResponseData) => void): void;
|
|
35
|
+
/** Set callback for when viewing progress on an already joined group */
|
|
36
|
+
setOnViewProgress(callback: (groupId: string, groupData: GroupListItem) => void): void;
|
|
37
|
+
/** Set the currently joined group ID to show appropriate button states */
|
|
38
|
+
setCurrentJoinedGroup(groupId: string): void;
|
|
39
|
+
/** Check if a group ID exists in the current groups list */
|
|
40
|
+
hasGroup(groupId: string): boolean;
|
|
41
|
+
open(productId?: string, sessionId?: string, joinedGroupId?: string): Promise<void>;
|
|
42
|
+
private fetchAndRenderGroups;
|
|
43
|
+
private formatTimeRemaining;
|
|
44
|
+
close(): void;
|
|
45
|
+
isOpen(): boolean;
|
|
46
|
+
/** Handle join group button click - calls API and executes callback */
|
|
47
|
+
private handleJoinGroup;
|
|
48
|
+
/** Handle create new group button click - creates and joins a group, then triggers callback */
|
|
49
|
+
private handleCreateNewGroup;
|
|
50
|
+
private buildOverlay;
|
|
51
|
+
private createLoadingSkeleton;
|
|
52
|
+
private createHeader;
|
|
53
|
+
private createLiveBox;
|
|
54
|
+
private createCardsGrid;
|
|
55
|
+
private startCountdown;
|
|
56
|
+
private setJoinButtonsDisabled;
|
|
57
|
+
private updateStartButtonState;
|
|
58
|
+
private createGroupCard;
|
|
59
|
+
private createMemberAvatar;
|
|
60
|
+
private injectStyles;
|
|
61
|
+
}
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
import { ApiClient } from "../../core/api-client";
|
|
2
|
+
import { AnalyticsClient } from "../../core/analytics";
|
|
3
|
+
import { SocketManager } from "../../core/socket";
|
|
4
|
+
import "./styles/styles.css";
|
|
5
|
+
export interface LobbyModalData {
|
|
6
|
+
productId: string;
|
|
7
|
+
groupId?: string;
|
|
8
|
+
groupNumber?: string;
|
|
9
|
+
status?: "active" | "complete";
|
|
10
|
+
progress?: number;
|
|
11
|
+
currentMembers?: number;
|
|
12
|
+
totalMembers?: number;
|
|
13
|
+
timeLeft?: number;
|
|
14
|
+
discount?: string;
|
|
15
|
+
groupLink?: string;
|
|
16
|
+
shareMessage?: string;
|
|
17
|
+
activities?: ActivityItem[];
|
|
18
|
+
isLocked?: boolean;
|
|
19
|
+
}
|
|
20
|
+
export interface ActivityItem {
|
|
21
|
+
emoji: string;
|
|
22
|
+
username: string;
|
|
23
|
+
location: string;
|
|
24
|
+
action: string;
|
|
25
|
+
timeAgo: string;
|
|
26
|
+
color: "pink" | "purple" | "blue" | "green" | "orange";
|
|
27
|
+
}
|
|
28
|
+
export interface LobbyModalCallbacks {
|
|
29
|
+
onClose?: () => void;
|
|
30
|
+
onCopyLink?: (link: string) => void;
|
|
31
|
+
onShare?: () => void;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* LobbyModal - Renders and manages the group buying lobby modal
|
|
35
|
+
*/
|
|
36
|
+
export declare class LobbyModal {
|
|
37
|
+
private logger;
|
|
38
|
+
private analyticsClient;
|
|
39
|
+
private socketManager;
|
|
40
|
+
private apiClient;
|
|
41
|
+
private modalElement;
|
|
42
|
+
private data;
|
|
43
|
+
private callbacks;
|
|
44
|
+
private timerInterval;
|
|
45
|
+
private activityInterval;
|
|
46
|
+
private activityCards;
|
|
47
|
+
private socketListenerRegistered;
|
|
48
|
+
private currentGroupId;
|
|
49
|
+
private shareOverlay;
|
|
50
|
+
constructor(data: LobbyModalData, callbacks: LobbyModalCallbacks, apiClient: ApiClient | null, analyticsClient: AnalyticsClient | null, socketManager?: SocketManager | null, debug?: boolean);
|
|
51
|
+
/**
|
|
52
|
+
* Derive lock state from data so UI reflects completion
|
|
53
|
+
*/
|
|
54
|
+
private computeIsLocked;
|
|
55
|
+
private getRewardText;
|
|
56
|
+
private getTitleText;
|
|
57
|
+
/**
|
|
58
|
+
* Default activity items
|
|
59
|
+
*/
|
|
60
|
+
private getDefaultActivities;
|
|
61
|
+
/**
|
|
62
|
+
* Create the modal DOM structure
|
|
63
|
+
*/
|
|
64
|
+
private createModalStructure;
|
|
65
|
+
/**
|
|
66
|
+
* Create close icon
|
|
67
|
+
*/
|
|
68
|
+
private createCloseIcon;
|
|
69
|
+
/**
|
|
70
|
+
* Create top section
|
|
71
|
+
*/
|
|
72
|
+
private createTopSection;
|
|
73
|
+
/**
|
|
74
|
+
* Create left section
|
|
75
|
+
*/
|
|
76
|
+
private createLeftSection;
|
|
77
|
+
/**
|
|
78
|
+
* Create status section
|
|
79
|
+
*/
|
|
80
|
+
private createStatusSection;
|
|
81
|
+
/**
|
|
82
|
+
* Create title section
|
|
83
|
+
*/
|
|
84
|
+
private createTitleSection;
|
|
85
|
+
/**
|
|
86
|
+
* Create link section
|
|
87
|
+
*/
|
|
88
|
+
private createLinkSection;
|
|
89
|
+
/**
|
|
90
|
+
* Create offer section
|
|
91
|
+
*/
|
|
92
|
+
private createOfferSection;
|
|
93
|
+
/**
|
|
94
|
+
* Create right section
|
|
95
|
+
*/
|
|
96
|
+
private createRightSection;
|
|
97
|
+
/**
|
|
98
|
+
* Create group info box
|
|
99
|
+
*/
|
|
100
|
+
private createGroupInfoBox;
|
|
101
|
+
/**
|
|
102
|
+
* Create progress card
|
|
103
|
+
*/
|
|
104
|
+
private createProgressCard;
|
|
105
|
+
/**
|
|
106
|
+
* Create team card
|
|
107
|
+
*/
|
|
108
|
+
private createTeamCard;
|
|
109
|
+
/**
|
|
110
|
+
* Create time card
|
|
111
|
+
*/
|
|
112
|
+
private createTimeCard;
|
|
113
|
+
/**
|
|
114
|
+
* Create activity section
|
|
115
|
+
*/
|
|
116
|
+
private createActivitySection;
|
|
117
|
+
/**
|
|
118
|
+
* Create activity card
|
|
119
|
+
*/
|
|
120
|
+
private createActivityCard;
|
|
121
|
+
/**
|
|
122
|
+
* Format time in HH:MM:SS format
|
|
123
|
+
*/
|
|
124
|
+
private formatTime;
|
|
125
|
+
/**
|
|
126
|
+
* Update timer
|
|
127
|
+
*/
|
|
128
|
+
private updateTimer;
|
|
129
|
+
/**
|
|
130
|
+
* Start timer
|
|
131
|
+
*/
|
|
132
|
+
private startTimer;
|
|
133
|
+
/**
|
|
134
|
+
* Stop timer
|
|
135
|
+
*/
|
|
136
|
+
private stopTimer;
|
|
137
|
+
/**
|
|
138
|
+
* Layout activity cards
|
|
139
|
+
*/
|
|
140
|
+
private layoutActivityCards;
|
|
141
|
+
/**
|
|
142
|
+
* Shuffle activity cards
|
|
143
|
+
*/
|
|
144
|
+
private shuffleActivityCards;
|
|
145
|
+
/**
|
|
146
|
+
* Start activity animation
|
|
147
|
+
*/
|
|
148
|
+
private startActivityAnimation;
|
|
149
|
+
/**
|
|
150
|
+
* Stop activity animation
|
|
151
|
+
*/
|
|
152
|
+
private stopActivityAnimation;
|
|
153
|
+
/**
|
|
154
|
+
* Record invite/share event and refresh share link/message
|
|
155
|
+
*/
|
|
156
|
+
private recordInvite;
|
|
157
|
+
/**
|
|
158
|
+
* Copy link to clipboard
|
|
159
|
+
*/
|
|
160
|
+
private copyLink;
|
|
161
|
+
/**
|
|
162
|
+
* Share functionality
|
|
163
|
+
*/
|
|
164
|
+
private share;
|
|
165
|
+
/**
|
|
166
|
+
* Create share overlay modal
|
|
167
|
+
*/
|
|
168
|
+
private createShareOverlay;
|
|
169
|
+
/**
|
|
170
|
+
* Create a share card
|
|
171
|
+
*/
|
|
172
|
+
private createShareCard;
|
|
173
|
+
/**
|
|
174
|
+
* Open share modal
|
|
175
|
+
*/
|
|
176
|
+
private openShareModal;
|
|
177
|
+
/**
|
|
178
|
+
* Close share modal
|
|
179
|
+
*/
|
|
180
|
+
private closeShareModal;
|
|
181
|
+
/**
|
|
182
|
+
* Copy link from modal
|
|
183
|
+
*/
|
|
184
|
+
private copyLinkFromModal;
|
|
185
|
+
/**
|
|
186
|
+
* Share to WhatsApp
|
|
187
|
+
*/
|
|
188
|
+
private shareToWhatsApp;
|
|
189
|
+
/**
|
|
190
|
+
* Share to Facebook
|
|
191
|
+
*/
|
|
192
|
+
private shareToFacebook;
|
|
193
|
+
/**
|
|
194
|
+
* Share to Twitter (X)
|
|
195
|
+
*/
|
|
196
|
+
private shareToTwitter;
|
|
197
|
+
/**
|
|
198
|
+
* Share via SMS
|
|
199
|
+
*/
|
|
200
|
+
private shareToSMS;
|
|
201
|
+
/**
|
|
202
|
+
* Open/render the modal
|
|
203
|
+
*/
|
|
204
|
+
open(groupId?: string): void;
|
|
205
|
+
/**
|
|
206
|
+
* Close the modal
|
|
207
|
+
*/
|
|
208
|
+
close(): void;
|
|
209
|
+
/**
|
|
210
|
+
* Check if modal is open
|
|
211
|
+
*/
|
|
212
|
+
isOpen(): boolean;
|
|
213
|
+
/**
|
|
214
|
+
* Update modal data
|
|
215
|
+
*/
|
|
216
|
+
updateData(data: Partial<LobbyModalData>): void;
|
|
217
|
+
/**
|
|
218
|
+
* Update title and subtitle dynamically from API/state
|
|
219
|
+
*/
|
|
220
|
+
private updateTitleUI;
|
|
221
|
+
/**
|
|
222
|
+
* Update status chip text and styling
|
|
223
|
+
*/
|
|
224
|
+
private updateStatusUI;
|
|
225
|
+
/**
|
|
226
|
+
* Update lock status and reward text in the UI
|
|
227
|
+
*/
|
|
228
|
+
private updateLockUI;
|
|
229
|
+
/**
|
|
230
|
+
* Show/hide link section based on lock state
|
|
231
|
+
*/
|
|
232
|
+
private updateLinkVisibility;
|
|
233
|
+
/**
|
|
234
|
+
* Subscribe to socket events
|
|
235
|
+
*/
|
|
236
|
+
private subscribeToSocketEvents;
|
|
237
|
+
/**
|
|
238
|
+
* Unsubscribe from socket events
|
|
239
|
+
*/
|
|
240
|
+
private unsubscribeFromSocketEvents;
|
|
241
|
+
/**
|
|
242
|
+
* Handle socket group update events
|
|
243
|
+
*/
|
|
244
|
+
private handleSocketGroupUpdate;
|
|
245
|
+
/**
|
|
246
|
+
* Create activity item from socket event data
|
|
247
|
+
*/
|
|
248
|
+
private createActivityFromEvent;
|
|
249
|
+
/**
|
|
250
|
+
* Update activity list dynamically from live data
|
|
251
|
+
*/
|
|
252
|
+
private updateActivityList;
|
|
253
|
+
/**
|
|
254
|
+
* Update team card members dynamically
|
|
255
|
+
*/
|
|
256
|
+
private updateTeamCard;
|
|
257
|
+
}
|