@smartico/public-api 0.0.379 → 0.0.380
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/.nvmrc +1 -1
- package/README.md +31 -2
- package/dist/Store/BuyStoreItemErrorCode.d.ts +9 -1
- package/dist/Tournaments/TournamentRegistrationError.d.ts +3 -1
- package/dist/WSAPI/WSAPI.d.ts +13 -1235
- package/dist/WSAPI/WSAPIAvatars.d.ts +78 -0
- package/dist/WSAPI/WSAPIBase.d.ts +71 -0
- package/dist/WSAPI/WSAPIBonuses.d.ts +26 -0
- package/dist/WSAPI/WSAPIClans.d.ts +388 -0
- package/dist/WSAPI/WSAPIGamePick.d.ts +308 -0
- package/dist/WSAPI/WSAPIGeneral.d.ts +30 -0
- package/dist/WSAPI/WSAPIInbox.d.ts +126 -0
- package/dist/WSAPI/WSAPIJackpots.d.ts +109 -0
- package/dist/WSAPI/WSAPILeaderBoard.d.ts +25 -0
- package/dist/WSAPI/WSAPIMiniGames.d.ts +94 -0
- package/dist/WSAPI/WSAPIMissions.d.ts +517 -0
- package/dist/WSAPI/WSAPIRaffles.d.ts +119 -0
- package/dist/WSAPI/WSAPIStore.d.ts +656 -0
- package/dist/WSAPI/WSAPITournaments.d.ts +501 -0
- package/dist/WSAPI/WSAPITypes.d.ts +145 -85
- package/dist/WSAPI/WSAPIUser.d.ts +383 -0
- package/dist/index.js +3818 -1528
- package/dist/index.js.map +1 -1
- package/dist/index.modern.mjs +3180 -981
- package/dist/index.modern.mjs.map +1 -1
- package/docs/api/README.md +56 -2
- package/docs/api/classes/WSAPIAvatars.md +116 -0
- package/docs/api/classes/WSAPIBonuses.md +50 -0
- package/docs/api/classes/WSAPIClans.md +66 -0
- package/docs/api/classes/WSAPIGamePick.md +181 -0
- package/docs/api/classes/WSAPIGeneral.md +63 -0
- package/docs/api/classes/WSAPIInbox.md +277 -0
- package/docs/api/classes/WSAPIJackpots.md +185 -0
- package/docs/api/classes/WSAPILeaderBoard.md +39 -0
- package/docs/api/classes/WSAPIMiniGames.md +175 -0
- package/docs/api/classes/WSAPIMissions.md +611 -0
- package/docs/api/classes/WSAPIRaffles.md +195 -0
- package/docs/api/classes/WSAPIStore.md +744 -0
- package/docs/api/classes/WSAPITournaments.md +104 -0
- package/docs/api/classes/WSAPIUser.md +200 -0
- package/docs/api/enumerations/AchievementClaimPeriodTypeId.md +13 -0
- package/docs/api/enumerations/BuyStoreItemErrorCode.md +32 -0
- package/docs/api/interfaces/ClanPrizePublicMeta.md +41 -0
- package/docs/api/interfaces/ClanPrizeStructureEntry.md +7 -1
- package/docs/api/interfaces/ClanPublicMeta.md +4 -0
- package/docs/api/interfaces/SAWTemplateUI.md +10 -0
- package/docs/api/interfaces/TAchCategory.md +19 -4
- package/docs/api/interfaces/TBuyStoreItemResult.md +26 -8
- package/docs/api/interfaces/TMissionClaimRewardResult.md +14 -3
- package/docs/api/interfaces/TMissionOptInResult.md +10 -3
- package/docs/api/interfaces/TMissionOrBadge.md +6 -2
- package/docs/api/interfaces/TStoreItem.md +21 -1
- package/docs/api/interfaces/TTournamentDetailed.md +8 -0
- package/docs/api/interfaces/UserAchievement.md +1 -1
- package/docs/ui/clans/UIGuide_getClanInfo.md +153 -0
- package/docs/ui/clans/UIGuide_getClans.md +172 -0
- package/docs/ui/clans/UIGuide_joinClan.md +196 -0
- package/docs/ui/missions/UIGuide_getAchCategories.md +17 -0
- package/docs/ui/missions/UIGuide_getBadges.md +237 -0
- package/docs/ui/missions/UIGuide_getMissions.md +268 -0
- package/docs/ui/missions/UIGuide_requestMissionClaimReward.md +21 -0
- package/docs/ui/missions/UIGuide_requestMissionOptIn.md +16 -0
- package/docs/ui/store/UIGuide_buyStoreItem.md +133 -0
- package/docs/ui/store/UIGuide_getStoreCategories.md +19 -0
- package/docs/ui/store/UIGuide_getStoreItems.md +264 -0
- package/docs/ui/store/UIGuide_getStorePurchasedItems.md +122 -0
- package/docs/ui/tournaments/UIGuide_getClanTournamentPlayers.md +140 -0
- package/docs/ui/tournaments/UIGuide_getTournamentInstanceInfo.md +265 -0
- package/docs/ui/tournaments/UIGuide_getTournamentsList.md +236 -0
- package/docs/ui/tournaments/UIGuide_registerInTournament.md +156 -0
- package/docs/ui/user/UIGuide_getLevels.md +162 -0
- package/docs/ui/user/UIGuide_getUserProfile.md +213 -0
- package/package.json +3 -3
- package/scripts/postdoc-cleanup.js +195 -0
- package/src/Missions/MissionsUtils.ts +5 -2
- package/src/Store/BuyStoreItemErrorCode.ts +8 -0
- package/src/Store/StoreItem.ts +1 -0
- package/src/Store/StoreItemPurchased.ts +1 -0
- package/src/Store/StoreItemType.ts +1 -1
- package/src/Tournaments/TournamentRegistrationError.ts +4 -0
- package/src/WSAPI/WSAPI.ts +27 -2007
- package/src/WSAPI/WSAPIAvatars.ts +127 -0
- package/src/WSAPI/WSAPIBase.ts +93 -0
- package/src/WSAPI/WSAPIBonuses.ts +54 -0
- package/src/WSAPI/WSAPIClans.ts +417 -0
- package/src/WSAPI/WSAPIGamePick.ts +382 -0
- package/src/WSAPI/WSAPIGeneral.ts +57 -0
- package/src/WSAPI/WSAPIInbox.ts +222 -0
- package/src/WSAPI/WSAPIJackpots.ts +212 -0
- package/src/WSAPI/WSAPILeaderBoard.ts +40 -0
- package/src/WSAPI/WSAPIMiniGames.ts +181 -0
- package/src/WSAPI/WSAPIMissions.ts +572 -0
- package/src/WSAPI/WSAPIRaffles.ts +175 -0
- package/src/WSAPI/WSAPIStore.ts +732 -0
- package/src/WSAPI/WSAPITournaments.ts +541 -0
- package/src/WSAPI/WSAPITypes.ts +145 -87
- package/src/WSAPI/WSAPIUser.ts +456 -0
- package/tsconfig.json +17 -1
- package/docs/api/classes/WSAPI.md +0 -1927
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# UI Guide — `getStoreCategories`
|
|
2
|
+
|
|
3
|
+
## UI guidance
|
|
4
|
+
- Treat categories as relatively static. Safe to fetch once on store-page entry and
|
|
5
|
+
reuse for the lifetime of the view; the SDK's 30 s cache handles short-term re-calls.
|
|
6
|
+
- Sort by `order` ascending before rendering. Items with the same `order` should fall
|
|
7
|
+
back to `name` or `id` for stable ordering.
|
|
8
|
+
- For tab UIs (the common store layout), generate one tab per non-empty category.
|
|
9
|
+
The reference UI also appends the count of items in parentheses on each tab label
|
|
10
|
+
(e.g. `Bonuses (12)`) — compute the count by intersecting `getStoreItems()` with
|
|
11
|
+
each category id.
|
|
12
|
+
- If you want an "All items" tab, generate it client-side; the server does not return one.
|
|
13
|
+
- Loading indicator: skip on cache hit; show a brief shimmer on cold fetch (typically
|
|
14
|
+
100–300 ms).
|
|
15
|
+
- Empty state: when this method returns `[]`, render the store as a flat grid (no tabs,
|
|
16
|
+
no section headers) over `getStoreItems()`.
|
|
17
|
+
|
|
18
|
+
**Visitor mode**: supported. Use `_smartico.vapi(lang).getStoreCategories()` to fetch
|
|
19
|
+
categories with `name` translated to the given language without an authenticated user.
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
# UI Guide — `getStoreItems`
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
- Register `onUpdate` on first render and treat each invocation as
|
|
5
|
+
"discard prior list, re-render from this array". Do not merge.
|
|
6
|
+
- Loading indicator: the first `getStoreItems()` is a server round-trip
|
|
7
|
+
(typically 100–500 ms); subsequent calls within the 30 s cache window
|
|
8
|
+
resolve effectively synchronously.
|
|
9
|
+
- The SDK returns a flat array; tabs/sections/filters are applied
|
|
10
|
+
client-side using `category_ids`, `custom_section_id`, and
|
|
11
|
+
`only_in_custom_section`.
|
|
12
|
+
- The catalog card UI is the SAME for all `type` values. Type-specific
|
|
13
|
+
behavior (lootbox reveal, bonus activation toast, SAW redirect) is
|
|
14
|
+
the consumer's responsibility AFTER the purchase succeeds, not on
|
|
15
|
+
the catalog tile itself.
|
|
16
|
+
|
|
17
|
+
## List view organization
|
|
18
|
+
- **Categories**: render `getStoreCategories()` as tabs/chips. For each
|
|
19
|
+
tab, filter the catalog to items whose `category_ids` includes the
|
|
20
|
+
active category id. An item present in multiple categories appears
|
|
21
|
+
under each.
|
|
22
|
+
- **Custom sections**: the operator can group items into
|
|
23
|
+
custom_section_id buckets that live on a separate route from the main
|
|
24
|
+
store. Items with `only_in_custom_section: true` MUST be hidden from
|
|
25
|
+
the main store and appear only inside their `custom_section_id`.
|
|
26
|
+
Items WITHOUT that flag (but with a `custom_section_id`) appear in
|
|
27
|
+
both places.
|
|
28
|
+
- **Sorting** (within a category): three modes, operator-configurable
|
|
29
|
+
default order:
|
|
30
|
+
1. "Natural" — a composite sort string from operator config
|
|
31
|
+
(commonly `canbuy desc, priority asc, price asc`). Sorts buyable
|
|
32
|
+
items above non-buyable, then by `priority` (lower first),
|
|
33
|
+
breaking ties by `price`.
|
|
34
|
+
2. "Price" — by numeric `price`, ASC or DESC.
|
|
35
|
+
3. "Name" — alphabetic by `name`, ASC or DESC.
|
|
36
|
+
Default is "Natural". Consumers may expose toggles.
|
|
37
|
+
- **No status bucketing** (unlike missions). Sold-out / can't-buy
|
|
38
|
+
items are intermixed with buyable items; the "Natural" sort just
|
|
39
|
+
pushes them lower. Render them with a status overlay (see status
|
|
40
|
+
treatments below) rather than putting them in a separate tab.
|
|
41
|
+
- **Search**: optional client-side substring match on `name`
|
|
42
|
+
(case-insensitive). The SDK does not paginate.
|
|
43
|
+
- **No pagination**: the SDK returns the full visible catalog in one
|
|
44
|
+
response. For very large catalogs (50+ items), consider client-side
|
|
45
|
+
virtualization. The default Smartico UI does NOT virtualize.
|
|
46
|
+
|
|
47
|
+
## Item card / tile (list view)
|
|
48
|
+
|
|
49
|
+
Fields to render on the card:
|
|
50
|
+
- `image` — documented source size **256×256 px**, 1:1 aspect ratio.
|
|
51
|
+
CSS `background-image` or `<img>` is conventional.
|
|
52
|
+
- `name` — the title. Pre-translated server-side. Safe to render as
|
|
53
|
+
HTML if the consumer sanitizes first.
|
|
54
|
+
- Price block — `price` rendered alongside a currency icon driven by
|
|
55
|
+
`purchase_type` (`'points'` / `'gems'` / `'diamonds'`). When
|
|
56
|
+
`discounted_price` is set, render `discounted_price` as the active
|
|
57
|
+
price and strike-through `price`.
|
|
58
|
+
- Ribbon overlay (`ribbon` field) — presets `'sale'`, `'hot'`, `'new'`,
|
|
59
|
+
`'vip'` use built-in styling; any other string is a custom URL
|
|
60
|
+
(250×300 px). Position: top-left corner overlay.
|
|
61
|
+
- Discount ribbon (`discount_price_ribbon`) — only when set. Presets
|
|
62
|
+
`'10' | '15' | '20' | '25' | '50'` use built-in percent-styled
|
|
63
|
+
ribbons; the literal `'custom'` uses `custom_ribbon_image` (250×300 px)
|
|
64
|
+
as the artwork. Position: top-right corner overlay (or opposite the
|
|
65
|
+
item ribbon).
|
|
66
|
+
- Stock indicator — when `pool !== null`:
|
|
67
|
+
- `pool > 0`: render "In stock — N left" (using
|
|
68
|
+
`pool` as the count).
|
|
69
|
+
- `pool === 0`: render "Out of stock" / "Sold out" overlay
|
|
70
|
+
and grey-out the card if the operator enabled the
|
|
71
|
+
`grey_out_unavailable_items` config flag.
|
|
72
|
+
When `pool === null`, render no stock indicator (unlimited supply).
|
|
73
|
+
- Countdown timer — render only when `active_till_date` is set AND the
|
|
74
|
+
operator enabled the per-item `show_timer` flag. Format below.
|
|
75
|
+
- Buy button — labeled with the "Buy Now" CTA, the price, and the
|
|
76
|
+
currency icon. Disabled / greyed when `can_buy === false`, when the
|
|
77
|
+
user can't afford the item (live balance < `price`), or when
|
|
78
|
+
`pool === 0`.
|
|
79
|
+
|
|
80
|
+
Fields NOT shown on the card (detail popup only):
|
|
81
|
+
- Full `description` HTML (cards typically show just the title)
|
|
82
|
+
- `hint_text` (T&C)
|
|
83
|
+
- `related_games`
|
|
84
|
+
- `related_item_ids`
|
|
85
|
+
- `cant_buy_message` (the verbose explanation; show on the popup or as
|
|
86
|
+
a toast when the Buy button is clicked while disabled)
|
|
87
|
+
- `limit_message` / `purchase_limit_message` (surfaced post-attempt via
|
|
88
|
+
the buy error toast, not pre-emptively on the card)
|
|
89
|
+
|
|
90
|
+
Click target: the **whole card** opens the detail popup. The Buy button
|
|
91
|
+
inside the popup is where the purchase is actually dispatched — there
|
|
92
|
+
is no inline buy from the card in the default Smartico UI.
|
|
93
|
+
|
|
94
|
+
## Detail popup
|
|
95
|
+
|
|
96
|
+
Top-to-bottom structure (omit sections whose source field is empty):
|
|
97
|
+
1. Close button.
|
|
98
|
+
2. Item ribbon overlay (same as card).
|
|
99
|
+
3. Discount ribbon overlay (same as card).
|
|
100
|
+
4. Title (`name`).
|
|
101
|
+
5. Countdown timer (when `active_till_date && show_timer`).
|
|
102
|
+
6. Stock indicator ("In stock — N left" / "Out of stock"), with
|
|
103
|
+
grey-out applied to the image when the item is unbuyable AND the
|
|
104
|
+
operator enabled `grey_out_unavailable_items`.
|
|
105
|
+
7. Image (`image`) — render larger than the card variant.
|
|
106
|
+
8. Full `description` (HTML).
|
|
107
|
+
9. Insufficient-balance line — when the live balance for
|
|
108
|
+
`purchase_type` is less than `price`, render a localized
|
|
109
|
+
"You're short by N {points|gems|diamonds}" copy with the deficit
|
|
110
|
+
computed client-side (`price − balance`).
|
|
111
|
+
10. `cant_buy_message` — when `can_buy === false` and there's a
|
|
112
|
+
reason string (e.g. "VIP only").
|
|
113
|
+
11. Buy button block. Disabled state combines the three conditions
|
|
114
|
+
above. While the purchase RPC is in flight, replace the inner
|
|
115
|
+
price/CTA with a loading dots animation.
|
|
116
|
+
12. T&C `hint_text` — surfaced as an info-icon tooltip below the
|
|
117
|
+
Buy button (tap to expand). Not inline.
|
|
118
|
+
13. Related items / related games carousel (collapsed by default,
|
|
119
|
+
expandable). `related_item_ids` resolves against the main
|
|
120
|
+
catalog; `related_games` filtered to those with
|
|
121
|
+
`game_public_meta.enabled === true`. Show navigation arrows when
|
|
122
|
+
5+ items on desktop, 4+ on mobile.
|
|
123
|
+
|
|
124
|
+
## Action button decision matrix
|
|
125
|
+
|
|
126
|
+
*(Buy button)*
|
|
127
|
+
|
|
128
|
+
Apply in priority order; first match wins:
|
|
129
|
+
|
|
130
|
+
1. **Purchase RPC in flight** — show loading dots over the price/CTA,
|
|
131
|
+
keep the button disabled until the response arrives. Guard
|
|
132
|
+
double-clicks at the UI layer.
|
|
133
|
+
2. `pool === 0` → **"Sold out"** state; button disabled. The card and
|
|
134
|
+
image may be greyed (operator config).
|
|
135
|
+
3. `can_buy === false` → button disabled. Surface `cant_buy_message`
|
|
136
|
+
(or `limit_message`) on the popup as the explanation.
|
|
137
|
+
4. Balance < `price` for the relevant `purchase_type` → button
|
|
138
|
+
disabled. Surface a localized insufficient-balance line with the
|
|
139
|
+
deficit.
|
|
140
|
+
5. All clear → **"Buy Now"** button enabled. On click: call
|
|
141
|
+
[buyStoreItem](../../api/classes/WSAPIStore.md#buystoreitem)(`id`) and show loading dots until the
|
|
142
|
+
response arrives.
|
|
143
|
+
|
|
144
|
+
After a successful purchase ([buyStoreItem](../../api/classes/WSAPIStore.md#buystoreitem) `err_code === 0`):
|
|
145
|
+
- Close the popup, show a success toast.
|
|
146
|
+
- The SDK auto-fires `onUpdate` with the refreshed catalog — re-render
|
|
147
|
+
from that array, do NOT manually decrement the local `pool`.
|
|
148
|
+
|
|
149
|
+
On a failed purchase, branch on `err_code` (see [buyStoreItem](../../api/classes/WSAPIStore.md#buystoreitem)
|
|
150
|
+
for the full error code table — codes `11000` / `11011` / `11012` for
|
|
151
|
+
insufficient balance per currency, `11006` for per-period cap reached,
|
|
152
|
+
`11009` for pool emptied between catalog fetch and buy, `11014` for
|
|
153
|
+
purchase-limit hit, etc.). Surface `purchase_limit_message` for the
|
|
154
|
+
limit-hit case, `limit_message` for the cap-reached case; fall back to
|
|
155
|
+
`err_message` otherwise.
|
|
156
|
+
|
|
157
|
+
## Price rendering per `purchase_type`
|
|
158
|
+
- **`'points'`**: render `price` with a "points" currency glyph; compare
|
|
159
|
+
against the user's `ach_points_balance`.
|
|
160
|
+
- **`'gems'`**: render with a "gems" glyph; compare against
|
|
161
|
+
`ach_gems_balance`.
|
|
162
|
+
- **`'diamonds'`**: render with a "diamonds" glyph; compare against
|
|
163
|
+
`ach_diamonds_balance`.
|
|
164
|
+
- When `discounted_price` is set: the **discounted** value is the
|
|
165
|
+
active price (used for affordability checks); `price` becomes the
|
|
166
|
+
strikethrough "before" value.
|
|
167
|
+
- All three balances update server-side as the user plays and arrive
|
|
168
|
+
on the user's gamification profile asynchronously — keep them live
|
|
169
|
+
without polling.
|
|
170
|
+
|
|
171
|
+
## Image / asset specs
|
|
172
|
+
- `image` (item icon): **256×256 px**, 1:1 aspect ratio.
|
|
173
|
+
- `ribbon` (when a URL): **250×300 px** custom artwork.
|
|
174
|
+
- `custom_ribbon_image` (discount ribbon when `discount_price_ribbon === 'custom'`):
|
|
175
|
+
**250×300 px**.
|
|
176
|
+
- Related game thumbnails: **1:1 aspect ratio** per
|
|
177
|
+
`game_public_meta.image`.
|
|
178
|
+
- No built-in fallback placeholders — consumers should provide one when
|
|
179
|
+
source fields are empty.
|
|
180
|
+
|
|
181
|
+
## Status-specific visual treatments
|
|
182
|
+
- **Sold out** (`pool === 0`): "Out of stock" badge on the card; image
|
|
183
|
+
greyscaled when the operator enabled `grey_out_unavailable_items`.
|
|
184
|
+
Buy button disabled.
|
|
185
|
+
- **Cannot afford** (balance < `price` for `purchase_type`): Buy button
|
|
186
|
+
disabled (greyed); the rest of the card is full-color. Detail popup
|
|
187
|
+
adds the deficit line. The card image is greyscaled only when the
|
|
188
|
+
operator enabled `grey_out_unavailable_items`.
|
|
189
|
+
- **Not eligible** (`can_buy === false`): same as cannot-afford
|
|
190
|
+
visually; the explanation source is `cant_buy_message` (popup) /
|
|
191
|
+
`limit_message` (post-buy-attempt).
|
|
192
|
+
- **Discount active** (`discounted_price` set): show the discount
|
|
193
|
+
ribbon overlay and the strikethrough+new-price treatment.
|
|
194
|
+
- **New item** (operator marked `ribbon === 'new'` OR client-side
|
|
195
|
+
tracking of newly-added ids in localStorage): "New" ribbon preset.
|
|
196
|
+
The SDK does not track "newness" — the operator's `ribbon` field is
|
|
197
|
+
the source of truth.
|
|
198
|
+
- **Flash sale** (`active_till_date && show_timer`): countdown timer
|
|
199
|
+
on the card and popup.
|
|
200
|
+
|
|
201
|
+
## Countdown / timing format
|
|
202
|
+
|
|
203
|
+
*(for `active_till_date`)*
|
|
204
|
+
|
|
205
|
+
Convention used by the default Smartico UI:
|
|
206
|
+
- `DD:HH:MM:SS` (zero-padded to 2 digits each) when the timer is set.
|
|
207
|
+
- Update the displayed text every **1 second**.
|
|
208
|
+
- When the timer reaches 0, the item disappears from the catalog on
|
|
209
|
+
the next refresh (server filters it out). The consumer should NOT
|
|
210
|
+
need a separate "expired" state for catalog items.
|
|
211
|
+
|
|
212
|
+
## Empty / loading / error states
|
|
213
|
+
- **Empty catalog**: "No store items" message + illustration.
|
|
214
|
+
- **Empty category** (after filter): same copy or a category-scoped
|
|
215
|
+
variant.
|
|
216
|
+
- **Empty search**: no-results state with the search term.
|
|
217
|
+
- **Loading**: spinner / skeleton until the first response. Subsequent
|
|
218
|
+
`onUpdate` refreshes are fast enough to render in-place without a
|
|
219
|
+
skeleton.
|
|
220
|
+
- **Buy error**: surface `purchase_limit_message` (for
|
|
221
|
+
`err_code === 11014`), `limit_message` (for `err_code === 11006`), or
|
|
222
|
+
the server `err_message` as a modal/toast.
|
|
223
|
+
|
|
224
|
+
## Animations / transitions
|
|
225
|
+
- List entry: stagger-fade-in per card (the default Smartico UI uses a
|
|
226
|
+
~100 ms stagger per index).
|
|
227
|
+
- Popup open: bounce + fade-in on title/image; fade-in on description,
|
|
228
|
+
stock line, and balance line.
|
|
229
|
+
- Buy button in flight: loading dots overlay; disable underlying CTA.
|
|
230
|
+
- Purchase success: close popup, show success toast; the auto-refresh
|
|
231
|
+
re-renders the catalog (pool decrements, `can_buy` re-evaluates).
|
|
232
|
+
- Card hover (desktop): optional scale/shadow per consumer's design.
|
|
233
|
+
|
|
234
|
+
## Mobile vs desktop
|
|
235
|
+
- Mobile: vertical scroll; the default Smartico UI uses a 2-column grid
|
|
236
|
+
for the main store and a list layout for purchase history.
|
|
237
|
+
- Desktop: wider multi-column grid. Related-items carousel shows
|
|
238
|
+
navigation arrows at 5+ items on desktop vs 4+ on mobile.
|
|
239
|
+
- The detail popup is structurally identical on both; only sizing
|
|
240
|
+
differs.
|
|
241
|
+
|
|
242
|
+
## Performance
|
|
243
|
+
- No pagination. The SDK returns the full visible catalog in one
|
|
244
|
+
response.
|
|
245
|
+
- For very large catalogs (50+ items) consider client-side
|
|
246
|
+
virtualization. The default Smartico UI does NOT virtualize.
|
|
247
|
+
- The 30-second SDK cache makes intra-session re-renders free; do NOT
|
|
248
|
+
poll `getStoreItems()`.
|
|
249
|
+
|
|
250
|
+
**Cache TTL**: the SDK caches the response for 30 seconds. The cache is
|
|
251
|
+
invalidated and re-fetched automatically after every `buyStoreItem(...)`
|
|
252
|
+
call resolves for the current user. It is NOT invalidated by other
|
|
253
|
+
users' purchases, by operator BO edits, or by `active_till_date`
|
|
254
|
+
elapsing while the page is open.
|
|
255
|
+
|
|
256
|
+
**Visitor mode**: supported, with caveats.
|
|
257
|
+
- The catalog reflects the brand's proxy "visitor" user, not the actual
|
|
258
|
+
anonymous viewer. Per-user fields (`can_buy`, `pool` decrements,
|
|
259
|
+
`purchased_*` flags) reflect the proxy user's state and are not
|
|
260
|
+
meaningful for display.
|
|
261
|
+
- `onUpdate` is accepted but NEVER fires in visitor mode — there is no
|
|
262
|
+
live channel, so push events are not delivered.
|
|
263
|
+
- [buyStoreItem](../../api/classes/WSAPIStore.md#buystoreitem) is not supported in visitor mode; the Buy button
|
|
264
|
+
should deep-link to a login/registration flow instead.
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# UI Guide — `getStorePurchasedItems`
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
Loading indicator recommended on cold fetch (no cache hit, typical
|
|
5
|
+
100–500 ms latency). The default Smartico UI renders a full-screen spinner
|
|
6
|
+
while the first page is in flight, then a fade-in on the list. On load-
|
|
7
|
+
more pagination, the recommended pattern is to hide the "Load more"
|
|
8
|
+
button while the next page is fetching rather than showing a separate
|
|
9
|
+
spinner.
|
|
10
|
+
|
|
11
|
+
## List view
|
|
12
|
+
- Flat newest-first list. The default Smartico UI does NOT group by date
|
|
13
|
+
(no "Today" / "This Week" / "Older" headers) and does NOT offer
|
|
14
|
+
category / type / status filter chips. If your design needs date
|
|
15
|
+
bucketing, use the SDK-provided `purchased_today` /
|
|
16
|
+
`purchased_this_week` / `purchased_this_month` booleans for grouping.
|
|
17
|
+
- Pagination UI: render a "Load more" button below the list when the
|
|
18
|
+
previous page returned exactly `limit` items. Hide it once a page
|
|
19
|
+
returns fewer than `limit` rows. The default Smartico UI uses an explicit
|
|
20
|
+
button; infinite scroll is a valid alternative but not the reference
|
|
21
|
+
pattern.
|
|
22
|
+
- Stagger animation: the default Smartico UI fades each row in with a
|
|
23
|
+
100 ms incremental `animationDelay` (row 0 at 0 ms, row 1 at 100 ms,
|
|
24
|
+
etc.) for a cascade effect on the first page. Optional.
|
|
25
|
+
|
|
26
|
+
## Item card (history row)
|
|
27
|
+
Two-column desktop / single-column-with-footer mobile layout. Rendered
|
|
28
|
+
fields, top-to-bottom:
|
|
29
|
+
1. Item image (`image`) on the left, 1:1 aspect (256×256 source spec,
|
|
30
|
+
typically rendered ~64–96 px on screen via CSS).
|
|
31
|
+
2. Stock indicator — only when `pool !== null`. `pool > 0` shows
|
|
32
|
+
"In stock — N left"; `pool === 0` shows "Out of stock".
|
|
33
|
+
(This reflects CURRENT stock for "Buy Again" context, not stock at
|
|
34
|
+
purchase time.)
|
|
35
|
+
3. Item name (`name`) — HTML, sanitize to plain text or render with
|
|
36
|
+
`dangerouslySetInnerHTML` after trusted sanitization.
|
|
37
|
+
4. Price stamp — `purchase_points_amount` paired with the currency
|
|
38
|
+
icon implied by `purchase_type`. This is the historical amount
|
|
39
|
+
paid, NOT the current item `price`.
|
|
40
|
+
5. Purchase date — `purchase_ts` formatted via
|
|
41
|
+
`toLocaleString(undefined, { dateStyle: 'short', timeStyle: 'medium' })`
|
|
42
|
+
and prefixed with a "Purchased:" label.
|
|
43
|
+
6. **"Buy Again" button** — opens the standard buy modal for the
|
|
44
|
+
same item. Disabled when:
|
|
45
|
+
- `can_buy === false` (server says the user cannot purchase it
|
|
46
|
+
right now), OR
|
|
47
|
+
- the user's current balance is below the item's CURRENT
|
|
48
|
+
`price` (not `purchase_points_amount`), OR
|
|
49
|
+
- `pool === 0` (out of stock).
|
|
50
|
+
Layout: inline on desktop (right column), in a bottom footer strip
|
|
51
|
+
on mobile.
|
|
52
|
+
|
|
53
|
+
## Fields explicitly NOT rendered on the row
|
|
54
|
+
- `description`, `ribbon`, `hint_text`, `custom_data`, `type`,
|
|
55
|
+
`related_games`, `category_ids`, `discounted_price`,
|
|
56
|
+
`discount_price_ribbon`, `custom_ribbon_image`, `active_till_date`,
|
|
57
|
+
`cant_buy_message` — the default Smartico UI omits these on the history
|
|
58
|
+
row.
|
|
59
|
+
|
|
60
|
+
## Detail view
|
|
61
|
+
No tap-to-expand inline detail view exists for history rows. "Buy
|
|
62
|
+
Again" is the only action; it routes through the standard
|
|
63
|
+
[getStoreItems](../../api/classes/WSAPIStore.md#getstoreitems) buy modal (full description, related games, etc.
|
|
64
|
+
are surfaced there).
|
|
65
|
+
|
|
66
|
+
## Status-specific treatments
|
|
67
|
+
- No fulfillment status field; rows have no delivered/pending/cancelled
|
|
68
|
+
visual variants.
|
|
69
|
+
- Stock-based modifier: when `pool === 0`, grey out / disable the "Buy
|
|
70
|
+
Again" button and show the "Out of stock" label in the info area.
|
|
71
|
+
This is a CURRENT availability signal, not a status on the past
|
|
72
|
+
purchase itself.
|
|
73
|
+
|
|
74
|
+
## Image / asset specs
|
|
75
|
+
- `image`: documented source size **256×256 px**, 1:1 aspect ratio.
|
|
76
|
+
- Typically rendered via `<img>` (the default Smartico UI uses an `<img>`,
|
|
77
|
+
not CSS background-image, for history rows).
|
|
78
|
+
- No built-in fallback placeholder — provide one when `image` is empty.
|
|
79
|
+
|
|
80
|
+
## Date formatting
|
|
81
|
+
- Format `purchase_ts` with `toLocaleString(undefined, ...)` to render
|
|
82
|
+
in the user's OS locale and timezone. Do NOT assume UTC display — the
|
|
83
|
+
stored timestamp is UTC milliseconds but humans read it locally.
|
|
84
|
+
- For relative formatting ("3 hours ago", "Yesterday"), use
|
|
85
|
+
`purchased_today` / `purchased_this_week` / `purchased_this_month`
|
|
86
|
+
as buckets or compute deltas client-side.
|
|
87
|
+
|
|
88
|
+
## Empty state
|
|
89
|
+
When the first page returns an empty array, render a "No purchases yet"
|
|
90
|
+
empty state (icon + copy). Do NOT distinguish "no purchases at all"
|
|
91
|
+
from "no purchases in selected period" — this method has no period
|
|
92
|
+
filter, so any empty response means the user has zero history entries
|
|
93
|
+
total.
|
|
94
|
+
|
|
95
|
+
## Error handling
|
|
96
|
+
On a network or server failure the Promise rejects. The SDK does not
|
|
97
|
+
surface an `err_code`/`err_message` shape on this method (the array
|
|
98
|
+
either resolves or the call throws). Wrap in `try { ... } catch` and
|
|
99
|
+
either retry with backoff or surface a generic "Couldn't load purchase
|
|
100
|
+
history" message — the default Smartico UI's behavior is to silently clear
|
|
101
|
+
the loading state, which leaves the previous list visible.
|
|
102
|
+
|
|
103
|
+
## Mobile vs desktop
|
|
104
|
+
- Desktop: two-column row (image left, info+actions right). "Buy Again"
|
|
105
|
+
and purchase-date inline in the info column.
|
|
106
|
+
- Mobile: single-column with a bottom footer strip carrying the
|
|
107
|
+
purchase-date and the "Buy Again" button.
|
|
108
|
+
- No CSS-breakpoint magic in the default Smartico UI — the layout toggle
|
|
109
|
+
is a runtime `isMobile` boolean.
|
|
110
|
+
|
|
111
|
+
## Performance
|
|
112
|
+
- 20 rows per page is small enough that virtualization is not needed
|
|
113
|
+
under typical history sizes.
|
|
114
|
+
- Cache (30 s) is fine for in-screen re-renders. Do not call this on
|
|
115
|
+
every render — fetch once on screen mount and on demand for "Load
|
|
116
|
+
more" / `onUpdate` triggers.
|
|
117
|
+
- Polling is unnecessary — the `onUpdate` callback delivers fresh data
|
|
118
|
+
automatically when the user makes another purchase. For background
|
|
119
|
+
activity (purchases made on other surfaces), the cache TTL gives
|
|
120
|
+
eventual consistency within 30 seconds of the next call.
|
|
121
|
+
|
|
122
|
+
**Visitor mode**: not supported.
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# UI Guide — `getClanTournamentPlayers`
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
- Powers the clan drill-down modal opened from a clan row on the
|
|
5
|
+
tournament detail's clan leaderboard tab (see
|
|
6
|
+
[`getTournamentInstanceInfo`](../../api/classes/WSAPITournaments.md#gettournamentinstanceinfo)).
|
|
7
|
+
- One-shot fetch. No cache, no polling, no subscription. Re-call to
|
|
8
|
+
refresh.
|
|
9
|
+
- Returns up to ~20 players, server-sorted by score DESC. Client-side
|
|
10
|
+
re-sort is unnecessary.
|
|
11
|
+
|
|
12
|
+
## Modal / drawer layout
|
|
13
|
+
|
|
14
|
+
Top-to-bottom layout (centered modal on desktop, full-screen
|
|
15
|
+
slide-up sheet on mobile):
|
|
16
|
+
|
|
17
|
+
1. **Close affordance** — explicit close button (top-right);
|
|
18
|
+
click-outside dismiss; Escape key dismiss.
|
|
19
|
+
2. **Clan header** — clan image (1:1 aspect ratio, fallback to
|
|
20
|
+
first-letter avatar with the clan's name), clan name, total
|
|
21
|
+
score, contributing-members count, and a rank badge (1/2/3) if
|
|
22
|
+
applicable.
|
|
23
|
+
|
|
24
|
+
The default Smartico UI populates this header from the **caller-side**
|
|
25
|
+
`ClanLeaderboardEntry` object (the row the user clicked) rather
|
|
26
|
+
than from the response's `clan_public_meta` and `clan_id` — they
|
|
27
|
+
contain the same identity but the parent context already has
|
|
28
|
+
richer data (total_score, contributing_members, position) that the
|
|
29
|
+
response doesn't carry. The response's `clan_id` and
|
|
30
|
+
`clan_public_meta.name`/`image_url` are still available for
|
|
31
|
+
consumers that need them.
|
|
32
|
+
|
|
33
|
+
3. **Table header row** — three columns: `#` (rank) · Player
|
|
34
|
+
(avatar + name) · Score.
|
|
35
|
+
4. **Player list** — one row per `players[i]`. See "Player row".
|
|
36
|
+
5. **Empty state** (when `players.length === 0`) — "No leaders" text.
|
|
37
|
+
Shown both during the loading round-trip AND when the result is
|
|
38
|
+
empty.
|
|
39
|
+
|
|
40
|
+
## Player row
|
|
41
|
+
|
|
42
|
+
Three columns:
|
|
43
|
+
|
|
44
|
+
| Column | Source | Notes |
|
|
45
|
+
|---|---|---|
|
|
46
|
+
| `#` (rank) | `position ?? 0` | Plain text. Server-side rank within this clan. |
|
|
47
|
+
| Player (avatar + name) | `avatar_url` (or derived from `avatar_id` + label `avatarDomain`) + `clean_ext_user_id ?? public_username` | Username prefers `clean_ext_user_id` over `public_username`; if both empty, the avatar fallback letter is also blank. |
|
|
48
|
+
| Score | `scores ?? 0` | Format with space-thousands ("1 234 567") + "pts" suffix. |
|
|
49
|
+
|
|
50
|
+
**"Me" row highlight**: when `is_me === true`, add a distinct
|
|
51
|
+
background (CSS class `is-me` in the default Smartico UI). There is no
|
|
52
|
+
sticky "me" footer in this modal — the user's row scrolls with the
|
|
53
|
+
list. If your UI has many players (rare — server caps at ~20), you may
|
|
54
|
+
want to auto-scroll the "me" row into view on first render.
|
|
55
|
+
|
|
56
|
+
**Avatar resolution**: if `avatar_url` is already populated by the SDK,
|
|
57
|
+
use it directly. Otherwise, derive a CDN URL from `avatar_id` and the
|
|
58
|
+
brand's avatar domain — the SDK's `CoreUtils.avatarUrl()` does this for
|
|
59
|
+
you on the response.
|
|
60
|
+
|
|
61
|
+
**Top-3 styling**: optional — apply podium accent (gold/silver/bronze)
|
|
62
|
+
to rows where `position <= 3`. The default Smartico UI applies the
|
|
63
|
+
podium treatment only on the clan header rank badge, not on individual
|
|
64
|
+
player rows.
|
|
65
|
+
|
|
66
|
+
## Empty / loading / error states
|
|
67
|
+
|
|
68
|
+
- **Loading**: render the modal frame and clan header immediately
|
|
69
|
+
(driven by caller-side data); render an "empty state" placeholder
|
|
70
|
+
in the player list area while the call is in flight. **Or** render a
|
|
71
|
+
skeleton rows (3–5 grey bars) — typically friendlier than the
|
|
72
|
+
empty-state text appearing then disappearing.
|
|
73
|
+
- **Empty (no players)**: render the "No leaders" text. This can mean:
|
|
74
|
+
- no one in the clan has scored yet,
|
|
75
|
+
- the call failed (network / server error — the default UI silently
|
|
76
|
+
swallows the error),
|
|
77
|
+
- the `(tournamentInstanceId, clanId)` combination is invalid.
|
|
78
|
+
|
|
79
|
+
These three are not distinguishable in the response itself. The
|
|
80
|
+
default UI treats them identically. If your UI cares to distinguish,
|
|
81
|
+
attach a `.catch()` to surface a transient-error toast.
|
|
82
|
+
- **Error**: not surfaced by default. Add explicit error handling if
|
|
83
|
+
needed — wrap the call in try/catch and show a "Failed to load — Try
|
|
84
|
+
again" affordance.
|
|
85
|
+
|
|
86
|
+
## Close affordance
|
|
87
|
+
|
|
88
|
+
Three independent dismiss mechanisms (all dispatch the same close
|
|
89
|
+
action):
|
|
90
|
+
|
|
91
|
+
1. Close button (top-right of modal).
|
|
92
|
+
2. Click outside the modal card.
|
|
93
|
+
3. `Escape` key.
|
|
94
|
+
|
|
95
|
+
The default Smartico UI wires all three via a shared `useModalClose`
|
|
96
|
+
hook. Mirror this pattern for parity.
|
|
97
|
+
|
|
98
|
+
## Refresh
|
|
99
|
+
|
|
100
|
+
- **Don't poll inside this modal**. The default Smartico UI doesn't
|
|
101
|
+
poll — the clan-leaderboard tab (parent) does poll via
|
|
102
|
+
`getTournamentInstanceInfo` and refreshes the visible clan rankings
|
|
103
|
+
when the modal closes. Live updates inside the modal are not part
|
|
104
|
+
of the default UX.
|
|
105
|
+
- If your product requires live updates inside this modal, call
|
|
106
|
+
`getClanTournamentPlayers` again on a 3 s interval. Be cautious —
|
|
107
|
+
each call is a fresh network round-trip (no cache).
|
|
108
|
+
|
|
109
|
+
## Pagination
|
|
110
|
+
|
|
111
|
+
None at the SDK level. The server returns up to ~20 players (configured
|
|
112
|
+
per tournament). There is no "load more" affordance in the default UI.
|
|
113
|
+
|
|
114
|
+
## Animations / transitions
|
|
115
|
+
|
|
116
|
+
- **Modal entry**: fade-in + scale (~150 ms ease-out).
|
|
117
|
+
- **Modal exit**: fade-out + scale-down (~120 ms).
|
|
118
|
+
- **List entry**: cards/rows fade-in staggered ~20 ms per row on
|
|
119
|
+
first render. No skeleton-to-data crossfade (the list is small
|
|
120
|
+
enough to render instantly once data arrives).
|
|
121
|
+
- **Rank change between calls** (if you implement live polling): FLIP
|
|
122
|
+
animation to reorder rows.
|
|
123
|
+
|
|
124
|
+
## Mobile vs desktop
|
|
125
|
+
|
|
126
|
+
- **Modal style**: centered overlay on desktop with backdrop dim;
|
|
127
|
+
full-screen slide-up sheet on mobile (with a swipe-down dismiss
|
|
128
|
+
gesture).
|
|
129
|
+
- **Header layout**: image left, identity right on desktop; stacked
|
|
130
|
+
(image above identity) on mobile.
|
|
131
|
+
- **Row density**: identical on both — the row is already compact.
|
|
132
|
+
|
|
133
|
+
## Performance
|
|
134
|
+
|
|
135
|
+
- Each call is a fresh network round-trip. The page typically has at
|
|
136
|
+
most one of these in flight at a time (driven by user clicks),
|
|
137
|
+
so cost is minimal.
|
|
138
|
+
- If your UI offers a "view all clans" affordance that pre-fetches
|
|
139
|
+
player lists for many clans, throttle the fetches — don't fan out
|
|
140
|
+
20 simultaneous round-trips.
|