@rpg-engine/long-bow 0.8.156 → 0.8.157

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.156",
3
+ "version": "0.8.157",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "typings": "dist/index.d.ts",
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  import styled from 'styled-components';
3
3
  import { uiColors } from '../../constants/uiColors';
4
+ import { Dropdown, IOptionsProps } from '../Dropdown';
4
5
  import { Pagination } from '../shared/Pagination/Pagination';
5
6
 
6
7
  export interface IDCTransaction {
@@ -35,16 +36,16 @@ const TRANSACTION_TYPE_COLORS: Record<string, string> = {
35
36
  AdminAdjustment: '#9ca3af', // gray — admin
36
37
  };
37
38
 
38
- const TRANSACTION_TYPE_OPTIONS = [
39
- { value: '', label: 'All Types' },
40
- { value: 'Purchase', label: 'Purchase' },
41
- { value: 'Transfer', label: 'Transfer' },
42
- { value: 'MarketplaceSale', label: 'Marketplace Sale' },
43
- { value: 'MarketplacePurchase', label: 'Marketplace Buy' },
44
- { value: 'StorePurchase', label: 'Store Purchase' },
45
- { value: 'Fee', label: 'Fee' },
46
- { value: 'Refund', label: 'Refund' },
47
- { value: 'AdminAdjustment', label: 'Admin Adjustment' },
39
+ const TRANSACTION_TYPE_OPTIONS: IOptionsProps[] = [
40
+ { id: 1, value: '', option: 'All Types' },
41
+ { id: 2, value: 'Purchase', option: 'Purchase' },
42
+ { id: 3, value: 'Transfer', option: 'Transfer' },
43
+ { id: 4, value: 'MarketplaceSale', option: 'Marketplace Sale' },
44
+ { id: 5, value: 'MarketplacePurchase', option: 'Marketplace Buy' },
45
+ { id: 6, value: 'StorePurchase', option: 'Store Purchase' },
46
+ { id: 7, value: 'Fee', option: 'Fee' },
47
+ { id: 8, value: 'Refund', option: 'Refund' },
48
+ { id: 9, value: 'AdminAdjustment', option: 'Admin Adjustment' },
48
49
  ];
49
50
 
50
51
  export interface IDCHistoryPanelProps {
@@ -70,8 +71,7 @@ export const DCHistoryPanel: React.FC<IDCHistoryPanelProps> = ({
70
71
  // eslint-disable-next-line react-hooks/exhaustive-deps
71
72
  }, []);
72
73
 
73
- const handleTypeChange = (e: React.ChangeEvent<HTMLSelectElement>): void => {
74
- const value = e.target.value;
74
+ const handleTypeChange = (value: string): void => {
75
75
  setSelectedType(value);
76
76
  onRequestHistory(1, value || undefined);
77
77
  };
@@ -88,12 +88,13 @@ export const DCHistoryPanel: React.FC<IDCHistoryPanelProps> = ({
88
88
  return (
89
89
  <PanelContainer>
90
90
  <FilterRow>
91
- <FilterLabel>Filter:</FilterLabel>
92
- <TypeSelect value={selectedType} onChange={handleTypeChange}>
93
- {TRANSACTION_TYPE_OPTIONS.map((opt) => (
94
- <option key={opt.value} value={opt.value}>{opt.label}</option>
95
- ))}
96
- </TypeSelect>
91
+ <FilterLabel>FILTER BY TYPE</FilterLabel>
92
+ <StyledDropdown
93
+ key={selectedType}
94
+ options={TRANSACTION_TYPE_OPTIONS}
95
+ onChange={handleTypeChange}
96
+ width="100%"
97
+ />
97
98
  </FilterRow>
98
99
 
99
100
  {loading && (
@@ -154,42 +155,24 @@ const PanelContainer = styled.div`
154
155
  const FilterRow = styled.div`
155
156
  display: flex;
156
157
  align-items: center;
157
- gap: 8px;
158
- margin-bottom: 2px;
158
+ gap: 12px;
159
+ background: rgba(0, 0, 0, 0.15);
160
+ border-radius: 4px;
161
+ border: 1px solid rgba(255, 255, 255, 0.05);
162
+ padding: 8px 12px;
159
163
  `;
160
164
 
161
- const FilterLabel = styled.span`
162
- font-size: 7px;
163
- color: #f59e0b;
164
- font-family: 'Press Start 2P', cursive;
165
+ const FilterLabel = styled.p`
166
+ margin: 0;
167
+ font-size: 0.7rem;
168
+ color: #ccc;
169
+ text-transform: uppercase;
170
+ letter-spacing: 1px;
165
171
  white-space: nowrap;
166
172
  `;
167
173
 
168
- const TypeSelect = styled.select`
169
- background: rgba(0, 0, 0, 0.7);
170
- border: 1px solid rgba(245, 158, 11, 0.4);
171
- border-radius: 3px;
172
- color: #f59e0b;
173
- font-size: 7px;
174
- font-family: 'Press Start 2P', cursive;
175
- padding: 3px 5px;
176
- cursor: pointer;
177
- outline: none;
178
- flex: 1;
179
-
180
- option {
181
- background: #1a1a2e;
182
- color: #f59e0b;
183
- }
184
-
185
- &:hover {
186
- border-color: #f59e0b;
187
- }
188
-
189
- &:focus {
190
- border-color: #f59e0b;
191
- box-shadow: 0 0 0 1px rgba(245, 158, 11, 0.3);
192
- }
174
+ const StyledDropdown = styled(Dropdown)`
175
+ margin: 0px !important;
193
176
  `;
194
177
 
195
178
  const TransactionList = styled.div`
@@ -0,0 +1,183 @@
1
+ import React, { useState } from 'react';
2
+ import { FaShoppingCart } from 'react-icons/fa';
3
+ import styled from 'styled-components';
4
+ import { uiColors } from '../../constants/uiColors';
5
+ import { InternalTabs } from '../InternalTabs/InternalTabs';
6
+ import { DCHistoryPanel, IDCTransaction } from './DCHistoryPanel';
7
+ import { DCTransferPanel, IDCTransferCharacterResult } from './DCTransferPanel';
8
+
9
+ type WalletTabId = 'balance' | 'transfer' | 'history';
10
+
11
+ export interface IDCWalletContentProps {
12
+ dcBalance: number;
13
+ historyData: { transactions: IDCTransaction[]; totalPages: number; currentPage: number } | null;
14
+ historyLoading: boolean;
15
+ onRequestHistory: (page: number, type?: string) => void;
16
+ transferLoading: boolean;
17
+ transferResult: { success: boolean; message: string } | null;
18
+ onSendTransfer: (recipientName: string, amount: number) => void;
19
+ onClearTransferResult: () => void;
20
+ characterName?: string;
21
+ onInputFocus?: () => void;
22
+ onInputBlur?: () => void;
23
+ onBuyDC?: () => void;
24
+ onSearchCharacter?: (name: string) => void;
25
+ searchResults?: IDCTransferCharacterResult[];
26
+ }
27
+
28
+ export const DCWalletContent: React.FC<IDCWalletContentProps> = ({
29
+ dcBalance,
30
+ historyData,
31
+ historyLoading,
32
+ onRequestHistory,
33
+ transferLoading,
34
+ transferResult,
35
+ onSendTransfer,
36
+ onClearTransferResult,
37
+ characterName,
38
+ onInputFocus,
39
+ onInputBlur,
40
+ onBuyDC,
41
+ onSearchCharacter,
42
+ searchResults,
43
+ }) => {
44
+ const [activeTab, setActiveTab] = useState<WalletTabId>('balance');
45
+
46
+ const tabs = [
47
+ {
48
+ id: 'balance',
49
+ title: 'Balance',
50
+ content: (
51
+ <BalanceContent>
52
+ <BalanceLabel>Your DC Balance</BalanceLabel>
53
+ <BalanceAmount>{dcBalance.toLocaleString()} DC</BalanceAmount>
54
+ <DCHint>Spend on the Store, buy items on the Marketplace, or transfer to any player.</DCHint>
55
+ {onBuyDC && (
56
+ <BuyButton onPointerDown={onBuyDC} title="Buy Definya Coins">
57
+ <FaShoppingCart />
58
+ <BuyButtonLabel>Buy More DC</BuyButtonLabel>
59
+ </BuyButton>
60
+ )}
61
+ </BalanceContent>
62
+ ),
63
+ },
64
+ {
65
+ id: 'transfer',
66
+ title: 'Transfer',
67
+ content: (
68
+ <DCTransferPanel
69
+ dcBalance={dcBalance}
70
+ transferLoading={transferLoading}
71
+ transferResult={transferResult}
72
+ onSendTransfer={onSendTransfer}
73
+ onClearTransferResult={onClearTransferResult}
74
+ characterName={characterName}
75
+ onInputFocus={onInputFocus}
76
+ onInputBlur={onInputBlur}
77
+ onSearchCharacter={onSearchCharacter}
78
+ searchResults={searchResults}
79
+ />
80
+ ),
81
+ },
82
+ {
83
+ id: 'history',
84
+ title: 'History',
85
+ content: (
86
+ <DCHistoryPanel
87
+ transactions={historyData?.transactions ?? []}
88
+ totalPages={historyData?.totalPages ?? 0}
89
+ currentPage={historyData?.currentPage ?? 1}
90
+ loading={historyLoading}
91
+ onRequestHistory={onRequestHistory}
92
+ />
93
+ ),
94
+ },
95
+ ];
96
+
97
+ return (
98
+ <WalletContainer>
99
+ <InternalTabs
100
+ tabs={tabs}
101
+ activeTab={activeTab}
102
+ onTabChange={(tabId: string) => {
103
+ setActiveTab(tabId as WalletTabId);
104
+ if (tabId === 'history') {
105
+ onRequestHistory(1);
106
+ }
107
+ }}
108
+ activeTextColor="#000000"
109
+ activeColor="#fef08a"
110
+ inactiveColor="#6b7280"
111
+ borderColor="#f59e0b"
112
+ hoverColor="#fef3c7"
113
+ />
114
+ </WalletContainer>
115
+ );
116
+ };
117
+
118
+ const WalletContainer = styled.div`
119
+ display: flex;
120
+ flex-direction: column;
121
+ width: 100%;
122
+ min-height: 300px;
123
+ gap: 0.5rem;
124
+ `;
125
+
126
+ const BalanceContent = styled.div`
127
+ display: flex;
128
+ flex-direction: column;
129
+ align-items: center;
130
+ gap: 12px;
131
+ padding: 32px 16px;
132
+ `;
133
+
134
+ const BalanceLabel = styled.span`
135
+ font-family: 'Press Start 2P', cursive;
136
+ font-size: 10px;
137
+ color: ${uiColors.lightGray};
138
+ `;
139
+
140
+ const BalanceAmount = styled.div`
141
+ font-family: 'Press Start 2P', cursive;
142
+ font-size: 28px;
143
+ color: #fef08a;
144
+ text-shadow: 2px 2px 0 #000;
145
+ letter-spacing: 2px;
146
+ `;
147
+
148
+ const DCHint = styled.p`
149
+ margin: 0 !important;
150
+ font-family: 'Press Start 2P', cursive !important;
151
+ font-size: 8px !important;
152
+ color: rgba(255, 255, 255, 0.4) !important;
153
+ text-align: center !important;
154
+ line-height: 1.8 !important;
155
+ max-width: 280px;
156
+ `;
157
+
158
+ const BuyButton = styled.button`
159
+ display: flex;
160
+ align-items: center;
161
+ gap: 8px;
162
+ margin-top: 8px;
163
+ padding: 10px 20px;
164
+ background: #f59e0b;
165
+ border: none;
166
+ border-radius: 6px;
167
+ color: #000;
168
+ cursor: pointer;
169
+ font-size: 1rem;
170
+
171
+ &:hover {
172
+ background: #fbbf24;
173
+ }
174
+
175
+ &:active {
176
+ background: #d97706;
177
+ }
178
+ `;
179
+
180
+ const BuyButtonLabel = styled.span`
181
+ font-family: 'Press Start 2P', cursive;
182
+ font-size: 8px;
183
+ `;
@@ -1,51 +1,14 @@
1
- import React, { useCallback, useState } from 'react';
2
- import { FaShoppingCart, FaTimes } from 'react-icons/fa';
1
+ import React, { useCallback } from 'react';
2
+ import { FaTimes } from 'react-icons/fa';
3
3
  import styled from 'styled-components';
4
- import { uiColors } from '../../constants/uiColors';
5
4
  import ModalPortal from '../Abstractions/ModalPortal';
6
- import { InternalTabs } from '../InternalTabs/InternalTabs';
7
- import { DCHistoryPanel, IDCTransaction } from './DCHistoryPanel';
8
- import { DCTransferPanel, IDCTransferCharacterResult } from './DCTransferPanel';
5
+ import { DCWalletContent, IDCWalletContentProps } from './DCWalletContent';
9
6
 
10
- type WalletTabId = 'balance' | 'transfer' | 'history';
11
-
12
- export interface IDCWalletModalProps {
13
- dcBalance: number;
7
+ export interface IDCWalletModalProps extends IDCWalletContentProps {
14
8
  onClose: () => void;
15
- historyData: { transactions: IDCTransaction[]; totalPages: number; currentPage: number } | null;
16
- historyLoading: boolean;
17
- onRequestHistory: (page: number, type?: string) => void;
18
- transferLoading: boolean;
19
- transferResult: { success: boolean; message: string } | null;
20
- onSendTransfer: (recipientName: string, amount: number) => void;
21
- onClearTransferResult: () => void;
22
- characterName?: string;
23
- onInputFocus?: () => void;
24
- onInputBlur?: () => void;
25
- onBuyDC?: () => void;
26
- onSearchCharacter?: (name: string) => void;
27
- searchResults?: IDCTransferCharacterResult[];
28
9
  }
29
10
 
30
- export const DCWalletModal: React.FC<IDCWalletModalProps> = ({
31
- dcBalance,
32
- onClose,
33
- historyData,
34
- historyLoading,
35
- onRequestHistory,
36
- transferLoading,
37
- transferResult,
38
- onSendTransfer,
39
- onClearTransferResult,
40
- characterName,
41
- onInputFocus,
42
- onInputBlur,
43
- onBuyDC,
44
- onSearchCharacter,
45
- searchResults,
46
- }) => {
47
- const [activeTab, setActiveTab] = useState<WalletTabId>('balance');
48
-
11
+ export const DCWalletModal: React.FC<IDCWalletModalProps> = ({ onClose, ...contentProps }) => {
49
12
  const stopPropagation = useCallback(
50
13
  (e: React.MouseEvent | React.TouchEvent | React.PointerEvent) => {
51
14
  e.stopPropagation();
@@ -53,56 +16,6 @@ export const DCWalletModal: React.FC<IDCWalletModalProps> = ({
53
16
  []
54
17
  );
55
18
 
56
- const tabs = [
57
- {
58
- id: 'balance',
59
- title: 'Balance',
60
- content: (
61
- <BalanceContent>
62
- <BalanceLabel>Your DC Balance</BalanceLabel>
63
- <BalanceAmount>{dcBalance.toLocaleString()} DC</BalanceAmount>
64
- {onBuyDC && (
65
- <BuyButton onPointerDown={onBuyDC} title="Buy Definya Coins">
66
- <FaShoppingCart />
67
- <BuyButtonLabel>Buy More DC</BuyButtonLabel>
68
- </BuyButton>
69
- )}
70
- </BalanceContent>
71
- ),
72
- },
73
- {
74
- id: 'transfer',
75
- title: 'Transfer',
76
- content: (
77
- <DCTransferPanel
78
- dcBalance={dcBalance}
79
- transferLoading={transferLoading}
80
- transferResult={transferResult}
81
- onSendTransfer={onSendTransfer}
82
- onClearTransferResult={onClearTransferResult}
83
- characterName={characterName}
84
- onInputFocus={onInputFocus}
85
- onInputBlur={onInputBlur}
86
- onSearchCharacter={onSearchCharacter}
87
- searchResults={searchResults}
88
- />
89
- ),
90
- },
91
- {
92
- id: 'history',
93
- title: 'History',
94
- content: (
95
- <DCHistoryPanel
96
- transactions={historyData?.transactions ?? []}
97
- totalPages={historyData?.totalPages ?? 0}
98
- currentPage={historyData?.currentPage ?? 1}
99
- loading={historyLoading}
100
- onRequestHistory={onRequestHistory}
101
- />
102
- ),
103
- },
104
- ];
105
-
106
19
  return (
107
20
  <ModalPortal>
108
21
  <Overlay onPointerDown={onClose} />
@@ -119,23 +32,7 @@ export const DCWalletModal: React.FC<IDCWalletModalProps> = ({
119
32
  </CloseButton>
120
33
  </Header>
121
34
 
122
- <WalletContainer>
123
- <InternalTabs
124
- tabs={tabs}
125
- activeTab={activeTab}
126
- onTabChange={(tabId: string) => {
127
- setActiveTab(tabId as WalletTabId);
128
- if (tabId === 'history') {
129
- onRequestHistory(1);
130
- }
131
- }}
132
- activeTextColor="#000000"
133
- activeColor="#fef08a"
134
- inactiveColor="#6b7280"
135
- borderColor="#f59e0b"
136
- hoverColor="#fef3c7"
137
- />
138
- </WalletContainer>
35
+ <DCWalletContent {...contentProps} />
139
36
  </ModalContent>
140
37
  </ModalContainer>
141
38
  </ModalPortal>
@@ -205,60 +102,3 @@ const CloseButton = styled.button`
205
102
  color: #ffffff;
206
103
  }
207
104
  `;
208
-
209
- const WalletContainer = styled.div`
210
- display: flex;
211
- flex-direction: column;
212
- width: 100%;
213
- min-height: 300px;
214
- gap: 0.5rem;
215
- `;
216
-
217
- const BalanceContent = styled.div`
218
- display: flex;
219
- flex-direction: column;
220
- align-items: center;
221
- gap: 12px;
222
- padding: 32px 16px;
223
- `;
224
-
225
- const BalanceLabel = styled.span`
226
- font-family: 'Press Start 2P', cursive;
227
- font-size: 10px;
228
- color: ${uiColors.lightGray};
229
- `;
230
-
231
- const BalanceAmount = styled.div`
232
- font-family: 'Press Start 2P', cursive;
233
- font-size: 28px;
234
- color: #fef08a;
235
- text-shadow: 2px 2px 0 #000;
236
- letter-spacing: 2px;
237
- `;
238
-
239
- const BuyButton = styled.button`
240
- display: flex;
241
- align-items: center;
242
- gap: 8px;
243
- margin-top: 8px;
244
- padding: 10px 20px;
245
- background: #f59e0b;
246
- border: none;
247
- border-radius: 6px;
248
- color: #000;
249
- cursor: pointer;
250
- font-size: 1rem;
251
-
252
- &:hover {
253
- background: #fbbf24;
254
- }
255
-
256
- &:active {
257
- background: #d97706;
258
- }
259
- `;
260
-
261
- const BuyButtonLabel = styled.span`
262
- font-family: 'Press Start 2P', cursive;
263
- font-size: 8px;
264
- `;
@@ -12,12 +12,14 @@ import { Settings2 } from 'pixelarticons/react/Settings2';
12
12
  import { ShoppingBag } from 'pixelarticons/react/ShoppingBag';
13
13
  import { ShoppingCart } from 'pixelarticons/react/ShoppingCart';
14
14
  import { Store } from 'pixelarticons/react/Store';
15
+ import { Wallet } from 'pixelarticons/react/Wallet';
15
16
  import React, { useState } from 'react';
16
17
  import styled from 'styled-components';
17
18
  import { DraggableContainer } from '../DraggableContainer';
18
19
  import { Pager } from '../Pager';
19
20
  import { RPGUIContainerTypes } from '../RPGUI/RPGUIContainer';
20
21
  import { Tabs } from '../shared/Tabs';
22
+ import { DCWalletContent, IDCWalletContentProps } from '../DCWallet/DCWalletContent';
21
23
  import { BlueprintSearchModal } from './BlueprintSearchModal';
22
24
  import { BuyOrderPanel } from './BuyOrderPanel';
23
25
  import { BuyPanel } from './BuyPanel';
@@ -104,9 +106,12 @@ export interface IMarketPlaceProps {
104
106
  historySelectedType?: string;
105
107
  onHistoryTypeChange?: (type: string) => void;
106
108
  onHistoryPageChange?: (page: number) => void;
109
+
110
+ // Wallet tab
111
+ walletProps?: IDCWalletContentProps;
107
112
  }
108
113
 
109
- type ActiveTab = 'marketplace' | 'sell' | 'buy-orders' | 'history' | 'settings';
114
+ type ActiveTab = 'marketplace' | 'sell' | 'buy-orders' | 'history' | 'wallet' | 'settings';
110
115
 
111
116
  export const Marketplace: React.FC<IMarketPlaceProps> = props => {
112
117
  const {
@@ -146,6 +151,8 @@ export const Marketplace: React.FC<IMarketPlaceProps> = props => {
146
151
  historySelectedType = 'All',
147
152
  onHistoryTypeChange,
148
153
  onHistoryPageChange,
154
+ // Wallet
155
+ walletProps,
149
156
  } = props;
150
157
 
151
158
  const [activeTab, setActiveTab] = useState<ActiveTab>('marketplace');
@@ -204,6 +211,15 @@ export const Marketplace: React.FC<IMarketPlaceProps> = props => {
204
211
  label: 'History',
205
212
  icon: <Clock width={18} height={18} />,
206
213
  },
214
+ ...(walletProps
215
+ ? [
216
+ {
217
+ id: 'wallet',
218
+ label: 'Wallet',
219
+ icon: <Wallet width={18} height={18} />,
220
+ },
221
+ ]
222
+ : []),
207
223
  {
208
224
  id: 'settings',
209
225
  label: 'Settings',
@@ -277,6 +293,10 @@ export const Marketplace: React.FC<IMarketPlaceProps> = props => {
277
293
  />
278
294
  )}
279
295
 
296
+ {activeTab === 'wallet' && walletProps && (
297
+ <DCWalletContent {...walletProps} />
298
+ )}
299
+
280
300
  {activeTab === 'settings' && (
281
301
  <MarketplaceSettingsPanel
282
302
  acceptedCurrency={acceptedCurrency}
@@ -32,7 +32,7 @@ export const Tabs: React.FC<ITabsProps> = ({ options, activeTabId, onTabChange,
32
32
 
33
33
  const TabsContainer = styled.div`
34
34
  display: flex;
35
- gap: 15px;
35
+ gap: 10px;
36
36
  width: 95%;
37
37
  margin: 0 auto 15px auto;
38
38
  border-bottom: 2px solid rgba(255, 255, 255, 0.1);
@@ -42,18 +42,19 @@ const TabsContainer = styled.div`
42
42
  const TabButton = styled.button<{ $active: boolean }>`
43
43
  display: flex;
44
44
  align-items: center;
45
- gap: 8px;
45
+ gap: 5px;
46
46
  background: transparent;
47
47
  border: none;
48
48
  border-bottom: ${({ $active }) => ($active ? '3px solid #f59e0b' : '3px solid transparent')};
49
49
  color: ${({ $active }) => ($active ? '#ffffff' : '#888888')};
50
50
  font-family: 'Press Start 2P', cursive;
51
- font-size: 0.70rem;
52
- letter-spacing: 1px;
51
+ font-size: 0.60rem;
52
+ letter-spacing: 0.5px;
53
53
  cursor: pointer;
54
- padding: 5px 10px 10px 10px;
54
+ padding: 5px 7px 10px 7px;
55
55
  transition: color 0.2s, border-bottom 0.2s;
56
-
56
+ white-space: nowrap;
57
+
57
58
  &:hover {
58
59
  color: #ffffff;
59
60
  }
package/src/index.tsx CHANGED
@@ -11,6 +11,7 @@ export * from './components/CheckItem';
11
11
  export * from './components/CircularController/CircularController';
12
12
  export * from './components/CraftBook/CraftBook';
13
13
  export * from './components/DailyTasks/DailyTasks';
14
+ export * from './components/DCWallet/DCWalletContent';
14
15
  export * from './components/DCWallet/DCWalletModal';
15
16
  export * from './components/LoginStreak/LoginStreakPanel';
16
17
  export * from './components/DPad/JoystickDPad';
@@ -188,6 +188,31 @@ const Template: Story = () => {
188
188
  onHistoryTypeChange={setHistoryType}
189
189
  onHistoryPageChange={p => console.log('history page:', p)}
190
190
  onActiveTabChange={tab => console.log('tab changed:', tab)}
191
+ // Wallet tab
192
+ walletProps={{
193
+ dcBalance: 150,
194
+ historyData: {
195
+ transactions: [
196
+ { _id: 'tx-1', type: 'Purchase', amount: 100, balanceAfter: 150, createdAt: new Date(Date.now() - 1 * 86400000).toISOString() },
197
+ { _id: 'tx-2', type: 'Transfer', amount: -25, balanceAfter: 50, relatedCharacterName: 'DarkKnight42', createdAt: new Date(Date.now() - 2 * 86400000).toISOString() },
198
+ { _id: 'tx-3', type: 'MarketplaceSale', amount: 10, balanceAfter: 75, note: 'Angelic Sword', createdAt: new Date(Date.now() - 3 * 86400000).toISOString() },
199
+ { _id: 'tx-4', type: 'StorePurchase', amount: -50, balanceAfter: 65, createdAt: new Date(Date.now() - 5 * 86400000).toISOString() },
200
+ { _id: 'tx-5', type: 'Fee', amount: -2, balanceAfter: 115, createdAt: new Date(Date.now() - 7 * 86400000).toISOString() },
201
+ ],
202
+ totalPages: 1,
203
+ currentPage: 1,
204
+ },
205
+ historyLoading: false,
206
+ onRequestHistory: (page, type) => console.log('wallet history:', page, type),
207
+ transferLoading: false,
208
+ transferResult: null,
209
+ onSendTransfer: (name, amount) => console.log('transfer:', name, amount),
210
+ onClearTransferResult: () => console.log('clear transfer result'),
211
+ characterName: 'HeroPlayer',
212
+ onBuyDC: () => console.log('buy DC'),
213
+ onSearchCharacter: (name) => console.log('search character:', name),
214
+ searchResults: [],
215
+ }}
191
216
  />
192
217
  </RPGUIRoot>
193
218
  );