@rpg-engine/long-bow 0.8.128 → 0.8.130

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.128",
3
+ "version": "0.8.130",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "typings": "dist/index.d.ts",
@@ -15,7 +15,7 @@ import { StorePacksSection } from './sections/StorePacksSection';
15
15
  import { StoreItemDetails } from './StoreItemDetails';
16
16
 
17
17
  // Define TabId union type for tab identifiers
18
- type TabId = 'premium' | 'packs' | 'items';
18
+ type TabId = 'premium' | 'packs' | 'items' | 'wallet';
19
19
 
20
20
  // Define IStoreProps locally as a workaround
21
21
  export interface IStoreProps {
@@ -33,6 +33,8 @@ export interface IStoreProps {
33
33
  tabOrder?: TabId[];
34
34
  defaultActiveTab?: TabId;
35
35
  textInputItemKeys?: string[];
36
+ customPacksContent?: React.ReactNode;
37
+ customWalletContent?: React.ReactNode;
36
38
  }
37
39
 
38
40
  export const Store: React.FC<IStoreProps> = ({
@@ -50,6 +52,8 @@ export const Store: React.FC<IStoreProps> = ({
50
52
  tabOrder,
51
53
  defaultActiveTab,
52
54
  textInputItemKeys = [],
55
+ customPacksContent,
56
+ customWalletContent,
53
57
  }) => {
54
58
  const [selectedPack, setSelectedPack] = useState<IItemPack | null>(null);
55
59
  const [activeTab, setActiveTab] = useState<TabId>(() => {
@@ -149,7 +153,7 @@ export const Store: React.FC<IStoreProps> = ({
149
153
  const tabIds: TabId[] = tabOrder ?? ['premium', 'packs', 'items'];
150
154
  const availableTabIds: TabId[] = tabIds.filter(id => !(hidePremiumTab && id === 'premium'));
151
155
 
152
- const tabsMap: Record<TabId, { id: TabId; title: string; content: ReactNode }> = {
156
+ const tabsMap: Record<string, { id: TabId; title: string; content: ReactNode }> = {
153
157
  premium: {
154
158
  id: 'premium',
155
159
  title: 'Premium',
@@ -164,7 +168,7 @@ export const Store: React.FC<IStoreProps> = ({
164
168
  packs: {
165
169
  id: 'packs',
166
170
  title: 'Packs',
167
- content: (
171
+ content: customPacksContent ?? (
168
172
  <StorePacksSection
169
173
  packs={packs.filter(pack => pack.priceUSD < 9.99)}
170
174
  onAddToCart={handleAddPackToCart}
@@ -186,6 +190,11 @@ export const Store: React.FC<IStoreProps> = ({
186
190
  />
187
191
  ),
188
192
  },
193
+ wallet: {
194
+ id: 'wallet',
195
+ title: 'Wallet',
196
+ content: customWalletContent ?? null,
197
+ },
189
198
  };
190
199
 
191
200
  const tabs = availableTabIds.map(id => tabsMap[id]);
@@ -4,7 +4,6 @@ import { FaCartPlus } from 'react-icons/fa';
4
4
  import styled from 'styled-components';
5
5
  import { CTAButton } from '../../shared/CTAButton/CTAButton';
6
6
  import { ScrollableContent } from '../../shared/ScrollableContent/ScrollableContent';
7
- import { ShoppingCardHorizontal } from '../../shared/ShoppingCart/CartCardHorizontal';
8
7
  import { usePackFiltering } from '../../../hooks/usePackFiltering';
9
8
 
10
9
  interface IStorePacksSectionProps {
@@ -18,39 +17,39 @@ export const StorePacksSection: React.FC<IStorePacksSectionProps> = ({
18
17
  onAddToCart,
19
18
  onSelectPack,
20
19
  }) => {
21
- const { searchQuery, setSearchQuery, filteredPacks } = usePackFiltering(
22
- packs
23
- );
20
+ const { searchQuery, setSearchQuery, filteredPacks } = usePackFiltering(packs);
24
21
 
25
- const renderPackFooter = useCallback(
26
- (pack: IItemPack) => (
27
- <FooterContainer>
28
- <Price>${pack.priceUSD}</Price>
29
- <CTAButton
30
- icon={<FaCartPlus />}
31
- label="Add"
32
- onClick={e => {
33
- e.stopPropagation();
34
- onAddToCart(pack);
35
- }}
36
- />
37
- </FooterContainer>
38
- ),
39
- [onAddToCart]
40
- );
22
+ const getImageSrc = (imageUrl: IItemPack['image']): string => {
23
+ if (typeof imageUrl === 'string') return imageUrl;
24
+ return imageUrl.default || imageUrl.src;
25
+ };
41
26
 
42
27
  const renderPack = useCallback(
43
28
  (pack: IItemPack) => (
44
- <ShoppingCardHorizontal
45
- key={pack.key}
46
- title={pack.title}
47
- description={pack.description}
48
- imageUrl={pack.image}
49
- footer={renderPackFooter(pack)}
50
- onClick={() => onSelectPack?.(pack)}
51
- />
29
+ <PackRow key={pack.key} onClick={() => onSelectPack?.(pack)}>
30
+ <PackIconContainer>
31
+ <img src={getImageSrc(pack.image)} alt={pack.title} />
32
+ </PackIconContainer>
33
+
34
+ <PackDetails>
35
+ <PackName>{pack.title}</PackName>
36
+ <PackPrice>${pack.priceUSD}</PackPrice>
37
+ {pack.description && <PackDescription>{pack.description}</PackDescription>}
38
+ </PackDetails>
39
+
40
+ <Controls>
41
+ <CTAButton
42
+ icon={<FaCartPlus />}
43
+ label="Add"
44
+ onClick={e => {
45
+ e.stopPropagation();
46
+ onAddToCart(pack);
47
+ }}
48
+ />
49
+ </Controls>
50
+ </PackRow>
52
51
  ),
53
- [onSelectPack, renderPackFooter]
52
+ [onSelectPack, onAddToCart]
54
53
  );
55
54
 
56
55
  return (
@@ -63,22 +62,73 @@ export const StorePacksSection: React.FC<IStorePacksSectionProps> = ({
63
62
  onChange: setSearchQuery,
64
63
  placeholder: 'Search packs...',
65
64
  }}
66
- layout="grid"
67
- gridColumns={2}
65
+ layout="list"
68
66
  maxHeight="420px"
69
67
  />
70
68
  );
71
69
  };
72
70
 
73
- const FooterContainer = styled.div`
71
+ const PackRow = styled.div`
74
72
  display: flex;
75
73
  align-items: center;
76
- justify-content: space-between;
77
- gap: 8px;
74
+ gap: 0.75rem;
75
+ padding: 0.5rem 1rem;
76
+ border-bottom: 1px solid rgba(255, 255, 255, 0.1);
77
+ cursor: pointer;
78
+
79
+ &:last-child {
80
+ border-bottom: none;
81
+ }
82
+
83
+ &:hover {
84
+ background: rgba(255, 255, 255, 0.04);
85
+ }
86
+ `;
87
+
88
+ const PackIconContainer = styled.div`
89
+ width: 40px;
90
+ height: 40px;
91
+ flex-shrink: 0;
92
+ display: flex;
93
+ align-items: center;
94
+ justify-content: center;
95
+
96
+ img {
97
+ width: 100%;
98
+ height: 100%;
99
+ object-fit: cover;
100
+ }
78
101
  `;
79
102
 
80
- const Price = styled.span`
103
+ const PackDetails = styled.div`
104
+ flex: 1;
105
+ display: flex;
106
+ flex-direction: column;
107
+ gap: 0.25rem;
108
+ min-width: 0;
109
+ `;
110
+
111
+ const PackName = styled.div`
81
112
  font-family: 'Press Start 2P', cursive;
82
- font-size: 0.6rem;
113
+ font-size: 0.75rem;
114
+ color: #ffffff;
115
+ `;
116
+
117
+ const PackPrice = styled.div`
118
+ font-family: 'Press Start 2P', cursive;
119
+ font-size: 0.625rem;
83
120
  color: #fef08a;
84
121
  `;
122
+
123
+ const PackDescription = styled.div`
124
+ font-family: 'Press Start 2P', cursive;
125
+ font-size: 0.625rem;
126
+ color: rgba(255, 255, 255, 0.7);
127
+ line-height: 1.4;
128
+ `;
129
+
130
+ const Controls = styled.div`
131
+ display: flex;
132
+ align-items: center;
133
+ flex-shrink: 0;
134
+ `;