@smartico/public-api 0.0.379 → 0.0.381

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 (219) hide show
  1. package/.nvmrc +1 -1
  2. package/CLAUDE.md +103 -0
  3. package/README.md +53 -2
  4. package/dist/Base/ClassId.d.ts +2 -0
  5. package/dist/Jackpots/JackpotDetails.d.ts +14 -15
  6. package/dist/Jackpots/JackpotPot.d.ts +10 -6
  7. package/dist/Raffle/GetRaffleWonPrizesRequest.d.ts +9 -0
  8. package/dist/Raffle/GetRaffleWonPrizesResponse.d.ts +52 -0
  9. package/dist/Raffle/index.d.ts +2 -0
  10. package/dist/SmarticoAPI.d.ts +6 -1
  11. package/dist/SmarticoLib/index.d.ts +5 -1
  12. package/dist/Store/BuyStoreItemErrorCode.d.ts +9 -1
  13. package/dist/Tournaments/TournamentRegistrationError.d.ts +3 -1
  14. package/dist/WSAPI/WSAPI.d.ts +13 -1235
  15. package/dist/WSAPI/WSAPIAvatars.d.ts +296 -0
  16. package/dist/WSAPI/WSAPIBase.d.ts +71 -0
  17. package/dist/WSAPI/WSAPIBonuses.d.ts +240 -0
  18. package/dist/WSAPI/WSAPIClans.d.ts +388 -0
  19. package/dist/WSAPI/WSAPIGamePick.d.ts +593 -0
  20. package/dist/WSAPI/WSAPIGeneral.d.ts +172 -0
  21. package/dist/WSAPI/WSAPIInbox.d.ts +615 -0
  22. package/dist/WSAPI/WSAPIJackpots.d.ts +344 -0
  23. package/dist/WSAPI/WSAPILeaderBoard.d.ts +139 -0
  24. package/dist/WSAPI/WSAPIMiniGames.d.ts +510 -0
  25. package/dist/WSAPI/WSAPIMissions.d.ts +517 -0
  26. package/dist/WSAPI/WSAPIRaffles.d.ts +643 -0
  27. package/dist/WSAPI/WSAPIStore.d.ts +656 -0
  28. package/dist/WSAPI/WSAPITournaments.d.ts +501 -0
  29. package/dist/WSAPI/WSAPITypes.d.ts +376 -205
  30. package/dist/WSAPI/WSAPIUser.d.ts +533 -0
  31. package/dist/index.js +6745 -1661
  32. package/dist/index.js.map +1 -1
  33. package/dist/index.modern.mjs +6324 -1342
  34. package/dist/index.modern.mjs.map +1 -1
  35. package/docs/Callbacks.md +162 -0
  36. package/docs/SmarticoObject.md +445 -0
  37. package/docs/Transforms.md +99 -0
  38. package/docs/api/README.md +82 -2
  39. package/docs/api/classes/WSAPIAvatars.md +344 -0
  40. package/docs/api/classes/WSAPIBonuses.md +271 -0
  41. package/docs/api/classes/WSAPIClans.md +436 -0
  42. package/docs/api/classes/WSAPIGamePick.md +710 -0
  43. package/docs/api/classes/WSAPIGeneral.md +212 -0
  44. package/docs/api/classes/WSAPIInbox.md +801 -0
  45. package/docs/api/classes/WSAPIJackpots.md +439 -0
  46. package/docs/api/classes/WSAPILeaderBoard.md +157 -0
  47. package/docs/api/classes/WSAPIMiniGames.md +612 -0
  48. package/docs/api/classes/WSAPIMissions.md +590 -0
  49. package/docs/api/classes/WSAPIRaffles.md +773 -0
  50. package/docs/api/classes/WSAPIStore.md +719 -0
  51. package/docs/api/classes/WSAPITournaments.md +571 -0
  52. package/docs/api/classes/WSAPIUser.md +637 -0
  53. package/docs/api/documents/Callbacks.md +162 -0
  54. package/docs/api/documents/SmarticoObject.md +445 -0
  55. package/docs/api/documents/Transforms.md +99 -0
  56. package/docs/api/enumerations/AchievementClaimPeriodTypeId.md +13 -0
  57. package/docs/api/enumerations/BonusStatus-1.md +11 -6
  58. package/docs/api/enumerations/BuyStoreItemErrorCode.md +32 -0
  59. package/docs/api/enumerations/JoinClanErrorCode.md +81 -0
  60. package/docs/api/enumerations/TournamentRegistrationError.md +12 -0
  61. package/docs/api/functions/clanTournamentPlayersTransform.md +13 -0
  62. package/docs/api/interfaces/AvatarCustomized.md +25 -0
  63. package/docs/api/interfaces/AvatarDefinition.md +94 -0
  64. package/docs/api/interfaces/AvatarPrompt.md +45 -0
  65. package/docs/api/interfaces/BonusMetaMap-1.md +4 -1
  66. package/docs/api/interfaces/BonusTemplateMetaMap-1.md +9 -4
  67. package/docs/api/interfaces/Clan.md +4 -0
  68. package/docs/api/interfaces/ClanInfo.md +109 -0
  69. package/docs/api/interfaces/ClanMember.md +53 -0
  70. package/docs/api/interfaces/ClanPrizePublicMeta.md +41 -0
  71. package/docs/api/interfaces/ClanPrizeStructureEntry.md +7 -1
  72. package/docs/api/interfaces/ClanPublicMeta.md +4 -0
  73. package/docs/api/interfaces/ClanTournamentPlayerRaw.md +67 -0
  74. package/docs/api/interfaces/GemsDiamondsLog.md +43 -0
  75. package/docs/api/interfaces/GetClanInfoResponse.md +61 -0
  76. package/docs/api/interfaces/GetClanTournamentPlayersResponse.md +81 -0
  77. package/docs/api/interfaces/GetRaffleWonPrizesRequest.md +59 -0
  78. package/docs/api/interfaces/GetRaffleWonPrizesResponse.md +95 -0
  79. package/docs/api/interfaces/InboxMarkMessageAction.md +10 -2
  80. package/docs/api/interfaces/JackpotDetails.md +14 -15
  81. package/docs/api/interfaces/JackpotPot.md +9 -6
  82. package/docs/api/interfaces/LeaderBoardDetailsT.md +14 -8
  83. package/docs/api/interfaces/LeaderBoardUserT.md +8 -5
  84. package/docs/api/interfaces/LeaderBoardsRewardsT.md +7 -0
  85. package/docs/api/interfaces/PointsLog.md +43 -0
  86. package/docs/api/interfaces/RaffleWonPrize.md +59 -0
  87. package/docs/api/interfaces/RaffleWonPrizePublicMeta.md +27 -0
  88. package/docs/api/interfaces/RaffleWonPrizeUser.md +43 -0
  89. package/docs/api/interfaces/SAWTemplateUI.md +10 -0
  90. package/docs/api/interfaces/TAchCategory.md +14 -4
  91. package/docs/api/interfaces/TAvatarCustomized.md +4 -4
  92. package/docs/api/interfaces/TAvatarDefinition.md +13 -14
  93. package/docs/api/interfaces/TAvatarPrompt.md +6 -6
  94. package/docs/api/interfaces/TBonus.md +16 -8
  95. package/docs/api/interfaces/TBuyStoreItemResult.md +4 -11
  96. package/docs/api/interfaces/TClaimBonusResult.md +5 -5
  97. package/docs/api/interfaces/TClan.md +8 -4
  98. package/docs/api/interfaces/TClanInfo.md +47 -0
  99. package/docs/api/interfaces/TClanJoinResult.md +11 -1
  100. package/docs/api/interfaces/TClanTournamentPlayer.md +55 -0
  101. package/docs/api/interfaces/TClanTournamentPlayersResult.md +27 -0
  102. package/docs/api/interfaces/TClans.md +3 -1
  103. package/docs/api/interfaces/TGetTranslations.md +4 -0
  104. package/docs/api/interfaces/TInboxMessage.md +14 -6
  105. package/docs/api/interfaces/TInboxMessageBody.md +18 -12
  106. package/docs/api/interfaces/TLevel.md +17 -20
  107. package/docs/api/interfaces/TLevelCurrent.md +19 -18
  108. package/docs/api/interfaces/TMiniGamePlayBatchResult.md +14 -6
  109. package/docs/api/interfaces/TMiniGamePlayResult.md +9 -4
  110. package/docs/api/interfaces/TMissionClaimRewardResult.md +6 -3
  111. package/docs/api/interfaces/TMissionOptInResult.md +6 -3
  112. package/docs/api/interfaces/TMissionOrBadge.md +5 -4
  113. package/docs/api/interfaces/TRaffleOptinResponse.md +4 -2
  114. package/docs/api/interfaces/TSegmentCheckResult.md +10 -0
  115. package/docs/api/interfaces/TSetAvatarResult.md +3 -3
  116. package/docs/api/interfaces/TStoreItem.md +11 -1
  117. package/docs/api/interfaces/TTournament.md +1 -1
  118. package/docs/api/interfaces/TTournamentDetailed.md +9 -1
  119. package/docs/api/interfaces/TTournamentRegistrationResult.md +4 -2
  120. package/docs/api/interfaces/TUICustomSection.md +23 -19
  121. package/docs/api/interfaces/TUserProfile.md +18 -16
  122. package/docs/api/interfaces/TransformedRaffleClaimPrizeResponse.md +6 -2
  123. package/docs/api/interfaces/UserAchievement.md +1 -1
  124. package/docs/api/interfaces/UserLevelExtraCountersT.md +9 -2
  125. package/docs/api/type-aliases/ActivityLogEntry.md +3 -0
  126. package/docs/native/ADDING_METHODS.md +7 -2
  127. package/docs/native/PROTOCOL.md +337 -0
  128. package/docs/ui/avatars/UIGuide_getAvatarPrompts.md +100 -0
  129. package/docs/ui/avatars/UIGuide_getAvatarsCustomized.md +90 -0
  130. package/docs/ui/avatars/UIGuide_getAvatarsList.md +105 -0
  131. package/docs/ui/avatars/UIGuide_setAvatar.md +118 -0
  132. package/docs/ui/bonuses/UIGuide_claimBonus.md +144 -0
  133. package/docs/ui/bonuses/UIGuide_getBonuses.md +176 -0
  134. package/docs/ui/clans/UIGuide_getClanInfo.md +153 -0
  135. package/docs/ui/clans/UIGuide_getClans.md +172 -0
  136. package/docs/ui/clans/UIGuide_joinClan.md +196 -0
  137. package/docs/ui/gamepick/UIGuide_gamePickGetActiveRound.md +99 -0
  138. package/docs/ui/gamepick/UIGuide_gamePickGetActiveRounds.md +76 -0
  139. package/docs/ui/gamepick/UIGuide_gamePickGetBoard.md +81 -0
  140. package/docs/ui/gamepick/UIGuide_gamePickGetGameInfo.md +78 -0
  141. package/docs/ui/gamepick/UIGuide_gamePickGetHistory.md +55 -0
  142. package/docs/ui/gamepick/UIGuide_gamePickGetRoundInfoForUser.md +71 -0
  143. package/docs/ui/gamepick/UIGuide_gamePickGetUserInfo.md +64 -0
  144. package/docs/ui/gamepick/UIGuide_gamePickSubmitSelection.md +103 -0
  145. package/docs/ui/gamepick/UIGuide_gamePickSubmitSelectionQuiz.md +67 -0
  146. package/docs/ui/general/UIGuide_getCustomSections.md +137 -0
  147. package/docs/ui/general/UIGuide_getRelatedItemsForGame.md +140 -0
  148. package/docs/ui/inbox/UIGuide_deleteInboxMessage.md +135 -0
  149. package/docs/ui/inbox/UIGuide_getInboxMessageBody.md +133 -0
  150. package/docs/ui/inbox/UIGuide_getInboxMessages.md +186 -0
  151. package/docs/ui/inbox/UIGuide_markInboxMessageAsRead.md +122 -0
  152. package/docs/ui/inbox/UIGuide_markUnmarkInboxMessageAsFavorite.md +84 -0
  153. package/docs/ui/jackpots/UIGuide_getJackpotEligibleGames.md +73 -0
  154. package/docs/ui/jackpots/UIGuide_getJackpotWinners.md +83 -0
  155. package/docs/ui/jackpots/UIGuide_jackpotGet.md +138 -0
  156. package/docs/ui/jackpots/UIGuide_jackpotOptIn.md +85 -0
  157. package/docs/ui/jackpots/UIGuide_jackpotOptOut.md +65 -0
  158. package/docs/ui/leaderboard/UIGuide_getLeaderBoard.md +166 -0
  159. package/docs/ui/minigames/UIGuide_getMiniGames.md +153 -0
  160. package/docs/ui/minigames/UIGuide_getMiniGamesHistory.md +90 -0
  161. package/docs/ui/minigames/UIGuide_playMiniGame.md +150 -0
  162. package/docs/ui/minigames/UIGuide_playMiniGameBatch.md +128 -0
  163. package/docs/ui/missions/UIGuide_getAchCategories.md +17 -0
  164. package/docs/ui/missions/UIGuide_getBadges.md +237 -0
  165. package/docs/ui/missions/UIGuide_getMissions.md +268 -0
  166. package/docs/ui/missions/UIGuide_requestMissionClaimReward.md +21 -0
  167. package/docs/ui/missions/UIGuide_requestMissionOptIn.md +16 -0
  168. package/docs/ui/raffles/UIGuide_claimRafflePrize.md +99 -0
  169. package/docs/ui/raffles/UIGuide_getRaffleDrawRun.md +117 -0
  170. package/docs/ui/raffles/UIGuide_getRaffleDrawRunsHistory.md +92 -0
  171. package/docs/ui/raffles/UIGuide_getRaffleWonPrizes.md +120 -0
  172. package/docs/ui/raffles/UIGuide_getRaffles.md +175 -0
  173. package/docs/ui/raffles/UIGuide_requestRaffleOptin.md +114 -0
  174. package/docs/ui/store/UIGuide_buyStoreItem.md +133 -0
  175. package/docs/ui/store/UIGuide_getStoreCategories.md +19 -0
  176. package/docs/ui/store/UIGuide_getStoreItems.md +264 -0
  177. package/docs/ui/store/UIGuide_getStorePurchasedItems.md +122 -0
  178. package/docs/ui/tournaments/UIGuide_getClanTournamentPlayers.md +140 -0
  179. package/docs/ui/tournaments/UIGuide_getTournamentInstanceInfo.md +265 -0
  180. package/docs/ui/tournaments/UIGuide_getTournamentsList.md +236 -0
  181. package/docs/ui/tournaments/UIGuide_registerInTournament.md +156 -0
  182. package/docs/ui/user/UIGuide_getActivityLog.md +130 -0
  183. package/docs/ui/user/UIGuide_getLevels.md +167 -0
  184. package/docs/ui/user/UIGuide_getUserProfile.md +213 -0
  185. package/package.json +3 -3
  186. package/scripts/postdoc-cleanup.js +195 -0
  187. package/src/Base/ClassId.ts +2 -0
  188. package/src/Jackpots/JackpotDetails.ts +14 -15
  189. package/src/Jackpots/JackpotPot.ts +10 -6
  190. package/src/Missions/MissionsUtils.ts +5 -2
  191. package/src/Raffle/GetRaffleWonPrizesRequest.ts +12 -0
  192. package/src/Raffle/GetRaffleWonPrizesResponse.ts +56 -0
  193. package/src/Raffle/index.ts +3 -1
  194. package/src/SmarticoAPI.ts +14 -1
  195. package/src/SmarticoLib/index.ts +4 -0
  196. package/src/Store/BuyStoreItemErrorCode.ts +8 -0
  197. package/src/Store/StoreItem.ts +1 -0
  198. package/src/Store/StoreItemPurchased.ts +1 -0
  199. package/src/Store/StoreItemType.ts +1 -1
  200. package/src/Tournaments/TournamentRegistrationError.ts +4 -0
  201. package/src/WSAPI/WSAPI.ts +27 -2007
  202. package/src/WSAPI/WSAPIAvatars.ts +345 -0
  203. package/src/WSAPI/WSAPIBase.ts +93 -0
  204. package/src/WSAPI/WSAPIBonuses.ts +268 -0
  205. package/src/WSAPI/WSAPIClans.ts +417 -0
  206. package/src/WSAPI/WSAPIGamePick.ts +667 -0
  207. package/src/WSAPI/WSAPIGeneral.ts +199 -0
  208. package/src/WSAPI/WSAPIInbox.ts +711 -0
  209. package/src/WSAPI/WSAPIJackpots.ts +448 -0
  210. package/src/WSAPI/WSAPILeaderBoard.ts +154 -0
  211. package/src/WSAPI/WSAPIMiniGames.ts +597 -0
  212. package/src/WSAPI/WSAPIMissions.ts +572 -0
  213. package/src/WSAPI/WSAPIRaffles.ts +703 -0
  214. package/src/WSAPI/WSAPIStore.ts +732 -0
  215. package/src/WSAPI/WSAPITournaments.ts +541 -0
  216. package/src/WSAPI/WSAPITypes.ts +376 -207
  217. package/src/WSAPI/WSAPIUser.ts +606 -0
  218. package/tsconfig.json +26 -2
  219. package/docs/api/classes/WSAPI.md +0 -1927
@@ -0,0 +1,172 @@
1
+ # UI Guide — `getClans`
2
+
3
+ ## Overview
4
+ - Powers the **clan-browser screen** (and the clan-pick modal during
5
+ tournament registration via
6
+ [`registerInTournament`](../../api/classes/WSAPITournaments.md#registerintournament)).
7
+ - Returned `clans[]` is already server-sorted by `rating_position` ASC
8
+ (1 = best). The default Smartico UI re-sorts on the same key as a
9
+ defensive measure but no client-side ordering work is required.
10
+ - Loading indicator: the first call is a server round-trip
11
+ (typically 100–500 ms); subsequent calls within the 30 s cache
12
+ window resolve effectively synchronously.
13
+ - `onUpdate` is poll-driven (no server push). For near-live state, the
14
+ consumer must poll on an interval — the default Smartico UI polls
15
+ every 30 s while the clan screen is open.
16
+
17
+ ## List view organization
18
+
19
+ A single flat ranked list — no tabs. Render `clans[]` in the order
20
+ returned (already sorted by `rating_position`).
21
+
22
+ **Client-side search filter**: filter `clan.public_meta.name` against
23
+ the user's typed query (case-insensitive). No server round-trip.
24
+
25
+ **Sticky "my clan" footer**: when the user is in a clan and the
26
+ visible list is long enough (the default Smartico UI uses ≥ 7 visible
27
+ items), pin a duplicate of the user's clan row at the bottom of the
28
+ scroll area so it remains visible while the user scrolls. Skip this
29
+ when the user is clanless or the list is short.
30
+
31
+ No dedicated "My Clan" panel at the top of the list — the user's clan
32
+ appears at its natural `rating_position`, just highlighted in place.
33
+
34
+ ## Item card / row
35
+
36
+ Fields rendered (column structure for desktop; mobile may collapse):
37
+
38
+ | Column | Source | Notes |
39
+ |---|---|---|
40
+ | Rank | `rating_position` | Display as `#N`. Apply `.top-1` / `.top-2` / `.top-3` styling for positions 1–3. |
41
+ | Icon / image | `public_meta.image_url` | Square. Fallback: first character of `public_meta.name` rendered as a letter avatar. |
42
+ | Name | `public_meta.name` | Translated server-side. Add "Your clan" badge next to the name if `clan.clan_id === user_clan_id`. |
43
+ | Rating score | `rating_score` | Numeric; the higher, the better. |
44
+ | Members | `member_count` / `capacity_limit` | Desktop: render a progress bar at `member_count / capacity_limit * 100%` with a label `N / M`. Mobile: text-only `N / M`. |
45
+ | Entry fee | `entry_fee_amount` + `entry_fee_currency_type_id` | "Free" when `entry_fee_amount === 0` or `entry_fee_currency_type_id === 3`. Otherwise `"{amount} {Points|Gems|Diamonds}"`. |
46
+
47
+ **Whole-row click target**: opens the detail modal (via
48
+ [`getClanInfo`](../../api/classes/WSAPIClans.md#getclaninfo) to load
49
+ members on demand). The row itself has no inline Join CTA — joining
50
+ happens from inside the detail modal (see "Action button decision
51
+ matrix" below).
52
+
53
+ **Detail-only fields** (not on row): `description`, full `members[]`
54
+ list (from `getClanInfo`), full progress bar styling on desktop.
55
+
56
+ ## Action button decision matrix
57
+
58
+ The Join CTA lives in the detail modal (or the clan-pick modal during
59
+ tournament registration). Evaluate in priority order — first match
60
+ wins.
61
+
62
+ | State | Condition | Button label | Enabled? | Notes |
63
+ |---|---|---|---|---|
64
+ | **Your clan** | `clan.clan_id === user_clan_id` | "Your clan" | No-op | Highlight; no join action. |
65
+ | **Cooldown active** | `cooldown_until !== null` | `"Cooldown until <local-date>"` | Disabled | Affects ALL clans — the cooldown is user-level, not per-clan. Format `cooldown_until` from UTC to local time (`DD-MM-YYYY HH:mm` style). |
66
+ | **Clan full** | `member_count >= capacity_limit` | "Clan is full" | Disabled | |
67
+ | **Insufficient balance** | `entry_fee_amount > 0` AND user's balance for `entry_fee_currency_type_id` < `entry_fee_amount` | `"Not enough {Points|Gems|Diamonds} (deficit)"` | Disabled | Cross-check against {@link getUserProfile} balance for the currency. |
68
+ | **Joinable — free** | `entry_fee_amount === 0` OR `entry_fee_currency_type_id === 3` | "Join free" | Enabled | |
69
+ | **Joinable — paid** | default | `"Join ({amount} {Points|Gems|Diamonds})"` | Enabled | |
70
+
71
+ The enabled Join click invokes
72
+ [`joinClan(clan_id)`](../../api/classes/WSAPIClans.md#joinclan). See
73
+ its own UI guide for the in-flight + error-code matrix.
74
+
75
+ **Picker mode (`registerInTournament` clan-pick modal)**: when the
76
+ user is in cooldown, the default Smartico UI disables every row in the
77
+ picker (not just the buttons) — `onClick` is suppressed entirely.
78
+
79
+ ## Cooldown rendering
80
+
81
+ - The cooldown is **user-level**, not per-clan. While
82
+ `cooldown_until !== null`, the user cannot join any clan.
83
+ - Format: `cooldown_until` is an ISO 8601 UTC string
84
+ (`"YYYY-MM-DDTHH:MM:SS"`, no timezone suffix). Parse as UTC, display
85
+ in user-local time. The default Smartico UI shows
86
+ `DD-MM-YYYY HH:mm` (e.g. `"01-06-2026 16:30"`).
87
+ - No "X days remaining" countdown — show the absolute expiry datetime.
88
+ If your product surface justifies a countdown, render one yourself.
89
+
90
+ ## Image / asset specs
91
+
92
+ | Field | Aspect ratio | Notes |
93
+ |---|---|---|
94
+ | `public_meta.image_url` | 1:1 (square) | Recommended source size not strictly enforced; the default Smartico UI sizes via CSS. Provide a square image for best results. |
95
+
96
+ **Fallback**: when `image_url` is missing or fails to load, render
97
+ the first character of `public_meta.name` as a letter avatar in the
98
+ icon container.
99
+
100
+ ## Status-specific visual treatments
101
+
102
+ - **Your clan**: row gets a `.highlight` background tint + "Your clan"
103
+ badge next to the name.
104
+ - **Top-3 rank**: rows for `rating_position` 1–3 get podium accents
105
+ (gold/silver/bronze).
106
+ - **Full clan**: no row-level treatment — only the detail-modal button
107
+ shows the disabled state.
108
+ - **Cooldown active**: only the detail-modal button is disabled (or
109
+ in the picker, the whole row is dimmed).
110
+ - **Insufficient balance**: only the detail-modal button is disabled.
111
+
112
+ ## Empty / loading / error states
113
+
114
+ - **Loading (first fetch)**: render a spinner / shimmer skeleton of
115
+ rows.
116
+ - **Empty list (no clans configured)**: render a neutral empty-state
117
+ illustration with copy like "No clans available".
118
+ - **Empty search results**: same empty-state illustration with
119
+ query-aware copy (e.g. "No clans matching '<query>'").
120
+ - **Error**: the default Smartico UI keeps the spinner visible
121
+ indefinitely on fetch failure (no error boundary). For a better UX,
122
+ catch the rejected promise and render a "Failed to load — Try again"
123
+ affordance.
124
+
125
+ ## Refresh
126
+
127
+ `onUpdate` is poll-driven only. Two ways to keep the list fresh:
128
+
129
+ 1. **Poll**: re-call `getClans()` on a 30-second interval while the
130
+ clan screen is visible. The cache deduplicates rapid refetches.
131
+ 2. **Re-call after mutations**: after a successful
132
+ [`joinClan`](../../api/classes/WSAPIClans.md#joinclan), re-call
133
+ `getClans()` immediately to pick up the new `user_clan_id` and any
134
+ refreshed `member_count` / `cooldown_until` fields.
135
+
136
+ There is no server push that refreshes the clans list automatically
137
+ — another user joining your clan, an operator kicking you, or a clan
138
+ being archived will all only surface on the next consumer-driven
139
+ fetch.
140
+
141
+ ## Animations / transitions
142
+
143
+ - **List entry**: rows fade-in with a ~30 ms stagger on first render.
144
+ - **Rank reorder between polls**: if you implement live updates,
145
+ detect `rating_position` changes by diffing the previous and
146
+ current arrays, and animate rows to their new position (FLIP
147
+ animation). Don't full-re-render the list.
148
+ - **Join success celebration**: when `user_clan_id` flips between
149
+ polls (detect by comparing pre- and post-refresh values), play a
150
+ brief "Welcome to {clan name}" toast and animate the now-highlighted
151
+ row.
152
+
153
+ ## Mobile vs desktop
154
+
155
+ - **Member fill**: desktop renders a progress bar; mobile renders
156
+ text-only (`N / M`).
157
+ - **Columns**: desktop shows `#`, Clan, Rating, Members, Entry;
158
+ mobile drops Members (entry fee inlines below the name).
159
+ - **Sticky my-clan footer**: same threshold on both (≥ 7 visible
160
+ rows).
161
+ - **Search**: same client-side filter; desktop typically has a
162
+ search input at the top; mobile may use a dedicated search sheet.
163
+
164
+ ## Performance
165
+
166
+ - 30 s polling on the clans surface is fine for typical clan
167
+ catalogs (< 200 clans). For very large catalogs, consider polling
168
+ only while the surface is in the viewport.
169
+ - Use keyed per-row rendering — celebration / rank-reorder animations
170
+ break if the DOM nodes are recreated on every poll tick.
171
+ - Image lazy-loading is safe; clans below the fold rarely need
172
+ immediate paint.
@@ -0,0 +1,196 @@
1
+ # UI Guide — `joinClan`
2
+
3
+ ## Overview
4
+ - Action-focused mutation. The user is on the clans browser or the
5
+ detail modal, the CTA is "Join (...)", and they click it.
6
+ - A successful response (`errCode === 0`) means: membership persisted,
7
+ entry fee (if any) already debited, cooldown restarted, CRM events
8
+ fired. The SDK has done all of this server-side by the time the
9
+ promise resolves.
10
+ - The SDK does NOT auto-refresh `getClans` after success. The
11
+ consumer must re-call manually.
12
+ - Latency: typically 200–800 ms for a healthy WebSocket connection
13
+ (the server performs balance checks + atomic DB writes
14
+ synchronously).
15
+
16
+ ## Loading state
17
+
18
+ - **Trigger**: set an in-flight flag (`joining = true`) immediately
19
+ on click, BEFORE the call. This is the consumer's responsibility
20
+ — the SDK has no in-flight guard.
21
+ - **Visual**: replace the button label with animated dots / spinner.
22
+ Disable the button. Keep the modal open.
23
+ - **Reset**: clear the in-flight flag on response — success or error.
24
+
25
+ ## Idempotency UI guard
26
+
27
+ **Two distinct hazards** the consumer must guard against:
28
+
29
+ 1. **Double-click during in-flight**: the SDK does NOT prevent two
30
+ simultaneous `joinClan` calls. If the user clicks twice before the
31
+ first response arrives, both requests reach the server. If the
32
+ first succeeds, the second behaves as a clan-switch to the same
33
+ clan — which, on labels with `CLAN_COOLDOWN_DAYS = 0`, will
34
+ **deduct the entry fee a second time**. Guard with an in-flight
35
+ flag (see "Loading state").
36
+
37
+ 2. **Same-clan re-click**: the SDK does NOT short-circuit when the
38
+ user clicks Join on the clan they're already in. The server
39
+ treats it as a clan-switch to the same clan, and on labels with
40
+ cooldown=0 will re-deduct the fee. The Join button MUST be
41
+ disabled (or show "Your clan") whenever
42
+ `target.clan_id === user_clan_id`. Don't rely on the server to
43
+ silently no-op.
44
+
45
+ Recommended pattern:
46
+
47
+ ```ts
48
+ const [joining, setJoining] = useState(false);
49
+
50
+ const onJoin = async () => {
51
+ if (joining) return; // in-flight guard
52
+ if (target.clan_id === userClanId) return; // same-clan guard
53
+ if (cooldownUntil) return; // cooldown guard
54
+ if (target.member_count >= target.capacity_limit) return;
55
+ // (also: balance guard — handled by the pre-render CTA state matrix)
56
+
57
+ setJoining(true);
58
+ const r = await window._smartico.api.joinClan(target.clan_id);
59
+ setJoining(false);
60
+ handleResponse(r);
61
+ if (r.errCode === 0) await window._smartico.api.getClans();
62
+ };
63
+ ```
64
+
65
+ ## Action button decision matrix
66
+
67
+ `errCode` branch behavior. Refer to the `joinClan` TSDoc for the full
68
+ table of codes; UI handling per code:
69
+
70
+ | `errCode` | Action |
71
+ |---|---|
72
+ | `0` (success) | Show success toast (e.g. `"Joined {clan.name}"`). Close modal (or transition it to the "Your clan" state). Call `getClans()` to refresh `user_clan_id`, `member_count`, and `cooldown_until`. The default Smartico UI also dispatches an optimistic local state update so the Join button instantly flips to "Your clan" before the refresh lands. |
73
+ | `1000` (invalid parameters) | Programming error from SDK consumer side — should not occur. Show a generic error toast. |
74
+ | `1001` (not found / archived) | Refresh `getClans()`; the clan should disappear from the list. Show a brief "clan no longer available" toast. |
75
+ | `1002` (full) | Show "Clan is full". Refresh `getClans()`; the now-full clan's button will pre-disable to "Clan is full". |
76
+ | `1003` (insufficient funds) | Show insufficient-balance UI naming the currency (`['points','gems','diamonds'][entry_fee_currency_type_id]`) and the deficit (`entry_fee_amount`). Optional: deep-link to a currency-earning surface. |
77
+ | `1004` (segment mismatch) | Show a gating message — operator-supplied copy if the clan exposes one; otherwise a generic "Not eligible for this clan". Don't retry. |
78
+ | `1005` | `joinClan` does NOT return `1005`. If you see it in this method's response, treat as a generic error. |
79
+ | `1006` (cooldown active) | Show "Cooldown until {cooldown_until local-formatted}". Disable the Join CTA across ALL clans until cooldown expires. |
80
+ | `1007` (archived) | Defined in the public enum but the server emits `1001` instead. Handle as a synonym for `1001` defensively. |
81
+ | `1011` | `joinClan` does NOT return `1011`. If you see it in this method's response, treat as a generic error. |
82
+ | Other | Generic error toast with `errMsg` if any. |
83
+
84
+ ## Per-error-code message strategy
85
+
86
+ | `errCode` | `errMsg` usable? | Operator-supplied copy | Best source |
87
+ |---|---|---|---|
88
+ | `0` (success) | — | — | Localized `"Joined {clan.name}"` |
89
+ | `1003` (insufficient funds) | Fallback | — | Localized `"Insufficient {currency}"` + deficit derived from `entry_fee_amount` and the user's balance |
90
+ | `1004` (segment mismatch) | Fallback | If the clan has an operator-supplied entry-conditions message, prefer it | Otherwise localized "Not eligible for this clan" |
91
+ | `1006` (cooldown) | Fallback | — | Localized "Cooldown until {date}" — format `cooldown_until` from UTC to local |
92
+ | `1002` (full) | Fallback | — | Localized "Clan is full" |
93
+ | All others | Use `errMsg` as a fallback when no specific localized copy is available | — | Localized error per code |
94
+
95
+ ## Optimistic update
96
+
97
+ The default Smartico UI optimistically flips the user's clan
98
+ membership state on `errCode === 0` (before `getClans()` refreshes).
99
+ This is **safe** for this method because:
100
+
101
+ - The server has already committed the membership row when the
102
+ response returns.
103
+ - The fee is already debited.
104
+ - If the optimistic update sets `user_clan_id` to the new clan, the
105
+ refresh from `getClans()` will confirm the same value.
106
+
107
+ You can mirror this pattern: on `errCode === 0`, immediately update
108
+ the UI to show the user in the new clan, then re-fetch in the
109
+ background. If the refresh disagrees (very unlikely), reconcile.
110
+
111
+ Do NOT optimistically update on any non-zero `errCode` — those are
112
+ real failures.
113
+
114
+ ## Success celebration
115
+
116
+ The default Smartico UI does not play a dedicated celebration
117
+ animation (no confetti, no full-screen overlay). The button flips
118
+ to "Your clan" immediately via optimistic update, and the modal
119
+ re-renders with refreshed member data once `getClans()` returns.
120
+
121
+ If your product surface justifies a celebration, drive it from the
122
+ `onUpdate` detection: when `result.user_clan_id` flips between
123
+ pre-join and post-join fetches, play your celebration.
124
+
125
+ ## Refresh after response
126
+
127
+ The SDK does NOT auto-refresh the `getClans` cache. After a
128
+ successful join, manually call `getClans()` to pick up:
129
+
130
+ - The new `user_clan_id`
131
+ - The new `cooldown_until` (cooldown restarts at join time)
132
+ - The updated `member_count` on the joined clan
133
+ - The decremented `member_count` on any previously-joined clan
134
+ (clan-switch case)
135
+
136
+ The user's balance update from the entry-fee debit arrives via the
137
+ SDK's user-properties update channel — subscribe separately to
138
+ {@link getUserProfile} if your UI shows the balance.
139
+
140
+ ## Clan-switch semantics
141
+
142
+ When the user is in clan A and successfully joins clan B, the
143
+ server performs an **atomic transition**: deactivate A membership,
144
+ insert B membership, debit fee — all in one transaction. The user
145
+ is never observably clanless during the switch.
146
+
147
+ From the UI's perspective, this is identical to a fresh join. No
148
+ special handling required — the response is the same `errCode === 0`,
149
+ and `getClans()` refresh will show the user in clan B with a fresh
150
+ cooldown.
151
+
152
+ ## Special case — tournament clan-pick flow
153
+
154
+ When `registerInTournament(tournamentId)` returns `1005` (user has
155
+ no clan and the tournament is clan-based), the default UI typically:
156
+
157
+ 1. Opens a clan-picker driven by `getClans`.
158
+ 2. User picks a clan → call `joinClan(clanId)`.
159
+ 3. On `errCode === 0`, automatically retry
160
+ `registerInTournament(tournamentId)`.
161
+ 4. Handle `1011` on the retry: user joined the clan but joined
162
+ after this tournament started (and has prior tournament scores)
163
+ — show an explanatory message; the user is in the clan but
164
+ blocked from this specific tournament run.
165
+
166
+ The SDK does NOT chain these calls automatically. Each step is the
167
+ consumer's responsibility. See the
168
+ [UI Guide for `registerInTournament`](../tournaments/UIGuide_registerInTournament.md)
169
+ for the recommended sequence.
170
+
171
+ ## Animations / transitions
172
+
173
+ - **Loading dots**: 3-dot bouncing animation on the button while the
174
+ promise is in flight.
175
+ - **Button state flip**: when the response arrives, animate the
176
+ button label transition (~150 ms ease-out).
177
+ - **Member list refresh**: after `getClans()` re-fetch, the affected
178
+ clan rows (`member_count` change, your clan now highlighted) get a
179
+ brief highlight pulse on update.
180
+
181
+ ## Mobile vs desktop
182
+
183
+ - **Loading state**: identical (dots on the button).
184
+ - **Error surfacing**: desktop typically uses a toast/snackbar;
185
+ mobile may use a centered modal with a clear "OK" affordance.
186
+ - **Cooldown / insufficient-balance disabled states**: rendered the
187
+ same way on both — the disabled button shows the constraint text.
188
+
189
+ ## Performance
190
+
191
+ - Single round-trip per click. No batching needed.
192
+ - The `getClans()` refresh after success adds ~50–500 ms (cache miss
193
+ → fresh fetch). Treat as fire-and-forget; the optimistic UI flip
194
+ has already happened.
195
+ - Don't poll `getClans()` to detect join completion — the response
196
+ promise is the authoritative signal.
@@ -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.
@@ -0,0 +1,81 @@
1
+ # UI Guide — `gamePickGetBoard`
2
+
3
+ ## Overview
4
+ - Returns a leaderboard scoped to one round, OR (with `round_id: -1`) the
5
+ season / overall leaderboard for the template.
6
+ - Powers leaderboard screens within the Game Pick experience.
7
+ - No cache; no push subscription.
8
+
9
+ ## List view organization
10
+
11
+ Server-ranked. `users[]` is the public top list; `my_user` carries the
12
+ current user's row separately (renders as a sticky "you are here" footer).
13
+
14
+ ## Row layout
15
+
16
+ Each leaderboard row shows:
17
+
18
+ | Field | Source | Notes |
19
+ |---|---|---|
20
+ | Rank | `gp_position` | Big number or "—" when null (not yet ranked) |
21
+ | Avatar | `avatar_url` | 32×32 px (1:1) |
22
+ | Username | `public_username` | May be masked / anonymized by label settings — see below |
23
+ | Score | `resolution_score` | Total score in the scoped period |
24
+ | Stats (full / part / lost) | `full_wins_count`, `part_wins_count`, `lost_count` | Optional inline pills |
25
+
26
+ ### Username masking
27
+
28
+ Label settings can anonymize `public_username` for other players. Pair the
29
+ username with the avatar so the user can still recognize themselves visually
30
+ even when usernames are masked.
31
+
32
+ ## "You are here" footer (`my_user`)
33
+
34
+ When the response includes `my_user`, render it as a sticky footer always
35
+ visible at the bottom of the leaderboard. This gives the user a fixed
36
+ anchor regardless of scroll position. When `my_user` is `null` (user
37
+ hasn't predicted in this scope), render a CTA: "Play a round to join the
38
+ leaderboard."
39
+
40
+ ## `round_id` modes
41
+
42
+ | `round_id` | Returns |
43
+ |---|---|
44
+ | Positive | Per-round leaderboard (only scores from that round's events) |
45
+ | `-1` | Season / overall leaderboard (aggregated across all rounds of the template) |
46
+
47
+ Use a top tab or segmented control to let the user switch between per-round
48
+ and season views.
49
+
50
+ ## Empty / loading / error states
51
+
52
+ - **Empty**: "No players ranked yet — be the first!"
53
+ - **Loading**: skeleton row list (5–10 placeholders).
54
+ - **Error (`errCode: 100002`)**: "Game not found" — bounce back.
55
+ - **Error (`errCode: 100000`)**: "Session expired" — re-init.
56
+
57
+ ## Refresh
58
+
59
+ - No SDK cache.
60
+ - Poll every 30–60 s while the leaderboard is on screen to surface rank
61
+ changes after events resolve.
62
+ - Re-call after every successful round resolution (status transitions to
63
+ `RoundResolved` (4)).
64
+
65
+ ## Click-through (view another player's picks)
66
+
67
+ From a leaderboard row, allow the user to tap-through to
68
+ [`gamePickGetRoundInfoForUser`](../../api/classes/WSAPIGamePick.md#gamepickgetroundinfoforuser)
69
+ using `users[].int_user_id` to inspect that player's predictions. The default
70
+ Smartico UI opens this in a modal / sheet over the leaderboard.
71
+
72
+ ## Mobile vs desktop
73
+
74
+ - **Mobile**: full-width rows; sticky footer for `my_user`.
75
+ - **Desktop**: full-width rows centered with max-width; sticky footer.
76
+
77
+ ## Performance
78
+
79
+ - Server-paginated implicitly — typical responses are top 20–100 players
80
+ plus the user's row.
81
+ - No virtualization needed unless the response is >200 rows.