@smartico/public-api 0.0.380 → 0.0.382

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.
Files changed (178) hide show
  1. package/CLAUDE.md +103 -0
  2. package/README.md +32 -10
  3. package/dist/Base/ClassId.d.ts +2 -0
  4. package/dist/Jackpots/JackpotDetails.d.ts +14 -15
  5. package/dist/Jackpots/JackpotPot.d.ts +10 -6
  6. package/dist/MiniGames/SAWGameType.d.ts +3 -1
  7. package/dist/MiniGames/SAWTemplateUI.d.ts +7 -0
  8. package/dist/Raffle/GetRaffleWonPrizesRequest.d.ts +9 -0
  9. package/dist/Raffle/GetRaffleWonPrizesResponse.d.ts +52 -0
  10. package/dist/Raffle/index.d.ts +2 -0
  11. package/dist/SmarticoAPI.d.ts +6 -1
  12. package/dist/SmarticoLib/index.d.ts +5 -1
  13. package/dist/WSAPI/WSAPIAvatars.d.ts +267 -49
  14. package/dist/WSAPI/WSAPIBonuses.d.ts +224 -10
  15. package/dist/WSAPI/WSAPIGamePick.d.ts +538 -253
  16. package/dist/WSAPI/WSAPIGeneral.d.ts +156 -14
  17. package/dist/WSAPI/WSAPIInbox.d.ts +547 -58
  18. package/dist/WSAPI/WSAPIJackpots.d.ts +292 -57
  19. package/dist/WSAPI/WSAPILeaderBoard.d.ts +127 -13
  20. package/dist/WSAPI/WSAPIMiniGames.d.ts +465 -49
  21. package/dist/WSAPI/WSAPIRaffles.d.ts +576 -52
  22. package/dist/WSAPI/WSAPITournaments.d.ts +3 -3
  23. package/dist/WSAPI/WSAPITypes.d.ts +243 -132
  24. package/dist/WSAPI/WSAPIUser.d.ts +193 -43
  25. package/dist/index.js +3412 -616
  26. package/dist/index.js.map +1 -1
  27. package/dist/index.modern.mjs +3395 -609
  28. package/dist/index.modern.mjs.map +1 -1
  29. package/docs/Callbacks.md +162 -0
  30. package/docs/SmarticoObject.md +445 -0
  31. package/docs/Transforms.md +99 -0
  32. package/docs/api/README.md +26 -0
  33. package/docs/api/classes/WSAPIAvatars.md +282 -54
  34. package/docs/api/classes/WSAPIBonuses.md +233 -12
  35. package/docs/api/classes/WSAPIClans.md +380 -10
  36. package/docs/api/classes/WSAPIGamePick.md +555 -26
  37. package/docs/api/classes/WSAPIGeneral.md +165 -16
  38. package/docs/api/classes/WSAPIInbox.md +588 -64
  39. package/docs/api/classes/WSAPIJackpots.md +320 -66
  40. package/docs/api/classes/WSAPILeaderBoard.md +133 -15
  41. package/docs/api/classes/WSAPIMiniGames.md +501 -64
  42. package/docs/api/classes/WSAPIMissions.md +58 -79
  43. package/docs/api/classes/WSAPIRaffles.md +647 -69
  44. package/docs/api/classes/WSAPIStore.md +83 -108
  45. package/docs/api/classes/WSAPITournaments.md +495 -28
  46. package/docs/api/classes/WSAPIUser.md +520 -83
  47. package/docs/api/documents/Callbacks.md +162 -0
  48. package/docs/api/documents/SmarticoObject.md +445 -0
  49. package/docs/api/documents/Transforms.md +99 -0
  50. package/docs/api/enumerations/BonusStatus-1.md +11 -6
  51. package/docs/api/enumerations/JoinClanErrorCode.md +81 -0
  52. package/docs/api/enumerations/TournamentRegistrationError.md +12 -0
  53. package/docs/api/functions/clanTournamentPlayersTransform.md +13 -0
  54. package/docs/api/interfaces/AvatarCustomized.md +25 -0
  55. package/docs/api/interfaces/AvatarDefinition.md +94 -0
  56. package/docs/api/interfaces/AvatarPrompt.md +45 -0
  57. package/docs/api/interfaces/BonusMetaMap-1.md +4 -1
  58. package/docs/api/interfaces/BonusTemplateMetaMap-1.md +9 -4
  59. package/docs/api/interfaces/Clan.md +4 -0
  60. package/docs/api/interfaces/ClanInfo.md +109 -0
  61. package/docs/api/interfaces/ClanMember.md +53 -0
  62. package/docs/api/interfaces/ClanTournamentPlayerRaw.md +67 -0
  63. package/docs/api/interfaces/GemsDiamondsLog.md +43 -0
  64. package/docs/api/interfaces/GetClanInfoResponse.md +61 -0
  65. package/docs/api/interfaces/GetClanTournamentPlayersResponse.md +81 -0
  66. package/docs/api/interfaces/GetRaffleWonPrizesRequest.md +59 -0
  67. package/docs/api/interfaces/GetRaffleWonPrizesResponse.md +95 -0
  68. package/docs/api/interfaces/InboxMarkMessageAction.md +10 -2
  69. package/docs/api/interfaces/JackpotDetails.md +14 -15
  70. package/docs/api/interfaces/JackpotPot.md +9 -6
  71. package/docs/api/interfaces/LeaderBoardDetailsT.md +14 -8
  72. package/docs/api/interfaces/LeaderBoardUserT.md +8 -5
  73. package/docs/api/interfaces/LeaderBoardsRewardsT.md +7 -0
  74. package/docs/api/interfaces/PointsLog.md +43 -0
  75. package/docs/api/interfaces/RaffleWonPrize.md +59 -0
  76. package/docs/api/interfaces/RaffleWonPrizePublicMeta.md +27 -0
  77. package/docs/api/interfaces/RaffleWonPrizeUser.md +43 -0
  78. package/docs/api/interfaces/TAchCategory.md +2 -7
  79. package/docs/api/interfaces/TAvatarCustomized.md +4 -4
  80. package/docs/api/interfaces/TAvatarDefinition.md +13 -14
  81. package/docs/api/interfaces/TAvatarPrompt.md +6 -6
  82. package/docs/api/interfaces/TBonus.md +16 -8
  83. package/docs/api/interfaces/TBuyStoreItemResult.md +4 -29
  84. package/docs/api/interfaces/TClaimBonusResult.md +5 -5
  85. package/docs/api/interfaces/TClan.md +8 -4
  86. package/docs/api/interfaces/TClanInfo.md +47 -0
  87. package/docs/api/interfaces/TClanJoinResult.md +11 -1
  88. package/docs/api/interfaces/TClanTournamentPlayer.md +55 -0
  89. package/docs/api/interfaces/TClanTournamentPlayersResult.md +27 -0
  90. package/docs/api/interfaces/TClans.md +3 -1
  91. package/docs/api/interfaces/TGetTranslations.md +4 -0
  92. package/docs/api/interfaces/TInboxMessage.md +14 -6
  93. package/docs/api/interfaces/TInboxMessageBody.md +18 -12
  94. package/docs/api/interfaces/TLevel.md +17 -20
  95. package/docs/api/interfaces/TLevelCurrent.md +19 -18
  96. package/docs/api/interfaces/TMiniGamePlayBatchResult.md +14 -6
  97. package/docs/api/interfaces/TMiniGamePlayResult.md +9 -4
  98. package/docs/api/interfaces/TMissionClaimRewardResult.md +1 -9
  99. package/docs/api/interfaces/TMissionOptInResult.md +1 -5
  100. package/docs/api/interfaces/TMissionOrBadge.md +4 -7
  101. package/docs/api/interfaces/TRaffleOptinResponse.md +4 -2
  102. package/docs/api/interfaces/TSegmentCheckResult.md +10 -0
  103. package/docs/api/interfaces/TSetAvatarResult.md +3 -3
  104. package/docs/api/interfaces/TStoreItem.md +3 -13
  105. package/docs/api/interfaces/TTournament.md +1 -1
  106. package/docs/api/interfaces/TTournamentDetailed.md +1 -1
  107. package/docs/api/interfaces/TTournamentRegistrationResult.md +4 -2
  108. package/docs/api/interfaces/TUICustomSection.md +23 -19
  109. package/docs/api/interfaces/TUserProfile.md +18 -16
  110. package/docs/api/interfaces/TransformedRaffleClaimPrizeResponse.md +6 -2
  111. package/docs/api/interfaces/UserLevelExtraCountersT.md +9 -2
  112. package/docs/api/type-aliases/ActivityLogEntry.md +3 -0
  113. package/docs/native/ADDING_METHODS.md +7 -2
  114. package/docs/native/PROTOCOL.md +337 -0
  115. package/docs/ui/avatars/UIGuide_getAvatarPrompts.md +100 -0
  116. package/docs/ui/avatars/UIGuide_getAvatarsCustomized.md +90 -0
  117. package/docs/ui/avatars/UIGuide_getAvatarsList.md +105 -0
  118. package/docs/ui/avatars/UIGuide_setAvatar.md +118 -0
  119. package/docs/ui/bonuses/UIGuide_claimBonus.md +144 -0
  120. package/docs/ui/bonuses/UIGuide_getBonuses.md +176 -0
  121. package/docs/ui/gamepick/UIGuide_gamePickGetActiveRound.md +99 -0
  122. package/docs/ui/gamepick/UIGuide_gamePickGetActiveRounds.md +76 -0
  123. package/docs/ui/gamepick/UIGuide_gamePickGetBoard.md +81 -0
  124. package/docs/ui/gamepick/UIGuide_gamePickGetGameInfo.md +78 -0
  125. package/docs/ui/gamepick/UIGuide_gamePickGetHistory.md +55 -0
  126. package/docs/ui/gamepick/UIGuide_gamePickGetRoundInfoForUser.md +71 -0
  127. package/docs/ui/gamepick/UIGuide_gamePickGetUserInfo.md +64 -0
  128. package/docs/ui/gamepick/UIGuide_gamePickSubmitSelection.md +103 -0
  129. package/docs/ui/gamepick/UIGuide_gamePickSubmitSelectionQuiz.md +67 -0
  130. package/docs/ui/general/UIGuide_getCustomSections.md +137 -0
  131. package/docs/ui/general/UIGuide_getRelatedItemsForGame.md +140 -0
  132. package/docs/ui/inbox/UIGuide_deleteInboxMessage.md +135 -0
  133. package/docs/ui/inbox/UIGuide_getInboxMessageBody.md +133 -0
  134. package/docs/ui/inbox/UIGuide_getInboxMessages.md +186 -0
  135. package/docs/ui/inbox/UIGuide_markInboxMessageAsRead.md +122 -0
  136. package/docs/ui/inbox/UIGuide_markUnmarkInboxMessageAsFavorite.md +84 -0
  137. package/docs/ui/jackpots/UIGuide_getJackpotEligibleGames.md +73 -0
  138. package/docs/ui/jackpots/UIGuide_getJackpotWinners.md +83 -0
  139. package/docs/ui/jackpots/UIGuide_jackpotGet.md +138 -0
  140. package/docs/ui/jackpots/UIGuide_jackpotOptIn.md +85 -0
  141. package/docs/ui/jackpots/UIGuide_jackpotOptOut.md +65 -0
  142. package/docs/ui/leaderboard/UIGuide_getLeaderBoard.md +166 -0
  143. package/docs/ui/minigames/UIGuide_getMiniGames.md +153 -0
  144. package/docs/ui/minigames/UIGuide_getMiniGamesHistory.md +90 -0
  145. package/docs/ui/minigames/UIGuide_playMiniGame.md +150 -0
  146. package/docs/ui/minigames/UIGuide_playMiniGameBatch.md +128 -0
  147. package/docs/ui/raffles/UIGuide_claimRafflePrize.md +99 -0
  148. package/docs/ui/raffles/UIGuide_getRaffleDrawRun.md +117 -0
  149. package/docs/ui/raffles/UIGuide_getRaffleDrawRunsHistory.md +92 -0
  150. package/docs/ui/raffles/UIGuide_getRaffleWonPrizes.md +120 -0
  151. package/docs/ui/raffles/UIGuide_getRaffles.md +175 -0
  152. package/docs/ui/raffles/UIGuide_requestRaffleOptin.md +114 -0
  153. package/docs/ui/user/UIGuide_getActivityLog.md +130 -0
  154. package/docs/ui/user/UIGuide_getLevels.md +47 -42
  155. package/package.json +1 -1
  156. package/src/Base/ClassId.ts +2 -0
  157. package/src/Jackpots/JackpotDetails.ts +14 -15
  158. package/src/Jackpots/JackpotPot.ts +10 -6
  159. package/src/MiniGames/SAWGameType.ts +3 -0
  160. package/src/MiniGames/SAWTemplateUI.ts +10 -0
  161. package/src/Raffle/GetRaffleWonPrizesRequest.ts +12 -0
  162. package/src/Raffle/GetRaffleWonPrizesResponse.ts +56 -0
  163. package/src/Raffle/index.ts +3 -1
  164. package/src/SmarticoAPI.ts +14 -1
  165. package/src/SmarticoLib/index.ts +4 -0
  166. package/src/WSAPI/WSAPIAvatars.ts +267 -49
  167. package/src/WSAPI/WSAPIBonuses.ts +224 -10
  168. package/src/WSAPI/WSAPIGamePick.ts +538 -253
  169. package/src/WSAPI/WSAPIGeneral.ts +156 -14
  170. package/src/WSAPI/WSAPIInbox.ts +545 -56
  171. package/src/WSAPI/WSAPIJackpots.ts +297 -61
  172. package/src/WSAPI/WSAPILeaderBoard.ts +127 -13
  173. package/src/WSAPI/WSAPIMiniGames.ts +465 -49
  174. package/src/WSAPI/WSAPIRaffles.ts +592 -64
  175. package/src/WSAPI/WSAPITournaments.ts +3 -3
  176. package/src/WSAPI/WSAPITypes.ts +243 -132
  177. package/src/WSAPI/WSAPIUser.ts +193 -43
  178. package/tsconfig.json +9 -1
@@ -0,0 +1,118 @@
1
+ # UI Guide — `setAvatar`
2
+
3
+ ## Overview
4
+ - Activates the chosen avatar as the user's profile avatar.
5
+ - Confirmation-style mutation — user picks an avatar in
6
+ [`getAvatarsList`](../../api/classes/WSAPIAvatars.md#getavatarslist)
7
+ (or a variant from
8
+ [`getAvatarsCustomized`](../../api/classes/WSAPIAvatars.md#getavatarscustomized)),
9
+ then taps "Apply".
10
+ - Server validates ownership — locked avatars are rejected.
11
+ - The SDK clears both the catalog and the customized-variant caches on
12
+ return; re-call those methods to surface the new `is_in_use` state.
13
+
14
+ ## Loading state
15
+
16
+ User taps "Apply" → the button enters an in-flight state (spinner +
17
+ disabled). The default Smartico UI keeps the picker open during the
18
+ call and closes it after the response lands.
19
+
20
+ ```ts
21
+ const [applying, setApplying] = useState(false);
22
+
23
+ const onApply = async (avatar: TAvatarDefinition) => {
24
+ if (applying) return;
25
+ setApplying(true);
26
+ const r = await window._smartico.api.setAvatar({
27
+ avatar_url: avatar.avatar_url,
28
+ avatar_real_id: avatar.avatar_real_id,
29
+ });
30
+ setApplying(false);
31
+ handleResult(r);
32
+ };
33
+ ```
34
+
35
+ ## Idempotency guard
36
+
37
+ The SDK does NOT prevent double-clicks. Guard the call site as above.
38
+ Re-applying the same avatar is safe server-side (returns `err_code: 0`,
39
+ no double side-effects), but the redundant roundtrip wastes the user's
40
+ time.
41
+
42
+ ## Action button decision matrix
43
+
44
+ UI behavior per `err_code`:
45
+
46
+ | `err_code` | Action |
47
+ |---|---|
48
+ | `0` (success) | Close picker; refresh header avatar; show brief "Avatar updated" confirmation (optional). |
49
+ | `1` (not in catalog) | Refresh catalog (operator may have removed the avatar); show "Avatar no longer available". |
50
+ | `2` (inactive) | Show "This avatar is no longer available"; refresh catalog. |
51
+ | `3` (outside time window) | Show "Available on {active_from_date} – {active_till_date}". |
52
+ | `4` (not owned) | Show unlock requirement / "Earn this avatar first" — possible if the catalog was stale. Refresh and re-render lock states. |
53
+ | Other non-zero | Show generic error toast. Surface `err_message` if present. Allow retry. |
54
+
55
+ The default Smartico UI shows a hardcoded "Failed to apply avatar" toast
56
+ on any non-zero code without branching. Custom UIs should branch on the
57
+ code and prefer `err_message` when present.
58
+
59
+ ## Refresh after success
60
+
61
+ - The SDK auto-clears the
62
+ [`getAvatarsList`](../../api/classes/WSAPIAvatars.md#getavatarslist)
63
+ and
64
+ [`getAvatarsCustomized`](../../api/classes/WSAPIAvatars.md#getavatarscustomized)
65
+ caches.
66
+ - The user's stored avatar updates server-side; the next call to
67
+ [`getUserProfile`](../../api/classes/WSAPIUser.md#getuserprofile)
68
+ reflects the new `avatar_url`.
69
+ - **No push to other open sessions.** A second device / tab the user is
70
+ logged in on will not see the change until it next calls
71
+ `getUserProfile()` or re-identifies. If you maintain a persistent
72
+ header avatar across tabs, plan a periodic refresh.
73
+
74
+ ## Selecting the right `avatar_url`
75
+
76
+ | Source | Pass as `avatar_url` |
77
+ |---|---|
78
+ | Catalog avatar (from `getAvatarsList`) | `avatar.avatar_url` |
79
+ | AI variant (from `getAvatarsCustomized`) | `variant.url` |
80
+
81
+ For both, pass the base `avatar_real_id` — for an AI variant, that is
82
+ the `avatar_real_id` of the base avatar the variant was derived from
83
+ (it's already on the `TAvatarCustomized` record).
84
+
85
+ ## Animations / transitions
86
+
87
+ Success sequence (default Smartico UI):
88
+
89
+ 1. Apply tap → spinner replaces button label.
90
+ 2. On `err_code === 0` → picker closes, header avatar fades to new
91
+ image.
92
+ 3. Optional: brief toast "Avatar updated" auto-dismissing after ~2 s.
93
+
94
+ Failure sequence:
95
+
96
+ 1. Apply tap → spinner replaces button label.
97
+ 2. On non-zero `err_code` → spinner clears; error toast shown; picker
98
+ remains open so the user can pick a different avatar.
99
+
100
+ ## Mobile vs desktop
101
+
102
+ - **Picker**: full-screen sheet on mobile; centered modal on desktop.
103
+ - **Apply button**: bottom bar on mobile; bottom-right of modal on
104
+ desktop.
105
+ - **Toast**: bottom-center on mobile; top-right on desktop.
106
+
107
+ ## Empty / no-selection state
108
+
109
+ The "Apply" button should be disabled until the user selects an avatar.
110
+ While selected avatar is the user's current one, the button label
111
+ becomes "In Use" and stays disabled.
112
+
113
+ ## Performance
114
+
115
+ - Single round-trip.
116
+ - No optimistic update — wait for `err_code === 0` before flipping the
117
+ header avatar. Locked-avatar rejection is real and would otherwise
118
+ produce a visible flicker.
@@ -0,0 +1,144 @@
1
+ # UI Guide — `claimBonus`
2
+
3
+ ## Overview
4
+ - Action-focused mutation. The user is on the bonuses screen, the
5
+ CTA is "Claim" on a pending bonus tile, and they click it.
6
+ - Success (`err_code === 0`) means the operator's integration has
7
+ been called to credit the bonus to the player's account. The
8
+ status flips to `REDEEMED` and the bonuses list auto-refreshes
9
+ via [`getBonuses`](../../api/classes/WSAPIBonuses.md#getbonuses)'s
10
+ `onUpdate`.
11
+ - Latency: typically 300 ms – 2 s — the server calls the operator's
12
+ bonus API synchronously inside the claim handler, so slow
13
+ operator endpoints translate to slow claim responses.
14
+ - Balance updates do NOT arrive in the claim response — the
15
+ operator credits the player externally and the change surfaces
16
+ separately (typically via the SDK's user-properties channel).
17
+
18
+ ## Loading state
19
+
20
+ - **Trigger**: set an in-flight flag (`claiming = true`) immediately
21
+ on click, BEFORE the call.
22
+ - **Visual**: replace the button label with animated dots / spinner.
23
+ Disable the button. Keep the claim modal open during the call.
24
+ - **Reset**: clear the flag on response — success or error.
25
+
26
+ Latency can reach 1–2 s for slow operator integrations. Use a
27
+ clearly-visible loading state (dots ≥ 3 frames, button width
28
+ preserved to prevent layout jump).
29
+
30
+ ## Idempotency UI guard
31
+
32
+ The SDK does NOT prevent double-clicks. Two simultaneous calls
33
+ both reach the server. The first succeeds; the second returns
34
+ `err_code = -1` (bonus already claimed). Guard the call site:
35
+
36
+ ```ts
37
+ const [claiming, setClaiming] = useState(false);
38
+
39
+ const onClaim = async () => {
40
+ if (claiming) return; // in-flight guard
41
+ if (!bonus.is_redeemable) return; // not claimable
42
+ setClaiming(true);
43
+ const r = await window._smartico.api.claimBonus(bonus.bonus_id);
44
+ setClaiming(false);
45
+ handleResponse(r);
46
+ };
47
+ ```
48
+
49
+ Treat `err_code === -1` (already claimed) as **idempotent success**
50
+ in the UI — close the modal, show the success toast, let the
51
+ auto-refresh land. Don't show an error.
52
+
53
+ ## Action button decision matrix
54
+
55
+ | `err_code` | Action |
56
+ |---|---|
57
+ | `0` (success) | Close the claim modal · Show a success toast (e.g. "Bonus claimed!") · The bonuses list auto-refreshes via `onUpdate`; the bonus moves from Pending to Redeemed tab on the next render — DON'T manually re-fetch. Balance credit arrives separately through the operator's integration. |
58
+ | `-1` (not claimable / already claimed) | Same as success — treat as idempotent. Usually means another tab/session already claimed it (or the bonus expired between list fetch and click). |
59
+ | `1` (generic server error) | Show a generic error toast. Allow retry — the bonus typically lands in `REDEEM_FAILED` and remains claimable. |
60
+ | `9999` (uncaught exception) | Same as `1` — generic error toast, retry allowed. |
61
+ | Other non-zero | Show a generic error toast with `err_message` if present. Allow retry. |
62
+
63
+ The bonus's `bonus_status_id` after a failed claim is typically
64
+ `REDEEM_FAILED (4)`. The default Smartico UI treats `REDEEM_FAILED`
65
+ identically to `COUPON_ISSUED` — the user sees a normal Claim
66
+ button on their next visit and can retry without any "previously
67
+ failed" indicator.
68
+
69
+ ## `success` field — ignore it
70
+
71
+ The wire response does NOT consistently carry a `success` boolean.
72
+ The `TClaimBonusResult.success?: boolean` field will be `undefined`
73
+ in practice. **Always branch on `err_code === 0`** for the success
74
+ check, not on the `success` field.
75
+
76
+ ## Acknowledge message — pre-click
77
+
78
+ `label_bonus_template_meta_map.acknowledge` is the operator-supplied
79
+ text shown in the claim modal (wagering terms, expiry notice, etc.).
80
+ It is **template-level and static** — shown regardless of whether
81
+ the user has clicked Claim yet, and regardless of whether the
82
+ claim eventually succeeds. Render it always in the modal body when
83
+ present.
84
+
85
+ ## Optimistic update
86
+
87
+ **Do NOT optimistically flip `bonus_status_id` to `REDEEMED`** before
88
+ the response. The server can fail (operator integration timeout,
89
+ business-rule rejection), and the failure state needs to surface as
90
+ a real error. Keep the bonus in its prior state until the response
91
+ lands.
92
+
93
+ The in-flight `claiming` flag provides the visual feedback during
94
+ the wait.
95
+
96
+ ## Refresh after response
97
+
98
+ The SDK auto-refreshes the bonuses cache on every response (success
99
+ OR error) via the same push that delivers the claim result. The
100
+ `onUpdate` callback registered via `getBonuses({ onUpdate })` fires
101
+ with the refreshed array shortly after — **don't manually call
102
+ `getBonuses()` after a claim response**, the refresh is already
103
+ happening.
104
+
105
+ The user's balance update (after a successful claim) does NOT come
106
+ through the bonuses channel. The operator's integration credits the
107
+ player externally; balance updates surface via
108
+ [`getUserProfile`](../../api/classes/WSAPIUser.md#getuserprofile)'s
109
+ `props_change` push channel — subscribe there separately if your UI
110
+ shows the balance.
111
+
112
+ ## Animations / transitions
113
+
114
+ - **Loading dots**: 3-dot bouncing animation on the button while
115
+ the promise is in flight.
116
+ - **Modal close on success**: animate the modal closure (~150 ms
117
+ ease-out).
118
+ - **Card cross-tab transition**: when the bonus moves from Pending
119
+ to Redeemed (detected via diffing the prior + refreshed lists
120
+ inside `onUpdate`), the default Smartico UI does not animate the
121
+ move — it relies on the list-level fade-in for the new Redeemed
122
+ card.
123
+ - **No celebration animation** (no confetti, no sound) — bonus claim
124
+ uses a plain success toast. Mission and store claims have
125
+ celebrations; bonuses don't.
126
+
127
+ ## Mobile vs desktop
128
+
129
+ - **Loading state**: identical (dots animation on the button).
130
+ - **Error surfacing**: desktop typically uses a toast/snackbar;
131
+ mobile may use a centered modal with a clear "OK" affordance.
132
+ - **Modal style**: desktop centered with backdrop dim; mobile
133
+ full-screen slide-up sheet.
134
+
135
+ ## Performance
136
+
137
+ - Single round-trip per click. The handler invokes the operator's
138
+ bonus API synchronously, so latency depends on the operator's
139
+ endpoint responsiveness.
140
+ - The refresh after the response (server push → SDK cache write →
141
+ `onUpdate` fire) adds ~50–100 ms beyond the claim response —
142
+ fine for UI purposes.
143
+ - Don't poll `getBonuses()` to detect claim completion — the
144
+ response promise is the authoritative signal.
@@ -0,0 +1,176 @@
1
+ # UI Guide — `getBonuses`
2
+
3
+ ## Overview
4
+ - Returns the user's bonuses (pending claims, redeemed history, and —
5
+ rarely — internal statuses). Drive the rendering from
6
+ `bonus_status_id` ({@link BonusStatus}) and `is_redeemable`.
7
+ - The list refreshes automatically only after
8
+ [`claimBonus`](../../api/classes/WSAPIBonuses.md#claimbonus). Server-
9
+ awarded bonuses (CRM, mission rewards, store redemptions) do NOT
10
+ push — poll on the 30 s cache TTL if you need near-live awareness.
11
+ - Loading indicator: skip on cache hit; show a shimmer on cold fetch
12
+ (typically 100–500 ms).
13
+
14
+ ## List view organization
15
+
16
+ The default Smartico UI splits bonuses into **two tabs**:
17
+
18
+ | Tab | Bucket rule | Sort |
19
+ |---|---|---|
20
+ | **Pending** | `bonus_status_id === 2` (`COUPON_ISSUED`) OR `bonus_status_id === 4` (`REDEEM_FAILED`) | `create_date` DESC |
21
+ | **Redeemed** | `bonus_status_id === 3` (`REDEEMED`) | `redeem_date` DESC |
22
+
23
+ Status values `New (1)`, `COUPON_ISSUE_FAILED (5)`, `EXPIRED (6)` are
24
+ typically filtered out by widget-level operator configuration. If they
25
+ appear, the default UI does not surface them — drop them from your
26
+ render.
27
+
28
+ **Pending tab auto-hides**: when the Pending bucket is empty, the
29
+ default Smartico UI removes the tab strip entirely and shows only the
30
+ Redeemed list. Restore the tab strip when a fresh pending bonus
31
+ appears (e.g. after a poll-driven refresh).
32
+
33
+ **Bucketing helper** for custom UIs:
34
+
35
+ ```ts
36
+ function bucket(bonus) {
37
+ if (bonus.bonus_status_id === 2 || bonus.bonus_status_id === 4) return 'pending';
38
+ if (bonus.bonus_status_id === 3) return 'redeemed';
39
+ return null; // drop internal statuses from the UI
40
+ }
41
+ ```
42
+
43
+ ## Bonus card / tile
44
+
45
+ Fields rendered per tile:
46
+
47
+ | Field | Source | Notes |
48
+ |---|---|---|
49
+ | Icon | `label_bonus_template_meta_map.image_url` | 1:1 aspect ratio. No SDK-provided fallback — supply a neutral placeholder if missing. |
50
+ | Amount / title | Prefer `bonus_meta_map.uiAmount` (e.g. `"€50"`, `"100 free spins"`); fall back to `label_bonus_template_meta_map.description` | `description` may include HTML; sanitize before injecting. |
51
+ | Date | `create_date` for pending bonuses; `redeem_date` for redeemed bonuses | ISO 8601 UTC; parse and format in user's local time (`new Date(create_date + 'Z')`). |
52
+ | Redirect affordance | Small icon when `label_bonus_template_meta_map.redirect_url` is set | Separate click target from the card itself (don't open the claim modal on icon click). |
53
+
54
+ **Whole-card click target** behavior depends on the bonus state:
55
+ - Pending + `is_redeemable: true` → opens the claim modal (see "Action
56
+ button decision matrix").
57
+ - All other states → card is non-interactive (apply a CSS class like
58
+ `hover-disable` and suppress the click handler).
59
+
60
+ ## Detail / claim modal
61
+
62
+ When the user clicks a claimable card, open a modal showing:
63
+
64
+ 1. Bonus icon (`label_bonus_template_meta_map.image_url`) at a
65
+ larger size.
66
+ 2. Amount / title (same fields as the card).
67
+ 3. Description (`label_bonus_template_meta_map.description`, HTML).
68
+ 4. **Acknowledge message** —
69
+ `label_bonus_template_meta_map.acknowledge` — operator-supplied
70
+ text always shown when set (wagering terms, expiry notice,
71
+ etc.). May include deep-links — pass through the SDK's deep-link
72
+ handler for safe execution.
73
+ 5. Claim button (see "Action button decision matrix").
74
+
75
+ The acknowledge message is **template-level static text**, not a
76
+ dynamic success message — it appears regardless of whether the
77
+ claim succeeds.
78
+
79
+ ## Action button decision matrix
80
+
81
+ Drive the Claim CTA from `bonus_status_id` + `is_redeemable`:
82
+
83
+ | `bonus_status_id` | `is_redeemable` | UI state |
84
+ |---|---|---|
85
+ | `COUPON_ISSUED` (2) | `true` | Claim button enabled — primary CTA |
86
+ | `REDEEM_FAILED` (4) | `true` | Claim button enabled — "Try again" label is appropriate; the default Smartico UI treats this identically to first-time claim |
87
+ | `COUPON_ISSUED` / `REDEEM_FAILED` | `false` | Card is informational only; no Claim button (auto-redeemed integration) |
88
+ | `REDEEMED` (3) | (irrelevant) | History row; no Claim button; show `redeem_date` |
89
+ | `New` / `COUPON_ISSUE_FAILED` / `EXPIRED` | — | Drop from UI |
90
+
91
+ Clicking the Claim button invokes
92
+ [`claimBonus`](../../api/classes/WSAPIBonuses.md#claimbonus). See its
93
+ own UI guide for the in-flight + per-error-code matrix.
94
+
95
+ ## Image / asset specs
96
+
97
+ | Field | Aspect ratio | Notes |
98
+ |---|---|---|
99
+ | `label_bonus_template_meta_map.image_url` | 1:1 (square) | Operator-supplied; recommended ~256×256 px. Fallback: render a neutral bonus icon if missing. |
100
+
101
+ ## Status-specific visual treatments
102
+
103
+ - **Pending (`COUPON_ISSUED` / `REDEEM_FAILED`)**: full-color card,
104
+ pointer cursor, clickable.
105
+ - **Non-redeemable pending** (`is_redeemable: false`): identical
106
+ visual but `hover-disable` CSS class, no click handler.
107
+ - **Redeemed**: same visual; appears in the Redeemed tab only; show
108
+ the redemption date.
109
+ - **No status-specific colors / badges** in the default Smartico UI
110
+ — branding for "successfully redeemed" lives only in tab placement,
111
+ not in the card chrome.
112
+
113
+ `REDEEM_FAILED` is visually identical to `COUPON_ISSUED` from the
114
+ player's perspective. The "failed" state is a server-internal
115
+ distinction that lets the integration record a prior failed attempt
116
+ without losing the bonus. Don't surface "failed" in the UI copy —
117
+ treat it as "claim available".
118
+
119
+ ## `redirect_url` handling
120
+
121
+ When `label_bonus_template_meta_map.redirect_url` is set, render a
122
+ small redirect icon on the card. Click behavior:
123
+
124
+ - URL starts with `http` / `https` → open in a new browser tab
125
+ (`window.open(url, '_blank')`).
126
+ - Anything else → treat as an internal deep-link; pass to the SDK's
127
+ deep-link handler (`_smartico.dp(url)`).
128
+
129
+ The redirect click target is **separate from** the card's click
130
+ target. Stop event propagation on the icon click so the claim modal
131
+ does not open simultaneously.
132
+
133
+ ## Empty / loading / error states
134
+
135
+ - **Loading (cold fetch)**: render a skeleton grid (3–6 placeholder
136
+ cards) matching the eventual layout.
137
+ - **Loading (cache hit)**: do not render a loading state — the
138
+ promise resolves within a microtask.
139
+ - **Empty list**: `[]` means no bonuses are visible. Show a neutral
140
+ empty-state illustration with copy like "No bonuses available".
141
+ - **Empty Pending tab (but Redeemed has items)**: per the default
142
+ Smartico UI, hide the tab strip entirely and show only the
143
+ Redeemed list. Reverse when a poll-driven refresh restores
144
+ pending bonuses.
145
+ - **Error**: keep the prior list visible if any; show a small
146
+ non-blocking error banner; retry on the next user-driven action.
147
+
148
+ ## Animations / transitions
149
+
150
+ - **Card entry**: stagger fade-in (~30 ms per card) on first render.
151
+ - **Card transition on claim success**: the redeemed bonus's card
152
+ fades out from the Pending tab and the Redeemed tab gains a new
153
+ card on its next render. The default Smartico UI does not animate
154
+ the cross-tab move — bonus rendering relies on the standard list
155
+ refresh.
156
+ - **No celebration animation on claim success** — unlike mission /
157
+ store claim, bonuses use a plain success toast.
158
+
159
+ ## Mobile vs desktop
160
+
161
+ - **Grid columns**: desktop typically 2–3 columns; mobile 1
162
+ (full-width cards).
163
+ - **Tab strip**: identical on both; auto-hidden when Pending is
164
+ empty.
165
+ - **Detail modal**: desktop centered with backdrop dim; mobile
166
+ full-screen slide-up.
167
+
168
+ ## Performance
169
+
170
+ - The 30 s cache deduplicates rapid refetches. A poll loop every
171
+ 5 s effectively translates to one round-trip per 30 s.
172
+ - Diff snapshots between fetches to detect status flips and animate
173
+ only the affected cards.
174
+ - For very large bonus histories, virtualize the Redeemed tab with
175
+ `IntersectionObserver` — the default Smartico UI doesn't
176
+ paginate, so the full list is rendered.
@@ -0,0 +1,99 @@
1
+ # UI Guide — `gamePickGetActiveRound`
2
+
3
+ ## Overview
4
+ - Returns a single round with its events, user selections, scoring rules.
5
+ - Powers the round-detail / prediction-input screen.
6
+ - No cache; no push subscription.
7
+
8
+ ## Detail view layout
9
+
10
+ Top-to-bottom sections in the default Smartico UI:
11
+
12
+ 1. **Header**: round name + description + status pill (see
13
+ [`gamePickGetActiveRounds`](../../api/classes/WSAPIGamePick.md#gamepickgetactiverounds)
14
+ for status mapping).
15
+ 2. **Timer / deadline**: countdown to `last_bet_date` ("Bets close in 2h 15m").
16
+ 3. **Score recap (if scored)**: `user_score`, full/partial/lost counts.
17
+ 4. **Event list**: one row per event in `events[]`.
18
+
19
+ ## Event row layout
20
+
21
+ Each event row carries:
22
+
23
+ | Field | Source | Notes |
24
+ |---|---|---|
25
+ | Teams / question | `event_meta.team1_name`, `event_meta.team2_name` (MatchX) or `event_meta.text` (Quiz) | Heading |
26
+ | Team images | `event_meta.team1_img`, `event_meta.team2_img` | 32×32 px (1:1) |
27
+ | Match date | `match_date` | "Sat 25 May · 16:00" |
28
+ | Sport | `event_meta.sport` | Small chip |
29
+ | Odds | `odds_details` | Optional display |
30
+ | User selection input | based on `market_type_id` | Score pickers (MatchX) / radio (Quiz) |
31
+ | Resolution badge | `resolution_type_id` (`GamePickResolutionType`) | Only after resolution |
32
+ | `is_open_for_bets` | boolean | Disable input when false |
33
+
34
+ ## Prediction input by `market_type_id`
35
+
36
+ | Market | Input type |
37
+ |---|---|
38
+ | MatchX Goals / Winner | Two numeric pickers (team1 score / team2 score) |
39
+ | Quiz 1×2 | Three buttons (1 / X / 2) |
40
+ | Quiz Yes / No | Two buttons (Yes / No) |
41
+ | Quiz custom | Operator-defined buttons |
42
+
43
+ ## Action button decision matrix
44
+
45
+ Bottom CTA per round state:
46
+
47
+ | State | CTA |
48
+ |---|---|
49
+ | `is_active_now && has_open_for_bet_events && !user_placed_bet` | "Submit predictions" (primary) |
50
+ | `is_active_now && has_open_for_bet_events && user_placed_bet` (and edits made) | "Update predictions" (primary) |
51
+ | `is_active_now && user_placed_bet` (no pending changes) | Disabled "Predictions submitted" |
52
+ | `!has_open_for_bet_events` | Hidden / "View only" message |
53
+ | `is_resolved` | "View results" — links to history |
54
+
55
+ ## Resolution badges (`GamePickResolutionType`)
56
+
57
+ | Value | Badge |
58
+ |---|---|
59
+ | `None` (0) | No badge (event not yet resolved) |
60
+ | `Lost` (2) | Red X icon |
61
+ | `PartialWin` (3) | Amber half-star |
62
+ | `FullWin` (4) | Green checkmark |
63
+
64
+ ## Edits and `allow_edit_answers`
65
+
66
+ When the round is open and an event's `is_open_for_bets` is true, the user
67
+ can edit predictions for that event. The `allow_edit_answers` flag on the
68
+ round controls whether edits are accepted; the server enforces this and
69
+ returns `errCode: 3` (no-op) if submits happen after the deadline.
70
+
71
+ ## Error states
72
+
73
+ | `errCode` | Treatment |
74
+ |---|---|
75
+ | `4` (round / event not found) | Refresh active rounds and bounce back to lobby |
76
+ | `100002` (template not found) | Bounce back to lobby |
77
+ | `100000` (auth) | Re-init session |
78
+
79
+ ## Refresh
80
+
81
+ - No SDK cache.
82
+ - Re-call after a submit to surface the persisted predictions and updated
83
+ state.
84
+ - Poll every 30–60 s while the user is on the screen if event resolution
85
+ updates matter.
86
+
87
+ ## Mobile vs desktop
88
+
89
+ - **Mobile**: event rows stack full-width with score pickers below the
90
+ teams.
91
+ - **Desktop**: 2-column event grid; score pickers inline with teams.
92
+
93
+ ## Performance
94
+
95
+ - Single round-trip. The full event list ships in one payload.
96
+ - For lobby views with many rounds, prefer
97
+ [`gamePickGetGameInfo`](../../api/classes/WSAPIGamePick.md#gamepickgetgameinfo)
98
+ for a metadata-only round list and only call this method when the user
99
+ opens a specific round.
@@ -0,0 +1,76 @@
1
+ # UI Guide — `gamePickGetActiveRounds`
2
+
3
+ ## Overview
4
+ - Returns every open round for a MatchX or Quiz game template, with full
5
+ event lists and the user's selections per event.
6
+ - Powers the rounds-lobby screen.
7
+ - No SDK cache; every call is a live HTTP roundtrip to the Game Pick games
8
+ server.
9
+ - No push subscription — poll if you need live status updates.
10
+
11
+ ## List view organization
12
+
13
+ Single flat list of round cards. The default Smartico UI sorts by `open_date`
14
+ ascending (closest-opening or already-open first). Rounds with status
15
+ `NoEventsDefined` (1) are filtered out server-side and never appear.
16
+
17
+ ## Item card / tile
18
+
19
+ Fields rendered per round card:
20
+
21
+ | Field | Source | Notes |
22
+ |---|---|---|
23
+ | Round name | `round_name` | Title |
24
+ | Description | `round_description` | Subtitle (truncated) |
25
+ | Open / close window | `open_date`, `last_bet_date` | "Bets close in 2h 15m" |
26
+ | Event count | `events.length` | "5 matches" / "10 questions" |
27
+ | User progress | `user_placed_bet` | "Predictions submitted" badge or "Make your picks" CTA |
28
+ | Score so far | `user_score` | Visible after resolution |
29
+ | Status pill | `round_status_id` | See mapping below |
30
+
31
+ ## Status pill mapping (`GPRoundStatus`)
32
+
33
+ | Value | Label / treatment |
34
+ |---|---|
35
+ | `Other` (-1) | Active — green pill "Open" |
36
+ | `NoMoreBetsAllowed` (2) | Amber pill "Bets closed" |
37
+ | `AllEventsResolved_ButNotRound` (3) | Blue pill "Awaiting resolution" |
38
+ | `RoundResolved` (4) | Gray pill "Resolved" |
39
+
40
+ (Status 1 `NoEventsDefined` never appears here.)
41
+
42
+ ## Click target
43
+
44
+ Single tap opens the round-detail view (calls
45
+ [`gamePickGetActiveRound`](../../api/classes/WSAPIGamePick.md#gamepickgetactiveround)
46
+ for that round).
47
+
48
+ ## Empty / loading / error states
49
+
50
+ - **Empty (`errCode: 100003`)**: "No open rounds right now — check back later."
51
+ - **Loading**: skeleton card list (2–3 placeholders).
52
+ - **Error (`errCode: 100002`)**: "Game not found" — likely template ID is
53
+ wrong; bounce back to the lobby.
54
+ - **Error (`errCode: 100000`)**: "Session expired — please log in again" —
55
+ hash auth failure.
56
+
57
+ ## Refresh
58
+
59
+ - No SDK cache.
60
+ - Poll every 30–60 s while the user is on the lobby screen to catch
61
+ status changes (events going from open to closed).
62
+ - Re-call after any submit ([`gamePickSubmitSelection`](../../api/classes/WSAPIGamePick.md#gamepicksubmitselection)
63
+ or [`gamePickSubmitSelectionQuiz`](../../api/classes/WSAPIGamePick.md#gamepicksubmitselectionquiz))
64
+ to reflect the new `user_placed_bet` state on the relevant round card.
65
+
66
+ ## Mobile vs desktop
67
+
68
+ - **Mobile**: full-width round cards stacked vertically.
69
+ - **Desktop**: 2- or 3-column grid of round cards.
70
+
71
+ ## Performance
72
+
73
+ - Each call ships the full event list. For lobbies with many rounds, prefer
74
+ [`gamePickGetGameInfo`](../../api/classes/WSAPIGamePick.md#gamepickgetgameinfo)
75
+ which returns round metadata only (no events), then call this method only
76
+ when the user wants to see prediction-able rounds in detail.