@rpg-engine/long-bow 0.8.136 → 0.8.137
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/dist/components/DCWallet/DCTransferPanel.d.ts +6 -0
- package/dist/components/DCWallet/DCWalletModal.d.ts +4 -0
- package/dist/long-bow.cjs.development.js +147 -69
- package/dist/long-bow.cjs.development.js.map +1 -1
- package/dist/long-bow.cjs.production.min.js +1 -1
- package/dist/long-bow.cjs.production.min.js.map +1 -1
- package/dist/long-bow.esm.js +148 -70
- package/dist/long-bow.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/components/DCWallet/DCHistoryPanel.tsx +116 -66
- package/src/components/DCWallet/DCTransferPanel.tsx +102 -10
- package/src/components/DCWallet/DCWalletModal.tsx +46 -7
package/package.json
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
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';
|
|
5
4
|
import { Pagination } from '../shared/Pagination/Pagination';
|
|
6
5
|
|
|
7
6
|
export interface IDCTransaction {
|
|
@@ -17,24 +16,24 @@ export interface IDCTransaction {
|
|
|
17
16
|
const TRANSACTION_TYPE_LABELS: Record<string, string> = {
|
|
18
17
|
Purchase: 'Purchase',
|
|
19
18
|
Transfer: 'Transfer',
|
|
20
|
-
MarketplaceSale: '
|
|
21
|
-
MarketplacePurchase: '
|
|
22
|
-
StorePurchase: 'Store
|
|
19
|
+
MarketplaceSale: 'Mkt Sale',
|
|
20
|
+
MarketplacePurchase: 'Mkt Buy',
|
|
21
|
+
StorePurchase: 'Store',
|
|
23
22
|
Fee: 'Fee',
|
|
24
23
|
Refund: 'Refund',
|
|
25
|
-
AdminAdjustment: 'Admin
|
|
24
|
+
AdminAdjustment: 'Admin',
|
|
26
25
|
};
|
|
27
26
|
|
|
28
|
-
const TRANSACTION_TYPE_OPTIONS
|
|
29
|
-
{
|
|
30
|
-
{
|
|
31
|
-
{
|
|
32
|
-
{
|
|
33
|
-
{
|
|
34
|
-
{
|
|
35
|
-
{
|
|
36
|
-
{
|
|
37
|
-
{
|
|
27
|
+
const TRANSACTION_TYPE_OPTIONS = [
|
|
28
|
+
{ value: '', label: 'All Types' },
|
|
29
|
+
{ value: 'Purchase', label: 'Purchase' },
|
|
30
|
+
{ value: 'Transfer', label: 'Transfer' },
|
|
31
|
+
{ value: 'MarketplaceSale', label: 'Marketplace Sale' },
|
|
32
|
+
{ value: 'MarketplacePurchase', label: 'Marketplace Buy' },
|
|
33
|
+
{ value: 'StorePurchase', label: 'Store Purchase' },
|
|
34
|
+
{ value: 'Fee', label: 'Fee' },
|
|
35
|
+
{ value: 'Refund', label: 'Refund' },
|
|
36
|
+
{ value: 'AdminAdjustment', label: 'Admin Adjustment' },
|
|
38
37
|
];
|
|
39
38
|
|
|
40
39
|
export interface IDCHistoryPanelProps {
|
|
@@ -54,7 +53,14 @@ export const DCHistoryPanel: React.FC<IDCHistoryPanelProps> = ({
|
|
|
54
53
|
}) => {
|
|
55
54
|
const [selectedType, setSelectedType] = React.useState<string>('');
|
|
56
55
|
|
|
57
|
-
|
|
56
|
+
// Auto-load on first mount (when History tab is opened)
|
|
57
|
+
React.useEffect(() => {
|
|
58
|
+
onRequestHistory(1);
|
|
59
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
60
|
+
}, []);
|
|
61
|
+
|
|
62
|
+
const handleTypeChange = (e: React.ChangeEvent<HTMLSelectElement>): void => {
|
|
63
|
+
const value = e.target.value;
|
|
58
64
|
setSelectedType(value);
|
|
59
65
|
onRequestHistory(1, value || undefined);
|
|
60
66
|
};
|
|
@@ -65,15 +71,18 @@ export const DCHistoryPanel: React.FC<IDCHistoryPanelProps> = ({
|
|
|
65
71
|
|
|
66
72
|
const formatDate = (dateStr: string): string => {
|
|
67
73
|
const d = new Date(dateStr);
|
|
68
|
-
|
|
69
|
-
return `${months[d.getMonth()]} ${d.getDate()}, ${d.getFullYear()}`;
|
|
74
|
+
return `${d.getMonth() + 1}/${d.getDate()}/${String(d.getFullYear()).slice(-2)}`;
|
|
70
75
|
};
|
|
71
76
|
|
|
72
77
|
return (
|
|
73
78
|
<PanelContainer>
|
|
74
79
|
<FilterRow>
|
|
75
80
|
<FilterLabel>Filter:</FilterLabel>
|
|
76
|
-
<
|
|
81
|
+
<TypeSelect value={selectedType} onChange={handleTypeChange}>
|
|
82
|
+
{TRANSACTION_TYPE_OPTIONS.map((opt) => (
|
|
83
|
+
<option key={opt.value} value={opt.value}>{opt.label}</option>
|
|
84
|
+
))}
|
|
85
|
+
</TypeSelect>
|
|
77
86
|
</FilterRow>
|
|
78
87
|
|
|
79
88
|
{loading && (
|
|
@@ -92,18 +101,20 @@ export const DCHistoryPanel: React.FC<IDCHistoryPanelProps> = ({
|
|
|
92
101
|
{transactions.map((tx) => {
|
|
93
102
|
const isCredit = tx.amount > 0;
|
|
94
103
|
const label = TRANSACTION_TYPE_LABELS[tx.type] ?? tx.type;
|
|
104
|
+
const subtitle = tx.note ?? (tx.relatedCharacterName ? tx.relatedCharacterName : '');
|
|
95
105
|
|
|
96
106
|
return (
|
|
97
107
|
<TransactionRow key={tx._id}>
|
|
98
|
-
<
|
|
99
|
-
|
|
100
|
-
{
|
|
101
|
-
</
|
|
102
|
-
<
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
108
|
+
<TxLeft>
|
|
109
|
+
<TxType>{label}</TxType>
|
|
110
|
+
{subtitle ? <TxNote>{subtitle}</TxNote> : null}
|
|
111
|
+
</TxLeft>
|
|
112
|
+
<TxRight>
|
|
113
|
+
<TxAmount $credit={isCredit}>
|
|
114
|
+
{isCredit ? '+' : ''}{tx.amount} DC
|
|
115
|
+
</TxAmount>
|
|
116
|
+
<TxDate>{formatDate(tx.createdAt)}</TxDate>
|
|
117
|
+
</TxRight>
|
|
107
118
|
</TransactionRow>
|
|
108
119
|
);
|
|
109
120
|
})}
|
|
@@ -132,76 +143,115 @@ const FilterRow = styled.div`
|
|
|
132
143
|
display: flex;
|
|
133
144
|
align-items: center;
|
|
134
145
|
gap: 8px;
|
|
135
|
-
margin-bottom:
|
|
146
|
+
margin-bottom: 2px;
|
|
136
147
|
`;
|
|
137
148
|
|
|
138
149
|
const FilterLabel = styled.span`
|
|
139
|
-
font-size:
|
|
150
|
+
font-size: 7px;
|
|
140
151
|
color: #f59e0b;
|
|
141
152
|
font-family: 'Press Start 2P', cursive;
|
|
142
153
|
white-space: nowrap;
|
|
143
154
|
`;
|
|
144
155
|
|
|
156
|
+
const TypeSelect = styled.select`
|
|
157
|
+
background: rgba(0, 0, 0, 0.7);
|
|
158
|
+
border: 1px solid rgba(245, 158, 11, 0.4);
|
|
159
|
+
border-radius: 3px;
|
|
160
|
+
color: #f59e0b;
|
|
161
|
+
font-size: 7px;
|
|
162
|
+
font-family: 'Press Start 2P', cursive;
|
|
163
|
+
padding: 3px 5px;
|
|
164
|
+
cursor: pointer;
|
|
165
|
+
outline: none;
|
|
166
|
+
flex: 1;
|
|
167
|
+
|
|
168
|
+
option {
|
|
169
|
+
background: #1a1a2e;
|
|
170
|
+
color: #f59e0b;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
&:hover {
|
|
174
|
+
border-color: #f59e0b;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
&:focus {
|
|
178
|
+
border-color: #f59e0b;
|
|
179
|
+
box-shadow: 0 0 0 1px rgba(245, 158, 11, 0.3);
|
|
180
|
+
}
|
|
181
|
+
`;
|
|
182
|
+
|
|
145
183
|
const TransactionList = styled.div`
|
|
146
184
|
display: flex;
|
|
147
185
|
flex-direction: column;
|
|
148
|
-
gap:
|
|
149
|
-
max-height:
|
|
186
|
+
gap: 3px;
|
|
187
|
+
max-height: 260px;
|
|
150
188
|
overflow-y: auto;
|
|
189
|
+
|
|
190
|
+
&::-webkit-scrollbar {
|
|
191
|
+
width: 4px;
|
|
192
|
+
}
|
|
193
|
+
&::-webkit-scrollbar-track {
|
|
194
|
+
background: rgba(0, 0, 0, 0.3);
|
|
195
|
+
}
|
|
196
|
+
&::-webkit-scrollbar-thumb {
|
|
197
|
+
background: rgba(245, 158, 11, 0.4);
|
|
198
|
+
border-radius: 2px;
|
|
199
|
+
}
|
|
151
200
|
`;
|
|
152
201
|
|
|
153
202
|
const TransactionRow = styled.div`
|
|
154
|
-
background: rgba(0, 0, 0, 0.
|
|
155
|
-
border: 1px solid rgba(
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
203
|
+
background: rgba(0, 0, 0, 0.35);
|
|
204
|
+
border: 1px solid rgba(245, 158, 11, 0.15);
|
|
205
|
+
border-radius: 2px;
|
|
206
|
+
padding: 5px 7px;
|
|
207
|
+
display: flex;
|
|
208
|
+
align-items: center;
|
|
209
|
+
gap: 8px;
|
|
210
|
+
`;
|
|
211
|
+
|
|
212
|
+
const TxLeft = styled.div`
|
|
213
|
+
flex: 1;
|
|
214
|
+
min-width: 0;
|
|
215
|
+
display: flex;
|
|
216
|
+
flex-direction: column;
|
|
217
|
+
gap: 2px;
|
|
218
|
+
`;
|
|
219
|
+
|
|
220
|
+
const TxRight = styled.div`
|
|
221
|
+
display: flex;
|
|
222
|
+
flex-direction: column;
|
|
223
|
+
align-items: flex-end;
|
|
160
224
|
gap: 2px;
|
|
225
|
+
flex-shrink: 0;
|
|
161
226
|
`;
|
|
162
227
|
|
|
163
228
|
const TxType = styled.span`
|
|
164
|
-
font-size:
|
|
229
|
+
font-size: 7px;
|
|
165
230
|
color: #f59e0b;
|
|
166
231
|
font-family: 'Press Start 2P', cursive;
|
|
167
|
-
grid-column: 1;
|
|
168
|
-
grid-row: 1;
|
|
169
232
|
`;
|
|
170
233
|
|
|
171
234
|
const TxAmount = styled.span<{ $credit: boolean }>`
|
|
172
|
-
font-size:
|
|
235
|
+
font-size: 8px;
|
|
173
236
|
font-family: 'Press Start 2P', cursive;
|
|
174
237
|
color: ${({ $credit }) => ($credit ? uiColors.green : uiColors.red)};
|
|
175
|
-
|
|
176
|
-
grid-column: 2;
|
|
177
|
-
grid-row: 1;
|
|
178
|
-
text-align: right;
|
|
238
|
+
white-space: nowrap;
|
|
179
239
|
`;
|
|
180
240
|
|
|
181
241
|
const TxNote = styled.span`
|
|
182
|
-
font-size:
|
|
242
|
+
font-size: 6px;
|
|
183
243
|
color: ${uiColors.lightGray};
|
|
184
244
|
font-family: 'Press Start 2P', cursive;
|
|
185
|
-
|
|
186
|
-
|
|
245
|
+
white-space: nowrap;
|
|
246
|
+
overflow: hidden;
|
|
247
|
+
text-overflow: ellipsis;
|
|
187
248
|
`;
|
|
188
249
|
|
|
189
250
|
const TxDate = styled.span`
|
|
190
|
-
font-size:
|
|
191
|
-
color:
|
|
251
|
+
font-size: 6px;
|
|
252
|
+
color: rgba(255, 255, 255, 0.4);
|
|
192
253
|
font-family: 'Press Start 2P', cursive;
|
|
193
|
-
|
|
194
|
-
grid-row: 2;
|
|
195
|
-
text-align: right;
|
|
196
|
-
`;
|
|
197
|
-
|
|
198
|
-
const TxBalance = styled.span`
|
|
199
|
-
font-size: 7px;
|
|
200
|
-
color: ${uiColors.white};
|
|
201
|
-
font-family: 'Press Start 2P', cursive;
|
|
202
|
-
grid-column: 1 / 3;
|
|
203
|
-
grid-row: 3;
|
|
204
|
-
opacity: 0.7;
|
|
254
|
+
white-space: nowrap;
|
|
205
255
|
`;
|
|
206
256
|
|
|
207
257
|
const LoadingRow = styled.div`
|
|
@@ -219,8 +269,8 @@ const Spinner = styled.div`
|
|
|
219
269
|
border: 3px solid rgba(255, 255, 255, 0.2);
|
|
220
270
|
border-radius: 50%;
|
|
221
271
|
border-top: 3px solid #f59e0b;
|
|
222
|
-
width:
|
|
223
|
-
height:
|
|
272
|
+
width: 16px;
|
|
273
|
+
height: 16px;
|
|
224
274
|
animation: spin 0.8s linear infinite;
|
|
225
275
|
|
|
226
276
|
@keyframes spin {
|
|
@@ -230,7 +280,7 @@ const Spinner = styled.div`
|
|
|
230
280
|
`;
|
|
231
281
|
|
|
232
282
|
const EmptyMessage = styled.div`
|
|
233
|
-
font-size:
|
|
283
|
+
font-size: 8px;
|
|
234
284
|
color: ${uiColors.lightGray};
|
|
235
285
|
font-family: 'Press Start 2P', cursive;
|
|
236
286
|
text-align: center;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { debounce } from 'lodash';
|
|
2
|
+
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
2
3
|
import { FaPaperPlane } from 'react-icons/fa';
|
|
3
4
|
import styled from 'styled-components';
|
|
4
5
|
import { uiColors } from '../../constants/uiColors';
|
|
@@ -6,6 +7,11 @@ import { ConfirmModal } from '../ConfirmModal';
|
|
|
6
7
|
import { Input } from '../Input';
|
|
7
8
|
import { CTAButton } from '../shared/CTAButton/CTAButton';
|
|
8
9
|
|
|
10
|
+
export interface IDCTransferCharacterResult {
|
|
11
|
+
_id: string;
|
|
12
|
+
name: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
9
15
|
export interface IDCTransferPanelProps {
|
|
10
16
|
dcBalance: number;
|
|
11
17
|
transferLoading: boolean;
|
|
@@ -15,6 +21,8 @@ export interface IDCTransferPanelProps {
|
|
|
15
21
|
characterName?: string;
|
|
16
22
|
onInputFocus?: () => void;
|
|
17
23
|
onInputBlur?: () => void;
|
|
24
|
+
onSearchCharacter?: (name: string) => void;
|
|
25
|
+
searchResults?: IDCTransferCharacterResult[];
|
|
18
26
|
}
|
|
19
27
|
|
|
20
28
|
export const DCTransferPanel: React.FC<IDCTransferPanelProps> = ({
|
|
@@ -26,13 +34,33 @@ export const DCTransferPanel: React.FC<IDCTransferPanelProps> = ({
|
|
|
26
34
|
characterName,
|
|
27
35
|
onInputFocus,
|
|
28
36
|
onInputBlur,
|
|
37
|
+
onSearchCharacter,
|
|
38
|
+
searchResults,
|
|
29
39
|
}) => {
|
|
30
40
|
const [recipientName, setRecipientName] = useState<string>('');
|
|
31
41
|
const [amount, setAmount] = useState<string>('');
|
|
32
42
|
const [validationError, setValidationError] = useState<string>('');
|
|
33
43
|
const [showConfirm, setShowConfirm] = useState<boolean>(false);
|
|
44
|
+
const [showDropdown, setShowDropdown] = useState<boolean>(false);
|
|
45
|
+
const dropdownRef = useRef<HTMLDivElement>(null);
|
|
34
46
|
const clearResultTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
35
47
|
|
|
48
|
+
const debouncedSearch = useMemo(
|
|
49
|
+
() =>
|
|
50
|
+
debounce((name: string) => {
|
|
51
|
+
if (name.trim().length >= 2) {
|
|
52
|
+
onSearchCharacter?.(name.trim());
|
|
53
|
+
}
|
|
54
|
+
}, 300),
|
|
55
|
+
[onSearchCharacter]
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
return () => {
|
|
60
|
+
debouncedSearch.cancel();
|
|
61
|
+
};
|
|
62
|
+
}, [debouncedSearch]);
|
|
63
|
+
|
|
36
64
|
useEffect(() => {
|
|
37
65
|
if (transferResult) {
|
|
38
66
|
if (clearResultTimerRef.current) {
|
|
@@ -93,15 +121,46 @@ export const DCTransferPanel: React.FC<IDCTransferPanelProps> = ({
|
|
|
93
121
|
return (
|
|
94
122
|
<PanelContainer>
|
|
95
123
|
<FieldLabel>Recipient Character Name</FieldLabel>
|
|
96
|
-
<
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
124
|
+
<AutocompleteWrapper ref={dropdownRef}>
|
|
125
|
+
<StyledInput
|
|
126
|
+
type="text"
|
|
127
|
+
value={recipientName}
|
|
128
|
+
onChange={(e) => {
|
|
129
|
+
setRecipientName(e.target.value);
|
|
130
|
+
debouncedSearch(e.target.value);
|
|
131
|
+
setShowDropdown(true);
|
|
132
|
+
}}
|
|
133
|
+
onFocus={() => {
|
|
134
|
+
onInputFocus?.();
|
|
135
|
+
if (recipientName.trim().length >= 2 && searchResults && searchResults.length > 0) {
|
|
136
|
+
setShowDropdown(true);
|
|
137
|
+
}
|
|
138
|
+
}}
|
|
139
|
+
onBlur={() => {
|
|
140
|
+
// Delay to allow dropdown click to register
|
|
141
|
+
setTimeout(() => setShowDropdown(false), 150);
|
|
142
|
+
onInputBlur?.();
|
|
143
|
+
}}
|
|
144
|
+
placeholder="Enter character name"
|
|
145
|
+
disabled={transferLoading}
|
|
146
|
+
autoComplete="off"
|
|
147
|
+
/>
|
|
148
|
+
{showDropdown && searchResults && searchResults.length > 0 && (
|
|
149
|
+
<DropdownList>
|
|
150
|
+
{searchResults.map((char) => (
|
|
151
|
+
<DropdownItem
|
|
152
|
+
key={char._id}
|
|
153
|
+
onPointerDown={() => {
|
|
154
|
+
setRecipientName(char.name);
|
|
155
|
+
setShowDropdown(false);
|
|
156
|
+
}}
|
|
157
|
+
>
|
|
158
|
+
{char.name}
|
|
159
|
+
</DropdownItem>
|
|
160
|
+
))}
|
|
161
|
+
</DropdownList>
|
|
162
|
+
)}
|
|
163
|
+
</AutocompleteWrapper>
|
|
105
164
|
|
|
106
165
|
<FieldLabel>Amount (DC)</FieldLabel>
|
|
107
166
|
<StyledInput
|
|
@@ -215,3 +274,36 @@ const ErrorMessage = styled.div`
|
|
|
215
274
|
color: ${uiColors.red};
|
|
216
275
|
font-family: 'Press Start 2P', cursive;
|
|
217
276
|
`;
|
|
277
|
+
|
|
278
|
+
const AutocompleteWrapper = styled.div`
|
|
279
|
+
position: relative;
|
|
280
|
+
width: 100%;
|
|
281
|
+
`;
|
|
282
|
+
|
|
283
|
+
const DropdownList = styled.ul`
|
|
284
|
+
position: absolute;
|
|
285
|
+
top: 100%;
|
|
286
|
+
left: 0;
|
|
287
|
+
right: 0;
|
|
288
|
+
background: rgba(10, 10, 30, 0.95);
|
|
289
|
+
border: 1px solid #f59e0b;
|
|
290
|
+
border-top: none;
|
|
291
|
+
list-style: none;
|
|
292
|
+
padding: 0;
|
|
293
|
+
margin: 0;
|
|
294
|
+
max-height: 120px;
|
|
295
|
+
overflow-y: auto;
|
|
296
|
+
z-index: 10;
|
|
297
|
+
`;
|
|
298
|
+
|
|
299
|
+
const DropdownItem = styled.li`
|
|
300
|
+
padding: 6px 8px;
|
|
301
|
+
font-size: 11px;
|
|
302
|
+
font-family: 'Press Start 2P', cursive;
|
|
303
|
+
color: ${uiColors.white};
|
|
304
|
+
cursor: pointer;
|
|
305
|
+
|
|
306
|
+
&:hover {
|
|
307
|
+
background: rgba(245, 158, 11, 0.3);
|
|
308
|
+
}
|
|
309
|
+
`;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import React, { useCallback, useState } from 'react';
|
|
2
|
-
import { FaTimes } from 'react-icons/fa';
|
|
2
|
+
import { FaShoppingCart, FaTimes } from 'react-icons/fa';
|
|
3
3
|
import styled from 'styled-components';
|
|
4
4
|
import { uiColors } from '../../constants/uiColors';
|
|
5
5
|
import ModalPortal from '../Abstractions/ModalPortal';
|
|
6
6
|
import { InternalTabs } from '../InternalTabs/InternalTabs';
|
|
7
7
|
import { DCHistoryPanel, IDCTransaction } from './DCHistoryPanel';
|
|
8
|
-
import { DCTransferPanel } from './DCTransferPanel';
|
|
8
|
+
import { DCTransferPanel, IDCTransferCharacterResult } from './DCTransferPanel';
|
|
9
9
|
|
|
10
10
|
type WalletTabId = 'balance' | 'transfer' | 'history';
|
|
11
11
|
|
|
@@ -22,6 +22,9 @@ export interface IDCWalletModalProps {
|
|
|
22
22
|
characterName?: string;
|
|
23
23
|
onInputFocus?: () => void;
|
|
24
24
|
onInputBlur?: () => void;
|
|
25
|
+
onBuyDC?: () => void;
|
|
26
|
+
onSearchCharacter?: (name: string) => void;
|
|
27
|
+
searchResults?: IDCTransferCharacterResult[];
|
|
25
28
|
}
|
|
26
29
|
|
|
27
30
|
export const DCWalletModal: React.FC<IDCWalletModalProps> = ({
|
|
@@ -37,6 +40,9 @@ export const DCWalletModal: React.FC<IDCWalletModalProps> = ({
|
|
|
37
40
|
characterName,
|
|
38
41
|
onInputFocus,
|
|
39
42
|
onInputBlur,
|
|
43
|
+
onBuyDC,
|
|
44
|
+
onSearchCharacter,
|
|
45
|
+
searchResults,
|
|
40
46
|
}) => {
|
|
41
47
|
const [activeTab, setActiveTab] = useState<WalletTabId>('balance');
|
|
42
48
|
|
|
@@ -55,7 +61,12 @@ export const DCWalletModal: React.FC<IDCWalletModalProps> = ({
|
|
|
55
61
|
<BalanceContent>
|
|
56
62
|
<BalanceLabel>Your DC Balance</BalanceLabel>
|
|
57
63
|
<BalanceAmount>{dcBalance.toLocaleString()} DC</BalanceAmount>
|
|
58
|
-
|
|
64
|
+
{onBuyDC && (
|
|
65
|
+
<BuyButton onPointerDown={onBuyDC} title="Buy Definya Coins">
|
|
66
|
+
<FaShoppingCart />
|
|
67
|
+
<BuyButtonLabel>Buy DC</BuyButtonLabel>
|
|
68
|
+
</BuyButton>
|
|
69
|
+
)}
|
|
59
70
|
</BalanceContent>
|
|
60
71
|
),
|
|
61
72
|
},
|
|
@@ -72,6 +83,8 @@ export const DCWalletModal: React.FC<IDCWalletModalProps> = ({
|
|
|
72
83
|
characterName={characterName}
|
|
73
84
|
onInputFocus={onInputFocus}
|
|
74
85
|
onInputBlur={onInputBlur}
|
|
86
|
+
onSearchCharacter={onSearchCharacter}
|
|
87
|
+
searchResults={searchResults}
|
|
75
88
|
/>
|
|
76
89
|
),
|
|
77
90
|
},
|
|
@@ -110,7 +123,12 @@ export const DCWalletModal: React.FC<IDCWalletModalProps> = ({
|
|
|
110
123
|
<InternalTabs
|
|
111
124
|
tabs={tabs}
|
|
112
125
|
activeTab={activeTab}
|
|
113
|
-
onTabChange={(tabId: string) =>
|
|
126
|
+
onTabChange={(tabId: string) => {
|
|
127
|
+
setActiveTab(tabId as WalletTabId);
|
|
128
|
+
if (tabId === 'history') {
|
|
129
|
+
onRequestHistory(1);
|
|
130
|
+
}
|
|
131
|
+
}}
|
|
114
132
|
activeTextColor="#000000"
|
|
115
133
|
activeColor="#fef08a"
|
|
116
134
|
inactiveColor="#6b7280"
|
|
@@ -218,8 +236,29 @@ const BalanceAmount = styled.div`
|
|
|
218
236
|
letter-spacing: 2px;
|
|
219
237
|
`;
|
|
220
238
|
|
|
221
|
-
const
|
|
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`
|
|
222
262
|
font-family: 'Press Start 2P', cursive;
|
|
223
|
-
font-size:
|
|
224
|
-
color: ${uiColors.lightGray};
|
|
263
|
+
font-size: 8px;
|
|
225
264
|
`;
|