Skip to content

Commit 9798734

Browse files
authored
Refactor/store headless components (#8)
1 parent 48571c5 commit 9798734

File tree

13 files changed

+1015
-1054
lines changed

13 files changed

+1015
-1054
lines changed

src/headless/store/Collection.tsx

Lines changed: 57 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@ import { CollectionServiceDefinition } from "./collection-service";
44
import { productsV3 } from "@wix/stores";
55

66
/**
7-
* Props for ProductGrid headless component
7+
* Props for Grid headless component
88
*/
9-
export interface ProductGridProps {
9+
export interface GridProps {
1010
/** Render prop function that receives product grid data */
11-
children: (props: ProductGridRenderProps) => React.ReactNode;
11+
children: (props: GridRenderProps) => React.ReactNode;
1212
}
1313

1414
/**
15-
* Render props for ProductGrid component
15+
* Render props for Grid component
1616
*/
17-
export interface ProductGridRenderProps {
17+
export interface GridRenderProps {
1818
/** Array of products */
1919
products: productsV3.V3Product[];
2020
/** Whether products are loading */
@@ -32,7 +32,7 @@ export interface ProductGridRenderProps {
3232
/**
3333
* Headless component for product grid
3434
*/
35-
export const ProductGrid = (props: ProductGridProps) => {
35+
export const Grid = (props: GridProps) => {
3636
const service = useService(CollectionServiceDefinition) as ServiceAPI<
3737
typeof CollectionServiceDefinition
3838
>;
@@ -80,79 +80,79 @@ export const ProductGrid = (props: ProductGridProps) => {
8080
};
8181

8282
/**
83-
* Props for ProductCard headless component
83+
* Props for Item headless component
8484
*/
85-
export interface ProductCardProps {
85+
export interface ItemProps {
8686
/** Product data */
8787
product: productsV3.V3Product;
88-
/** Render prop function that receives product card data */
89-
children: (props: ProductCardRenderProps) => React.ReactNode;
88+
/** Render prop function that receives product item data */
89+
children: (props: ItemRenderProps) => React.ReactNode;
9090
}
9191

9292
/**
93-
* Render props for ProductCard component
93+
* Render props for Item component
9494
*/
95-
export interface ProductCardRenderProps {
95+
export interface ItemRenderProps {
9696
/** Product ID */
97-
productId: string;
98-
/** Product name */
99-
name: string;
97+
id: string;
98+
/** Product title */
99+
title: string;
100100
/** Product slug for URL */
101101
slug: string;
102102
/** Main product image URL */
103-
imageUrl: string | null;
103+
image: string | null;
104104
/** Product price */
105105
price: string;
106106
/** Product description */
107107
description: string;
108-
/** Whether product is in stock */
109-
inStock: boolean;
108+
/** Whether product is available */
109+
available: boolean;
110110
/** Product URL */
111-
productUrl: string;
111+
href: string;
112112
}
113113

114114
/**
115-
* Headless component for individual product card
115+
* Headless component for individual product item
116116
*/
117-
export const ProductCard = (props: ProductCardProps) => {
117+
export const Item = (props: ItemProps) => {
118118
const { product } = props;
119119

120120
// Use actual v3 API structure based on real data
121121
// Images are in media.main.image, not media.itemsInfo.items
122-
const imageUrl = product?.media?.main?.image || null;
122+
const image = product?.media?.main?.image || null;
123123

124124
// Create formatted price since formattedAmount is not available
125125
const rawAmount = product.actualPriceRange?.minValue?.amount;
126126
const price = rawAmount ? `$${rawAmount}` : "$0.00";
127127

128-
const inStock = product.inventory?.availabilityStatus === "IN_STOCK";
128+
const available = product.inventory?.availabilityStatus === "IN_STOCK";
129129
const description =
130130
typeof product.description === "string" ? product.description : "";
131131

132132
return props.children({
133-
productId: product._id || "",
134-
name: product.name || "",
133+
id: product._id || "",
134+
title: product.name || "",
135135
slug: product.slug || "",
136-
imageUrl,
136+
image,
137137
price,
138138
description,
139-
inStock,
140-
productUrl: `/store/products/${product.slug}`,
139+
available,
140+
href: `/store/products/${product.slug}`,
141141
});
142142
};
143143

144144
/**
145-
* Props for LoadMoreProducts headless component
145+
* Props for LoadMore headless component
146146
*/
147-
export interface LoadMoreProductsProps {
147+
export interface LoadMoreProps {
148148
/** Render prop function that receives load more data */
149-
children: (props: LoadMoreProductsRenderProps) => React.ReactNode;
149+
children: (props: LoadMoreRenderProps) => React.ReactNode;
150150
}
151151

152152
/**
153-
* Render props for LoadMoreProducts component
153+
* Render props for LoadMore component
154154
*/
155-
export interface LoadMoreProductsRenderProps {
155+
export interface LoadMoreRenderProps {
156156
/** Function to load more products */
157157
loadMore: () => Promise<void>;
158158
/** Function to refresh products */
@@ -169,14 +169,14 @@ export interface LoadMoreProductsRenderProps {
169169
* Headless component for load more products functionality
170170
* Note: V3 API uses simplified loading without traditional pagination
171171
*/
172-
export const LoadMoreProducts = (props: LoadMoreProductsProps) => {
172+
export const LoadMore = (props: LoadMoreProps) => {
173173
const service = useService(CollectionServiceDefinition) as ServiceAPI<
174174
typeof CollectionServiceDefinition
175175
>;
176176

177177
// Error handling for undefined service
178178
if (!service) {
179-
console.error("CollectionService is undefined in LoadMoreProducts");
179+
console.error("CollectionService is undefined in LoadMore");
180180
return props.children({
181181
loadMore: async () => {},
182182
refresh: async () => {},
@@ -199,7 +199,7 @@ export const LoadMoreProducts = (props: LoadMoreProductsProps) => {
199199
totalProducts,
200200
});
201201
} catch (err) {
202-
console.error("Error in LoadMoreProducts:", err);
202+
console.error("Error in LoadMore:", err);
203203
return props.children({
204204
loadMore: async () => {},
205205
refresh: async () => {},
@@ -211,17 +211,17 @@ export const LoadMoreProducts = (props: LoadMoreProductsProps) => {
211211
};
212212

213213
/**
214-
* Props for CollectionHeader headless component
214+
* Props for Header headless component
215215
*/
216-
export interface CollectionHeaderProps {
216+
export interface HeaderProps {
217217
/** Render prop function that receives collection header data */
218-
children: (props: CollectionHeaderRenderProps) => React.ReactNode;
218+
children: (props: HeaderRenderProps) => React.ReactNode;
219219
}
220220

221221
/**
222-
* Render props for CollectionHeader component
222+
* Render props for Header component
223223
*/
224-
export interface CollectionHeaderRenderProps {
224+
export interface HeaderRenderProps {
225225
/** Total number of products */
226226
totalProducts: number;
227227
/** Whether collection is loading */
@@ -233,14 +233,14 @@ export interface CollectionHeaderRenderProps {
233233
/**
234234
* Headless component for collection header with product count
235235
*/
236-
export const CollectionHeader = (props: CollectionHeaderProps) => {
236+
export const Header = (props: HeaderProps) => {
237237
const service = useService(CollectionServiceDefinition) as ServiceAPI<
238238
typeof CollectionServiceDefinition
239239
>;
240240

241241
// Error handling for undefined service
242242
if (!service) {
243-
console.error("CollectionService is undefined in CollectionHeader");
243+
console.error("CollectionService is undefined in Header");
244244
return props.children({
245245
totalProducts: 0,
246246
isLoading: false,
@@ -259,7 +259,7 @@ export const CollectionHeader = (props: CollectionHeaderProps) => {
259259
hasProducts,
260260
});
261261
} catch (err) {
262-
console.error("Error in CollectionHeader:", err);
262+
console.error("Error in Header:", err);
263263
return props.children({
264264
totalProducts: 0,
265265
isLoading: false,
@@ -269,17 +269,17 @@ export const CollectionHeader = (props: CollectionHeaderProps) => {
269269
};
270270

271271
/**
272-
* Props for CollectionActions headless component
272+
* Props for Actions headless component
273273
*/
274-
export interface CollectionActionsProps {
274+
export interface ActionsProps {
275275
/** Render prop function that receives collection actions data */
276-
children: (props: CollectionActionsRenderProps) => React.ReactNode;
276+
children: (props: ActionsRenderProps) => React.ReactNode;
277277
}
278278

279279
/**
280-
* Render props for CollectionActions component
280+
* Render props for Actions component
281281
*/
282-
export interface CollectionActionsRenderProps {
282+
export interface ActionsRenderProps {
283283
/** Function to refresh the collection */
284284
refresh: () => Promise<void>;
285285
/** Function to load more products */
@@ -294,14 +294,14 @@ export interface CollectionActionsRenderProps {
294294
* Headless component for collection actions (refresh, load more)
295295
* Replaces traditional pagination for V3 API
296296
*/
297-
export const CollectionActions = (props: CollectionActionsProps) => {
297+
export const Actions = (props: ActionsProps) => {
298298
const service = useService(CollectionServiceDefinition) as ServiceAPI<
299299
typeof CollectionServiceDefinition
300300
>;
301301

302302
// Error handling for undefined service
303303
if (!service) {
304-
console.error("CollectionService is undefined in CollectionActions");
304+
console.error("CollectionService is undefined in Actions");
305305
return props.children({
306306
refresh: async () => {},
307307
loadMore: async () => {},
@@ -321,7 +321,7 @@ export const CollectionActions = (props: CollectionActionsProps) => {
321321
error,
322322
});
323323
} catch (err) {
324-
console.error("Error in CollectionActions:", err);
324+
console.error("Error in Actions:", err);
325325
return props.children({
326326
refresh: async () => {},
327327
loadMore: async () => {},
@@ -331,11 +331,10 @@ export const CollectionActions = (props: CollectionActionsProps) => {
331331
}
332332
};
333333

334-
// Namespace export for clean API
335334
export const Collection = {
336-
ProductGrid,
337-
ProductCard,
338-
LoadMoreProducts,
339-
CollectionHeader,
340-
CollectionActions,
335+
Grid,
336+
Item,
337+
LoadMore,
338+
Header,
339+
Actions,
341340
} as const;

0 commit comments

Comments
 (0)