@fleetbase/storefront-engine 0.0.1
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/LICENSE.md +9 -0
- package/README.md +32 -0
- package/addon/adapters/addon-category.js +1 -0
- package/addon/adapters/customer.js +1 -0
- package/addon/adapters/gateway.js +1 -0
- package/addon/adapters/network.js +1 -0
- package/addon/adapters/notification-channel.js +1 -0
- package/addon/adapters/product-addon-category.js +1 -0
- package/addon/adapters/product-addon.js +1 -0
- package/addon/adapters/product-hour.js +1 -0
- package/addon/adapters/product-store-location.js +1 -0
- package/addon/adapters/product-variant-option.js +1 -0
- package/addon/adapters/product-variant.js +1 -0
- package/addon/adapters/product.js +1 -0
- package/addon/adapters/store-hour.js +1 -0
- package/addon/adapters/store-location.js +1 -0
- package/addon/adapters/store.js +1 -0
- package/addon/adapters/storefront.js +5 -0
- package/addon/components/file-record.hbs +22 -0
- package/addon/components/file-record.js +43 -0
- package/addon/components/modals/add-store-hours.hbs +8 -0
- package/addon/components/modals/add-stores-to-network.hbs +5 -0
- package/addon/components/modals/assign-driver.hbs +25 -0
- package/addon/components/modals/create-first-store.hbs +21 -0
- package/addon/components/modals/create-gateway.hbs +35 -0
- package/addon/components/modals/create-network-category.hbs +50 -0
- package/addon/components/modals/create-network.hbs +20 -0
- package/addon/components/modals/create-new-variant.hbs +15 -0
- package/addon/components/modals/create-notification-channel.hbs +45 -0
- package/addon/components/modals/create-product-category.hbs +30 -0
- package/addon/components/modals/create-store.hbs +9 -0
- package/addon/components/modals/edit-network.hbs +1 -0
- package/addon/components/modals/import-products.hbs +97 -0
- package/addon/components/modals/incoming-order.hbs +242 -0
- package/addon/components/modals/manage-addons.hbs +50 -0
- package/addon/components/modals/manage-addons.js +86 -0
- package/addon/components/modals/order-ready-assign-driver.hbs +36 -0
- package/addon/components/modals/select-addon-category.hbs +5 -0
- package/addon/components/modals/share-network.hbs +35 -0
- package/addon/components/modals/store-location-form.hbs +30 -0
- package/addon/components/order-card.hbs +1 -0
- package/addon/components/order-card.js +3 -0
- package/addon/components/schedule-manager.hbs +22 -0
- package/addon/components/schedule-manager.js +73 -0
- package/addon/components/settings-container.hbs +7 -0
- package/addon/components/store-selector.hbs +21 -0
- package/addon/components/store-selector.js +20 -0
- package/addon/components/widget/customers.hbs +44 -0
- package/addon/components/widget/customers.js +53 -0
- package/addon/components/widget/orders.hbs +111 -0
- package/addon/components/widget/orders.js +248 -0
- package/addon/components/widget/storefront-metrics.hbs +54 -0
- package/addon/components/widget/storefront-metrics.js +61 -0
- package/addon/controllers/application.js +33 -0
- package/addon/controllers/customers/index.js +267 -0
- package/addon/controllers/home.js +3 -0
- package/addon/controllers/networks/index/network/customers.js +3 -0
- package/addon/controllers/networks/index/network/index.js +147 -0
- package/addon/controllers/networks/index/network/orders.js +3 -0
- package/addon/controllers/networks/index/network/stores.js +370 -0
- package/addon/controllers/networks/index/network.js +29 -0
- package/addon/controllers/networks/index.js +138 -0
- package/addon/controllers/orders/index.js +331 -0
- package/addon/controllers/products/index/category/edit.js +62 -0
- package/addon/controllers/products/index/category/new.js +287 -0
- package/addon/controllers/products/index/category.js +163 -0
- package/addon/controllers/products/index/index/edit.js +1 -0
- package/addon/controllers/products/index/index.js +136 -0
- package/addon/controllers/products/index.js +203 -0
- package/addon/controllers/settings/api.js +3 -0
- package/addon/controllers/settings/gateways.js +110 -0
- package/addon/controllers/settings/index.js +102 -0
- package/addon/controllers/settings/locations.js +186 -0
- package/addon/controllers/settings/notifications.js +102 -0
- package/addon/engine.js +19 -0
- package/addon/helpers/get-tip-amount.js +5 -0
- package/addon/models/addon-category.js +6 -0
- package/addon/models/gateway.js +46 -0
- package/addon/models/network.js +166 -0
- package/addon/models/notification-channel.js +47 -0
- package/addon/models/product-addon-category.js +41 -0
- package/addon/models/product-addon.js +41 -0
- package/addon/models/product-hour.js +72 -0
- package/addon/models/product-store-location.js +41 -0
- package/addon/models/product-variant-option.js +39 -0
- package/addon/models/product-variant.js +44 -0
- package/addon/models/product.js +208 -0
- package/addon/models/store-hour.js +72 -0
- package/addon/models/store-location.js +93 -0
- package/addon/models/store.js +100 -0
- package/addon/routes/application.js +47 -0
- package/addon/routes/customers/index/edit.js +3 -0
- package/addon/routes/customers/index.js +25 -0
- package/addon/routes/home.js +3 -0
- package/addon/routes/networks/index/network/customers.js +3 -0
- package/addon/routes/networks/index/network/index.js +15 -0
- package/addon/routes/networks/index/network/orders.js +3 -0
- package/addon/routes/networks/index/network/stores.js +28 -0
- package/addon/routes/networks/index/network.js +10 -0
- package/addon/routes/networks/index.js +19 -0
- package/addon/routes/orders/index/edit.js +3 -0
- package/addon/routes/orders/index/new.js +3 -0
- package/addon/routes/orders/index/view.js +3 -0
- package/addon/routes/orders/index.js +29 -0
- package/addon/routes/products/index/category/edit.js +15 -0
- package/addon/routes/products/index/category/new.js +7 -0
- package/addon/routes/products/index/category.js +54 -0
- package/addon/routes/products/index/index/edit.js +1 -0
- package/addon/routes/products/index/index.js +22 -0
- package/addon/routes/products/index.js +21 -0
- package/addon/routes/settings/api.js +10 -0
- package/addon/routes/settings/gateways.js +11 -0
- package/addon/routes/settings/index.js +16 -0
- package/addon/routes/settings/locations.js +14 -0
- package/addon/routes/settings/notifications.js +11 -0
- package/addon/routes.js +48 -0
- package/addon/serializers/addon-category.js +15 -0
- package/addon/serializers/network.js +19 -0
- package/addon/serializers/notification-channel.js +15 -0
- package/addon/serializers/product-addon-category.js +15 -0
- package/addon/serializers/product-variant.js +15 -0
- package/addon/serializers/product.js +20 -0
- package/addon/serializers/store-location.js +17 -0
- package/addon/serializers/store.js +19 -0
- package/addon/services/storefront.js +208 -0
- package/addon/templates/application.hbs +16 -0
- package/addon/templates/customers/index/edit.hbs +2 -0
- package/addon/templates/customers/index.hbs +22 -0
- package/addon/templates/home.hbs +7 -0
- package/addon/templates/networks/index/network/customers.hbs +2 -0
- package/addon/templates/networks/index/network/index.hbs +254 -0
- package/addon/templates/networks/index/network/orders.hbs +2 -0
- package/addon/templates/networks/index/network/stores.hbs +164 -0
- package/addon/templates/networks/index/network.hbs +38 -0
- package/addon/templates/networks/index.hbs +60 -0
- package/addon/templates/orders/index/edit.hbs +2 -0
- package/addon/templates/orders/index/new.hbs +2 -0
- package/addon/templates/orders/index/view.hbs +2 -0
- package/addon/templates/orders/index.hbs +22 -0
- package/addon/templates/products/index/category/edit.hbs +1 -0
- package/addon/templates/products/index/category/new.hbs +248 -0
- package/addon/templates/products/index/category.hbs +41 -0
- package/addon/templates/products/index/index/edit.hbs +1 -0
- package/addon/templates/products/index/index.hbs +40 -0
- package/addon/templates/products/index.hbs +22 -0
- package/addon/templates/settings/api.hbs +18 -0
- package/addon/templates/settings/gateways.hbs +48 -0
- package/addon/templates/settings/index.hbs +229 -0
- package/addon/templates/settings/locations.hbs +39 -0
- package/addon/templates/settings/notifications.hbs +35 -0
- package/addon/templates/settings.hbs +30 -0
- package/addon/utils/get-gateway-schemas.js +34 -0
- package/addon/utils/get-notification-schemas.js +18 -0
- package/app/adapters/addon-category.js +1 -0
- package/app/adapters/gateway.js +1 -0
- package/app/adapters/network.js +1 -0
- package/app/adapters/notification-channel.js +1 -0
- package/app/adapters/product-addon-category.js +1 -0
- package/app/adapters/product-addon.js +1 -0
- package/app/adapters/product-hour.js +1 -0
- package/app/adapters/product-store-location.js +1 -0
- package/app/adapters/product-variant-option.js +1 -0
- package/app/adapters/product-variant.js +1 -0
- package/app/adapters/product.js +1 -0
- package/app/adapters/store-hour.js +1 -0
- package/app/adapters/store-location.js +1 -0
- package/app/adapters/store.js +1 -0
- package/app/adapters/storefront.js +1 -0
- package/app/components/file-record.js +1 -0
- package/app/components/modals/add-store-hours.js +1 -0
- package/app/components/modals/add-stores-to-network.js +1 -0
- package/app/components/modals/assign-driver.js +1 -0
- package/app/components/modals/create-first-store.js +1 -0
- package/app/components/modals/create-gateway.js +1 -0
- package/app/components/modals/create-network-category.js +1 -0
- package/app/components/modals/create-network.js +1 -0
- package/app/components/modals/create-new-variant.js +1 -0
- package/app/components/modals/create-notification-channel.js +1 -0
- package/app/components/modals/create-product-category.js +1 -0
- package/app/components/modals/create-store.js +1 -0
- package/app/components/modals/edit-network.js +1 -0
- package/app/components/modals/import-products.js +1 -0
- package/app/components/modals/incoming-order.js +1 -0
- package/app/components/modals/manage-addons.js +1 -0
- package/app/components/modals/order-ready-assign-driver.js +1 -0
- package/app/components/modals/select-addon-category.js +1 -0
- package/app/components/modals/share-network.js +1 -0
- package/app/components/modals/store-location-form.js +1 -0
- package/app/components/order-card.js +1 -0
- package/app/components/schedule-manager.js +1 -0
- package/app/components/settings-container.js +1 -0
- package/app/components/store-selector.js +1 -0
- package/app/components/widget/customers.js +1 -0
- package/app/components/widget/orders.js +1 -0
- package/app/components/widget/storefront-metrics.js +1 -0
- package/app/controllers/application.js +1 -0
- package/app/controllers/customers/index.js +1 -0
- package/app/controllers/home.js +1 -0
- package/app/controllers/networks/index/network/customers.js +1 -0
- package/app/controllers/networks/index/network/index.js +1 -0
- package/app/controllers/networks/index/network/orders.js +1 -0
- package/app/controllers/networks/index/network/stores.js +1 -0
- package/app/controllers/networks/index/network.js +1 -0
- package/app/controllers/networks/index.js +1 -0
- package/app/controllers/orders/index.js +1 -0
- package/app/controllers/products/index/category/edit.js +1 -0
- package/app/controllers/products/index/category/new.js +1 -0
- package/app/controllers/products/index/category.js +1 -0
- package/app/controllers/products/index/index/edit.js +1 -0
- package/app/controllers/products/index/index.js +1 -0
- package/app/controllers/products/index.js +1 -0
- package/app/controllers/settings/api.js +1 -0
- package/app/controllers/settings/gateways.js +1 -0
- package/app/controllers/settings/index.js +1 -0
- package/app/controllers/settings/locations.js +1 -0
- package/app/controllers/settings/notifications.js +1 -0
- package/app/helpers/get-tip-amount.js +1 -0
- package/app/models/addon-category.js +1 -0
- package/app/models/gateway.js +1 -0
- package/app/models/network.js +1 -0
- package/app/models/notification-channel.js +1 -0
- package/app/models/product-addon-category.js +1 -0
- package/app/models/product-addon.js +1 -0
- package/app/models/product-hour.js +1 -0
- package/app/models/product-store-location.js +1 -0
- package/app/models/product-variant-option.js +1 -0
- package/app/models/product-variant.js +1 -0
- package/app/models/product.js +1 -0
- package/app/models/store-hour.js +1 -0
- package/app/models/store-location.js +1 -0
- package/app/models/store.js +1 -0
- package/app/routes/application.js +1 -0
- package/app/routes/customers/index/edit.js +1 -0
- package/app/routes/customers/index.js +1 -0
- package/app/routes/home.js +1 -0
- package/app/routes/networks/index/network/customers.js +1 -0
- package/app/routes/networks/index/network/index.js +1 -0
- package/app/routes/networks/index/network/orders.js +1 -0
- package/app/routes/networks/index/network/stores.js +1 -0
- package/app/routes/networks/index/network.js +1 -0
- package/app/routes/networks/index.js +1 -0
- package/app/routes/orders/index/edit.js +1 -0
- package/app/routes/orders/index/new.js +1 -0
- package/app/routes/orders/index/view.js +1 -0
- package/app/routes/orders/index.js +1 -0
- package/app/routes/products/index/category/edit.js +1 -0
- package/app/routes/products/index/category/new.js +1 -0
- package/app/routes/products/index/category.js +1 -0
- package/app/routes/products/index/index/edit.js +1 -0
- package/app/routes/products/index/index.js +1 -0
- package/app/routes/products/index.js +1 -0
- package/app/routes/settings/api.js +1 -0
- package/app/routes/settings/gateways.js +1 -0
- package/app/routes/settings/index.js +1 -0
- package/app/routes/settings/locations.js +1 -0
- package/app/routes/settings/notifications.js +1 -0
- package/app/serializers/addon-category.js +1 -0
- package/app/serializers/network.js +1 -0
- package/app/serializers/notification-channel.js +1 -0
- package/app/serializers/product-addon-category.js +1 -0
- package/app/serializers/product-variant.js +1 -0
- package/app/serializers/product.js +1 -0
- package/app/serializers/store-location.js +1 -0
- package/app/serializers/store.js +1 -0
- package/app/services/storefront.js +1 -0
- package/app/templates/customers/index/edit.js +1 -0
- package/app/templates/customers/index.js +1 -0
- package/app/templates/home.js +1 -0
- package/app/templates/networks/index/network/customers.js +1 -0
- package/app/templates/networks/index/network/index.js +1 -0
- package/app/templates/networks/index/network/orders.js +1 -0
- package/app/templates/networks/index/network/stores.js +1 -0
- package/app/templates/networks/index/network.js +1 -0
- package/app/templates/networks/index.js +1 -0
- package/app/templates/orders/index/edit.js +1 -0
- package/app/templates/orders/index/new.js +1 -0
- package/app/templates/orders/index/view.js +1 -0
- package/app/templates/orders/index.js +1 -0
- package/app/templates/products/index/category/edit.js +1 -0
- package/app/templates/products/index/category/new.js +1 -0
- package/app/templates/products/index/category.js +1 -0
- package/app/templates/products/index/index/edit.js +1 -0
- package/app/templates/products/index/index.js +1 -0
- package/app/templates/products/index.js +1 -0
- package/app/templates/settings/api.js +1 -0
- package/app/templates/settings/gateways.js +1 -0
- package/app/templates/settings/index.js +1 -0
- package/app/templates/settings/locations.js +1 -0
- package/app/templates/settings/notifications.js +1 -0
- package/app/templates/settings.js +1 -0
- package/app/utils/get-gateway-schemas.js +1 -0
- package/app/utils/get-notification-schemas.js +1 -0
- package/config/environment.js +21 -0
- package/index.js +22 -0
- package/package.json +123 -0
- package/pnpm-lock.yaml +12509 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import ApplicationSerializer from '@fleetbase/ember-core/serializers/application';
|
|
2
|
+
import { EmbeddedRecordsMixin } from '@ember-data/serializer/rest';
|
|
3
|
+
|
|
4
|
+
export default class ProductSerializer extends ApplicationSerializer.extend(EmbeddedRecordsMixin) {
|
|
5
|
+
/**
|
|
6
|
+
* Embedded relationship attributes
|
|
7
|
+
*
|
|
8
|
+
* @var {Object}
|
|
9
|
+
*/
|
|
10
|
+
get attrs() {
|
|
11
|
+
return {
|
|
12
|
+
variants: { embedded: 'always' },
|
|
13
|
+
addon_categories: { embedded: 'always' },
|
|
14
|
+
primary_image: { embedded: 'always' },
|
|
15
|
+
files: { embedded: 'always' },
|
|
16
|
+
hours: { embedded: 'always' },
|
|
17
|
+
category: { embedded: 'always' },
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import ApplicationSerializer from '@fleetbase/ember-core/serializers/application';
|
|
2
|
+
import { EmbeddedRecordsMixin } from '@ember-data/serializer/rest';
|
|
3
|
+
|
|
4
|
+
export default class StoreLocationSerializer extends ApplicationSerializer.extend(EmbeddedRecordsMixin) {
|
|
5
|
+
/**
|
|
6
|
+
* Embedded relationship attributes
|
|
7
|
+
*
|
|
8
|
+
* @var {Object}
|
|
9
|
+
*/
|
|
10
|
+
get attrs() {
|
|
11
|
+
return {
|
|
12
|
+
place: { embedded: 'always' },
|
|
13
|
+
store: { embedded: 'always' },
|
|
14
|
+
hours: { embedded: 'always' },
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import ApplicationSerializer from '@fleetbase/ember-core/serializers/application';
|
|
2
|
+
import { EmbeddedRecordsMixin } from '@ember-data/serializer/rest';
|
|
3
|
+
|
|
4
|
+
export default class StoreSerializer extends ApplicationSerializer.extend(EmbeddedRecordsMixin) {
|
|
5
|
+
/**
|
|
6
|
+
* Embedded relationship attributes
|
|
7
|
+
*
|
|
8
|
+
* @var {Object}
|
|
9
|
+
*/
|
|
10
|
+
get attrs() {
|
|
11
|
+
return {
|
|
12
|
+
gateways: { embedded: 'always' },
|
|
13
|
+
notification_channels: { embedded: 'always' },
|
|
14
|
+
logo: { embedded: 'always' },
|
|
15
|
+
backdrop: { embedded: 'always' },
|
|
16
|
+
files: { embedded: 'always' },
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import Service from '@ember/service';
|
|
2
|
+
import Evented from '@ember/object/evented';
|
|
3
|
+
import { inject as service } from '@ember/service';
|
|
4
|
+
import socketClusterClient from 'socketcluster';
|
|
5
|
+
|
|
6
|
+
export default class StorefrontService extends Service.extend(Evented) {
|
|
7
|
+
@service store;
|
|
8
|
+
@service fetch;
|
|
9
|
+
@service notifications;
|
|
10
|
+
@service currentUser;
|
|
11
|
+
@service modalsManager;
|
|
12
|
+
@service hostRouter;
|
|
13
|
+
|
|
14
|
+
get activeStore() {
|
|
15
|
+
return this.findActiveStore();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
setActiveStorefront(store) {
|
|
19
|
+
this.currentUser.setOption('activeStorefront', store.id);
|
|
20
|
+
this.trigger('storefront.changed', store);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
findActiveStore() {
|
|
24
|
+
const activeStoreId = this.currentUser.getOption('activeStorefront');
|
|
25
|
+
|
|
26
|
+
if (!activeStoreId) {
|
|
27
|
+
const stores = this.store.peekAll('store');
|
|
28
|
+
|
|
29
|
+
if (stores.firstObject) {
|
|
30
|
+
this.currentUser.setOption('activeStorefront', stores.firstObject.id);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return stores.firstObject;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const activeStore = this.store.peekRecord('store', activeStoreId);
|
|
37
|
+
|
|
38
|
+
if (!activeStore) {
|
|
39
|
+
this.currentUser.setOption('activeStorefront', undefined);
|
|
40
|
+
|
|
41
|
+
return this.findActiveStore();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return activeStore;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async alertIncomingOrder(orderId, store) {
|
|
48
|
+
const order = await this.store.queryRecord('order', {
|
|
49
|
+
public_id: orderId,
|
|
50
|
+
single: true,
|
|
51
|
+
with: ['customer', 'payload', 'trackingNumber'],
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
this.playAlert();
|
|
55
|
+
this.trigger('order.incoming', order, store);
|
|
56
|
+
|
|
57
|
+
this.modalsManager.show('modals/incoming-order', {
|
|
58
|
+
title: 'You have a new incoming order!',
|
|
59
|
+
acceptButtonText: 'Accept Order',
|
|
60
|
+
acceptButtonIcon: 'check',
|
|
61
|
+
acceptButtonIconPrefix: 'fas',
|
|
62
|
+
declineButtonText: 'Decline Order',
|
|
63
|
+
declineButtonScheme: 'danger',
|
|
64
|
+
closeButton: false,
|
|
65
|
+
backdropClose: false,
|
|
66
|
+
order,
|
|
67
|
+
store,
|
|
68
|
+
confirm: (modal) => {
|
|
69
|
+
modal.startLoading();
|
|
70
|
+
|
|
71
|
+
return this.fetch
|
|
72
|
+
.post('orders/accept', { order: order.id }, { namespace: 'storefront/int/v1' })
|
|
73
|
+
.then(() => {
|
|
74
|
+
this.trigger('order.accepted', order);
|
|
75
|
+
modal.stopLoading();
|
|
76
|
+
})
|
|
77
|
+
.catch((error) => {
|
|
78
|
+
this.notifications.serverError(error);
|
|
79
|
+
});
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
async listenForIncomingOrders() {
|
|
85
|
+
const store = this.findActiveStore();
|
|
86
|
+
|
|
87
|
+
if (!store) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const socket = socketClusterClient.create({
|
|
92
|
+
hostname: 'socket.fleetbase.io',
|
|
93
|
+
secure: true,
|
|
94
|
+
port: 8000,
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// listen on company channel
|
|
98
|
+
const channel = socket.subscribe(`storefront.${store.public_id}`);
|
|
99
|
+
|
|
100
|
+
// listen to channel for events
|
|
101
|
+
await channel.listener('subscribe').once();
|
|
102
|
+
|
|
103
|
+
// get incoming data and console out
|
|
104
|
+
for await (let broadcast of channel) {
|
|
105
|
+
if (broadcast.event === 'order.created') {
|
|
106
|
+
console.log('[new order]', broadcast);
|
|
107
|
+
this.trigger('order.broadcasted', broadcast);
|
|
108
|
+
this.alertIncomingOrder(broadcast.data.id, store);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// disconnect when transitioning
|
|
113
|
+
this.hostRouter.on('routeWillChange', channel.close);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
createFirstStore(options = {}) {
|
|
117
|
+
const store = this.store.createRecord('store');
|
|
118
|
+
const currency = this.currentUser.getWhoisProperty('currency.code');
|
|
119
|
+
|
|
120
|
+
if (currency) {
|
|
121
|
+
store.setProperties({ currency });
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
this.modalsManager.show('modals/create-first-store', {
|
|
125
|
+
title: 'Create your first Storefront',
|
|
126
|
+
acceptButtonIcon: 'check',
|
|
127
|
+
acceptButtonIconPrefix: 'fas',
|
|
128
|
+
closeButton: false,
|
|
129
|
+
backdropClose: false,
|
|
130
|
+
keyboard: true,
|
|
131
|
+
hideDeclineButton: false,
|
|
132
|
+
declineButtonDisabled: false,
|
|
133
|
+
declineButtonIcon: 'times',
|
|
134
|
+
declineButtonIconPrefix: 'fas',
|
|
135
|
+
store,
|
|
136
|
+
confirm: (modal, done) => {
|
|
137
|
+
modal.startLoading();
|
|
138
|
+
|
|
139
|
+
store
|
|
140
|
+
.save()
|
|
141
|
+
.then((store) => {
|
|
142
|
+
this.notifications.success('Your new storefront has been created!');
|
|
143
|
+
this.setActiveStorefront(store);
|
|
144
|
+
return done();
|
|
145
|
+
})
|
|
146
|
+
.catch((error) => {
|
|
147
|
+
modal.stopLoading();
|
|
148
|
+
this.notifications.serverError(error);
|
|
149
|
+
});
|
|
150
|
+
},
|
|
151
|
+
decline: () => {
|
|
152
|
+
this.hostRouter.transitionTo('console');
|
|
153
|
+
},
|
|
154
|
+
...options,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
createNewStorefront(options = {}) {
|
|
159
|
+
const store = this.store.createRecord('store');
|
|
160
|
+
const currency = this.currentUser.getWhoisProperty('currency.code');
|
|
161
|
+
|
|
162
|
+
if (currency) {
|
|
163
|
+
store.setProperties({ currency });
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
this.modalsManager.show('modals/create-store', {
|
|
167
|
+
title: 'Create a new Storefront',
|
|
168
|
+
acceptButtonIcon: 'check',
|
|
169
|
+
acceptButtonIconPrefix: 'fas',
|
|
170
|
+
declineButtonIcon: 'times',
|
|
171
|
+
declineButtonIconPrefix: 'fas',
|
|
172
|
+
store,
|
|
173
|
+
confirm: (modal, done) => {
|
|
174
|
+
modal.startLoading();
|
|
175
|
+
|
|
176
|
+
store
|
|
177
|
+
.save()
|
|
178
|
+
.then((store) => {
|
|
179
|
+
this.notifications.success('Your new storefront has been created!');
|
|
180
|
+
// this.currentUser.setOption('activeStorefront', store.id);
|
|
181
|
+
this.setActiveStorefront(store);
|
|
182
|
+
|
|
183
|
+
if (typeof options?.onSuccess === 'function') {
|
|
184
|
+
options.onSuccess(store);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
return done();
|
|
188
|
+
})
|
|
189
|
+
.catch((error) => {
|
|
190
|
+
modal.stopLoading();
|
|
191
|
+
this.notifications.serverError(error);
|
|
192
|
+
});
|
|
193
|
+
},
|
|
194
|
+
...options,
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
playAlert() {
|
|
199
|
+
// eslint-disable-next-line no-undef
|
|
200
|
+
const alert = new Audio('/sounds/storefront_order_alert.mp3');
|
|
201
|
+
|
|
202
|
+
try {
|
|
203
|
+
alert.play();
|
|
204
|
+
} catch (error) {
|
|
205
|
+
// do nothing with error
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<EmberWormhole @to="sidebar-menu-items">
|
|
2
|
+
<StoreSelector @stores={{@model}} @activeStore={{this.activeStore}} @wrapperClass="mb-2" @onCreateStore={{this.createNewStorefront}} @onSwitchStore={{this.switchActiveStore}} />
|
|
3
|
+
<Layout::Sidebar::Panel @open={{true}} @title="Storefront">
|
|
4
|
+
<Layout::Sidebar::Item @route="console.storefront.home" @icon="home">Dashboard</Layout::Sidebar::Item>
|
|
5
|
+
<Layout::Sidebar::Item @route="console.storefront.products" @icon="box" disabled={{not this.activeStore.id}}>Products</Layout::Sidebar::Item>
|
|
6
|
+
<Layout::Sidebar::Item @route="console.storefront.customers" @icon="users" disabled={{not this.activeStore.id}}>Customers</Layout::Sidebar::Item>
|
|
7
|
+
<Layout::Sidebar::Item @route="console.storefront.orders" @icon="file-invoice-dollar" disabled={{not this.activeStore.id}}>Orders</Layout::Sidebar::Item>
|
|
8
|
+
<Layout::Sidebar::Item @route="console.storefront.networks" @icon="network-wired" disabled={{not this.activeStore.id}}>Networks</Layout::Sidebar::Item>
|
|
9
|
+
<Layout::Sidebar::Item @route="console.storefront.settings" @icon="cogs" disabled={{not this.activeStore.id}}>Settings</Layout::Sidebar::Item>
|
|
10
|
+
</Layout::Sidebar::Panel>
|
|
11
|
+
<Layout::Sidebar::Item @url="https://github.com/fleetbase/storefront-app" @target="_github" @icon="rocket">Launch App</Layout::Sidebar::Item>
|
|
12
|
+
</EmberWormhole>
|
|
13
|
+
|
|
14
|
+
<Layout::Section::Container>
|
|
15
|
+
{{outlet}}
|
|
16
|
+
</Layout::Section::Container>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<Layout::Section::Header @title="Customers" @searchQuery={{this.query}} @onSearch={{perform this.search}}>
|
|
2
|
+
<FiltersPicker @columns={{this.columns}} @onApply={{fn this.filters.apply this}} @onClear={{fn this.filters.reset this}} @onFilterClear={{this.filters.clear}} @onChange={{this.filters.set}} @buttonWrapperClass="mr-2" />
|
|
3
|
+
<VisibleColumnPicker @columns={{this.columns}} @onChange={{fn (mut this.columns)}} class="mr-2" />
|
|
4
|
+
{{#if (safe-has this.table "selectedRows")}}
|
|
5
|
+
<DropdownButton @icon="layer-group" @text="Bulk Action" @type="magic" @size="sm" @buttonWrapperClass="mr-2" @contentClass="dropdown-menu" as |dd|>
|
|
6
|
+
<div class="next-dd-menu mt-2 mx-0">
|
|
7
|
+
<div class="px-1">
|
|
8
|
+
<a href="#" class="text-red-500 next-dd-item" {{on "click" (dropdown-fn dd this.bulkDeleteCustomers)}}>
|
|
9
|
+
Delete Drivers
|
|
10
|
+
</a>
|
|
11
|
+
</div>
|
|
12
|
+
</div>
|
|
13
|
+
</DropdownButton>
|
|
14
|
+
{{/if}}
|
|
15
|
+
<Button @icon="long-arrow-up" @iconClass="rotate-icon-45" @text="Export" />
|
|
16
|
+
</Layout::Section::Header>
|
|
17
|
+
|
|
18
|
+
<Layout::Section::Body>
|
|
19
|
+
<Table @rows={{@model}} @columns={{this.columns}} @selectable={{true}} @canSelectAll={{true}} @onSetup={{fn (mut this.table)}} @pagination={{true}} @paginationMeta={{@model.meta}} @page={{this.page}} @onPageChange={{fn (mut this.page)}} @tfootVerticalOffset="53" @tfootVerticalOffsetElements=".next-view-section-subheader" />
|
|
20
|
+
</Layout::Section::Body>
|
|
21
|
+
|
|
22
|
+
{{outlet}}
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
<div class="space-y-4">
|
|
2
|
+
<ContentPanel @title="General Network Settings" @open={{true}} @pad={{true}}>
|
|
3
|
+
<div class="space-y-4">
|
|
4
|
+
<div>
|
|
5
|
+
<h1 class="text-lg leading-6 font-bold text-gray-900 dark:text-gray-100">
|
|
6
|
+
General Network Settings
|
|
7
|
+
</h1>
|
|
8
|
+
<p class="mt-1 text-sm text-gray-500">
|
|
9
|
+
Provide the general settings for your network or marketplace.
|
|
10
|
+
</p>
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
<InputGroup @name="Name" @value={{@model.name}} @placeholder="Storefront Name" @helpText="The name of your network or marketplace." />
|
|
14
|
+
<InputGroup @name="Description" @value={{@model.description}} @placeholder="Storefront Description" @helpText="Give your store a brief description to let users know what your network is about." />
|
|
15
|
+
<InputGroup @name="Currency">
|
|
16
|
+
<CurrencySelect @value={{@model.currency}} @onSelect={{fn (mut @model.currency)}} @triggerClass="w-full form-select" />
|
|
17
|
+
</InputGroup>
|
|
18
|
+
|
|
19
|
+
<ContentPanel @title="Contact & Social" @open={{false}} @pad={{true}}>
|
|
20
|
+
<InputGroup @name="Phone">
|
|
21
|
+
<PhoneInput @value={{@model.phone}} @onInput={{fn (mut @model.phone)}} class="form-input w-full" />
|
|
22
|
+
</InputGroup>
|
|
23
|
+
<InputGroup @name="Email" @value={{@model.email}} @placeholder="Email" @helpText="Your business email." />
|
|
24
|
+
<InputGroup @name="Website" @value={{@model.website}} @placeholder="Website" @helpText="Your business website URL." />
|
|
25
|
+
<InputGroup @name="Facebook" @value={{@model.facebook}} @placeholder="Facebook ID" @helpText="Your business Facebook page ID." />
|
|
26
|
+
<InputGroup @name="Instagram" @value={{@model.instagram}} @placeholder="Instagram Username" @helpText="Your business Instagram username." />
|
|
27
|
+
<InputGroup @name="Twitter" @value={{@model.twitter}} @placeholder="Twitter Username" @helpText="Your business Twitter username." />
|
|
28
|
+
</ContentPanel>
|
|
29
|
+
|
|
30
|
+
<ContentPanel @title="Logo & Backdrop" @open={{false}} @pad={{true}}>
|
|
31
|
+
<InputGroup @name="Logo" @helpText="Logo for your store.">
|
|
32
|
+
<div class="flex flex-row items-center">
|
|
33
|
+
<img src={{@model.logo_url}} alt={{concat @model.name " logo"}} class="h-20 w-64 border dark:border-gray-900 rounded-md mr-4" />
|
|
34
|
+
<FileUpload @name="logo" @accept="image/*" @onFileAdded={{fn this.uploadFile "storefront_logo"}} as |queue|>
|
|
35
|
+
<a tabindex={{0}} class="flex items-center px-0 mt-2 text-xs no-underline truncate btn btn-sm btn-default">
|
|
36
|
+
{{#if queue.files.length}}
|
|
37
|
+
<Spinner class="mr-1" />
|
|
38
|
+
<span>
|
|
39
|
+
Uploading...
|
|
40
|
+
</span>
|
|
41
|
+
{{else}}
|
|
42
|
+
<FaIcon @icon="image" class="mr-1" />
|
|
43
|
+
<span>
|
|
44
|
+
Upload new logo
|
|
45
|
+
</span>
|
|
46
|
+
{{/if}}
|
|
47
|
+
</a>
|
|
48
|
+
</FileUpload>
|
|
49
|
+
</div>
|
|
50
|
+
</InputGroup>
|
|
51
|
+
|
|
52
|
+
<InputGroup @name="Backdrop" @helpText="Optional banner or background image for your store.">
|
|
53
|
+
<div class="flex flex-row items-center">
|
|
54
|
+
<img src={{@model.backdrop_url}} alt={{concat @model.name " backdrop"}} class="h-20 w-64 border dark:border-gray-900 rounded-md mr-4" />
|
|
55
|
+
<FileUpload @name="backdrop" @accept="image/*" @onFileAdded={{fn this.uploadFile "storefront_backdrop"}} as |queue|>
|
|
56
|
+
<a tabindex={{0}} class="flex items-center px-0 mt-2 text-xs no-underline truncate btn btn-sm btn-default">
|
|
57
|
+
{{#if queue.files.length}}
|
|
58
|
+
<Spinner class="mr-1" />
|
|
59
|
+
<span>
|
|
60
|
+
Uploading...
|
|
61
|
+
</span>
|
|
62
|
+
{{else}}
|
|
63
|
+
<FaIcon @icon="image" class="mr-1" />
|
|
64
|
+
<span>
|
|
65
|
+
Upload new backdrop
|
|
66
|
+
</span>
|
|
67
|
+
{{/if}}
|
|
68
|
+
</a>
|
|
69
|
+
</FileUpload>
|
|
70
|
+
</div>
|
|
71
|
+
</InputGroup>
|
|
72
|
+
</ContentPanel>
|
|
73
|
+
|
|
74
|
+
<ContentPanel @title="Alerts" @open={{false}} @pad={{true}} @panelBodyClass="bg-gray-800">
|
|
75
|
+
<div>
|
|
76
|
+
<p class="dark:text-gray-100 mb-4">Configure who should be alerted for certain events.</p>
|
|
77
|
+
<InputGroup @name="New order alert" @wrapperClass="mb-0">
|
|
78
|
+
<ModelSelectMultiple @modelName="user" @selectedModel={{@model.alertable.for_new_order}} @placeholder="Select users to alert for new order" @triggerClass="form-select form-input multiple" @infiniteScroll={{false}} @renderInPlace={{true}} @onChange={{fn this.makeAlertable "for_new_order"}} as |model|>
|
|
79
|
+
{{model.name}}
|
|
80
|
+
</ModelSelectMultiple>
|
|
81
|
+
</InputGroup>
|
|
82
|
+
</div>
|
|
83
|
+
</ContentPanel>
|
|
84
|
+
|
|
85
|
+
<div class="store-boolean-settings">
|
|
86
|
+
<div class="input-group">
|
|
87
|
+
<Toggle @isToggled={{@model.online}} @onToggle={{fn (mut @model.online)}}>
|
|
88
|
+
<FaIcon @icon="plug" class="text-gray-600 dark:text-gray-400 mx-2" /><span class="dark:text-gray-100 text-sm">Online</span>
|
|
89
|
+
</Toggle>
|
|
90
|
+
</div>
|
|
91
|
+
<div class="input-group">
|
|
92
|
+
<Toggle @isToggled={{@model.options.tax_enabled}} @onToggle={{fn (mut @model.options.tax_enabled)}}>
|
|
93
|
+
<FaIcon @icon="percent" class="text-gray-600 dark:text-gray-400 mx-2" /><span class="dark:text-gray-100 text-sm">Enable tax</span>
|
|
94
|
+
</Toggle>
|
|
95
|
+
{{#if @model.options.tax_enabled}}
|
|
96
|
+
<InputGroup @wrapperClass="mb-0 mt-2" @type="number" @name="Tax Percentage" @value={{@model.options.tax_percentage}} @placeholder="Tax Percentage" @helpText="The sales tax percentage to apply to orders." />
|
|
97
|
+
{{/if}}
|
|
98
|
+
</div>
|
|
99
|
+
<div class="input-group">
|
|
100
|
+
<Toggle @isToggled={{@model.options.auto_accept_orders}} @onToggle={{fn (mut @model.options.auto_accept_orders)}}>
|
|
101
|
+
<FaIcon @icon="robot" class="text-gray-600 dark:text-gray-400 mx-2" /><span class="dark:text-gray-100 text-sm">Auto accept incoming orders</span>
|
|
102
|
+
</Toggle>
|
|
103
|
+
</div>
|
|
104
|
+
<div class="input-group">
|
|
105
|
+
<Toggle @isToggled={{@model.options.auto_dispatch}} @onToggle={{fn (mut @model.options.auto_dispatch)}}>
|
|
106
|
+
<FaIcon @icon="paper-plane" class="text-gray-600 dark:text-gray-400 mx-2" /><span class="dark:text-gray-100 text-sm">Auto dispatch orders</span>
|
|
107
|
+
</Toggle>
|
|
108
|
+
</div>
|
|
109
|
+
<div class="input-group">
|
|
110
|
+
<Toggle @isToggled={{@model.options.require_pod}} @onToggle={{fn (mut @model.options.require_pod)}}>
|
|
111
|
+
<FaIcon @icon="signature" class="text-gray-600 dark:text-gray-400 mx-2" /><span class="dark:text-gray-100 text-sm">Require proof of delivery</span>
|
|
112
|
+
</Toggle>
|
|
113
|
+
{{#if @model.options.require_pod}}
|
|
114
|
+
<InputGroup @wrapperClass="mb-0 mt-2" @name="Proof of Delivery Method">
|
|
115
|
+
<Select @options={{this.podMethods}} @optionValue="value" @optionLabel="name" @value={{@model.pod_method}} @onSelect={{fn (mut @model.pod_method)}} class="w-full" />
|
|
116
|
+
</InputGroup>
|
|
117
|
+
{{/if}}
|
|
118
|
+
</div>
|
|
119
|
+
<div class="input-group">
|
|
120
|
+
<Toggle @isToggled={{@model.options.cod_enabled}} @onToggle={{fn (mut @model.options.cod_enabled)}}>
|
|
121
|
+
<FaIcon @icon="money-bill-wave" class="text-gray-600 dark:text-gray-400 mx-2" /><span class="dark:text-gray-100 text-sm">Enable cash on delivery</span>
|
|
122
|
+
</Toggle>
|
|
123
|
+
</div>
|
|
124
|
+
<div class="input-group">
|
|
125
|
+
<Toggle @isToggled={{@model.options.pickup_enabled}} @onToggle={{fn (mut @model.options.pickup_enabled)}}>
|
|
126
|
+
<FaIcon @icon="person-booth" class="text-gray-600 dark:text-gray-400 mx-2" /><span class="dark:text-gray-100 text-sm">Enable order pickup</span>
|
|
127
|
+
</Toggle>
|
|
128
|
+
</div>
|
|
129
|
+
<div class="input-group">
|
|
130
|
+
<Toggle @isToggled={{@model.options.tips_enabled}} @onToggle={{fn (mut @model.options.tips_enabled)}}>
|
|
131
|
+
<FaIcon @icon="cash-register" class="text-gray-600 dark:text-gray-400 mx-2" /><span class="dark:text-gray-100 text-sm">Enable tips</span>
|
|
132
|
+
</Toggle>
|
|
133
|
+
</div>
|
|
134
|
+
<div class="input-group">
|
|
135
|
+
<Toggle @isToggled={{@model.options.delivery_tips_enabled}} @onToggle={{fn (mut @model.options.delivery_tips_enabled)}}>
|
|
136
|
+
<FaIcon @icon="face-smile" class="text-gray-600 dark:text-gray-400 mx-2" /><span class="dark:text-gray-100 text-sm">Enable delivery tips</span>
|
|
137
|
+
</Toggle>
|
|
138
|
+
</div>
|
|
139
|
+
<div class="input-group">
|
|
140
|
+
<Toggle @isToggled={{@model.options.multi_cart_enabled}} @onToggle={{fn (mut @model.options.multi_cart_enabled)}}>
|
|
141
|
+
<FaIcon @icon="gifts" class="text-gray-600 dark:text-gray-400 mx-2" /><span class="dark:text-gray-100 text-sm">Enable multi-cart checkout</span>
|
|
142
|
+
</Toggle>
|
|
143
|
+
</div>
|
|
144
|
+
<div class="input-group">
|
|
145
|
+
<Toggle @isToggled={{@model.options.reviews_enabled}} @onToggle={{fn (mut @model.options.reviews_enabled)}}>
|
|
146
|
+
<FaIcon @icon="star" @prefix="fas" class="text-gray-600 dark:text-gray-400 mx-2" /><span class="dark:text-gray-100 text-sm">Enable user reviews</span>
|
|
147
|
+
</Toggle>
|
|
148
|
+
</div>
|
|
149
|
+
</div>
|
|
150
|
+
|
|
151
|
+
<div class="flex justify-end">
|
|
152
|
+
<Button @type="primary" @text="Save Changes" @icon="save" @size="lg" @isLoading={{this.isLoading}} @onClick={{this.saveSettings}} />
|
|
153
|
+
</div>
|
|
154
|
+
</div>
|
|
155
|
+
</ContentPanel>
|
|
156
|
+
|
|
157
|
+
<ContentPanel @title="API" @open={{false}} @pad={{true}}>
|
|
158
|
+
<div class="space-y-6">
|
|
159
|
+
<div>
|
|
160
|
+
<h1 class="text-lg leading-6 font-bold text-gray-900 dark:text-gray-100">
|
|
161
|
+
API Settings
|
|
162
|
+
</h1>
|
|
163
|
+
<p class="mt-1 text-sm text-gray-500">
|
|
164
|
+
Access key for Storefront API & Integrations.
|
|
165
|
+
</p>
|
|
166
|
+
</div>
|
|
167
|
+
|
|
168
|
+
<InputGroup @name="Network Key" @helpText="This is your network key, use this to enable apps and integrations for your network.">
|
|
169
|
+
<ClickToReveal @value={{@model.key}} @clickToCopy={{true}} class="form-input disabled" />
|
|
170
|
+
</InputGroup>
|
|
171
|
+
</div>
|
|
172
|
+
</ContentPanel>
|
|
173
|
+
|
|
174
|
+
<ContentPanel @title="Payment Gateways" @open={{false}} @pad={{true}}>
|
|
175
|
+
<div class="space-y-6">
|
|
176
|
+
<div class="flex justify-between">
|
|
177
|
+
<div>
|
|
178
|
+
<h1 class="text-lg leading-6 font-bold text-gray-900 dark:text-gray-100">
|
|
179
|
+
Gateway Settings
|
|
180
|
+
</h1>
|
|
181
|
+
<p class="mt-1 text-sm text-gray-500">
|
|
182
|
+
Add or manage your payment gateway settings here.
|
|
183
|
+
</p>
|
|
184
|
+
</div>
|
|
185
|
+
<div>
|
|
186
|
+
<Button @icon="plus" @iconPrefix="fas" @type="primary" @text="Create new gateway" @onClick={{this.createGateway}} />
|
|
187
|
+
</div>
|
|
188
|
+
</div>
|
|
189
|
+
|
|
190
|
+
{{#each this.gateways as |gateway|}}
|
|
191
|
+
<ContentPanel @title={{gateway.name}} @open={{true}} @pad={{true}}>
|
|
192
|
+
<InputGroup @name="Gateway name" @value={{gateway.name}} @helpText="Give your payment gateway a name, this will only be relevent internally" />
|
|
193
|
+
<InputGroup @name="Gateway code" @value={{gateway.code}} @disabled={{true}} @helpText="Identifier code used to identify gateway to the SDK" />
|
|
194
|
+
<InputGroup @name="Callback URL" @value={{gateway.callback_url}} @helpText="Callback URL if applicable" />
|
|
195
|
+
<InputGroup @name="Return URL" @value={{gateway.return_url}} @helpText="Return URL if applicable" />
|
|
196
|
+
<div class="input-group">
|
|
197
|
+
<Checkbox @value={{gateway.sandbox}} @label="This is a sandbox gateway" @onToggle={{fn (mut gateway.sandbox)}} />
|
|
198
|
+
</div>
|
|
199
|
+
<div>
|
|
200
|
+
<h4 class="mb-2 font-semibold text-sm dark:text-white">Config</h4>
|
|
201
|
+
{{#each-in gateway.config as |key value|}}
|
|
202
|
+
{{#if (is-bool-value value)}}
|
|
203
|
+
<div class="input-group">
|
|
204
|
+
<Checkbox @value={{value}} @label={{humanize key}} />
|
|
205
|
+
</div>
|
|
206
|
+
{{else}}
|
|
207
|
+
<InputGroup @name={{humanize key}}>
|
|
208
|
+
<Input class="form-input w-full" placeholder={{humanize key}} @value={{value}} />
|
|
209
|
+
</InputGroup>
|
|
210
|
+
{{/if}}
|
|
211
|
+
{{/each-in}}
|
|
212
|
+
</div>
|
|
213
|
+
<div>
|
|
214
|
+
<Button @size="sm" @type="danger" @icon="trash" @text="Delete payment gateway" @onClick={{fn this.deleteGateway gateway}} />
|
|
215
|
+
</div>
|
|
216
|
+
</ContentPanel>
|
|
217
|
+
{{/each}}
|
|
218
|
+
</div>
|
|
219
|
+
</ContentPanel>
|
|
220
|
+
|
|
221
|
+
<ContentPanel @title="Notification Channels" @open={{false}} @pad={{true}}>
|
|
222
|
+
<div class="space-y-6">
|
|
223
|
+
<div class="flex justify-between">
|
|
224
|
+
<div class="w-3/4">
|
|
225
|
+
<h1 class="text-lg leading-6 font-bold text-gray-900 dark:text-gray-100">
|
|
226
|
+
Notification Settings
|
|
227
|
+
</h1>
|
|
228
|
+
<p class="mt-1 text-sm text-gray-500">
|
|
229
|
+
Configure notification channels for your storefront, each notification channel additionally can
|
|
230
|
+
have
|
|
231
|
+
it's own rules and options.
|
|
232
|
+
</p>
|
|
233
|
+
</div>
|
|
234
|
+
<div>
|
|
235
|
+
<Button @icon="plus" @iconPrefix="fas" @type="primary" @text="New channel" @onClick={{this.createChannel}} />
|
|
236
|
+
</div>
|
|
237
|
+
</div>
|
|
238
|
+
|
|
239
|
+
<div class="space-y-3">
|
|
240
|
+
{{#each this.channels as |notificationChannel|}}
|
|
241
|
+
<div class="flex px-4 py-2 items-center justify-between shadow-sm rounded-md dark:bg-gray-900 bg-gray-200">
|
|
242
|
+
<div>
|
|
243
|
+
<span class="dark:text-gray-50">{{notificationChannel.name}}</span>
|
|
244
|
+
</div>
|
|
245
|
+
<div class="flex items-center">
|
|
246
|
+
<Button @size="xs" @type="default" @text="Edit" @wrapperClass="mr-2" @onClick={{fn this.editChannel notificationChannel}} />
|
|
247
|
+
<Button @size="xs" @type="danger" @text="Delete" @onClick={{fn this.deleteChannel notificationChannel}} />
|
|
248
|
+
</div>
|
|
249
|
+
</div>
|
|
250
|
+
{{/each}}
|
|
251
|
+
</div>
|
|
252
|
+
</div>
|
|
253
|
+
</ContentPanel>
|
|
254
|
+
</div>
|