@evershop/evershop 1.0.0-beta.2 → 1.0.0-beta.4
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 +34 -51
- package/bin/lib/app.js +2 -1
- package/package.json +1 -1
- package/src/lib/components/Area.js +3 -3
- package/src/lib/components/form/Form.js +19 -5
- package/src/lib/components/form/fields/Hidden.js +13 -9
- package/src/lib/components/form/fields/Radio.js +1 -1
- package/src/modules/base/graphql/types/Country/Country.graphql +2 -0
- package/src/modules/base/graphql/types/Country/Country.resolvers.js +11 -1
- package/src/modules/catalog/components/product/list/List.js +18 -2
- package/src/modules/catalog/graphql/types/Category/Category.resolvers.js +37 -3
- package/src/modules/catalog/graphql/types/FeaturedProduct/FeaturedProduct.resolvers.js +1 -0
- package/src/modules/catalog/migration/Version-1.0.1.js +8 -0
- package/src/modules/catalog/pages/admin/attributeEdit/index.js +2 -2
- package/src/modules/catalog/pages/admin/attributeEdit+attributeNew/General.js +1 -1
- package/src/modules/catalog/pages/admin/attributeGrid/rows/GroupRow.js +2 -1
- package/src/modules/catalog/pages/admin/productEdit+productNew/VariantGroup.js +1 -0
- package/src/modules/catalog/pages/admin/productEdit+productNew/variants/Variant.js +1 -1
- package/src/modules/catalog/pages/frontStore/categoryView/CategoryView.js +22 -0
- package/src/modules/catalog/pages/frontStore/categoryView/Filter.js +68 -52
- package/src/modules/catalog/pages/frontStore/categoryView/Filter.scss +43 -8
- package/src/modules/catalog/pages/frontStore/categoryView/General.js +12 -40
- package/src/modules/catalog/pages/frontStore/categoryView/General.scss +5 -0
- package/src/modules/catalog/pages/frontStore/categoryView/Pagination.js +2 -2
- package/src/modules/catalog/pages/frontStore/categoryView/Products.js +5 -5
- package/src/modules/catalog/{components/product/list → pages/frontStore/categoryView}/Sorting.js +31 -17
- package/src/modules/catalog/pages/frontStore/categoryView/[index]filters.js +0 -1
- package/src/modules/catalog/pages/frontStore/homepage/FeaturedCategories.js +3 -3
- package/src/modules/catalog/pages/frontStore/homepage/FeaturedProducts.js +1 -1
- package/src/modules/checkout/api/frontStore/addToCart/{addToCart.js → [detectCurrentCart]addToCart.js} +1 -1
- package/src/modules/checkout/api/frontStore/addToCart/[tokenVerify]detectCurrentCart[auth].js +3 -0
- package/src/modules/checkout/api/frontStore/checkoutPlaceOrder/route +1 -1
- package/src/modules/checkout/api/frontStore/checkoutSetContactInfo/saveContactInfo.js +4 -4
- package/src/modules/checkout/api/frontStore/checkoutSetPaymentInfo/savePaymentInfo.js +26 -4
- package/src/modules/checkout/api/frontStore/checkoutSetShipmentInfo/saveShipmentInfo.js +4 -4
- package/src/modules/checkout/components/frontStore/checkout/payment/paymentStep/StepContent.js +43 -83
- package/src/modules/checkout/components/frontStore/checkout/shipment/StepContent.js +1 -2
- package/src/modules/checkout/pages/admin/all/CheckoutMenuGroup.js +1 -1
- package/src/modules/checkout/pages/admin/orderEdit/Payment.js +8 -1
- package/src/modules/checkout/pages/admin/orderEdit/payment/Total.js +1 -0
- package/src/modules/checkout/pages/frontStore/all/[tokenVerify]detectCurrentCart[auth].js +7 -1
- package/src/modules/checkout/pages/frontStore/cart/ShoppingCart.js +1 -0
- package/src/modules/checkout/pages/frontStore/checkout/Checkout.js +1 -1
- package/src/modules/checkout/pages/frontStore/checkout/PaymentStep.js +1 -2
- package/src/modules/checkout/pages/frontStore/checkoutSuccess/CustomerInfo.js +1 -1
- package/src/modules/checkout/services/cart/Cart.js +130 -106
- package/src/modules/checkout/services/cart/DataObject.js +37 -11
- package/src/modules/checkout/services/cart/Item.js +153 -115
- package/src/modules/checkout/services/orderCreator.js +2 -0
- package/src/modules/checkout/services/toPrice.js +1 -0
- package/src/modules/cms/api/admin/imageUpload/[context]multerFile[auth].js +1 -1
- package/src/modules/cms/pages/admin/all/CmsMenuGroup.js +1 -1
- package/src/modules/cms/pages/frontStore/all/Meta.js +1 -0
- package/src/modules/cms/pages/frontStore/all/MobileMenu.js +2 -2
- package/src/modules/cms/pages/frontStore/homepage/MainBanner.js +8 -4
- package/src/modules/cms/pages/frontStore/homepage/MainBanner.scss +6 -7
- package/src/modules/cod/api/frontStore/codCapturePayment/[bodyParser]capture.js +51 -0
- package/src/modules/cod/api/frontStore/codCapturePayment/bodyParser.js +5 -0
- package/src/modules/cod/api/frontStore/codCapturePayment/route +2 -0
- package/src/modules/cod/api/frontStore/paymentMethods/[validateCart]registerCod[sendMethods].js +14 -0
- package/src/modules/cod/bootstrap.js +20 -0
- package/src/modules/cod/components/CODLogo.js +5 -0
- package/src/modules/cod/graphql/types/CODSetting/CODSetting.graphql +5 -0
- package/src/modules/cod/graphql/types/CODSetting/CODSetting.resolvers.js +20 -0
- package/src/modules/cod/pages/admin/orderEdit/CaptureButton.js +54 -0
- package/src/modules/cod/pages/admin/paymentSetting/CODSetting.js +59 -0
- package/src/modules/cod/pages/frontStore/checkout/CashOnDelivery.js +70 -0
- package/src/modules/customer/components/Address/AddressForm/AddressForm.js +106 -0
- package/src/modules/customer/components/Address/AddressForm/AddressFormLoadingSkeleton.js +18 -0
- package/src/modules/customer/components/Address/AddressForm/AddressFormLoadingSkeleton.scss +27 -0
- package/src/modules/customer/components/Address/AddressForm/Country.js +36 -0
- package/src/modules/customer/components/Address/AddressForm/Index.js +35 -0
- package/src/modules/customer/components/Address/AddressForm/NameAndTelephone.js +43 -0
- package/src/modules/customer/components/Address/AddressForm/Province.js +42 -0
- package/src/modules/customer/components/Address/AddressForm/ProvinceAndPostcode.js +52 -0
- package/src/modules/customer/{pages/frontStore/address → components/Address}/AddressSummary.js +1 -1
- package/src/modules/customer/pages/admin/all/CustomerMenuGroup.js +1 -1
- package/src/modules/customer/pages/frontStore/all/UserIcon.js +1 -1
- package/src/modules/customer/pages/frontStore/checkout/CustomerInfoStep.js +7 -2
- package/src/modules/graphql/api/frontStore/graphql/[bodyParser]graphql.js +8 -0
- package/src/modules/paypal/api/frontStore/paymentMethods/[validateCart]registerPaypal[sendMethods].js +21 -0
- package/src/modules/paypal/api/frontStore/paypalAuthorizePayment/[bodyParser]authorize.js +76 -0
- package/src/modules/paypal/api/frontStore/paypalAuthorizePayment/bodyParser.js +5 -0
- package/src/modules/paypal/api/frontStore/paypalAuthorizePayment/route +2 -0
- package/src/modules/paypal/api/frontStore/paypalCapturePayment/[bodyParser]capture.js +74 -0
- package/src/modules/paypal/api/frontStore/paypalCapturePayment/bodyParser.js +5 -0
- package/src/modules/paypal/api/frontStore/paypalCapturePayment/route +2 -0
- package/src/modules/paypal/api/frontStore/paypalCreateOrder/[bodyParser]createOrder.js +168 -0
- package/src/modules/paypal/api/frontStore/paypalCreateOrder/bodyParser.js +5 -0
- package/src/modules/paypal/api/frontStore/paypalCreateOrder/route +2 -0
- package/src/modules/paypal/api/frontStore/paypalGetAccessToken/[bodyParser]getAccessToken.js +66 -0
- package/src/modules/paypal/api/frontStore/paypalGetAccessToken/bodyParser.js +5 -0
- package/src/modules/paypal/api/frontStore/paypalGetAccessToken/route +2 -0
- package/src/modules/paypal/bootstrap.js +20 -0
- package/src/modules/paypal/components/PaypalLogo.js +5 -0
- package/src/modules/paypal/graphql/types/PaypalSetting/PaypalSetting.graphql +9 -0
- package/src/modules/paypal/graphql/types/PaypalSetting/PaypalSetting.resolvers.js +90 -0
- package/src/modules/paypal/migration/Version-1.0.0.js +7 -0
- package/src/modules/paypal/pages/admin/paymentSetting/PaypalSetting.js +119 -0
- package/src/modules/paypal/pages/frontStore/checkout/Paypal.js +137 -0
- package/src/modules/paypal/pages/frontStore/paypalCancel/index.js +29 -0
- package/src/modules/paypal/pages/frontStore/paypalCancel/route +2 -0
- package/src/modules/paypal/pages/frontStore/paypalReturn/Error.js +13 -0
- package/src/modules/paypal/pages/frontStore/paypalReturn/index.js +51 -0
- package/src/modules/paypal/pages/frontStore/paypalReturn/route +2 -0
- package/src/modules/paypal/services/getApiBaseUrl.js +5 -0
- package/src/modules/promotion/bootstrap.js +67 -66
- package/src/modules/promotion/pages/admin/all/CouponMenuGroup.js +1 -1
- package/src/modules/promotion/services/{couponValidator.js → CouponValidator.js} +0 -0
- package/src/modules/promotion/services/{discountCalculator.js → DiscountCalculator.js} +21 -18
- package/src/modules/setting/graphql/types/ShippingSetting/ShippingSetting.graphql +1 -1
- package/src/modules/setting/graphql/types/ShippingSetting/ShippingSetting.resolvers.js +5 -5
- package/src/modules/setting/pages/admin/paymentSetting/PaymentSetting.js +1 -1
- package/src/modules/setting/pages/admin/shippingSetting/ShippingSetting.js +4 -4
- package/src/modules/setting/pages/admin/storeSetting/StoreSetting.js +6 -6
- package/src/modules/stripe/bootstrap.js +20 -0
- package/src/modules/stripe/components/StripeLogo.js +5 -0
- package/src/modules/stripe/pages/frontStore/checkout/CheckoutForm.js +20 -26
- package/src/modules/stripe/pages/frontStore/checkout/Stripe.js +87 -0
- package/src/modules/checkout/components/frontStore/checkout/address/AddressBook.js +0 -82
- package/src/modules/checkout/components/frontStore/checkout/address/NewBillingAddressForm.js +0 -36
- package/src/modules/checkout/components/frontStore/checkout/address/NewShippingAddressForm.js +0 -38
- package/src/modules/checkout/components/frontStore/checkout/address/UseShippingAddress.js +0 -64
- package/src/modules/customer/pages/admin/customerGrid/NewCustomertButton.js +0 -17
- package/src/modules/customer/pages/admin/customerNew/index.js +0 -8
- package/src/modules/customer/pages/admin/customerNew/route +0 -2
- package/src/modules/customer/pages/frontStore/address/AddressForm.js +0 -238
- package/src/modules/stripe/index.js +0 -1
- package/src/modules/stripe/pages/frontStore/checkout/PaymentFormContext.js +0 -40
- package/src/modules/stripe/pages/frontStore/checkout/PaymentFormCustom.js +0 -71
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<p> </p>
|
|
2
2
|
<p align="center">
|
|
3
|
-
<h1 align="center">Lightweight
|
|
3
|
+
<h1 align="center">Lightweight And Extendable React E-commerce Platform</h1>
|
|
4
4
|
</p>
|
|
5
5
|
<p align="center">
|
|
6
6
|
<a href="https://evershop.io/docs/development/getting-started/introduction">Documentation</a>
|
|
@@ -15,49 +15,36 @@
|
|
|
15
15
|
</a>
|
|
16
16
|
</p>
|
|
17
17
|
|
|
18
|
-
##
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
url
|
|
40
|
-
}
|
|
41
|
-
url
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
`
|
|
45
|
-
```
|
|
18
|
+
## Introduction
|
|
19
|
+
|
|
20
|
+
EverShop is a GraphQL Based and React ecommerce platform with essential commerce features. Built with React, modular and fully customizable.
|
|
21
|
+
|
|
22
|
+
## Features
|
|
23
|
+
- Catalog management
|
|
24
|
+
- Product management
|
|
25
|
+
- Category management
|
|
26
|
+
- Attribute and attribute group
|
|
27
|
+
- Variant management
|
|
28
|
+
- Custom options
|
|
29
|
+
- Product layered navigation
|
|
30
|
+
- Order management
|
|
31
|
+
- Customer management
|
|
32
|
+
- Customer group
|
|
33
|
+
- Customer address
|
|
34
|
+
- Login, register and my account
|
|
35
|
+
- Advanced coupon management
|
|
36
|
+
- Online payment methods
|
|
37
|
+
- Stripe
|
|
38
|
+
- Paypal
|
|
46
39
|
|
|
47
40
|
## Demo
|
|
48
41
|
|
|
49
42
|
Explore our demo store.
|
|
50
43
|
|
|
51
44
|
<p align="center">
|
|
52
|
-
|
|
53
|
-
</p-->
|
|
54
|
-
<p align="left">
|
|
55
|
-
<a href="https://demo.evershop.io/" target="_blank">
|
|
56
|
-
<img alt="evershop-store-demo" height="35" alt="EverShop Store Demo" src="https://raw.githubusercontent.com/evershopcommerce/evershop/dev/.github/images/evershop-store-front-demo.png"/>
|
|
57
|
-
</a>
|
|
45
|
+
<img alt="EverShop Admin Demo" width="950" src="https://raw.githubusercontent.com/evershopcommerce/evershop/dev/.github/images/evershop-backend-demo.png"/>
|
|
58
46
|
</p>
|
|
59
|
-
|
|
60
|
-
<p align="left">
|
|
47
|
+
<p align="center">
|
|
61
48
|
<a href="https://demo.evershop.io/admin" target="_blank">
|
|
62
49
|
<img alt="evershop-backend-demo" height="35" alt="EverShop Admin Demo" src="https://raw.githubusercontent.com/evershopcommerce/evershop/dev/.github/images/evershop-admin-demo.png"/>
|
|
63
50
|
</a>
|
|
@@ -66,10 +53,14 @@ Explore our demo store.
|
|
|
66
53
|
|
|
67
54
|
Email: demo@gmail.com<br/>
|
|
68
55
|
Password: 123456
|
|
69
|
-
|
|
56
|
+
<p align="center">
|
|
70
57
|
<img alt="EverShop Store Demo" width="950" src="https://raw.githubusercontent.com/evershopcommerce/evershop/dev/.github/images/evershop-product-detail.png"/>
|
|
71
|
-
</p
|
|
72
|
-
|
|
58
|
+
</p>
|
|
59
|
+
<p align="center">
|
|
60
|
+
<a href="https://demo.evershop.io/" target="_blank">
|
|
61
|
+
<img alt="evershop-store-demo" height="35" alt="EverShop Store Demo" src="https://raw.githubusercontent.com/evershopcommerce/evershop/dev/.github/images/evershop-store-front-demo.png"/>
|
|
62
|
+
</a>
|
|
63
|
+
</p>
|
|
73
64
|
|
|
74
65
|
## Quick Start
|
|
75
66
|
|
|
@@ -85,22 +76,14 @@ npx create-evershop-app my-app --playAround
|
|
|
85
76
|
|
|
86
77
|
- [Theme development](https://evershop.io/docs/development/theme/theme-overview).
|
|
87
78
|
|
|
88
|
-
|
|
89
|
-
- Catalog management(with product attribute, custom option and variants)
|
|
90
|
-
- Order management
|
|
91
|
-
- Customer management
|
|
92
|
-
- Coupon management
|
|
93
|
-
- Tax
|
|
94
|
-
- Online payment (For now using Stripe)
|
|
95
|
-
- Basic CMS pages management
|
|
96
|
-
- Easy to customize by developing extensions
|
|
79
|
+
|
|
97
80
|
|
|
98
81
|
## Support
|
|
99
82
|
|
|
100
83
|
If you like my work, feel free to:
|
|
101
84
|
|
|
102
|
-
- ⭐ this repository. It
|
|
103
|
-
- [][tweet] about EverShop
|
|
85
|
+
- ⭐ this repository. It helps.
|
|
86
|
+
- [][tweet] about EverShop. Please accept my gratitude.
|
|
104
87
|
|
|
105
88
|
[tweet]: https://twitter.com/intent/tweet?url=https%3A%2F%2Fgithub.com%2Fevershopcommerce%2Fevershop&text=Awesome%20React%20Ecommerce%20Project&hashtags=react,ecommerce,expressjs,graphql
|
|
106
89
|
### Ask a question about EverShop
|
package/bin/lib/app.js
CHANGED
|
@@ -13,7 +13,8 @@ const { getEnabledExtensions } = require('../extension');
|
|
|
13
13
|
module.exports.createApp = () => {
|
|
14
14
|
/** Create express app */
|
|
15
15
|
const app = express();
|
|
16
|
-
|
|
16
|
+
// Enable trust proxy
|
|
17
|
+
app.enable('trust proxy');
|
|
17
18
|
/* Loading modules and initilize routes, components and services */
|
|
18
19
|
const modules = getCoreModules();
|
|
19
20
|
|
package/package.json
CHANGED
|
@@ -34,7 +34,7 @@ function Area(props) {
|
|
|
34
34
|
|
|
35
35
|
return (
|
|
36
36
|
<WrapperComponent {...areaWrapperProps}>
|
|
37
|
-
{areaComponents.map((w) => {
|
|
37
|
+
{areaComponents.map((w, index) => {
|
|
38
38
|
const C = w.component.default;
|
|
39
39
|
const id = w.id;
|
|
40
40
|
const propsMap = context.propsMap;
|
|
@@ -48,8 +48,8 @@ function Area(props) {
|
|
|
48
48
|
if (w.props) {
|
|
49
49
|
Object.assign(componentProps, w.props);
|
|
50
50
|
}
|
|
51
|
-
if (typeof C === 'string') return <C key={
|
|
52
|
-
return <C key={
|
|
51
|
+
if (typeof C === 'string') return <C key={index} {...componentProps} />;
|
|
52
|
+
return <C key={index} areaProps={props} {...componentProps} />;
|
|
53
53
|
})}
|
|
54
54
|
</WrapperComponent>
|
|
55
55
|
);
|
|
@@ -50,10 +50,22 @@ export function Form(props) {
|
|
|
50
50
|
const errors = {};
|
|
51
51
|
fields.forEach((f) => {
|
|
52
52
|
f.validationRules.forEach((r) => {
|
|
53
|
-
|
|
54
|
-
if
|
|
55
|
-
if (
|
|
56
|
-
|
|
53
|
+
let rule;
|
|
54
|
+
// Check if r is a string or an object
|
|
55
|
+
if (typeof r === 'string') {
|
|
56
|
+
rule = r;
|
|
57
|
+
} else {
|
|
58
|
+
rule = r.rule;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const ruleValidator = validator.getRule(rule);
|
|
62
|
+
if (ruleValidator === undefined) return;
|
|
63
|
+
if (!ruleValidator.handler.call(fields, f.value)) {
|
|
64
|
+
if (r.message) {
|
|
65
|
+
errors[f.name] = r.message;
|
|
66
|
+
} else {
|
|
67
|
+
errors[f.name] = ruleValidator.errorMessage;
|
|
68
|
+
}
|
|
57
69
|
}
|
|
58
70
|
});
|
|
59
71
|
});
|
|
@@ -119,7 +131,9 @@ export function Form(props) {
|
|
|
119
131
|
// Get the first element with the name of the field with error
|
|
120
132
|
const firstElementWithError = document.getElementsByName(firstFieldWithError)[0];
|
|
121
133
|
// Focus on the first element with error
|
|
122
|
-
firstElementWithError
|
|
134
|
+
if (firstElementWithError) {
|
|
135
|
+
firstElementWithError.focus();
|
|
136
|
+
}
|
|
123
137
|
}
|
|
124
138
|
} catch (error) {
|
|
125
139
|
if (onError) {
|
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
import PropTypes from 'prop-types';
|
|
2
2
|
import React from 'react';
|
|
3
|
+
import Error from './Error';
|
|
3
4
|
|
|
4
|
-
export function Hidden({ name, value }) {
|
|
5
|
+
export function Hidden({ name, value, error }) {
|
|
5
6
|
return (
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
7
|
+
<>
|
|
8
|
+
{error && <Error error={error} />}
|
|
9
|
+
<input
|
|
10
|
+
type="text"
|
|
11
|
+
id={name}
|
|
12
|
+
name={name}
|
|
13
|
+
value={value}
|
|
14
|
+
readOnly
|
|
15
|
+
style={{ display: 'none' }}
|
|
16
|
+
/>
|
|
17
|
+
</>
|
|
14
18
|
);
|
|
15
19
|
}
|
|
16
20
|
|
|
@@ -66,7 +66,7 @@ Radio.propTypes = {
|
|
|
66
66
|
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
67
67
|
text: PropTypes.string
|
|
68
68
|
})).isRequired,
|
|
69
|
-
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number])
|
|
69
|
+
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number])
|
|
70
70
|
};
|
|
71
71
|
|
|
72
72
|
Radio.defaultProps = {
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
const { contries } = require("../../../../../lib/locale/countries")
|
|
1
|
+
const { contries } = require("../../../../../lib/locale/countries");
|
|
2
|
+
const { getSetting } = require("../../../../setting/services/setting");
|
|
3
|
+
const { provinces } = require("../../../../../lib/locale/provinces");
|
|
2
4
|
|
|
3
5
|
module.exports = {
|
|
4
6
|
Query: {
|
|
@@ -9,6 +11,11 @@ module.exports = {
|
|
|
9
11
|
} else {
|
|
10
12
|
return contries.filter((c) => list.includes(c.code));
|
|
11
13
|
}
|
|
14
|
+
},
|
|
15
|
+
allowedCountries: async () => {
|
|
16
|
+
const allowedCountries = await getSetting("allowedCountries", '["US"]');
|
|
17
|
+
let list = JSON.parse(allowedCountries);
|
|
18
|
+
return contries.filter((c) => list.includes(c.code));
|
|
12
19
|
}
|
|
13
20
|
},
|
|
14
21
|
Country: {
|
|
@@ -26,6 +33,9 @@ module.exports = {
|
|
|
26
33
|
} else {
|
|
27
34
|
return country;
|
|
28
35
|
}
|
|
36
|
+
},
|
|
37
|
+
provinces: (country) => {
|
|
38
|
+
return provinces.filter((p) => p.countryCode === country.code);
|
|
29
39
|
}
|
|
30
40
|
}
|
|
31
41
|
}
|
|
@@ -6,7 +6,7 @@ import { Price } from './item/Price';
|
|
|
6
6
|
import Area from '../../../../../lib/components/Area';
|
|
7
7
|
import { get } from '../../../../../lib/util/get';
|
|
8
8
|
|
|
9
|
-
export default function ProductList({ products = [] }) {
|
|
9
|
+
export default function ProductList({ products = [], countPerRow = 3 }) {
|
|
10
10
|
if (products.length === 0) {
|
|
11
11
|
return (
|
|
12
12
|
<div className="product-list">
|
|
@@ -14,8 +14,24 @@ export default function ProductList({ products = [] }) {
|
|
|
14
14
|
</div>
|
|
15
15
|
);
|
|
16
16
|
}
|
|
17
|
+
|
|
18
|
+
let className;
|
|
19
|
+
switch (countPerRow) {
|
|
20
|
+
case 3:
|
|
21
|
+
className = 'grid grid-cols-2 md:grid-cols-3 gap-2';
|
|
22
|
+
break;
|
|
23
|
+
case 4:
|
|
24
|
+
className = 'grid grid-cols-2 md:grid-cols-4 gap-2';
|
|
25
|
+
break;
|
|
26
|
+
case 5:
|
|
27
|
+
className = 'grid grid-cols-2 md:grid-cols-5 gap-2';
|
|
28
|
+
break;
|
|
29
|
+
default:
|
|
30
|
+
className = 'grid grid-cols-2 md:grid-cols-3 gap-2';
|
|
31
|
+
}
|
|
32
|
+
|
|
17
33
|
return (
|
|
18
|
-
<div className=
|
|
34
|
+
<div className={className}>
|
|
19
35
|
{
|
|
20
36
|
products.map((p) => (
|
|
21
37
|
<Area
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
const { select } = require('@evershop/mysql-query-builder');
|
|
1
|
+
const { select, node } = require('@evershop/mysql-query-builder');
|
|
2
2
|
const { buildUrl } = require('../../../../../lib/router/buildUrl');
|
|
3
3
|
const { camelCase } = require('../../../../../lib/util/camelCase');
|
|
4
4
|
const uniqid = require('uniqid');
|
|
5
|
-
const {
|
|
5
|
+
const { getProductsBaseQuery } = require('../../../services/getProductsBaseQuery');
|
|
6
|
+
const { pool } = require('../../../../../lib/mysql/connection');
|
|
6
7
|
|
|
7
8
|
module.exports = {
|
|
8
9
|
Query: {
|
|
@@ -198,7 +199,7 @@ module.exports = {
|
|
|
198
199
|
},
|
|
199
200
|
Category: {
|
|
200
201
|
products: async (category, { filters = [] }, { filterableAttributes, priceRange }) => {
|
|
201
|
-
const query = await
|
|
202
|
+
const query = await getProductsBaseQuery(category.categoryId);
|
|
202
203
|
const currentFilters = [];
|
|
203
204
|
// Price filter
|
|
204
205
|
const priceFilter = filters.find((f) => f.key === 'price');
|
|
@@ -271,6 +272,39 @@ module.exports = {
|
|
|
271
272
|
value: sortOrder.value
|
|
272
273
|
});
|
|
273
274
|
}
|
|
275
|
+
|
|
276
|
+
// Visibility. For variant group
|
|
277
|
+
const copy = query.clone();
|
|
278
|
+
// Get all group that have at lease 1 item visibile
|
|
279
|
+
const visibleGroups = (await select('variant_group_id')
|
|
280
|
+
.from('variant_group')
|
|
281
|
+
.where('visibility', '=', 1)
|
|
282
|
+
.execute(pool)).map((v) => v.variant_group_id);
|
|
283
|
+
|
|
284
|
+
if (visibleGroups) {
|
|
285
|
+
// Get all invisible variants from current query
|
|
286
|
+
copy.select('SUM(product.`visibility`)', 'sumv')
|
|
287
|
+
.select('product.`product_id`')
|
|
288
|
+
.andWhere('product.`variant_group_id`', 'IN', visibleGroups);
|
|
289
|
+
copy.groupBy('product.`variant_group_id`')
|
|
290
|
+
.having('sumv', '=', 0);
|
|
291
|
+
|
|
292
|
+
const invisibleIds = (await copy.execute(pool)).map((v) => v.product_id);
|
|
293
|
+
if (invisibleIds.length > 0) {
|
|
294
|
+
const n = node('AND');
|
|
295
|
+
n.addLeaf('AND', 'product.`product_id`', 'IN', invisibleIds)
|
|
296
|
+
.addNode(
|
|
297
|
+
node('OR')
|
|
298
|
+
.addLeaf('OR', 'product.`visibility`', '=', 1)
|
|
299
|
+
);
|
|
300
|
+
query.getWhere().addNode(n);
|
|
301
|
+
} else {
|
|
302
|
+
query.andWhere('product.`visibility`', '=', 1);
|
|
303
|
+
}
|
|
304
|
+
} else {
|
|
305
|
+
query.andWhere('product.`visibility`', '=', 1);
|
|
306
|
+
}
|
|
307
|
+
|
|
274
308
|
// Clone the main query for getting total right before doing the paging
|
|
275
309
|
const cloneQuery = query.clone();
|
|
276
310
|
cloneQuery.select('COUNT(product.`product_id`)', 'total');
|
|
@@ -17,6 +17,7 @@ module.exports = {
|
|
|
17
17
|
query.leftJoin('cart_item')
|
|
18
18
|
.on('cart_item.`product_id`', '=', 'product.`product_id`');
|
|
19
19
|
query.where('product.`status`', '=', 1);
|
|
20
|
+
query.andWhere('product.`visibility`', '=', 1);
|
|
20
21
|
query.groupBy('product.`product_id`');
|
|
21
22
|
query.orderBy('soldQty', 'desc');
|
|
22
23
|
query.limit(0, 4);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
const { execute } = require('@evershop/mysql-query-builder');
|
|
2
|
+
const { pool } = require('../../../lib/mysql/connection');
|
|
3
|
+
|
|
4
|
+
// eslint-disable-next-line no-multi-assign
|
|
5
|
+
module.exports = exports = async () => {
|
|
6
|
+
await execute(pool, `UPDATE product SET visibility = 1 WHERE visibility IS NULL`);
|
|
7
|
+
await execute(pool, `ALTER TABLE product MODIFY COLUMN visibility smallint(2) NOT NULL DEFAULT 1`);
|
|
8
|
+
};
|
|
@@ -15,8 +15,8 @@ module.exports = async (request, response, delegate, next) => {
|
|
|
15
15
|
} else {
|
|
16
16
|
setContextValue(request, 'attributeId', attribute.attribute_id);
|
|
17
17
|
setContextValue(request, 'pageInfo', {
|
|
18
|
-
title: attribute.
|
|
19
|
-
description: attribute.
|
|
18
|
+
title: attribute.attribute_name,
|
|
19
|
+
description: attribute.attribute_name
|
|
20
20
|
});
|
|
21
21
|
next();
|
|
22
22
|
}
|
|
@@ -21,11 +21,12 @@ export default function GroupRow({ groups, saveAttributeGroupUrl }) {
|
|
|
21
21
|
onSuccess={() => {
|
|
22
22
|
location.reload();
|
|
23
23
|
}}
|
|
24
|
+
isJSON={true}
|
|
24
25
|
>
|
|
25
26
|
<Field
|
|
26
27
|
formId="group-edit"
|
|
27
28
|
type="text"
|
|
28
|
-
name="
|
|
29
|
+
name="group_name"
|
|
29
30
|
value={group.groupName}
|
|
30
31
|
/>
|
|
31
32
|
<Field
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import Area from '../../../../../lib/components/Area';
|
|
3
|
+
|
|
4
|
+
export default function CategoryView() {
|
|
5
|
+
return (
|
|
6
|
+
<div className="page-width grid grid-cols-1 md:grid-cols-4 gap-2">
|
|
7
|
+
<Area
|
|
8
|
+
id="leftColumn"
|
|
9
|
+
className="md:col-span-1"
|
|
10
|
+
/>
|
|
11
|
+
<Area
|
|
12
|
+
id="rightColumn"
|
|
13
|
+
className="md:col-span-3"
|
|
14
|
+
/>
|
|
15
|
+
</div>
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const layout = {
|
|
20
|
+
areaId: 'content',
|
|
21
|
+
sortOrder: 10
|
|
22
|
+
}
|