@rpg-engine/long-bow 0.8.220 → 0.8.221
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/Store/CartView.d.ts +0 -2
- package/dist/components/Store/Store.d.ts +0 -1
- package/dist/long-bow.cjs.development.js +32 -47
- 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 +33 -48
- package/dist/long-bow.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/components/Store/CartView.tsx +111 -137
- package/src/components/Store/Store.tsx +0 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { IProductBlueprint, MetadataType } from '@rpg-engine/shared';
|
|
2
2
|
import React, { useState } from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import { FaInfoCircle, FaShoppingBag, FaTimes, FaTrash } from 'react-icons/fa';
|
|
4
4
|
import styled from 'styled-components';
|
|
5
5
|
import characterAtlasJSON from '../../mocks/atlas/entities/entities.json';
|
|
6
6
|
import characterAtlasIMG from '../../mocks/atlas/entities/entities.png';
|
|
@@ -27,8 +27,6 @@ export interface ICartViewProps {
|
|
|
27
27
|
paymentMethodLabel?: string;
|
|
28
28
|
trustSignals?: ITrustSignal[];
|
|
29
29
|
onCloseStore?: () => void;
|
|
30
|
-
/** Called when user taps the "Buy DC" nudge — open wallet/DC purchase flow */
|
|
31
|
-
onBuyDC?: () => void;
|
|
32
30
|
/** Fires when user taps the pay button — before the purchase resolves */
|
|
33
31
|
onCheckoutStart?: (items: Array<{ key: string; name: string; quantity: number }>, total: number) => void;
|
|
34
32
|
/** Fires after a successful purchase */
|
|
@@ -69,7 +67,6 @@ export const CartView: React.FC<ICartViewProps> = ({
|
|
|
69
67
|
paymentMethodLabel,
|
|
70
68
|
trustSignals,
|
|
71
69
|
onCloseStore,
|
|
72
|
-
onBuyDC,
|
|
73
70
|
onCheckoutStart,
|
|
74
71
|
onPurchaseSuccess,
|
|
75
72
|
onPurchaseError,
|
|
@@ -118,10 +115,6 @@ export const CartView: React.FC<ICartViewProps> = ({
|
|
|
118
115
|
}
|
|
119
116
|
};
|
|
120
117
|
|
|
121
|
-
// Show DC discount nudge when items have DC pricing and user might benefit
|
|
122
|
-
const hasDCItems = cartItems.some(ci => (ci.item as any).dcPrice);
|
|
123
|
-
const showDCNudge = hasDCItems && onBuyDC;
|
|
124
|
-
|
|
125
118
|
if (purchasedItems) {
|
|
126
119
|
return (
|
|
127
120
|
<PurchaseSuccess
|
|
@@ -150,100 +143,95 @@ export const CartView: React.FC<ICartViewProps> = ({
|
|
|
150
143
|
</CloseButton>
|
|
151
144
|
</Header>
|
|
152
145
|
|
|
153
|
-
<
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
/>
|
|
175
|
-
</ItemIconContainer>
|
|
176
|
-
<ItemDetails>
|
|
177
|
-
<ItemName>{cartItem.item.name}</ItemName>
|
|
178
|
-
{cartItem.metadata?.inputValue && (
|
|
179
|
-
<CartMeta>{cartItem.metadata.inputValue}</CartMeta>
|
|
180
|
-
)}
|
|
181
|
-
<ItemInfo>
|
|
182
|
-
<span>{currencySymbol}{formatPrice((cartItem.item as any).regionalPrice ?? cartItem.item.price)}</span>
|
|
183
|
-
<span>×</span>
|
|
184
|
-
<span>{cartItem.quantity}</span>
|
|
185
|
-
<span>=</span>
|
|
186
|
-
<span>
|
|
187
|
-
{currencySymbol}{formatPrice(((cartItem.item as any).regionalPrice ?? cartItem.item.price) * cartItem.quantity)}
|
|
188
|
-
</span>
|
|
189
|
-
</ItemInfo>
|
|
190
|
-
|
|
191
|
-
{cartItem.metadata && cartItem.item.metadataType && (
|
|
192
|
-
<MetadataDisplay
|
|
193
|
-
type={cartItem.item.metadataType}
|
|
194
|
-
metadata={cartItem.metadata}
|
|
146
|
+
<MainContent>
|
|
147
|
+
<CartItems>
|
|
148
|
+
{cartItems.length === 0 ? (
|
|
149
|
+
<EmptyCart>Your cart is empty</EmptyCart>
|
|
150
|
+
) : (
|
|
151
|
+
cartItems.map(cartItem => {
|
|
152
|
+
const getSpriteKey = (textureKey: string) => {
|
|
153
|
+
return textureKey + '/down/standing/0.png';
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
return (
|
|
157
|
+
<CartItemRow key={cartItem.item.key}>
|
|
158
|
+
<ItemIconContainer>
|
|
159
|
+
<SpriteFromAtlas
|
|
160
|
+
atlasJSON={cartItem.item.metadataType === MetadataType.CharacterSkin ? characterAtlasJSON : atlasJSON}
|
|
161
|
+
atlasIMG={cartItem.item.metadataType === MetadataType.CharacterSkin ? characterAtlasIMG : atlasIMG}
|
|
162
|
+
spriteKey={cartItem.item.metadataType === MetadataType.CharacterSkin && cartItem.metadata?.selectedSkinTextureKey ? getSpriteKey(cartItem.metadata.selectedSkinTextureKey) : cartItem.item.texturePath}
|
|
163
|
+
width={24}
|
|
164
|
+
height={24}
|
|
165
|
+
imgScale={1.5}
|
|
166
|
+
centered
|
|
195
167
|
/>
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
168
|
+
</ItemIconContainer>
|
|
169
|
+
<ItemDetails>
|
|
170
|
+
<ItemName>{cartItem.item.name}</ItemName>
|
|
171
|
+
{cartItem.metadata?.inputValue && (
|
|
172
|
+
<CartMeta>{cartItem.metadata.inputValue}</CartMeta>
|
|
173
|
+
)}
|
|
174
|
+
<ItemInfo>
|
|
175
|
+
<span>{currencySymbol}{formatPrice((cartItem.item as any).regionalPrice ?? cartItem.item.price)}</span>
|
|
176
|
+
<span>×</span>
|
|
177
|
+
<span>{cartItem.quantity}</span>
|
|
178
|
+
<span>=</span>
|
|
179
|
+
<span>
|
|
180
|
+
{currencySymbol}{formatPrice(((cartItem.item as any).regionalPrice ?? cartItem.item.price) * cartItem.quantity)}
|
|
181
|
+
</span>
|
|
182
|
+
</ItemInfo>
|
|
183
|
+
|
|
184
|
+
{cartItem.metadata && cartItem.item.metadataType && (
|
|
185
|
+
<MetadataDisplay
|
|
186
|
+
type={cartItem.item.metadataType}
|
|
187
|
+
metadata={cartItem.metadata}
|
|
188
|
+
/>
|
|
189
|
+
)}
|
|
190
|
+
</ItemDetails>
|
|
191
|
+
|
|
192
|
+
<CTAButton
|
|
193
|
+
icon={<FaTrash />}
|
|
194
|
+
onClick={e => {
|
|
195
|
+
e.stopPropagation();
|
|
196
|
+
onRemoveFromCart(cartItem.item.key);
|
|
197
|
+
}}
|
|
198
|
+
/>
|
|
199
|
+
</CartItemRow>
|
|
200
|
+
);
|
|
201
|
+
})
|
|
202
|
+
)}
|
|
203
|
+
</CartItems>
|
|
211
204
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
<
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
205
|
+
{cartItems.length > 0 && (
|
|
206
|
+
<OrderSummaryPanel>
|
|
207
|
+
<OrderSummaryLabel>Order Summary</OrderSummaryLabel>
|
|
208
|
+
<TotalRow>
|
|
209
|
+
<span>Subtotal:</span>
|
|
210
|
+
<span>{currencySymbol}{formatPrice(total)}</span>
|
|
211
|
+
</TotalRow>
|
|
212
|
+
{dcTotal > 0 && (
|
|
213
|
+
<TotalRow>
|
|
214
|
+
<span>DC:</span>
|
|
215
|
+
<span><MMORPGNumber value={dcTotal} /> DC</span>
|
|
216
|
+
</TotalRow>
|
|
217
|
+
)}
|
|
218
|
+
<TotalRow $isTotal>
|
|
219
|
+
<span>Total:</span>
|
|
220
|
+
<span>{currencySymbol}{formatPrice(total)}</span>
|
|
221
|
+
</TotalRow>
|
|
222
|
+
{paymentMethodLabel && (
|
|
223
|
+
<PaymentMethodRow>
|
|
224
|
+
<span>Paying with:</span>
|
|
225
|
+
<span>{paymentMethodLabel}</span>
|
|
226
|
+
</PaymentMethodRow>
|
|
227
|
+
)}
|
|
228
|
+
</OrderSummaryPanel>
|
|
219
229
|
)}
|
|
230
|
+
</MainContent>
|
|
220
231
|
|
|
232
|
+
<Footer>
|
|
221
233
|
<TrustBar signals={trustSignals} />
|
|
222
|
-
|
|
223
|
-
<TotalInfo>
|
|
224
|
-
<OrderSummaryLabel>Order Summary</OrderSummaryLabel>
|
|
225
|
-
<TotalRow>
|
|
226
|
-
<span>Subtotal:</span>
|
|
227
|
-
<span>{currencySymbol}{formatPrice(total)}</span>
|
|
228
|
-
</TotalRow>
|
|
229
|
-
{dcTotal > 0 && (
|
|
230
|
-
<TotalRow>
|
|
231
|
-
<span>DC:</span>
|
|
232
|
-
<span><MMORPGNumber value={dcTotal} /> DC</span>
|
|
233
|
-
</TotalRow>
|
|
234
|
-
)}
|
|
235
|
-
<TotalRow $isTotal>
|
|
236
|
-
<span>Total:</span>
|
|
237
|
-
<span>{currencySymbol}{formatPrice(total)}</span>
|
|
238
|
-
</TotalRow>
|
|
239
|
-
{paymentMethodLabel && (
|
|
240
|
-
<PaymentMethodRow>
|
|
241
|
-
<span>Paying with:</span>
|
|
242
|
-
<span>{paymentMethodLabel}</span>
|
|
243
|
-
</PaymentMethodRow>
|
|
244
|
-
)}
|
|
245
|
-
{error && <ErrorMessage>{error}</ErrorMessage>}
|
|
246
|
-
</TotalInfo>
|
|
234
|
+
{error && <ErrorMessage>{error}</ErrorMessage>}
|
|
247
235
|
<CTAButton
|
|
248
236
|
icon={<FaShoppingBag />}
|
|
249
237
|
label={isLoading ? 'Processing...' : `Pay ${currencySymbol}${formatPrice(total)}`}
|
|
@@ -292,14 +280,26 @@ const CloseButton = styled.div`
|
|
|
292
280
|
justify-content: center;
|
|
293
281
|
`;
|
|
294
282
|
|
|
283
|
+
const MainContent = styled.div`
|
|
284
|
+
display: grid;
|
|
285
|
+
grid-template-columns: 1fr 260px;
|
|
286
|
+
gap: 1rem;
|
|
287
|
+
flex: 1;
|
|
288
|
+
min-height: 0;
|
|
289
|
+
margin: 1rem 0;
|
|
290
|
+
|
|
291
|
+
@media (max-width: 700px) {
|
|
292
|
+
grid-template-columns: 1fr;
|
|
293
|
+
gap: 0.75rem;
|
|
294
|
+
}
|
|
295
|
+
`;
|
|
296
|
+
|
|
295
297
|
const CartItems = styled.div`
|
|
296
298
|
display: flex;
|
|
297
299
|
flex-direction: column;
|
|
298
300
|
gap: 0.5rem;
|
|
299
|
-
flex: 1;
|
|
300
301
|
min-height: 0;
|
|
301
302
|
overflow-y: auto;
|
|
302
|
-
margin: 1rem 0;
|
|
303
303
|
padding-right: 0.5rem;
|
|
304
304
|
|
|
305
305
|
&::-webkit-scrollbar {
|
|
@@ -312,13 +312,24 @@ const CartItems = styled.div`
|
|
|
312
312
|
&::-webkit-scrollbar-thumb {
|
|
313
313
|
background: #f59e0b;
|
|
314
314
|
border-radius: 4px;
|
|
315
|
-
|
|
315
|
+
|
|
316
316
|
&:hover {
|
|
317
317
|
background: #fbbf24;
|
|
318
318
|
}
|
|
319
319
|
}
|
|
320
320
|
`;
|
|
321
321
|
|
|
322
|
+
const OrderSummaryPanel = styled.div`
|
|
323
|
+
display: flex;
|
|
324
|
+
flex-direction: column;
|
|
325
|
+
gap: 0.5rem;
|
|
326
|
+
padding: 1rem;
|
|
327
|
+
background: rgba(0, 0, 0, 0.25);
|
|
328
|
+
border: 1px solid rgba(255, 255, 255, 0.08);
|
|
329
|
+
border-radius: 6px;
|
|
330
|
+
align-self: start;
|
|
331
|
+
`;
|
|
332
|
+
|
|
322
333
|
const EmptyCart = styled.div`
|
|
323
334
|
display: flex;
|
|
324
335
|
align-items: center;
|
|
@@ -385,12 +396,6 @@ const Footer = styled.div`
|
|
|
385
396
|
}
|
|
386
397
|
`;
|
|
387
398
|
|
|
388
|
-
const TotalInfo = styled.div`
|
|
389
|
-
display: flex;
|
|
390
|
-
flex-direction: column;
|
|
391
|
-
gap: 0.5rem;
|
|
392
|
-
`;
|
|
393
|
-
|
|
394
399
|
const OrderSummaryLabel = styled.div`
|
|
395
400
|
font-family: 'Press Start 2P', cursive;
|
|
396
401
|
font-size: 0.55rem;
|
|
@@ -434,37 +439,6 @@ const PaymentMethodRow = styled.div`
|
|
|
434
439
|
}
|
|
435
440
|
`;
|
|
436
441
|
|
|
437
|
-
const DCNudge = styled.div`
|
|
438
|
-
display: flex;
|
|
439
|
-
align-items: center;
|
|
440
|
-
gap: 0.5rem;
|
|
441
|
-
padding: 0.5rem 0.75rem;
|
|
442
|
-
background: rgba(245, 158, 11, 0.1);
|
|
443
|
-
border: 1px solid rgba(245, 158, 11, 0.3);
|
|
444
|
-
border-radius: 4px;
|
|
445
|
-
cursor: pointer;
|
|
446
|
-
font-family: 'Press Start 2P', cursive;
|
|
447
|
-
font-size: 0.45rem;
|
|
448
|
-
color: #fbbf24;
|
|
449
|
-
transition: background 0.15s;
|
|
450
|
-
line-height: 1.4;
|
|
451
|
-
flex-wrap: wrap;
|
|
452
|
-
|
|
453
|
-
&:hover {
|
|
454
|
-
background: rgba(245, 158, 11, 0.18);
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
svg { flex-shrink: 0; font-size: 0.7rem; }
|
|
458
|
-
span { flex: 1; min-width: 140px; }
|
|
459
|
-
`;
|
|
460
|
-
|
|
461
|
-
const DCNudgeLink = styled.span`
|
|
462
|
-
color: #f59e0b;
|
|
463
|
-
white-space: nowrap;
|
|
464
|
-
text-decoration: underline;
|
|
465
|
-
flex: 0 0 auto !important;
|
|
466
|
-
`;
|
|
467
|
-
|
|
468
442
|
const ErrorMessage = styled.div`
|
|
469
443
|
color: #ef4444;
|
|
470
444
|
font-size: 0.875rem;
|
|
@@ -61,7 +61,6 @@ export interface IStoreProps {
|
|
|
61
61
|
onCheckoutStart?: (items: Array<{ key: string; name: string; quantity: number }>, total: number) => void;
|
|
62
62
|
onPurchaseSuccess?: (items: Array<{ key: string; name: string; quantity: number }>, total: number) => void;
|
|
63
63
|
onPurchaseError?: (error: string) => void;
|
|
64
|
-
onBuyDC?: () => void;
|
|
65
64
|
currencySymbol?: string;
|
|
66
65
|
onRedeem?: (code: string) => Promise<{ success: boolean; dcAmount?: number; error?: string }>;
|
|
67
66
|
onRedeemInputFocus?: () => void;
|
|
@@ -114,7 +113,6 @@ export const Store: React.FC<IStoreProps> = ({
|
|
|
114
113
|
onCheckoutStart,
|
|
115
114
|
onPurchaseSuccess,
|
|
116
115
|
onPurchaseError,
|
|
117
|
-
onBuyDC,
|
|
118
116
|
currencySymbol = '$',
|
|
119
117
|
onRedeem,
|
|
120
118
|
onRedeemInputFocus,
|
|
@@ -321,7 +319,6 @@ export const Store: React.FC<IStoreProps> = ({
|
|
|
321
319
|
onCheckoutStart={onCheckoutStart}
|
|
322
320
|
onPurchaseSuccess={onPurchaseSuccess}
|
|
323
321
|
onPurchaseError={onPurchaseError}
|
|
324
|
-
onBuyDC={onBuyDC}
|
|
325
322
|
currencySymbol={currencySymbol}
|
|
326
323
|
/>
|
|
327
324
|
) : selectedPack ? (
|