@rpg-engine/long-bow 0.8.141 → 0.8.145

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.
Files changed (62) hide show
  1. package/dist/components/Marketplace/BlueprintSearchModal.d.ts +17 -0
  2. package/dist/components/Marketplace/BuyOrderDetailsModal.d.ts +17 -0
  3. package/dist/components/Marketplace/BuyOrderPanel.d.ts +24 -0
  4. package/dist/components/Marketplace/BuyOrderRows.d.ts +13 -0
  5. package/dist/components/Marketplace/BuyPanel.d.ts +9 -1
  6. package/dist/components/Marketplace/HistoryPanel.d.ts +18 -0
  7. package/dist/components/Marketplace/ManagmentPanel.d.ts +3 -2
  8. package/dist/components/Marketplace/Marketplace.d.ts +35 -2
  9. package/dist/components/Marketplace/MarketplaceSettingsPanel.d.ts +2 -1
  10. package/dist/components/Store/PaymentMethodModal.d.ts +1 -0
  11. package/dist/components/shared/LabelPill/LabelPill.d.ts +9 -0
  12. package/dist/components/shared/LabelPill/index.d.ts +1 -0
  13. package/dist/components/shared/SegmentedToggle/SegmentedToggle.d.ts +12 -0
  14. package/dist/components/shared/SegmentedToggle/index.d.ts +1 -0
  15. package/dist/index.d.ts +4 -0
  16. package/dist/long-bow.cjs.development.js +11529 -1288
  17. package/dist/long-bow.cjs.development.js.map +1 -1
  18. package/dist/long-bow.cjs.production.min.js +1 -1
  19. package/dist/long-bow.cjs.production.min.js.map +1 -1
  20. package/dist/long-bow.esm.js +11518 -1290
  21. package/dist/long-bow.esm.js.map +1 -1
  22. package/dist/stories/Features/marketplace/BlueprintSearchModal.stories.d.ts +1 -0
  23. package/dist/stories/Features/marketplace/BuyOrderPanel.stories.d.ts +1 -0
  24. package/dist/stories/Features/marketplace/BuyOrderRows.stories.d.ts +1 -0
  25. package/dist/stories/Features/marketplace/HistoryPanel.stories.d.ts +1 -0
  26. package/dist/stories/Features/trading/MarketplaceRows.stories.d.ts +2 -1
  27. package/dist/stories/UI/buttonsAndInputs/SegmentedToggle.stories.d.ts +6 -0
  28. package/dist/stories/UI/text/LabelPill.stories.d.ts +7 -0
  29. package/dist/utils/atlasUtils.d.ts +2 -0
  30. package/package.json +2 -2
  31. package/src/components/Marketplace/BlueprintSearchModal.tsx +418 -0
  32. package/src/components/Marketplace/BuyOrderDetailsModal.tsx +307 -0
  33. package/src/components/Marketplace/BuyOrderPanel.tsx +266 -0
  34. package/src/components/Marketplace/BuyOrderRows.tsx +287 -0
  35. package/src/components/Marketplace/BuyPanel.tsx +406 -166
  36. package/src/components/Marketplace/HistoryPanel.tsx +422 -0
  37. package/src/components/Marketplace/ManagmentPanel.tsx +13 -15
  38. package/src/components/Marketplace/Marketplace.tsx +181 -30
  39. package/src/components/Marketplace/MarketplaceBuyModal.tsx +1 -0
  40. package/src/components/Marketplace/MarketplaceRows.tsx +41 -10
  41. package/src/components/Marketplace/MarketplaceSettingsPanel.tsx +4 -3
  42. package/src/components/Store/CartView.tsx +11 -0
  43. package/src/components/Store/PaymentMethodModal.tsx +26 -9
  44. package/src/components/shared/LabelPill/LabelPill.tsx +45 -0
  45. package/src/components/shared/LabelPill/index.ts +1 -0
  46. package/src/components/shared/SegmentedToggle/SegmentedToggle.tsx +61 -0
  47. package/src/components/shared/SegmentedToggle/index.ts +1 -0
  48. package/src/components/shared/SpriteFromAtlas.tsx +7 -2
  49. package/src/index.tsx +4 -0
  50. package/src/mocks/atlas/items/items.json +33998 -25238
  51. package/src/mocks/atlas/items/items.png +0 -0
  52. package/src/mocks/itemContainer.mocks.ts +31 -0
  53. package/src/stories/Features/marketplace/BlueprintSearchModal.stories.tsx +145 -0
  54. package/src/stories/Features/marketplace/BuyOrderPanel.stories.tsx +207 -0
  55. package/src/stories/Features/marketplace/BuyOrderRows.stories.tsx +116 -0
  56. package/src/stories/Features/marketplace/HistoryPanel.stories.tsx +157 -0
  57. package/src/stories/Features/trading/Marketplace.stories.tsx +107 -0
  58. package/src/stories/Features/trading/MarketplaceRows.stories.tsx +11 -0
  59. package/src/stories/UI/buttonsAndInputs/SegmentedToggle.stories.tsx +54 -0
  60. package/src/stories/UI/text/LabelPill.stories.tsx +43 -0
  61. package/src/utils/__test__/atlasUtils.spec.ts +26 -0
  62. package/src/utils/atlasUtils.ts +80 -0
@@ -1,4 +1,5 @@
1
- import { Meta } from '@storybook/react';
1
+ import { Meta, Story } from '@storybook/react';
2
2
  declare const meta: Meta;
3
3
  export default meta;
4
4
  export declare const Default: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react").ReactFramework, import("@storybook/react").Args>;
5
+ export declare const HighStackQuantity: Story;
@@ -0,0 +1,6 @@
1
+ import { Meta } from '@storybook/react';
2
+ import { ISegmentedToggleProps } from '../../../components/shared/SegmentedToggle';
3
+ declare const meta: Meta;
4
+ export default meta;
5
+ export declare const MarketplaceModes: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react").ReactFramework, ISegmentedToggleProps>;
6
+ export declare const ShortOptions: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react").ReactFramework, ISegmentedToggleProps>;
@@ -0,0 +1,7 @@
1
+ import { Meta } from '@storybook/react';
2
+ import { ILabelPillProps } from '../../../components/shared/LabelPill';
3
+ declare const meta: Meta;
4
+ export default meta;
5
+ export declare const Default: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react").ReactFramework, ILabelPillProps>;
6
+ export declare const BuyRequest: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react").ReactFramework, ILabelPillProps>;
7
+ export declare const Status: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react").ReactFramework, ILabelPillProps>;
@@ -0,0 +1,2 @@
1
+ export declare const NO_IMAGE_SPRITE_KEY = "others/no-image.png";
2
+ export declare const resolveAtlasSpriteKey: (atlasJSON: any, spriteKey?: string | null | undefined) => string | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rpg-engine/long-bow",
3
- "version": "0.8.141",
3
+ "version": "0.8.145",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "typings": "dist/index.d.ts",
@@ -84,7 +84,7 @@
84
84
  "dependencies": {
85
85
  "@capacitor/core": "^6.1.0",
86
86
  "@rollup/plugin-image": "^2.1.1",
87
- "@rpg-engine/shared": "0.10.83",
87
+ "@rpg-engine/shared": "file:../rpg-shared",
88
88
  "dayjs": "^1.11.2",
89
89
  "font-awesome": "^4.7.0",
90
90
  "fs-extra": "^10.1.0",
@@ -0,0 +1,418 @@
1
+ import {
2
+ IMarketplaceBlueprintSearchRequest,
3
+ IMarketplaceBlueprintSummary,
4
+ ItemSubType,
5
+ } from '@rpg-engine/shared';
6
+ import React, { useState } from 'react';
7
+ import { FaTimes } from 'react-icons/fa';
8
+ import styled from 'styled-components';
9
+ import { Dropdown } from '../Dropdown';
10
+ import { IOptionsProps } from '../Dropdown';
11
+ import { Input } from '../Input';
12
+ import { Pager } from '../Pager';
13
+ import ModalPortal from '../Abstractions/ModalPortal';
14
+ import { SpriteFromAtlas } from '../shared/SpriteFromAtlas';
15
+
16
+ export interface IBlueprintSearchModalProps {
17
+ isOpen: boolean;
18
+ onClose: () => void;
19
+ onSelect: (blueprint: IMarketplaceBlueprintSummary) => void;
20
+ onSearch: (request: IMarketplaceBlueprintSearchRequest) => void;
21
+ blueprints: IMarketplaceBlueprintSummary[];
22
+ totalCount: number;
23
+ currentPage: number;
24
+ isLoading: boolean;
25
+ atlasJSON: any;
26
+ atlasIMG: any;
27
+ }
28
+
29
+ const BLUEPRINTS_PER_PAGE = 10;
30
+
31
+ const typeOptions: IOptionsProps[] = [
32
+ { id: 1, value: '', option: 'All Types' },
33
+ ...Object.keys(ItemSubType)
34
+ .filter((t) => t !== 'DeadBody')
35
+ .map((t, index) => ({ id: index + 2, value: t, option: t })),
36
+ ];
37
+
38
+ const subTypeOptions: IOptionsProps[] = [
39
+ { id: 1, value: '', option: 'All Sub Types' },
40
+ ...Object.keys(ItemSubType)
41
+ .filter((t) => t !== 'DeadBody')
42
+ .map((t, index) => ({ id: index + 2, value: t, option: t })),
43
+ ];
44
+
45
+ export const BlueprintSearchModal: React.FC<IBlueprintSearchModalProps> = ({
46
+ isOpen,
47
+ onClose,
48
+ onSelect,
49
+ onSearch,
50
+ blueprints,
51
+ totalCount,
52
+ currentPage,
53
+ isLoading,
54
+ atlasJSON,
55
+ atlasIMG,
56
+ }) => {
57
+ const [searchName, setSearchName] = useState('');
58
+ const [selectedType, setSelectedType] = useState('');
59
+ const [selectedSubType, setSelectedSubType] = useState('');
60
+
61
+ if (!isOpen) return null;
62
+
63
+ const triggerSearch = (overrides?: Partial<{ name: string; itemType: string; itemSubType: string; page: number }>): void => {
64
+ onSearch({
65
+ npcId: '',
66
+ name: overrides?.name ?? searchName,
67
+ itemType: overrides?.itemType ?? selectedType,
68
+ itemSubType: overrides?.itemSubType ?? selectedSubType,
69
+ page: overrides?.page ?? 1,
70
+ limit: BLUEPRINTS_PER_PAGE,
71
+ });
72
+ };
73
+
74
+ const handleNameChange = (e: React.ChangeEvent<HTMLInputElement>): void => {
75
+ setSearchName(e.target.value);
76
+ triggerSearch({ name: e.target.value, page: 1 });
77
+ };
78
+
79
+ const handleTypeChange = (value: string): void => {
80
+ setSelectedType(value);
81
+ triggerSearch({ itemType: value, page: 1 });
82
+ };
83
+
84
+ const handleSubTypeChange = (value: string): void => {
85
+ setSelectedSubType(value);
86
+ triggerSearch({ itemSubType: value, page: 1 });
87
+ };
88
+
89
+ const handlePageChange = (page: number): void => {
90
+ triggerSearch({ page });
91
+ };
92
+
93
+ const stopPropagation = (e: React.MouseEvent | React.PointerEvent): void => {
94
+ e.stopPropagation();
95
+ };
96
+
97
+ const handleClose = (e: React.PointerEvent | React.MouseEvent): void => {
98
+ e.preventDefault();
99
+ e.stopPropagation();
100
+ onClose();
101
+ };
102
+
103
+ return (
104
+ <ModalPortal>
105
+ <Overlay onPointerDown={handleClose} />
106
+ <ModalContainer>
107
+ <ModalContent
108
+ onClick={stopPropagation as React.MouseEventHandler}
109
+ onPointerDown={stopPropagation as React.PointerEventHandler}
110
+ >
111
+ <Header>
112
+ <Title>Select Item</Title>
113
+ <CloseButton onPointerDown={handleClose} aria-label="Close">
114
+ <FaTimes />
115
+ </CloseButton>
116
+ </Header>
117
+
118
+ <InputWrapper>
119
+ <p>SEARCH</p>
120
+ <StyledInput
121
+ value={searchName}
122
+ onChange={handleNameChange}
123
+ placeholder="Search by name..."
124
+ />
125
+ </InputWrapper>
126
+
127
+ <FiltersRow>
128
+ <StyledDropdown
129
+ key={`type-${selectedType}`}
130
+ options={typeOptions}
131
+ onChange={handleTypeChange}
132
+ width="100%"
133
+ />
134
+ <StyledDropdown
135
+ key={`subtype-${selectedSubType}`}
136
+ options={subTypeOptions}
137
+ onChange={handleSubTypeChange}
138
+ width="100%"
139
+ />
140
+ </FiltersRow>
141
+
142
+ <ResultsWrapper>
143
+ {isLoading ? (
144
+ <EmptyState>Loading...</EmptyState>
145
+ ) : blueprints.length === 0 ? (
146
+ <EmptyState>No blueprints found</EmptyState>
147
+ ) : (
148
+ <>
149
+ <ResultsHeader>
150
+ <ColName>Name</ColName>
151
+ <ColType>Type</ColType>
152
+ <ColTier>Tier</ColTier>
153
+ </ResultsHeader>
154
+ {blueprints.map((blueprint) => (
155
+ <ResultRow
156
+ key={blueprint.key}
157
+ onPointerDown={() => onSelect(blueprint)}
158
+ >
159
+ <SpriteWrapper>
160
+ <SpriteFromAtlas
161
+ atlasJSON={atlasJSON}
162
+ atlasIMG={atlasIMG}
163
+ spriteKey={blueprint.texturePath || blueprint.key}
164
+ width={32}
165
+ height={32}
166
+ imgScale={2}
167
+ centered
168
+ />
169
+ </SpriteWrapper>
170
+ <ColName>
171
+ <BlueprintName>{blueprint.name}</BlueprintName>
172
+ <BlueprintKey>{blueprint.key}</BlueprintKey>
173
+ </ColName>
174
+ <ColType>
175
+ <TypeText>{blueprint.type}</TypeText>
176
+ {blueprint.subType && blueprint.subType !== blueprint.type && (
177
+ <SubTypeText>{blueprint.subType}</SubTypeText>
178
+ )}
179
+ </ColType>
180
+ <ColTier>T{blueprint.tier}</ColTier>
181
+ </ResultRow>
182
+ ))}
183
+ </>
184
+ )}
185
+ </ResultsWrapper>
186
+
187
+ <PagerContainer>
188
+ <Pager
189
+ totalItems={totalCount}
190
+ currentPage={currentPage}
191
+ itemsPerPage={BLUEPRINTS_PER_PAGE}
192
+ onPageChange={handlePageChange}
193
+ />
194
+ </PagerContainer>
195
+ </ModalContent>
196
+ </ModalContainer>
197
+ </ModalPortal>
198
+ );
199
+ };
200
+
201
+ const Overlay = styled.div`
202
+ position: fixed;
203
+ inset: 0;
204
+ background: rgba(0, 0, 0, 0.7);
205
+ z-index: 1000;
206
+ `;
207
+
208
+ const ModalContainer = styled.div`
209
+ position: fixed;
210
+ inset: 0;
211
+ display: flex;
212
+ align-items: center;
213
+ justify-content: center;
214
+ z-index: 1001;
215
+ pointer-events: none;
216
+ `;
217
+
218
+ const ModalContent = styled.div`
219
+ background: #1a1a2e;
220
+ border: 2px solid #f59e0b;
221
+ border-radius: 8px;
222
+ padding: 20px 24px;
223
+ width: 600px;
224
+ max-width: 90%;
225
+ display: flex;
226
+ flex-direction: column;
227
+ gap: 12px;
228
+ pointer-events: auto;
229
+ animation: scaleIn 0.15s ease-out;
230
+
231
+ @keyframes scaleIn {
232
+ from { transform: scale(0.85); opacity: 0; }
233
+ to { transform: scale(1); opacity: 1; }
234
+ }
235
+ `;
236
+
237
+ const Header = styled.div`
238
+ display: flex;
239
+ align-items: center;
240
+ justify-content: space-between;
241
+ `;
242
+
243
+ const Title = styled.h3`
244
+ margin: 0;
245
+ font-family: 'Press Start 2P', cursive;
246
+ font-size: 0.7rem;
247
+ color: #fef08a;
248
+ `;
249
+
250
+ const CloseButton = styled.button`
251
+ background: none;
252
+ border: none;
253
+ color: rgba(255, 255, 255, 0.6);
254
+ cursor: pointer;
255
+ font-size: 1rem;
256
+ padding: 4px;
257
+ display: flex;
258
+ align-items: center;
259
+ pointer-events: auto;
260
+
261
+ &:hover {
262
+ color: #ffffff;
263
+ }
264
+ `;
265
+
266
+ const InputWrapper = styled.div`
267
+ display: flex;
268
+ align-items: center;
269
+ gap: 12px;
270
+ padding: 8px 12px;
271
+ background: rgba(0, 0, 0, 0.2);
272
+ border-radius: 4px;
273
+ border: 1px solid rgba(255, 255, 255, 0.05);
274
+
275
+ p {
276
+ margin: 0;
277
+ font-size: 0.7rem;
278
+ color: #ccc;
279
+ text-transform: uppercase;
280
+ letter-spacing: 1px;
281
+ white-space: nowrap;
282
+ }
283
+ `;
284
+
285
+ const StyledInput = styled(Input)`
286
+ flex: 1;
287
+ height: 10px;
288
+ `;
289
+
290
+ const FiltersRow = styled.div`
291
+ display: grid;
292
+ grid-template-columns: 1fr 1fr;
293
+ gap: 8px;
294
+ `;
295
+
296
+ const StyledDropdown = styled(Dropdown)`
297
+ margin: 0px !important;
298
+ width: 100% !important;
299
+ `;
300
+
301
+ const ResultsWrapper = styled.div`
302
+ overflow-y: auto;
303
+ max-height: 320px;
304
+ background: rgba(0, 0, 0, 0.2);
305
+ border: 1px solid rgba(255, 255, 255, 0.05);
306
+ border-radius: 4px;
307
+ `;
308
+
309
+ const tableRowBase = `
310
+ display: grid;
311
+ grid-template-columns: 32px 1fr 120px 60px;
312
+ align-items: center;
313
+ gap: 8px;
314
+ padding: 6px 12px;
315
+ `;
316
+
317
+ const ResultsHeader = styled.div`
318
+ ${tableRowBase}
319
+ background: rgba(0, 0, 0, 0.4);
320
+ border-bottom: 1px solid rgba(255, 255, 255, 0.1);
321
+ position: sticky;
322
+ top: 0;
323
+ z-index: 1;
324
+
325
+ > * {
326
+ font-size: 0.45rem;
327
+ color: #888;
328
+ text-transform: uppercase;
329
+ letter-spacing: 1px;
330
+ }
331
+ `;
332
+
333
+ const ResultRow = styled.div`
334
+ ${tableRowBase}
335
+ border-bottom: 1px solid rgba(255, 255, 255, 0.04);
336
+ cursor: pointer;
337
+ transition: background 0.1s;
338
+
339
+ &:hover {
340
+ background: rgba(245, 158, 11, 0.08);
341
+ }
342
+
343
+ &:last-child {
344
+ border-bottom: none;
345
+ }
346
+ `;
347
+
348
+ const SpriteWrapper = styled.div`
349
+ display: flex;
350
+ align-items: center;
351
+ justify-content: center;
352
+ width: 32px;
353
+ height: 32px;
354
+ `;
355
+
356
+ const ColName = styled.div`
357
+ display: flex;
358
+ flex-direction: column;
359
+ gap: 2px;
360
+ overflow: hidden;
361
+ `;
362
+
363
+ const BlueprintName = styled.span`
364
+ font-size: 0.5rem;
365
+ color: #ddd;
366
+ overflow: hidden;
367
+ text-overflow: ellipsis;
368
+ white-space: nowrap;
369
+ `;
370
+
371
+ const BlueprintKey = styled.span`
372
+ font-size: 0.4rem;
373
+ color: #666;
374
+ overflow: hidden;
375
+ text-overflow: ellipsis;
376
+ white-space: nowrap;
377
+ `;
378
+
379
+ const ColType = styled.div`
380
+ display: flex;
381
+ flex-direction: column;
382
+ gap: 2px;
383
+ `;
384
+
385
+ const TypeText = styled.span`
386
+ font-size: 0.45rem;
387
+ color: #aaa;
388
+ `;
389
+
390
+ const SubTypeText = styled.span`
391
+ font-size: 0.4rem;
392
+ color: #666;
393
+ `;
394
+
395
+ const ColTier = styled.div`
396
+ font-size: 0.5rem;
397
+ color: #f59e0b;
398
+ text-align: center;
399
+ `;
400
+
401
+ const EmptyState = styled.div`
402
+ display: flex;
403
+ align-items: center;
404
+ justify-content: center;
405
+ height: 100px;
406
+ font-size: 0.55rem;
407
+ color: #666;
408
+ text-transform: uppercase;
409
+ letter-spacing: 1px;
410
+ `;
411
+
412
+ const PagerContainer = styled.div`
413
+ display: flex;
414
+ justify-content: center;
415
+ align-items: center;
416
+ `;
417
+
418
+ export { BLUEPRINTS_PER_PAGE };