@webbycrown/webbycommerce 1.2.1 → 2.0.0
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/README.md +21 -3
- package/admin/app.js +3 -0
- package/admin/jsconfig.json +20 -0
- package/admin/src/components/ApiCollectionsContent.jsx +4626 -0
- package/admin/src/components/CompareContent.jsx +300 -0
- package/admin/src/components/ConfigureContent.jsx +407 -0
- package/admin/src/components/Initializer.jsx +64 -0
- package/admin/src/components/LoginRegisterContent.jsx +280 -0
- package/admin/src/components/PluginIcon.jsx +6 -0
- package/admin/src/components/ShippingTypeContent.jsx +230 -0
- package/admin/src/components/SmtpContent.jsx +316 -0
- package/admin/src/components/WishlistContent.jsx +273 -0
- package/admin/src/index.js +81 -0
- package/admin/src/pages/ApiCollections.jsx +169 -0
- package/admin/src/pages/Configure.jsx +55 -0
- package/admin/src/pages/Settings.jsx +93 -0
- package/admin/src/pluginId.js +4 -0
- package/{dist/_chunks/en-CiQ97iC8.js → admin/src/translations/en.json} +712 -574
- package/bin/setup.js +50 -3
- package/package.json +14 -13
- package/server/bootstrap.js +3 -0
- package/server/register.js +3 -0
- package/server/src/bootstrap.js +3826 -0
- package/server/src/components/content-block.json +37 -0
- package/server/src/components/shipping-zone-location.json +27 -0
- package/server/src/config/index.js +7 -0
- package/server/src/content-types/address/index.js +7 -0
- package/server/src/content-types/address/schema.json +74 -0
- package/server/src/content-types/cart/index.js +61 -0
- package/server/src/content-types/cart-item/index.js +79 -0
- package/server/src/content-types/compare.js +73 -0
- package/server/src/content-types/coupon/index.js +7 -0
- package/server/src/content-types/coupon/schema.json +67 -0
- package/server/src/content-types/index.js +42 -0
- package/server/src/content-types/order/index.js +7 -0
- package/server/src/content-types/order/schema.json +121 -0
- package/server/src/content-types/payment-transaction/index.js +7 -0
- package/server/src/content-types/payment-transaction/schema.json +73 -0
- package/server/src/content-types/product/index.js +7 -0
- package/server/src/content-types/product/schema.json +104 -0
- package/server/src/content-types/product-attribute/index.js +7 -0
- package/server/src/content-types/product-attribute/schema.json +80 -0
- package/server/src/content-types/product-attribute-value/index.js +7 -0
- package/server/src/content-types/product-attribute-value/schema.json +52 -0
- package/server/src/content-types/product-category/index.js +7 -0
- package/server/src/content-types/product-category/schema.json +54 -0
- package/server/src/content-types/product-tag/index.js +7 -0
- package/server/src/content-types/product-tag/schema.json +38 -0
- package/server/src/content-types/product-variation/index.js +7 -0
- package/server/src/content-types/product-variation/schema.json +74 -0
- package/server/src/content-types/shipping-method/index.js +7 -0
- package/server/src/content-types/shipping-method/schema.json +91 -0
- package/server/src/content-types/shipping-rate/index.js +7 -0
- package/server/src/content-types/shipping-rate/schema.json +73 -0
- package/server/src/content-types/shipping-rule/index.js +7 -0
- package/server/src/content-types/shipping-rule/schema.json +84 -0
- package/server/src/content-types/shipping-zone/index.js +7 -0
- package/server/src/content-types/shipping-zone/schema.json +57 -0
- package/server/src/content-types/wishlist.js +66 -0
- package/server/src/controllers/address.js +374 -0
- package/server/src/controllers/auth.js +1409 -0
- package/server/src/controllers/cart.js +337 -0
- package/server/src/controllers/category.js +388 -0
- package/server/src/controllers/compare.js +246 -0
- package/server/src/controllers/controller.js +168 -0
- package/server/src/controllers/ecommerce.js +20 -0
- package/server/src/controllers/index.js +34 -0
- package/server/src/controllers/order.js +1100 -0
- package/server/src/controllers/payment.js +243 -0
- package/server/src/controllers/product.js +1006 -0
- package/server/src/controllers/productTag.js +370 -0
- package/server/src/controllers/productVariation.js +181 -0
- package/server/src/controllers/shipping.js +1046 -0
- package/server/src/controllers/wishlist.js +332 -0
- package/server/src/destroy.js +6 -0
- package/server/src/index.js +26 -0
- package/server/src/middlewares/index.js +4 -0
- package/server/src/policies/index.js +4 -0
- package/server/src/register.js +67 -0
- package/server/src/routes/index.js +1130 -0
- package/server/src/services/cart.js +531 -0
- package/server/src/services/compare.js +300 -0
- package/server/src/services/index.js +16 -0
- package/server/src/services/service.js +19 -0
- package/server/src/services/shipping.js +513 -0
- package/server/src/services/wishlist.js +238 -0
- package/server/src/utils/check-ecommerce-permission.js +204 -0
- package/server/src/utils/extend-user-schema.js +161 -0
- package/server/src/utils/seed-data.js +639 -0
- package/server/src/utils/send-email.js +98 -0
- package/strapi-server.js +1 -6
- package/dist/_chunks/Settings-Bg2JyQ4c.js +0 -31518
- package/dist/_chunks/Settings-BonPzbwr.mjs +0 -31499
- package/dist/_chunks/en-DE15m4xZ.mjs +0 -574
- package/dist/_chunks/index-BWVy9o1d.mjs +0 -128
- package/dist/_chunks/index-NRuOdjd7.js +0 -127
- package/dist/admin/index.js +0 -3
- package/dist/admin/index.mjs +0 -4
- package/dist/robots.txt +0 -3
- package/dist/server/index.js +0 -27336
- package/dist/uploads/.gitkeep +0 -0
- package/dist/uploads/accessories_category_2a5631094b.jpeg +0 -0
- package/dist/uploads/beauty_personal_care_category_57f8a8f1e3.jpeg +0 -0
- package/dist/uploads/books_category_a9a253eada.jpeg +0 -0
- package/dist/uploads/classic_cotton_tshirt_1_cd713425f6.png +0 -0
- package/dist/uploads/clothing_category_d5c60ef07b.jpeg +0 -0
- package/dist/uploads/daviddoe_strapi_adbcd41787.jpeg +0 -0
- package/dist/uploads/electronics_category_fc3e5ef571.jpeg +0 -0
- package/dist/uploads/ergonomic_office_chair_1_c751cffb07.png +0 -0
- package/dist/uploads/home_garden_category_4f6eb3f8d6.jpeg +0 -0
- package/dist/uploads/istockphoto_1188462138_612x612_11f295b9c0.jpg +0 -0
- package/dist/uploads/istockphoto_1188462138_612x612_396fb272fd.jpg +0 -0
- package/dist/uploads/large_daviddoe_strapi_adbcd41787.jpeg +0 -0
- package/dist/uploads/leather_travel_backpack_1_238bc1ae4d.png +0 -0
- package/dist/uploads/mechanical_keyboard_pro_1_0cd391a6ac.png +0 -0
- package/dist/uploads/medium_classic_cotton_tshirt_1_cd713425f6.png +0 -0
- package/dist/uploads/medium_daviddoe_strapi_adbcd41787.jpeg +0 -0
- package/dist/uploads/medium_ergonomic_office_chair_1_c751cffb07.png +0 -0
- package/dist/uploads/medium_leather_travel_backpack_1_238bc1ae4d.png +0 -0
- package/dist/uploads/medium_mechanical_keyboard_pro_1_0cd391a6ac.png +0 -0
- package/dist/uploads/medium_smart_watch_series_5_1_cdc2511fb7.png +0 -0
- package/dist/uploads/medium_smartphone_x_pro_1_c3f0cbd080.png +0 -0
- package/dist/uploads/medium_the_great_gatsby_special_1_2e7c76d997.png +0 -0
- package/dist/uploads/medium_wireless_headphones_1_fa75cd50c3.png +0 -0
- package/dist/uploads/medium_yoga_mat_premium_1_01f9a3b5fa.png +0 -0
- package/dist/uploads/predictive_maintenance_icons_industry_automation_600nw_2685943461_e18a8aa3b0.webp +0 -0
- package/dist/uploads/small_classic_cotton_tshirt_1_cd713425f6.png +0 -0
- package/dist/uploads/small_daviddoe_strapi_adbcd41787.jpeg +0 -0
- package/dist/uploads/small_ergonomic_office_chair_1_c751cffb07.png +0 -0
- package/dist/uploads/small_leather_travel_backpack_1_238bc1ae4d.png +0 -0
- package/dist/uploads/small_mechanical_keyboard_pro_1_0cd391a6ac.png +0 -0
- package/dist/uploads/small_smart_watch_series_5_1_cdc2511fb7.png +0 -0
- package/dist/uploads/small_smartphone_x_pro_1_c3f0cbd080.png +0 -0
- package/dist/uploads/small_the_great_gatsby_special_1_2e7c76d997.png +0 -0
- package/dist/uploads/small_wireless_headphones_1_fa75cd50c3.png +0 -0
- package/dist/uploads/small_yoga_mat_premium_1_01f9a3b5fa.png +0 -0
- package/dist/uploads/smart_watch_series_5_1_cdc2511fb7.png +0 -0
- package/dist/uploads/smartphone_x_pro_1_c3f0cbd080.png +0 -0
- package/dist/uploads/the_great_gatsby_special_1_2e7c76d997.png +0 -0
- package/dist/uploads/thumbnail_accessories_category_2a5631094b.jpeg +0 -0
- package/dist/uploads/thumbnail_beauty_personal_care_category_57f8a8f1e3.jpeg +0 -0
- package/dist/uploads/thumbnail_books_category_a9a253eada.jpeg +0 -0
- package/dist/uploads/thumbnail_classic_cotton_tshirt_1_cd713425f6.png +0 -0
- package/dist/uploads/thumbnail_clothing_category_d5c60ef07b.jpeg +0 -0
- package/dist/uploads/thumbnail_daviddoe_strapi_adbcd41787.jpeg +0 -0
- package/dist/uploads/thumbnail_electronics_category_fc3e5ef571.jpeg +0 -0
- package/dist/uploads/thumbnail_ergonomic_office_chair_1_c751cffb07.png +0 -0
- package/dist/uploads/thumbnail_home_garden_category_4f6eb3f8d6.jpeg +0 -0
- package/dist/uploads/thumbnail_istockphoto_1188462138_612x612_11f295b9c0.jpg +0 -0
- package/dist/uploads/thumbnail_istockphoto_1188462138_612x612_396fb272fd.jpg +0 -0
- package/dist/uploads/thumbnail_leather_travel_backpack_1_238bc1ae4d.png +0 -0
- package/dist/uploads/thumbnail_mechanical_keyboard_pro_1_0cd391a6ac.png +0 -0
- package/dist/uploads/thumbnail_predictive_maintenance_icons_industry_automation_600nw_2685943461_e18a8aa3b0.webp +0 -0
- package/dist/uploads/thumbnail_smart_watch_series_5_1_cdc2511fb7.png +0 -0
- package/dist/uploads/thumbnail_smartphone_x_pro_1_c3f0cbd080.png +0 -0
- package/dist/uploads/thumbnail_the_great_gatsby_special_1_2e7c76d997.png +0 -0
- package/dist/uploads/thumbnail_wireless_headphones_1_fa75cd50c3.png +0 -0
- package/dist/uploads/thumbnail_yoga_mat_premium_1_01f9a3b5fa.png +0 -0
- package/dist/uploads/webby-commerce.png +0 -0
- package/dist/uploads/wireless_headphones_1_fa75cd50c3.png +0 -0
- package/dist/uploads/yoga_mat_premium_1_01f9a3b5fa.png +0 -0
- /package/{dist → server/src}/data/demo-data.json +0 -0
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* compare service
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const { createCoreService } = require('@strapi/strapi').factories;
|
|
8
|
+
|
|
9
|
+
module.exports = createCoreService('plugin::webbycommerce.compare', ({ strapi }) => ({
|
|
10
|
+
async findUserCompare(userId) {
|
|
11
|
+
try {
|
|
12
|
+
const compares = await strapi.db.query('plugin::webbycommerce.compare').findMany({
|
|
13
|
+
where: {
|
|
14
|
+
userId: String(userId),
|
|
15
|
+
},
|
|
16
|
+
orderBy: { createdAt: 'desc' },
|
|
17
|
+
populate: {
|
|
18
|
+
products: {
|
|
19
|
+
populate: {
|
|
20
|
+
images: true,
|
|
21
|
+
product_categories: true,
|
|
22
|
+
tags: true,
|
|
23
|
+
variations: {
|
|
24
|
+
populate: {
|
|
25
|
+
attributes: true,
|
|
26
|
+
attributeValues: true,
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
category: true,
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
return compares.length > 0 ? compares[0] : null;
|
|
36
|
+
} catch (error) {
|
|
37
|
+
throw new Error(`Failed to find user compare: ${error.message}`);
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
async createUserCompare(userId, userEmail, data = {}) {
|
|
42
|
+
try {
|
|
43
|
+
const compareData = {
|
|
44
|
+
userId: String(userId),
|
|
45
|
+
userEmail,
|
|
46
|
+
products: [],
|
|
47
|
+
isPublic: data.isPublic || false,
|
|
48
|
+
name: data.name || null,
|
|
49
|
+
notes: data.notes || null,
|
|
50
|
+
category: data.categoryId || null,
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
await strapi.entityService.create('plugin::webbycommerce.compare', {
|
|
54
|
+
data: compareData,
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// Refetch compare with populated products
|
|
58
|
+
return await this.findUserCompare(userId);
|
|
59
|
+
} catch (error) {
|
|
60
|
+
throw new Error(`Failed to create user compare: ${error.message}`);
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
async addProductToCompare(userId, userEmail, productId) {
|
|
65
|
+
try {
|
|
66
|
+
// Find existing compare or create new one
|
|
67
|
+
let compare = await this.findUserCompare(userId);
|
|
68
|
+
|
|
69
|
+
if (!compare) {
|
|
70
|
+
compare = await this.createUserCompare(userId, userEmail);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Ensure products array exists
|
|
74
|
+
if (!compare.products) {
|
|
75
|
+
compare.products = [];
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Check if compare list is already full (max 4 products)
|
|
79
|
+
if (compare.products.length >= 4) {
|
|
80
|
+
throw new Error('Compare list is full. Maximum 4 products allowed.');
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Check if product already exists in compare
|
|
84
|
+
// Handle both populated (object with id) and unpopulated (just id) cases
|
|
85
|
+
const productExists = compare.products.some(product => {
|
|
86
|
+
const productIdValue = typeof product === 'object' && product !== null ? product.id : product;
|
|
87
|
+
return productIdValue === parseInt(productId);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
if (productExists) {
|
|
91
|
+
throw new Error('Product already exists in compare list');
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Verify product exists
|
|
95
|
+
const product = await strapi.entityService.findOne('plugin::webbycommerce.product', productId, {
|
|
96
|
+
populate: ['product_categories'],
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
if (!product) {
|
|
100
|
+
throw new Error('Product not found');
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Check if product belongs to same category (optional but recommended)
|
|
104
|
+
if (compare.category && product.product_categories && product.product_categories.length > 0 && compare.category.id !== product.product_categories[0].id) {
|
|
105
|
+
// Allow but log warning - user can compare different categories if they want
|
|
106
|
+
strapi.log.warn(`Adding product from different category to compare list. Compare category: ${compare.category.name}, Product category: ${product.product_categories[0].name}`);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Get existing product IDs (handle both populated and unpopulated cases)
|
|
110
|
+
const existingProductIds = compare.products.map(p => {
|
|
111
|
+
return typeof p === 'object' && p !== null ? p.id : p;
|
|
112
|
+
}).filter(id => id != null);
|
|
113
|
+
|
|
114
|
+
// Add product to compare
|
|
115
|
+
await strapi.entityService.update('plugin::webbycommerce.compare', compare.id, {
|
|
116
|
+
data: {
|
|
117
|
+
products: { set: [...existingProductIds, parseInt(productId, 10)].map((id) => ({ id })) },
|
|
118
|
+
category: compare.category || product.product_categories?.[0]?.id || null,
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
// Refetch compare with populated products
|
|
123
|
+
return await this.findUserCompare(userId);
|
|
124
|
+
} catch (error) {
|
|
125
|
+
throw new Error(`Failed to add product to compare: ${error.message}`);
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
|
|
129
|
+
async removeProductFromCompare(userId, productId) {
|
|
130
|
+
try {
|
|
131
|
+
const compare = await this.findUserCompare(userId);
|
|
132
|
+
|
|
133
|
+
if (!compare) {
|
|
134
|
+
throw new Error('Compare list not found');
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Ensure products array exists
|
|
138
|
+
if (!compare.products) {
|
|
139
|
+
compare.products = [];
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Remove product from compare
|
|
143
|
+
// Handle both populated (object with id) and unpopulated (just id) cases
|
|
144
|
+
const updatedProducts = compare.products
|
|
145
|
+
.filter(product => {
|
|
146
|
+
const productIdValue = typeof product === 'object' && product !== null ? product.id : product;
|
|
147
|
+
return productIdValue !== parseInt(productId);
|
|
148
|
+
})
|
|
149
|
+
.map(product => {
|
|
150
|
+
return typeof product === 'object' && product !== null ? product.id : product;
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
await strapi.entityService.update('plugin::webbycommerce.compare', compare.id, {
|
|
154
|
+
data: {
|
|
155
|
+
products: { set: updatedProducts.map((id) => ({ id })) },
|
|
156
|
+
// Reset category if no products left
|
|
157
|
+
category: updatedProducts.length === 0 ? null : compare.category,
|
|
158
|
+
},
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
// Refetch compare with populated products
|
|
162
|
+
return await this.findUserCompare(userId);
|
|
163
|
+
} catch (error) {
|
|
164
|
+
throw new Error(`Failed to remove product from compare: ${error.message}`);
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
|
|
168
|
+
async clearCompare(userId) {
|
|
169
|
+
try {
|
|
170
|
+
const compare = await this.findUserCompare(userId);
|
|
171
|
+
|
|
172
|
+
if (!compare) {
|
|
173
|
+
throw new Error('Compare list not found');
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
await strapi.entityService.update('plugin::webbycommerce.compare', compare.id, {
|
|
177
|
+
data: {
|
|
178
|
+
products: { set: [] },
|
|
179
|
+
category: null,
|
|
180
|
+
},
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
// Refetch compare with populated products
|
|
184
|
+
return await this.findUserCompare(userId);
|
|
185
|
+
} catch (error) {
|
|
186
|
+
throw new Error(`Failed to clear compare list: ${error.message}`);
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
|
|
190
|
+
async updateCompare(userId, data) {
|
|
191
|
+
try {
|
|
192
|
+
const compare = await this.findUserCompare(userId);
|
|
193
|
+
|
|
194
|
+
if (!compare) {
|
|
195
|
+
throw new Error('Compare list not found');
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
await strapi.entityService.update('plugin::webbycommerce.compare', compare.id, {
|
|
199
|
+
data: {
|
|
200
|
+
name: data.name !== undefined ? data.name : compare.name,
|
|
201
|
+
notes: data.notes !== undefined ? data.notes : compare.notes,
|
|
202
|
+
isPublic: data.isPublic !== undefined ? data.isPublic : compare.isPublic,
|
|
203
|
+
},
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
// Refetch compare with populated products
|
|
207
|
+
return await this.findUserCompare(userId);
|
|
208
|
+
} catch (error) {
|
|
209
|
+
throw new Error(`Failed to update compare list: ${error.message}`);
|
|
210
|
+
}
|
|
211
|
+
},
|
|
212
|
+
|
|
213
|
+
async getCompareData(userId) {
|
|
214
|
+
try {
|
|
215
|
+
const compare = await this.findUserCompare(userId);
|
|
216
|
+
|
|
217
|
+
if (!compare) {
|
|
218
|
+
return {
|
|
219
|
+
products: [],
|
|
220
|
+
category: null,
|
|
221
|
+
comparisonData: {},
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// Ensure products array exists
|
|
226
|
+
if (!compare.products) {
|
|
227
|
+
compare.products = [];
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Generate comparison data
|
|
231
|
+
const comparisonData = this.generateComparisonData(compare.products);
|
|
232
|
+
|
|
233
|
+
return {
|
|
234
|
+
products: compare.products,
|
|
235
|
+
category: compare.category,
|
|
236
|
+
comparisonData,
|
|
237
|
+
};
|
|
238
|
+
} catch (error) {
|
|
239
|
+
throw new Error(`Failed to get compare data: ${error.message}`);
|
|
240
|
+
}
|
|
241
|
+
},
|
|
242
|
+
|
|
243
|
+
generateComparisonData(products) {
|
|
244
|
+
if (!products || products.length === 0) {
|
|
245
|
+
return {};
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const comparisonData = {
|
|
249
|
+
specifications: {},
|
|
250
|
+
pricing: {},
|
|
251
|
+
availability: {},
|
|
252
|
+
ratings: {},
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
// Extract common specifications
|
|
256
|
+
const specKeys = new Set();
|
|
257
|
+
products.forEach(product => {
|
|
258
|
+
if (product.specifications) {
|
|
259
|
+
Object.keys(product.specifications).forEach(key => specKeys.add(key));
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
// Build comparison matrix
|
|
264
|
+
specKeys.forEach(specKey => {
|
|
265
|
+
comparisonData.specifications[specKey] = {};
|
|
266
|
+
products.forEach(product => {
|
|
267
|
+
comparisonData.specifications[specKey][product.id] =
|
|
268
|
+
product.specifications?.[specKey] || 'N/A';
|
|
269
|
+
});
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
// Pricing comparison
|
|
273
|
+
products.forEach(product => {
|
|
274
|
+
comparisonData.pricing[product.id] = {
|
|
275
|
+
regularPrice: product.regularPrice || 0,
|
|
276
|
+
salePrice: product.salePrice || null,
|
|
277
|
+
discount: product.discount || 0,
|
|
278
|
+
};
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
// Availability comparison
|
|
282
|
+
products.forEach(product => {
|
|
283
|
+
comparisonData.availability[product.id] = {
|
|
284
|
+
inStock: product.stockQuantity > 0,
|
|
285
|
+
stockQuantity: product.stockQuantity || 0,
|
|
286
|
+
status: product.status || 'active',
|
|
287
|
+
};
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
// Ratings comparison
|
|
291
|
+
products.forEach(product => {
|
|
292
|
+
comparisonData.ratings[product.id] = {
|
|
293
|
+
averageRating: product.averageRating || 0,
|
|
294
|
+
totalReviews: product.totalReviews || 0,
|
|
295
|
+
};
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
return comparisonData;
|
|
299
|
+
},
|
|
300
|
+
}));
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const service = require('./service');
|
|
4
|
+
const compare = require('./compare');
|
|
5
|
+
const cart = require('./cart');
|
|
6
|
+
const wishlist = require('./wishlist');
|
|
7
|
+
const shipping = require('./shipping');
|
|
8
|
+
|
|
9
|
+
module.exports = {
|
|
10
|
+
service,
|
|
11
|
+
compare,
|
|
12
|
+
cart,
|
|
13
|
+
wishlist,
|
|
14
|
+
shipping,
|
|
15
|
+
};
|
|
16
|
+
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const PLUGIN_ID = 'webbycommerce';
|
|
4
|
+
|
|
5
|
+
const { seedDemoData } = require('../utils/seed-data');
|
|
6
|
+
|
|
7
|
+
module.exports = ({ strapi }) => ({
|
|
8
|
+
getPluginInfo() {
|
|
9
|
+
return {
|
|
10
|
+
name: PLUGIN_ID,
|
|
11
|
+
version: '1.0.0',
|
|
12
|
+
};
|
|
13
|
+
},
|
|
14
|
+
|
|
15
|
+
async seedDemoData() {
|
|
16
|
+
return await seedDemoData(strapi);
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
|