@rpg-engine/long-bow 0.8.185 → 0.8.187
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/Marketplace/CharacterDetailModal.d.ts +17 -0
- package/dist/index.d.ts +1 -0
- package/dist/long-bow.cjs.development.js +370 -170
- 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 +393 -194
- package/dist/long-bow.esm.js.map +1 -1
- package/dist/stories/Features/marketplace/CharacterDetailModal.stories.d.ts +7 -0
- package/package.json +1 -1
- package/src/components/Marketplace/CharacterDetailModal.tsx +477 -0
- package/src/components/Marketplace/CharacterMarketplacePanel.tsx +19 -97
- package/src/index.tsx +1 -0
- package/src/stories/Features/marketplace/CharacterDetailModal.stories.tsx +129 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { ICharacterListing } from '@rpg-engine/shared';
|
|
2
|
+
import { Meta, Story } from '@storybook/react';
|
|
3
|
+
import React, { useState } from 'react';
|
|
4
|
+
import { RPGUIRoot } from '../../..';
|
|
5
|
+
import { CharacterDetailModal, ICharacterDetailModalProps } from '../../../components/Marketplace/CharacterDetailModal';
|
|
6
|
+
import entitiesAtlasJSON from '../../../mocks/atlas/entities/entities.json';
|
|
7
|
+
import entitiesAtlasIMG from '../../../mocks/atlas/entities/entities.png';
|
|
8
|
+
import itemsAtlasJSON from '../../../mocks/atlas/items/items.json';
|
|
9
|
+
import itemsAtlasIMG from '../../../mocks/atlas/items/items.png';
|
|
10
|
+
|
|
11
|
+
const meta: Meta<ICharacterDetailModalProps> = {
|
|
12
|
+
title: 'Features/Marketplace/CharacterDetailModal',
|
|
13
|
+
component: CharacterDetailModal,
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export default meta;
|
|
17
|
+
|
|
18
|
+
const now = new Date();
|
|
19
|
+
|
|
20
|
+
const warriorListing: ICharacterListing = {
|
|
21
|
+
_id: 'cl-1',
|
|
22
|
+
character: 'char-1',
|
|
23
|
+
seller: 'player-2',
|
|
24
|
+
listedByCharacterName: 'WarriorKing',
|
|
25
|
+
price: 50000,
|
|
26
|
+
isBeingBought: false,
|
|
27
|
+
characterSnapshot: {
|
|
28
|
+
name: 'Sir Galahad',
|
|
29
|
+
level: 25,
|
|
30
|
+
class: 'Warrior',
|
|
31
|
+
race: 'Human',
|
|
32
|
+
faction: 'Alliance',
|
|
33
|
+
mode: 'Standard',
|
|
34
|
+
skills: { level: 25, sword: 10, shielding: 8, strength: 18, dexterity: 7, resistance: 15 },
|
|
35
|
+
equipment: [
|
|
36
|
+
{ slot: 'rightHand', itemName: 'Broad Sword', itemKey: 'broad-sword', rarity: 'Common' },
|
|
37
|
+
{ slot: 'armor', itemName: 'Steel Armor', itemKey: 'steel-armor', rarity: 'Rare' },
|
|
38
|
+
{ slot: 'head', itemName: 'Iron Helm', itemKey: 'iron-helm', rarity: 'Uncommon' },
|
|
39
|
+
],
|
|
40
|
+
textureKey: 'black-knight',
|
|
41
|
+
},
|
|
42
|
+
createdAt: now,
|
|
43
|
+
updatedAt: now,
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const hardcoreListing: ICharacterListing = {
|
|
47
|
+
_id: 'cl-2',
|
|
48
|
+
character: 'char-2',
|
|
49
|
+
seller: 'player-3',
|
|
50
|
+
listedByCharacterName: 'MageLord',
|
|
51
|
+
price: 100000,
|
|
52
|
+
isBeingBought: false,
|
|
53
|
+
characterSnapshot: {
|
|
54
|
+
name: 'Merlin Jr.',
|
|
55
|
+
level: 40,
|
|
56
|
+
class: 'Mage',
|
|
57
|
+
race: 'Elf',
|
|
58
|
+
faction: 'Horde',
|
|
59
|
+
mode: 'Hardcore',
|
|
60
|
+
skills: { level: 40, magic: 20, magicResistance: 18, dexterity: 12, stamina: 15 },
|
|
61
|
+
equipment: [
|
|
62
|
+
{ slot: 'rightHand', itemName: 'Staff of Flames', itemKey: 'fire-staff', rarity: 'Epic' },
|
|
63
|
+
{ slot: 'armor', itemName: 'Arcane Robe', itemKey: 'arcane-robe', rarity: 'Legendary' },
|
|
64
|
+
{ slot: 'neck', itemName: 'Mana Amulet', itemKey: 'mana-amulet', rarity: 'Rare' },
|
|
65
|
+
],
|
|
66
|
+
textureKey: 'pink-mage-1',
|
|
67
|
+
},
|
|
68
|
+
createdAt: now,
|
|
69
|
+
updatedAt: now,
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const pendingListing: ICharacterListing = {
|
|
73
|
+
...warriorListing,
|
|
74
|
+
_id: 'cl-3',
|
|
75
|
+
isBeingBought: true,
|
|
76
|
+
price: 35000,
|
|
77
|
+
characterSnapshot: {
|
|
78
|
+
...warriorListing.characterSnapshot,
|
|
79
|
+
name: 'ShadowStep',
|
|
80
|
+
textureKey: 'redhair-girl-1',
|
|
81
|
+
class: 'Rogue',
|
|
82
|
+
mode: 'Hardcore',
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const ModalWrapper: React.FC<{ listing: ICharacterListing }> = ({ listing }) => {
|
|
87
|
+
const [isOpen, setIsOpen] = useState(true);
|
|
88
|
+
const [lastAction, setLastAction] = useState<string | null>(null);
|
|
89
|
+
|
|
90
|
+
return (
|
|
91
|
+
<RPGUIRoot>
|
|
92
|
+
<div style={{ padding: '20px', fontFamily: 'monospace', fontSize: '12px', color: '#fff' }}>
|
|
93
|
+
{lastAction ? (
|
|
94
|
+
<p>✅ {lastAction}</p>
|
|
95
|
+
) : (
|
|
96
|
+
<p>Click "Buy Character" inside the modal</p>
|
|
97
|
+
)}
|
|
98
|
+
<button
|
|
99
|
+
style={{ marginTop: 8, padding: '6px 12px', cursor: 'pointer' }}
|
|
100
|
+
onClick={() => { setIsOpen(true); setLastAction(null); }}
|
|
101
|
+
>
|
|
102
|
+
Reopen Modal
|
|
103
|
+
</button>
|
|
104
|
+
</div>
|
|
105
|
+
<CharacterDetailModal
|
|
106
|
+
listing={listing}
|
|
107
|
+
isOpen={isOpen}
|
|
108
|
+
onClose={() => setIsOpen(false)}
|
|
109
|
+
onBuy={(id) => {
|
|
110
|
+
setLastAction(`Buying listing ID=${id}`);
|
|
111
|
+
setIsOpen(false);
|
|
112
|
+
}}
|
|
113
|
+
atlasJSON={itemsAtlasJSON}
|
|
114
|
+
atlasIMG={itemsAtlasIMG}
|
|
115
|
+
characterAtlasJSON={entitiesAtlasJSON}
|
|
116
|
+
characterAtlasIMG={entitiesAtlasIMG}
|
|
117
|
+
/>
|
|
118
|
+
</RPGUIRoot>
|
|
119
|
+
);
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
export const WarriorListing: Story = () => <ModalWrapper listing={warriorListing} />;
|
|
123
|
+
WarriorListing.storyName = 'Standard warrior listing';
|
|
124
|
+
|
|
125
|
+
export const HardcoreMageListing: Story = () => <ModalWrapper listing={hardcoreListing} />;
|
|
126
|
+
HardcoreMageListing.storyName = 'Hardcore mage — high price';
|
|
127
|
+
|
|
128
|
+
export const PendingPurchase: Story = () => <ModalWrapper listing={pendingListing} />;
|
|
129
|
+
PendingPurchase.storyName = 'Listing with pending purchase (buy disabled)';
|