@rpg-engine/long-bow 0.8.179 → 0.8.181

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rpg-engine/long-bow",
3
- "version": "0.8.179",
3
+ "version": "0.8.181",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "typings": "dist/index.d.ts",
@@ -34,6 +34,8 @@ export interface ICartViewProps {
34
34
  onPurchaseSuccess?: (items: Array<{ key: string; name: string; quantity: number }>, total: number) => void;
35
35
  /** Fires when a purchase fails */
36
36
  onPurchaseError?: (error: string) => void;
37
+ /** Currency symbol to display (e.g. "$" for USD, "R$" for BRL). Defaults to "$". */
38
+ currencySymbol?: string;
37
39
  }
38
40
 
39
41
  const MetadataDisplay: React.FC<{
@@ -70,13 +72,14 @@ export const CartView: React.FC<ICartViewProps> = ({
70
72
  onCheckoutStart,
71
73
  onPurchaseSuccess,
72
74
  onPurchaseError,
75
+ currencySymbol = '$',
73
76
  }) => {
74
77
  const [isLoading, setIsLoading] = useState(false);
75
78
  const [error, setError] = useState<string | null>(null);
76
79
  const [purchasedItems, setPurchasedItems] = useState<ICartItem[] | null>(null);
77
80
 
78
81
  const total = cartItems.reduce(
79
- (sum, cartItem) => sum + cartItem.item.price * cartItem.quantity,
82
+ (sum, cartItem) => sum + ((cartItem.item as any).regionalPrice ?? cartItem.item.price) * cartItem.quantity,
80
83
  0
81
84
  );
82
85
 
@@ -175,12 +178,12 @@ export const CartView: React.FC<ICartViewProps> = ({
175
178
  <CartMeta>{cartItem.metadata.inputValue}</CartMeta>
176
179
  )}
177
180
  <ItemInfo>
178
- <span>${formatPrice(cartItem.item.price)}</span>
181
+ <span>{currencySymbol}{formatPrice((cartItem.item as any).regionalPrice ?? cartItem.item.price)}</span>
179
182
  <span>×</span>
180
183
  <span>{cartItem.quantity}</span>
181
184
  <span>=</span>
182
185
  <span>
183
- ${formatPrice(cartItem.item.price * cartItem.quantity)}
186
+ {currencySymbol}{formatPrice(((cartItem.item as any).regionalPrice ?? cartItem.item.price) * cartItem.quantity)}
184
187
  </span>
185
188
  </ItemInfo>
186
189
 
@@ -220,7 +223,7 @@ export const CartView: React.FC<ICartViewProps> = ({
220
223
  <OrderSummaryLabel>Order Summary</OrderSummaryLabel>
221
224
  <TotalRow>
222
225
  <span>Subtotal:</span>
223
- <span>${formatPrice(total)}</span>
226
+ <span>{currencySymbol}{formatPrice(total)}</span>
224
227
  </TotalRow>
225
228
  {dcTotal > 0 && (
226
229
  <TotalRow>
@@ -230,7 +233,7 @@ export const CartView: React.FC<ICartViewProps> = ({
230
233
  )}
231
234
  <TotalRow $isTotal>
232
235
  <span>Total:</span>
233
- <span>${formatPrice(total)}</span>
236
+ <span>{currencySymbol}{formatPrice(total)}</span>
234
237
  </TotalRow>
235
238
  {paymentMethodLabel && (
236
239
  <PaymentMethodRow>
@@ -242,7 +245,7 @@ export const CartView: React.FC<ICartViewProps> = ({
242
245
  </TotalInfo>
243
246
  <CTAButton
244
247
  icon={<FaShoppingBag />}
245
- label={isLoading ? 'Processing...' : `Pay $${formatPrice(total)}`}
248
+ label={isLoading ? 'Processing...' : `Pay ${currencySymbol}${formatPrice(total)}`}
246
249
  onClick={handlePurchase}
247
250
  fullWidth
248
251
  disabled={cartItems.length === 0 || isLoading}
@@ -72,6 +72,8 @@ export interface IStoreProps {
72
72
  onPurchaseError?: (error: string) => void;
73
73
  /** Called when the DC nudge in CartView is tapped — open the DC purchase flow. */
74
74
  onBuyDC?: () => void;
75
+ /** Currency symbol to display (e.g. "$" for USD, "R$" for BRL). Defaults to "$". */
76
+ currencySymbol?: string;
75
77
  }
76
78
 
77
79
  export type { IFeaturedItem };
@@ -113,6 +115,7 @@ export const Store: React.FC<IStoreProps> = ({
113
115
  onPurchaseSuccess,
114
116
  onPurchaseError,
115
117
  onBuyDC,
118
+ currencySymbol = '$',
116
119
  }) => {
117
120
  const [selectedPack, setSelectedPack] = useState<IItemPack | null>(null);
118
121
  const [activeTab, setActiveTab] = useState<TabId>(() => {
@@ -266,6 +269,7 @@ export const Store: React.FC<IStoreProps> = ({
266
269
  atlasIMG={atlasIMG}
267
270
  packBadges={packBadges}
268
271
  onPackView={onPackView}
272
+ currencySymbol={currencySymbol}
269
273
  />
270
274
  ),
271
275
  },
@@ -307,6 +311,7 @@ export const Store: React.FC<IStoreProps> = ({
307
311
  atlasIMG={atlasIMG}
308
312
  packBadges={packBadges}
309
313
  onPackView={onPackView}
314
+ currencySymbol={currencySymbol}
310
315
  />
311
316
  ),
312
317
  },
@@ -326,6 +331,7 @@ export const Store: React.FC<IStoreProps> = ({
326
331
  itemBadges={itemBadges}
327
332
  onItemView={onItemView}
328
333
  onCategoryChange={onCategoryChange}
334
+ currencySymbol={currencySymbol}
329
335
  />
330
336
  ),
331
337
  },
@@ -383,6 +389,7 @@ export const Store: React.FC<IStoreProps> = ({
383
389
  onPurchaseSuccess={onPurchaseSuccess}
384
390
  onPurchaseError={onPurchaseError}
385
391
  onBuyDC={onBuyDC}
392
+ currencySymbol={currencySymbol}
386
393
  />
387
394
  ) : selectedPack ? (
388
395
  <StoreItemDetails
@@ -394,6 +401,7 @@ export const Store: React.FC<IStoreProps> = ({
394
401
  imageUrl={selectedPack.image}
395
402
  onBack={() => setSelectedPack(null)}
396
403
  onAddToCart={() => handleAddPackToCart(selectedPack)}
404
+ currencySymbol={currencySymbol}
397
405
  />
398
406
  ) : (
399
407
  <Container>
@@ -475,12 +483,12 @@ export const Store: React.FC<IStoreProps> = ({
475
483
  </CartInfo>
476
484
  <CartInfo>
477
485
  <span>Total:</span>
478
- <span>${getTotalPrice().toFixed(2)}</span>
486
+ <span>{currencySymbol}{getTotalPrice().toFixed(2)}</span>
479
487
  </CartInfo>
480
488
  </CartSummary>
481
489
  <CTAButton
482
490
  icon={<FaShoppingCart />}
483
- label={`Proceed to Checkout ($${getTotalPrice().toFixed(2)})`}
491
+ label={`Proceed to Checkout (${currencySymbol}${getTotalPrice().toFixed(2)})`}
484
492
  onClick={handleOpenCart}
485
493
  fullWidth
486
494
  />
@@ -9,6 +9,7 @@ interface IStoreItemDetailsProps {
9
9
  imageUrl: string | { src: string; default?: string };
10
10
  onBack: () => void;
11
11
  onAddToCart: (item: IProductBlueprint) => void;
12
+ currencySymbol?: string;
12
13
  }
13
14
 
14
15
  export const StoreItemDetails: React.FC<IStoreItemDetailsProps> = ({
@@ -16,6 +17,7 @@ export const StoreItemDetails: React.FC<IStoreItemDetailsProps> = ({
16
17
  onBack,
17
18
  onAddToCart,
18
19
  imageUrl,
20
+ currencySymbol = '$',
19
21
  }) => {
20
22
  const getImageSrc = () => {
21
23
  if (!imageUrl) return '/placeholder-thumbnail.png';
@@ -43,7 +45,7 @@ export const StoreItemDetails: React.FC<IStoreItemDetailsProps> = ({
43
45
  <ItemInfo>
44
46
  <ItemName>{item.name}</ItemName>
45
47
  <ItemPrice>
46
- ${'priceUSD' in item ? item.priceUSD : item.price}
48
+ {currencySymbol}{'priceUSD' in item ? item.priceUSD : ((item as any).regionalPrice ?? item.price)}
47
49
  {(item as any).dcPrice ? ` · ${((item as any).dcPrice as number).toLocaleString()} DC` : ''}
48
50
  </ItemPrice>
49
51
  <Description>{item.description}</Description>
@@ -31,6 +31,8 @@ interface IStoreItemRowProps {
31
31
  /** Fires once on mount — use for store_item_viewed analytics. */
32
32
  onView?: (item: IProductBlueprint, position: number) => void;
33
33
  positionInList?: number;
34
+ /** Currency symbol to display (e.g. "$" for USD, "R$" for BRL). Defaults to "$". */
35
+ currencySymbol?: string;
34
36
  }
35
37
 
36
38
  export const StoreItemRow: React.FC<IStoreItemRowProps> = ({
@@ -49,6 +51,7 @@ export const StoreItemRow: React.FC<IStoreItemRowProps> = ({
49
51
  originalPrice,
50
52
  onView,
51
53
  positionInList = 0,
54
+ currencySymbol = '$',
52
55
  }) => {
53
56
  const [textInputValue, setTextInputValue] = useState('');
54
57
 
@@ -117,7 +120,7 @@ export const StoreItemRow: React.FC<IStoreItemRowProps> = ({
117
120
  </DCCoinWrapper>
118
121
  {originalPrice.toLocaleString()}
119
122
  </>
120
- ) : `$${originalPrice.toFixed(2)}`}
123
+ ) : `${currencySymbol}${originalPrice.toFixed(2)}`}
121
124
  </OriginalPrice>
122
125
  )}
123
126
  {(item.currency as string) === 'DC' ? (
@@ -131,7 +134,7 @@ export const StoreItemRow: React.FC<IStoreItemRowProps> = ({
131
134
  </ItemPrice>
132
135
  ) : (
133
136
  <ItemPrice $onSale={originalPrice != null} style={{ display: 'flex', alignItems: 'center', gap: '2px' }}>
134
- ${item.price.toFixed(2)}
137
+ {currencySymbol}{((item as any).regionalPrice ?? item.price).toFixed(2)}
135
138
  {(item as any).dcPrice ? (
136
139
  <>
137
140
  <span style={{ margin: '0 4px' }}>·</span>
@@ -138,7 +138,7 @@ export const useStoreCart = (): IUseStoreCart => {
138
138
  const getTotalPrice = () =>
139
139
  Number(
140
140
  cartItems
141
- .reduce((sum, item) => sum + item.item.price * item.quantity, 0)
141
+ .reduce((sum, item) => sum + (((item.item as any).regionalPrice ?? item.item.price) * item.quantity), 0)
142
142
  .toFixed(2)
143
143
  );
144
144
 
@@ -177,4 +177,3 @@ function uuidv4(): string {
177
177
  return v.toString(16);
178
178
  });
179
179
  }
180
-
@@ -31,6 +31,8 @@ interface IStoreItemsSectionProps {
31
31
  onItemView?: (item: IProductBlueprint, position: number) => void;
32
32
  /** Fires when the category filter changes. Passes new category and item count. */
33
33
  onCategoryChange?: (category: string, itemsShown: number) => void;
34
+ /** Currency symbol to display (e.g. "$" for USD, "R$" for BRL). Defaults to "$". */
35
+ currencySymbol?: string;
34
36
  }
35
37
 
36
38
  export const StoreItemsSection: React.FC<IStoreItemsSectionProps> = ({
@@ -44,6 +46,7 @@ export const StoreItemsSection: React.FC<IStoreItemsSectionProps> = ({
44
46
  itemBadges = {},
45
47
  onItemView,
46
48
  onCategoryChange,
49
+ currencySymbol = '$',
47
50
  }) => {
48
51
  const {
49
52
  searchQuery,
@@ -89,6 +92,7 @@ export const StoreItemsSection: React.FC<IStoreItemsSectionProps> = ({
89
92
  showTextInput
90
93
  onView={onItemView}
91
94
  positionInList={position}
95
+ currencySymbol={currencySymbol}
92
96
  {...meta}
93
97
  />
94
98
  );
@@ -105,6 +109,7 @@ export const StoreItemsSection: React.FC<IStoreItemsSectionProps> = ({
105
109
  userAccountType={userAccountType || UserAccountTypes.Free}
106
110
  onView={onItemView}
107
111
  positionInList={position}
112
+ currencySymbol={currencySymbol}
108
113
  {...meta}
109
114
  />
110
115
  );
@@ -21,6 +21,8 @@ interface IStorePacksSectionProps {
21
21
  packBadges?: Record<string, { badges?: IStoreBadge[]; buyCount?: number; viewersCount?: number; saleEndsAt?: string; originalPrice?: number }>;
22
22
  /** Fires once on mount per pack row — use for pack_viewed analytics. */
23
23
  onPackView?: (pack: IItemPack, position: number) => void;
24
+ /** Currency symbol to display (e.g. "$" for USD, "R$" for BRL). Defaults to "$". */
25
+ currencySymbol?: string;
24
26
  }
25
27
 
26
28
  interface IPackRowItemProps {
@@ -35,12 +37,14 @@ interface IPackRowItemProps {
35
37
  originalPrice?: number;
36
38
  onPackView?: (pack: IItemPack, position: number) => void;
37
39
  positionInList?: number;
40
+ currencySymbol?: string;
38
41
  }
39
42
 
40
43
  const PackRowItem: React.FC<IPackRowItemProps> = ({
41
44
  pack, onAddToCart, onQuickBuy, renderPackIcon,
42
45
  badges, buyCount, viewersCount, saleEndsAt, originalPrice,
43
46
  onPackView, positionInList = 0,
47
+ currencySymbol = '$',
44
48
  }) => {
45
49
  const { quantity, handleQuantityChange, handleBlur, incrementQuantity, decrementQuantity, resetQuantity } = useQuantityControl();
46
50
 
@@ -69,9 +73,9 @@ const PackRowItem: React.FC<IPackRowItemProps> = ({
69
73
  <PackName>{pack.title}</PackName>
70
74
  <PackPriceRow>
71
75
  {originalPrice != null && (
72
- <PackOriginalPrice>${originalPrice.toFixed(2)}</PackOriginalPrice>
76
+ <PackOriginalPrice>{currencySymbol}{originalPrice.toFixed(2)}</PackOriginalPrice>
73
77
  )}
74
- <PackPrice $onSale={originalPrice != null}>${pack.priceUSD}</PackPrice>
78
+ <PackPrice $onSale={originalPrice != null}>{currencySymbol}{pack.priceUSD}</PackPrice>
75
79
  </PackPriceRow>
76
80
  {pack.description && <PackDescription>{pack.description}</PackDescription>}
77
81
  <StoreBadges badges={badges} buyCount={buyCount} viewersCount={viewersCount} saleEndsAt={saleEndsAt} />
@@ -109,6 +113,7 @@ export const StorePacksSection: React.FC<IStorePacksSectionProps> = ({
109
113
  atlasIMG,
110
114
  packBadges = {},
111
115
  onPackView,
116
+ currencySymbol = '$',
112
117
  }) => {
113
118
  const { searchQuery, setSearchQuery, filteredPacks } = usePackFiltering(packs);
114
119
 
@@ -141,11 +146,12 @@ export const StorePacksSection: React.FC<IStorePacksSectionProps> = ({
141
146
  renderPackIcon={renderPackIcon}
142
147
  onPackView={onPackView}
143
148
  positionInList={position}
149
+ currencySymbol={currencySymbol}
144
150
  {...meta}
145
151
  />
146
152
  );
147
153
  },
148
- [onAddToCart, onQuickBuy, renderPackIcon, packBadges, onPackView, filteredPacks]
154
+ [onAddToCart, onQuickBuy, renderPackIcon, packBadges, onPackView, filteredPacks, currencySymbol]
149
155
  );
150
156
 
151
157
  return (
@@ -234,7 +234,7 @@ export const Default: Story = {
234
234
  console.log('Purchase details:', purchase);
235
235
  return Promise.resolve(true);
236
236
  }}
237
- customWalletContent={<DCWalletContent
237
+ customWalletContent={<DCWalletContent
238
238
  dcBalance={1200}
239
239
  historyData={{ transactions: [], totalPages: 1, currentPage: 1 }}
240
240
  historyLoading={false}
@@ -279,3 +279,288 @@ export const Default: Story = {
279
279
  />
280
280
  ),
281
281
  };
282
+
283
+ // Brazilian Real currency
284
+ export const BRL: Story = {
285
+ render: () => (
286
+ <Store
287
+ items={duplicatedItems}
288
+ packs={mockPacks}
289
+ userAccountType={UserAccountTypes.Free}
290
+ onPurchase={(purchase: Partial<IPurchase>) => {
291
+ console.log('Purchase details:', purchase);
292
+ return Promise.resolve(true);
293
+ }}
294
+ customWalletContent={<DCWalletContent
295
+ dcBalance={1200}
296
+ historyData={{ transactions: [], totalPages: 1, currentPage: 1 }}
297
+ historyLoading={false}
298
+ onRequestHistory={() => {}}
299
+ transferLoading={false}
300
+ transferResult={null}
301
+ onSendTransfer={() => {}}
302
+ onClearTransferResult={() => {}}
303
+ onBuyDC={() => console.log('Buy DC')}
304
+ />}
305
+ customHistoryContent={<DCHistoryPanel
306
+ transactions={[]}
307
+ totalPages={1}
308
+ currentPage={1}
309
+ loading={false}
310
+ onRequestHistory={() => {}}
311
+ />}
312
+ onClose={() => console.log('Store closed')}
313
+ atlasJSON={itemsAtlasJSON}
314
+ atlasIMG={itemsAtlasIMG}
315
+ hidePremiumTab={true}
316
+ tabOrder={['items', 'packs']}
317
+ defaultActiveTab="packs"
318
+ textInputItemKeys={['original-greater-life-potion-2', 'original-angelic-sword-1', 'character-name-change']}
319
+ currencySymbol="R$"
320
+ onTabChange={(tab, count) => console.log('[tracking] tab_change', { tab, count })}
321
+ onCategoryChange={(category, count) => console.log('[tracking] category_change', { category, count })}
322
+ onItemView={(item, position) => console.log('[tracking] item_viewed', { key: item.key, position })}
323
+ onPackView={(pack, position) => console.log('[tracking] pack_viewed', { key: pack.key, position })}
324
+ onCartOpen={() => console.log('[tracking] cart_opened')}
325
+ onAddToCart={(item, qty) => console.log('[tracking] add_to_cart', { key: item.key, qty })}
326
+ onRemoveFromCart={(key) => console.log('[tracking] remove_from_cart', { key })}
327
+ onCheckoutStart={(items, total) => console.log('[tracking] checkout_start', { items, total })}
328
+ onPurchaseSuccess={(items, total) => console.log('[tracking] purchase_success', { items, total })}
329
+ onPurchaseError={(error) => console.log('[tracking] purchase_error', { error })}
330
+ itemBadges={{
331
+ 'original-greater-life-potion-0': { originalPrice: 15.00 },
332
+ 'character-name-change': { originalPrice: 15.00 },
333
+ 'skin-character-customization': { originalPrice: 20.00 },
334
+ 'starter-pack': { originalPrice: 9.99 }
335
+ }}
336
+ />
337
+ ),
338
+ };
339
+
340
+ // Euro currency
341
+ export const EUR: Story = {
342
+ render: () => (
343
+ <Store
344
+ items={duplicatedItems}
345
+ packs={mockPacks}
346
+ userAccountType={UserAccountTypes.Free}
347
+ onPurchase={(purchase: Partial<IPurchase>) => {
348
+ console.log('Purchase details:', purchase);
349
+ return Promise.resolve(true);
350
+ }}
351
+ customWalletContent={<DCWalletContent
352
+ dcBalance={1200}
353
+ historyData={{ transactions: [], totalPages: 1, currentPage: 1 }}
354
+ historyLoading={false}
355
+ onRequestHistory={() => {}}
356
+ transferLoading={false}
357
+ transferResult={null}
358
+ onSendTransfer={() => {}}
359
+ onClearTransferResult={() => {}}
360
+ onBuyDC={() => console.log('Buy DC')}
361
+ />}
362
+ customHistoryContent={<DCHistoryPanel
363
+ transactions={[]}
364
+ totalPages={1}
365
+ currentPage={1}
366
+ loading={false}
367
+ onRequestHistory={() => {}}
368
+ />}
369
+ onClose={() => console.log('Store closed')}
370
+ atlasJSON={itemsAtlasJSON}
371
+ atlasIMG={itemsAtlasIMG}
372
+ hidePremiumTab={true}
373
+ tabOrder={['items', 'packs']}
374
+ defaultActiveTab="packs"
375
+ textInputItemKeys={['original-greater-life-potion-2', 'original-angelic-sword-1', 'character-name-change']}
376
+ currencySymbol="€"
377
+ onTabChange={(tab, count) => console.log('[tracking] tab_change', { tab, count })}
378
+ onCategoryChange={(category, count) => console.log('[tracking] category_change', { category, count })}
379
+ onItemView={(item, position) => console.log('[tracking] item_viewed', { key: item.key, position })}
380
+ onPackView={(pack, position) => console.log('[tracking] pack_viewed', { key: pack.key, position })}
381
+ onCartOpen={() => console.log('[tracking] cart_opened')}
382
+ onAddToCart={(item, qty) => console.log('[tracking] add_to_cart', { key: item.key, qty })}
383
+ onRemoveFromCart={(key) => console.log('[tracking] remove_from_cart', { key })}
384
+ onCheckoutStart={(items, total) => console.log('[tracking] checkout_start', { items, total })}
385
+ onPurchaseSuccess={(items, total) => console.log('[tracking] purchase_success', { items, total })}
386
+ onPurchaseError={(error) => console.log('[tracking] purchase_error', { error })}
387
+ itemBadges={{
388
+ 'original-greater-life-potion-0': { originalPrice: 15.00 },
389
+ 'character-name-change': { originalPrice: 15.00 },
390
+ 'skin-character-customization': { originalPrice: 20.00 },
391
+ 'starter-pack': { originalPrice: 9.99 }
392
+ }}
393
+ />
394
+ ),
395
+ };
396
+
397
+ // British Pound currency
398
+ export const GBP: Story = {
399
+ render: () => (
400
+ <Store
401
+ items={duplicatedItems}
402
+ packs={mockPacks}
403
+ userAccountType={UserAccountTypes.Free}
404
+ onPurchase={(purchase: Partial<IPurchase>) => {
405
+ console.log('Purchase details:', purchase);
406
+ return Promise.resolve(true);
407
+ }}
408
+ customWalletContent={<DCWalletContent
409
+ dcBalance={1200}
410
+ historyData={{ transactions: [], totalPages: 1, currentPage: 1 }}
411
+ historyLoading={false}
412
+ onRequestHistory={() => {}}
413
+ transferLoading={false}
414
+ transferResult={null}
415
+ onSendTransfer={() => {}}
416
+ onClearTransferResult={() => {}}
417
+ onBuyDC={() => console.log('Buy DC')}
418
+ />}
419
+ customHistoryContent={<DCHistoryPanel
420
+ transactions={[]}
421
+ totalPages={1}
422
+ currentPage={1}
423
+ loading={false}
424
+ onRequestHistory={() => {}}
425
+ />}
426
+ onClose={() => console.log('Store closed')}
427
+ atlasJSON={itemsAtlasJSON}
428
+ atlasIMG={itemsAtlasIMG}
429
+ hidePremiumTab={true}
430
+ tabOrder={['items', 'packs']}
431
+ defaultActiveTab="packs"
432
+ textInputItemKeys={['original-greater-life-potion-2', 'original-angelic-sword-1', 'character-name-change']}
433
+ currencySymbol="£"
434
+ onTabChange={(tab, count) => console.log('[tracking] tab_change', { tab, count })}
435
+ onCategoryChange={(category, count) => console.log('[tracking] category_change', { category, count })}
436
+ onItemView={(item, position) => console.log('[tracking] item_viewed', { key: item.key, position })}
437
+ onPackView={(pack, position) => console.log('[tracking] pack_viewed', { key: pack.key, position })}
438
+ onCartOpen={() => console.log('[tracking] cart_opened')}
439
+ onAddToCart={(item, qty) => console.log('[tracking] add_to_cart', { key: item.key, qty })}
440
+ onRemoveFromCart={(key) => console.log('[tracking] remove_from_cart', { key })}
441
+ onCheckoutStart={(items, total) => console.log('[tracking] checkout_start', { items, total })}
442
+ onPurchaseSuccess={(items, total) => console.log('[tracking] purchase_success', { items, total })}
443
+ onPurchaseError={(error) => console.log('[tracking] purchase_error', { error })}
444
+ itemBadges={{
445
+ 'original-greater-life-potion-0': { originalPrice: 15.00 },
446
+ 'character-name-change': { originalPrice: 15.00 },
447
+ 'skin-character-customization': { originalPrice: 20.00 },
448
+ 'starter-pack': { originalPrice: 9.99 }
449
+ }}
450
+ />
451
+ ),
452
+ };
453
+
454
+ // Japanese Yen currency
455
+ export const JPY: Story = {
456
+ render: () => (
457
+ <Store
458
+ items={duplicatedItems}
459
+ packs={mockPacks}
460
+ userAccountType={UserAccountTypes.Free}
461
+ onPurchase={(purchase: Partial<IPurchase>) => {
462
+ console.log('Purchase details:', purchase);
463
+ return Promise.resolve(true);
464
+ }}
465
+ customWalletContent={<DCWalletContent
466
+ dcBalance={1200}
467
+ historyData={{ transactions: [], totalPages: 1, currentPage: 1 }}
468
+ historyLoading={false}
469
+ onRequestHistory={() => {}}
470
+ transferLoading={false}
471
+ transferResult={null}
472
+ onSendTransfer={() => {}}
473
+ onClearTransferResult={() => {}}
474
+ onBuyDC={() => console.log('Buy DC')}
475
+ />}
476
+ customHistoryContent={<DCHistoryPanel
477
+ transactions={[]}
478
+ totalPages={1}
479
+ currentPage={1}
480
+ loading={false}
481
+ onRequestHistory={() => {}}
482
+ />}
483
+ onClose={() => console.log('Store closed')}
484
+ atlasJSON={itemsAtlasJSON}
485
+ atlasIMG={itemsAtlasIMG}
486
+ hidePremiumTab={true}
487
+ tabOrder={['items', 'packs']}
488
+ defaultActiveTab="packs"
489
+ textInputItemKeys={['original-greater-life-potion-2', 'original-angelic-sword-1', 'character-name-change']}
490
+ currencySymbol="¥"
491
+ onTabChange={(tab, count) => console.log('[tracking] tab_change', { tab, count })}
492
+ onCategoryChange={(category, count) => console.log('[tracking] category_change', { category, count })}
493
+ onItemView={(item, position) => console.log('[tracking] item_viewed', { key: item.key, position })}
494
+ onPackView={(pack, position) => console.log('[tracking] pack_viewed', { key: pack.key, position })}
495
+ onCartOpen={() => console.log('[tracking] cart_opened')}
496
+ onAddToCart={(item, qty) => console.log('[tracking] add_to_cart', { key: item.key, qty })}
497
+ onRemoveFromCart={(key) => console.log('[tracking] remove_from_cart', { key })}
498
+ onCheckoutStart={(items, total) => console.log('[tracking] checkout_start', { items, total })}
499
+ onPurchaseSuccess={(items, total) => console.log('[tracking] purchase_success', { items, total })}
500
+ onPurchaseError={(error) => console.log('[tracking] purchase_error', { error })}
501
+ itemBadges={{
502
+ 'original-greater-life-potion-0': { originalPrice: 15.00 },
503
+ 'character-name-change': { originalPrice: 15.00 },
504
+ 'skin-character-customization': { originalPrice: 20.00 },
505
+ 'starter-pack': { originalPrice: 9.99 }
506
+ }}
507
+ />
508
+ ),
509
+ };
510
+
511
+ // Indian Rupee currency
512
+ export const INR: Story = {
513
+ render: () => (
514
+ <Store
515
+ items={duplicatedItems}
516
+ packs={mockPacks}
517
+ userAccountType={UserAccountTypes.Free}
518
+ onPurchase={(purchase: Partial<IPurchase>) => {
519
+ console.log('Purchase details:', purchase);
520
+ return Promise.resolve(true);
521
+ }}
522
+ customWalletContent={<DCWalletContent
523
+ dcBalance={1200}
524
+ historyData={{ transactions: [], totalPages: 1, currentPage: 1 }}
525
+ historyLoading={false}
526
+ onRequestHistory={() => {}}
527
+ transferLoading={false}
528
+ transferResult={null}
529
+ onSendTransfer={() => {}}
530
+ onClearTransferResult={() => {}}
531
+ onBuyDC={() => console.log('Buy DC')}
532
+ />}
533
+ customHistoryContent={<DCHistoryPanel
534
+ transactions={[]}
535
+ totalPages={1}
536
+ currentPage={1}
537
+ loading={false}
538
+ onRequestHistory={() => {}}
539
+ />}
540
+ onClose={() => console.log('Store closed')}
541
+ atlasJSON={itemsAtlasJSON}
542
+ atlasIMG={itemsAtlasIMG}
543
+ hidePremiumTab={true}
544
+ tabOrder={['items', 'packs']}
545
+ defaultActiveTab="packs"
546
+ textInputItemKeys={['original-greater-life-potion-2', 'original-angelic-sword-1', 'character-name-change']}
547
+ currencySymbol="₹"
548
+ onTabChange={(tab, count) => console.log('[tracking] tab_change', { tab, count })}
549
+ onCategoryChange={(category, count) => console.log('[tracking] category_change', { category, count })}
550
+ onItemView={(item, position) => console.log('[tracking] item_viewed', { key: item.key, position })}
551
+ onPackView={(pack, position) => console.log('[tracking] pack_viewed', { key: pack.key, position })}
552
+ onCartOpen={() => console.log('[tracking] cart_opened')}
553
+ onAddToCart={(item, qty) => console.log('[tracking] add_to_cart', { key: item.key, qty })}
554
+ onRemoveFromCart={(key) => console.log('[tracking] remove_from_cart', { key })}
555
+ onCheckoutStart={(items, total) => console.log('[tracking] checkout_start', { items, total })}
556
+ onPurchaseSuccess={(items, total) => console.log('[tracking] purchase_success', { items, total })}
557
+ onPurchaseError={(error) => console.log('[tracking] purchase_error', { error })}
558
+ itemBadges={{
559
+ 'original-greater-life-potion-0': { originalPrice: 15.00 },
560
+ 'character-name-change': { originalPrice: 15.00 },
561
+ 'skin-character-customization': { originalPrice: 20.00 },
562
+ 'starter-pack': { originalPrice: 9.99 }
563
+ }}
564
+ />
565
+ ),
566
+ };