@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,164 @@
|
|
|
1
|
+
<div class="flex flex-col md:flex-row justify-start md:justify-between mb-6">
|
|
2
|
+
<div class="flex-1 pb-4 md:pb-0 md:pr-4">
|
|
3
|
+
{{#if this.stores.length}}
|
|
4
|
+
<div>
|
|
5
|
+
<h4 class="font-semibold dark:text-gray-50 mb-4">{{pluralize @model.meta.total "Store"}} in your network</h4>
|
|
6
|
+
<p class="dark:text-gray-100">
|
|
7
|
+
You can organize your network by creating categories and dragging stores into the categories.
|
|
8
|
+
</p>
|
|
9
|
+
</div>
|
|
10
|
+
{{else}}
|
|
11
|
+
<h1 class="font-semibold dark:text-gray-50 mb-4">This network is empty</h1>
|
|
12
|
+
<p class="dark:text-gray-100">
|
|
13
|
+
Grow your network by sending invitations to others to create a storefront or add their existing storefront to your network. Optionally you may also add your own stores to your network to begin.
|
|
14
|
+
</p>
|
|
15
|
+
{{/if}}
|
|
16
|
+
</div>
|
|
17
|
+
<div class="flex items-start">
|
|
18
|
+
<Button @wrapperClass="mr-2 flex-shrink-0" @type="default" @icon="folder" @text="Add Category" @onClick={{fn this.createNewCategory this.network}} />
|
|
19
|
+
<Button @wrapperClass="mr-2 flex-shrink-0" @type="default" @icon="paper-plane" @text="Invite stores" @onClick={{fn this.invite this.network}} />
|
|
20
|
+
<Button @wrapperClass="flex-shrink-0" @type="default" @icon="plus" @iconPrefix="fas" @text="Add stores" @onClick={{fn this.addStores this.network}} />
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
23
|
+
|
|
24
|
+
<EmberDragula @options={{this.dragulaConfig}} @onReady={{this.setDragulaInstance}} as |d|>
|
|
25
|
+
<div>
|
|
26
|
+
<div class="flex items-center mb-6">
|
|
27
|
+
{{#if this.category}}
|
|
28
|
+
<div>
|
|
29
|
+
<div class="flex items-center mb-3">
|
|
30
|
+
<FaIcon @prefix="fas" @icon="folder" @size="2x" class="text-blue-400 mr-3" />
|
|
31
|
+
{{#if this.category.parent_category}}
|
|
32
|
+
<div class="dark:text-blue-400 flex flex-row items-center">
|
|
33
|
+
<span class="text-xl font-bold">{{this.category.parent_category.name}}</span>
|
|
34
|
+
{{#if this.category.parent_category.icon}}
|
|
35
|
+
<FaIcon @icon={{this.category.parent_category.icon}} class="ml-1" />
|
|
36
|
+
{{/if}}
|
|
37
|
+
</div>
|
|
38
|
+
<span class="mx-2">
|
|
39
|
+
<FaIcon @icon="chevron-right" @prefix="fas" class="dark:text-blue-400 -mb-px" />
|
|
40
|
+
</span>
|
|
41
|
+
{{/if}}
|
|
42
|
+
<div class="dark:text-blue-400 flex flex-row items-center">
|
|
43
|
+
<span class="text-xl font-bold">{{this.category.name}}</span>
|
|
44
|
+
{{#if this.category.icon}}
|
|
45
|
+
<FaIcon @icon={{this.category.icon}} class="ml-1" />
|
|
46
|
+
{{/if}}
|
|
47
|
+
</div>
|
|
48
|
+
{{#if this.isLoading}}
|
|
49
|
+
<div class="ml-2 flex items-center">
|
|
50
|
+
<Spinner class="mr-2 text-sky-400" />
|
|
51
|
+
<span class="dark:text-sky-100 text-xs">Loading...</span>
|
|
52
|
+
</div>
|
|
53
|
+
{{/if}}
|
|
54
|
+
</div>
|
|
55
|
+
<div class="flex items-center">
|
|
56
|
+
<Button @wrapperClass="mr-2" @icon="long-arrow-alt-left" @text="Back" @onClick={{fn this.leaveCategory this.category.parent_category}} />
|
|
57
|
+
<Button @wrapperClass="mr-2" @icon="plus" @iconPrefix="fas" @text="Add Sub-Category" @onClick={{fn this.createNewSubCategory this.category}} />
|
|
58
|
+
<Button @wrapperClass="mr-2" @icon="edit" @text="Edit Category" @onClick={{fn this.editCategory this.category}} />
|
|
59
|
+
<Button @type="danger" @wrapperClass="mr-4" @icon="trash" @text="Delete Category" @onClick={{fn this.deleteCategory this.category}} />
|
|
60
|
+
</div>
|
|
61
|
+
</div>
|
|
62
|
+
{{else}}
|
|
63
|
+
<div class="flex items-center">
|
|
64
|
+
<FaIcon @prefix="fas" @icon="folder" @size="2x" class="text-blue-400 mr-2" />
|
|
65
|
+
<span class="text-xl font-bold dark:text-blue-400">Top Level</span>
|
|
66
|
+
</div>
|
|
67
|
+
{{#if this.isLoading}}
|
|
68
|
+
<div class="ml-2 flex items-center">
|
|
69
|
+
<Spinner class="mr-2 text-sky-400" />
|
|
70
|
+
<span class="dark:text-sky-100 text-xs">Loading...</span>
|
|
71
|
+
</div>
|
|
72
|
+
{{/if}}
|
|
73
|
+
{{/if}}
|
|
74
|
+
</div>
|
|
75
|
+
</div>
|
|
76
|
+
|
|
77
|
+
{{#if this.category}}
|
|
78
|
+
<div class="grid grid-cols-2 md:grid-cols-3 gap-2 md:gap-4 mb-6">
|
|
79
|
+
{{#each this.subCategories as |category|}}
|
|
80
|
+
<d.Container class="dragula-container network-folder" data-category={{category.id}}>
|
|
81
|
+
<a href="javascript:;" class="block" {{on "click" (fn this.enterCategory category)}}>
|
|
82
|
+
<div class="flex items-center justify-center mb-3">
|
|
83
|
+
<FaIcon @prefix="fas" @icon="folder" @size={{if (media 'isMobile') "4x" "5x"}} class="text-blue-400" />
|
|
84
|
+
</div>
|
|
85
|
+
<div class="flex items-center justify-center">
|
|
86
|
+
<div class="flex flex-col items-center justify-center rounded-md border bg-blue-400 border-blue-400 px-4 py-1 text-center text-blue-100 font-semibold truncate w-40">
|
|
87
|
+
{{category.name}}
|
|
88
|
+
{{#each-in category.translations as |lang translation|}}
|
|
89
|
+
<div>{{translation.name}}</div>
|
|
90
|
+
{{/each-in}}
|
|
91
|
+
</div>
|
|
92
|
+
</div>
|
|
93
|
+
</a>
|
|
94
|
+
</d.Container>
|
|
95
|
+
{{/each}}
|
|
96
|
+
</div>
|
|
97
|
+
{{else}}
|
|
98
|
+
<div class="grid grid-cols-2 md:grid-cols-3 gap-2 md:gap-4 mb-6">
|
|
99
|
+
{{#each this.categories as |category|}}
|
|
100
|
+
<d.Container class="dragula-container network-folder" data-category={{category.id}}>
|
|
101
|
+
<a href="javascript:;" class="block" {{on "click" (fn this.enterCategory category)}}>
|
|
102
|
+
<div class="flex items-center justify-center mb-3">
|
|
103
|
+
<FaIcon @prefix="fas" @icon="folder" @size={{if (media 'isMobile') "4x" "5x"}} class="text-blue-400" />
|
|
104
|
+
</div>
|
|
105
|
+
<div class="flex items-center justify-center">
|
|
106
|
+
<div class="flex flex-col items-center justify-center rounded-md border bg-blue-400 border-blue-400 px-4 py-1 text-center text-blue-100 font-semibold truncate w-40">
|
|
107
|
+
{{category.name}}
|
|
108
|
+
{{#each-in category.translations as |lang translation|}}
|
|
109
|
+
<div>{{translation.name}}</div>
|
|
110
|
+
{{/each-in}}
|
|
111
|
+
</div>
|
|
112
|
+
</div>
|
|
113
|
+
</a>
|
|
114
|
+
</d.Container>
|
|
115
|
+
{{/each}}
|
|
116
|
+
</div>
|
|
117
|
+
{{/if}}
|
|
118
|
+
|
|
119
|
+
<d.Container class="grid grid-cols-2 md:grid-cols-3 gap-2 md:gap-4 {{if this.isLoading 'hidden'}}">
|
|
120
|
+
{{#each this.stores as |store|}}
|
|
121
|
+
<div class="network-store" data-store={{store.id}}>
|
|
122
|
+
<div class="rounded-md border dark:border-gray-800 shadow-sm">
|
|
123
|
+
<div class="p-4 flex items-center justify-center rounded-t-md h-36" {{background-url store.backdrop_url overlay=true}}>
|
|
124
|
+
<img src={{store.logo_url}} class="w-32" alt={{store.name}} />
|
|
125
|
+
</div>
|
|
126
|
+
<div class="border-t dark:border-gray-800 px-4 py-2">
|
|
127
|
+
<div class="flex items-center justify-between">
|
|
128
|
+
<div class="flex-1 dark:text-gray-100 truncate">
|
|
129
|
+
{{store.name}}
|
|
130
|
+
</div>
|
|
131
|
+
<div>
|
|
132
|
+
<DropdownButton @size="xs" @icon="cog" @iconPrefix="fas" @textClass="block truncate" as |dd|>
|
|
133
|
+
<div class="next-dd-menu" aria-orientation="vertical" aria-labelledby="user-menu">
|
|
134
|
+
<div class="px-1">
|
|
135
|
+
<div class="next-dd-title">
|
|
136
|
+
Store Options
|
|
137
|
+
</div>
|
|
138
|
+
</div>
|
|
139
|
+
<div class="next-dd-menu-seperator"></div>
|
|
140
|
+
<div class="px-1">
|
|
141
|
+
{{!-- <a href="javascript:;" class="next-dd-item" role="menuitem">
|
|
142
|
+
<FaIcon @icon="receipt" class="mr-2" />
|
|
143
|
+
<span>View orders via network</span>
|
|
144
|
+
</a>
|
|
145
|
+
<a href="javascript:;" class="next-dd-item" role="menuitem">
|
|
146
|
+
<FaIcon @icon="users" class="mr-2" />
|
|
147
|
+
<span>View customers via network</span>
|
|
148
|
+
</a> --}}
|
|
149
|
+
<a href="javascript:;" class="next-dd-item text-danger" role="menuitem" {{on "click" (fn this.dropdownAction dd "removeStore" store this.network)}}>
|
|
150
|
+
<FaIcon @icon="vote-nay" class="mr-2 text-red-500" />
|
|
151
|
+
<span>Remove store from network</span>
|
|
152
|
+
</a>
|
|
153
|
+
</div>
|
|
154
|
+
</div>
|
|
155
|
+
</DropdownButton>
|
|
156
|
+
</div>
|
|
157
|
+
</div>
|
|
158
|
+
</div>
|
|
159
|
+
</div>
|
|
160
|
+
</div>
|
|
161
|
+
{{/each}}
|
|
162
|
+
</d.Container>
|
|
163
|
+
</EmberDragula>
|
|
164
|
+
<div class="mb-96 h-96 block w-full"></div>
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<Overlay @position="right" @noBackdrop={{true}} @fullHeight={{true}} @width={{if (media "isAnyDesktop") "868px"}}>
|
|
2
|
+
<Overlay::Header @title="Manage Network" @onPressCancel={{this.transitionBack}} />
|
|
3
|
+
|
|
4
|
+
<Overlay::Body class="p-0i" @increaseInnerBodyHeightBy="0" @wrapperClass="space-y-4 pt-4">
|
|
5
|
+
<div class="flex flex-col">
|
|
6
|
+
<div class="px-4 flex items-center section-header-title mb-4">
|
|
7
|
+
<FaIcon @icon="network-wired" @size="lg" class="text-sky-500 mr-3" />
|
|
8
|
+
<h3 class="text-lg font-semibold dark:text-white">
|
|
9
|
+
{{@model.name}}
|
|
10
|
+
</h3>
|
|
11
|
+
</div>
|
|
12
|
+
<div class="section-header-actions w-full overflow-x-scroll lg:overflow-x-auto">
|
|
13
|
+
<div class="ui-tabs">
|
|
14
|
+
<nav>
|
|
15
|
+
<LinkTo @route="networks.index.network.index" class="ui-tab">
|
|
16
|
+
<FaIcon @icon="cogs" class="mr-2" />
|
|
17
|
+
<span>Settings</span>
|
|
18
|
+
</LinkTo>
|
|
19
|
+
<LinkTo @route="networks.index.network.stores" class="ui-tab">
|
|
20
|
+
<FaIcon @icon="store" class="mr-2" />
|
|
21
|
+
<span>Stores</span>
|
|
22
|
+
</LinkTo>
|
|
23
|
+
<LinkTo @route="networks.index.network.orders" class="ui-tab">
|
|
24
|
+
<FaIcon @icon="file-invoice-dollar" class="mr-2" />
|
|
25
|
+
<span>Orders</span>
|
|
26
|
+
</LinkTo>
|
|
27
|
+
<LinkTo @route="networks.index.network.customers" class="ui-tab">
|
|
28
|
+
<FaIcon @icon="users" class="mr-2" />
|
|
29
|
+
<span>Customers</span>
|
|
30
|
+
</LinkTo>
|
|
31
|
+
</nav>
|
|
32
|
+
</div>
|
|
33
|
+
</div>
|
|
34
|
+
</div>
|
|
35
|
+
|
|
36
|
+
<div class="p-6">{{outlet}}</div>
|
|
37
|
+
</Overlay::Body>
|
|
38
|
+
</Overlay>
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
<Layout::Section::Header @title="Networks" @searchQuery={{this.query}} @onSearch={{perform this.search}}>
|
|
2
|
+
<Button @type="primary" @icon="plus" @iconPrefix="fas" @text="New" class="mr-2" @onClick={{this.createNetwork}} />
|
|
3
|
+
</Layout::Section::Header>
|
|
4
|
+
|
|
5
|
+
<Layout::Section::Body>
|
|
6
|
+
<div class="h-screen overflow-y-scroll p-6">
|
|
7
|
+
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-2 lg:gap-4">
|
|
8
|
+
{{#each @model as |network|}}
|
|
9
|
+
<div class="mr-4 w-full">
|
|
10
|
+
<div class="rounded-md border dark:border-gray-700 shadow-sm">
|
|
11
|
+
<div class="p-4 flex items-center justify-center rounded-t-md h-36" {{background-url network.backdrop_url overlay=true}}>
|
|
12
|
+
<Image src={{network.logo_url}} class="w-32" alt={{network.name}} @fallbackSrc="https://flb-assets.s3.ap-southeast-1.amazonaws.com/static/image-file-icon.png" />
|
|
13
|
+
</div>
|
|
14
|
+
<div class="border-t dark:border-gray-700 px-4 py-2">
|
|
15
|
+
<div class="flex items-center justify-between">
|
|
16
|
+
<div>
|
|
17
|
+
<LinkTo @route="networks.index.network" @model={{network}} class="font-bold text-lg text-gray-700 dark:text-gray-100">{{network.name}}</LinkTo>
|
|
18
|
+
</div>
|
|
19
|
+
<div>
|
|
20
|
+
<DropdownButton @renderInPlace={{true}} @size="xs" @icon="cog" @iconPrefix="fas" @textClass="block truncate text-gray-700 dark:text-gray-100" as |dd|>
|
|
21
|
+
<div class="next-dd-menu" aria-orientation="vertical" aria-labelledby="user-menu">
|
|
22
|
+
<div class="px-1">
|
|
23
|
+
<div class="next-dd-title">
|
|
24
|
+
Network Options
|
|
25
|
+
</div>
|
|
26
|
+
</div>
|
|
27
|
+
<div class="next-dd-menu-seperator"></div>
|
|
28
|
+
<div class="px-1">
|
|
29
|
+
<a href="javascript:;" class="next-dd-item" role="menuitem" {{on "click" (dropdown-fn dd this.manageNetwork network)}}>
|
|
30
|
+
<div class="w-7">
|
|
31
|
+
<FaIcon @icon="network-wired" class="mr-2" />
|
|
32
|
+
</div>
|
|
33
|
+
<span>Manage Network</span>
|
|
34
|
+
</a>
|
|
35
|
+
<a href="javascript:;" class="next-dd-item" role="menuitem" {{on "click" (dropdown-fn dd this.sendInvites network)}}>
|
|
36
|
+
<div class="w-7">
|
|
37
|
+
<FaIcon @icon="envelope-open-text" class="mr-2" />
|
|
38
|
+
</div>
|
|
39
|
+
<span>Send Invites</span>
|
|
40
|
+
</a>
|
|
41
|
+
<a href="javascript:;" class="next-dd-item text-red-500 hover:bg-opacity-75" role="menuitem" {{on "click" (dropdown-fn dd this.deleteNetwork network)}}>
|
|
42
|
+
<div class="w-7">
|
|
43
|
+
<FaIcon @icon="trash" class="mr-2 text-red-500" />
|
|
44
|
+
</div>
|
|
45
|
+
<span class="text-red-500">Delete Network</span>
|
|
46
|
+
</a>
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|
|
49
|
+
</DropdownButton>
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
{{/each}}
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
</Layout::Section::Body>
|
|
59
|
+
|
|
60
|
+
{{outlet}}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<Layout::Section::Header @title="Orders" @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.bulkDeleteOrders)}}>
|
|
9
|
+
Delete Orders
|
|
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 @@
|
|
|
1
|
+
{{outlet}}
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
<Overlay @position="right" @noBackdrop={{true}} @fullHeight={{true}} @containerClass="border-l border-transparent dark:border-gray-700">
|
|
2
|
+
<Overlay::Header @title={{this.overlayTitle}} @titleClass="truncate" @titleWrapperClass="w-3/4" @headerLeftClass="w-70pc" @headerLeftInnerClass="w-full flex-1" @onPressCancel={{this.transitionBack}}>
|
|
3
|
+
<Button @icon={{this.overlayActionButtonIcon}} @type="primary" @text={{this.overlayActionButtonTitle}} @onClick={{this.saveProduct}} @isLoading={{this.isSaving}} @isSubscriptionRequired={{true}} />
|
|
4
|
+
</Overlay::Header>
|
|
5
|
+
|
|
6
|
+
<Overlay::Body @increaseInnerBodyHeightBy="0" @wrapperClass="new-order-overlay-body px-4 space-y-4 pt-4">
|
|
7
|
+
<InputGroup @name="Product Name" @value={{this.product.name}} @helpText="Enter your product's name" />
|
|
8
|
+
<InputGroup @name="Product Description" @helpText="Enter a description of your product">
|
|
9
|
+
<Textarea @value={{this.product.description}} class="form-input w-full" placeholder="Enter a description of your product...." rows={{4}} />
|
|
10
|
+
</InputGroup>
|
|
11
|
+
<InputGroup @name="Product Tags">
|
|
12
|
+
<TagInput class="form-input" @placeholder="Add tags" @allowSpacesInTags={{true}} @tags={{this.product.tags}} @addTag={{this.addTag}} @removeTagAtIndex={{this.removeTag}} as |tag|>
|
|
13
|
+
{{tag}}
|
|
14
|
+
</TagInput>
|
|
15
|
+
</InputGroup>
|
|
16
|
+
<InputGroup @name="Product SKU" @value={{this.product.sku}} @helpText="Enter product SKU if applicable" />
|
|
17
|
+
<div class="grid grid-cols-2 gap-2">
|
|
18
|
+
<InputGroup @name="Price" @helpText="Enter a price users will pay to purchase this product">
|
|
19
|
+
<MoneyInput class="w-full" @currency={{this.product.currency}} @value={{this.product.price}} @canSelectCurrency={{true}} @onCurrencyChange={{fn (mut this.product.currency)}} />
|
|
20
|
+
</InputGroup>
|
|
21
|
+
<InputGroup @name="Sale Price" @helpText="Optionally add a sale price for the product if the product is put on sale">
|
|
22
|
+
<MoneyInput class="w-full" @currency={{this.product.currency}} @value={{this.product.sale_price}} @canSelectCurrency={{true}} @onCurrencyChange={{fn (mut this.product.currency)}} />
|
|
23
|
+
</InputGroup>
|
|
24
|
+
</div>
|
|
25
|
+
|
|
26
|
+
<ContentPanel @title="Metadata" @open={{this.product.meta_array.length}} @actionButtons={{this.metadataButtons}} @pad={{true}} @panelBodyWrapperClass="px-0 py-4" @panelBodyClass="bg-white dark:bg-gray-800">
|
|
27
|
+
{{#each this.product.meta_array as |metaField index|}}
|
|
28
|
+
<div class="px-4 py-3 border-b border-gray-200 dark:border-gray-700">
|
|
29
|
+
<div class="input-group">
|
|
30
|
+
<div class="flex justify-between items-center mb-1">
|
|
31
|
+
<Input class="form-input border-0 px-2 py-1 m-0 bg-white dark:bg-gray-900 shadow-none" @value={{metaField.label}} placeholder={{metaField.label}} />
|
|
32
|
+
<a href="javascript:;" class="text-xs" tabindex="-1" {{on "click" (fn this.removeMetaField index)}}>
|
|
33
|
+
<FaIcon @icon="trash" @size="sm" class="mr-1" /> Remove
|
|
34
|
+
</a>
|
|
35
|
+
</div>
|
|
36
|
+
<Input class="w-full form-input" @value={{metaField.value}} placeholder={{metaField.label}} />
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
{{/each}}
|
|
40
|
+
</ContentPanel>
|
|
41
|
+
|
|
42
|
+
<InputGroup>
|
|
43
|
+
<TranslationsEditor @value={{this.product.translations}} @defaultKeys={{array "name" "description"}} @onChange={{fn (mut this.product.translations)}} />
|
|
44
|
+
</InputGroup>
|
|
45
|
+
|
|
46
|
+
<div class="store-boolean-settings">
|
|
47
|
+
<div class="input-group mb-0">
|
|
48
|
+
<Checkbox @value={{this.product.is_service}} @onToggle={{fn (mut this.product.is_service)}}>
|
|
49
|
+
<FaIcon @icon="house-leave" class="text-indigo-400 mx-2" /><span class="dark:text-gray-100 text-sm">This is a service</span>
|
|
50
|
+
</Checkbox>
|
|
51
|
+
</div>
|
|
52
|
+
|
|
53
|
+
{{#if this.product.is_service}}
|
|
54
|
+
<div class="input-group mb-0">
|
|
55
|
+
<Checkbox @value={{this.product.is_bookable}} @onToggle={{fn (mut this.product.is_bookable)}}>
|
|
56
|
+
<FaIcon @icon="calendar-star" class="text-yellow-400 mx-2" /><span class="dark:text-gray-100 text-sm">This service is bookable</span>
|
|
57
|
+
</Checkbox>
|
|
58
|
+
</div>
|
|
59
|
+
{{/if}}
|
|
60
|
+
|
|
61
|
+
<div class="input-group mb-0">
|
|
62
|
+
<Checkbox @value={{this.product.is_on_sale}} @onToggle={{fn (mut this.product.is_on_sale)}}>
|
|
63
|
+
<FaIcon @icon="badge-percent" class="text-blue-400 mx-2" /><span class="dark:text-gray-100 text-sm">This product is on sale</span>
|
|
64
|
+
</Checkbox>
|
|
65
|
+
</div>
|
|
66
|
+
|
|
67
|
+
<div class="input-group">
|
|
68
|
+
<Checkbox @value={{this.product.is_recommended}} @onToggle={{fn (mut this.product.is_recommended)}}>
|
|
69
|
+
<FaIcon @icon="check" class="text-green-400 mx-2" /><span class="dark:text-gray-100 text-sm">This product is recommended</span>
|
|
70
|
+
</Checkbox>
|
|
71
|
+
</div>
|
|
72
|
+
|
|
73
|
+
<div class="input-group">
|
|
74
|
+
<Checkbox @value={{this.product.is_available}} @onToggle={{fn (mut this.product.is_available)}}>
|
|
75
|
+
<FaIcon @icon="eye" class="text-blue-400 mx-2" /><span class="dark:text-gray-100 text-sm">This product is available</span>
|
|
76
|
+
</Checkbox>
|
|
77
|
+
</div>
|
|
78
|
+
</div>
|
|
79
|
+
|
|
80
|
+
<ContentPanel @title="Variants" @open={{this.product.variants.length}} @pad={{false}} @panelBodyWrapperClass="px-0 py-4" @panelBodyClass="bg-white dark:bg-gray-800">
|
|
81
|
+
<div class="content-panel-body p-4">
|
|
82
|
+
<div class="flex items-center justify-end">
|
|
83
|
+
<Button @text="New Variant" @icon="plus" @iconPrefix="fas" @onClick={{this.createProductVariant}} />
|
|
84
|
+
</div>
|
|
85
|
+
</div>
|
|
86
|
+
<Tabs as |Tab|>
|
|
87
|
+
{{#each this.product.variants as |variant|}}
|
|
88
|
+
<Tab @title={{variant.name}}>
|
|
89
|
+
<div class="px-4 py-3">
|
|
90
|
+
<div class="flex items-center justify-end mb-3">
|
|
91
|
+
<Button class="mr-2" @type="danger" @text="Remove Variant" @icon="trash" @onClick={{fn this.removeProductVariant variant}} />
|
|
92
|
+
<Button class="mr-2" @type="warning" @text="Edit Variant" @icon="pencil" @onClick={{fn this.editProductVariant variant}} />
|
|
93
|
+
<Button @text={{concat "New " (lowercase variant.name) " option"}} @icon="plus" @iconPrefix="fas" @onClick={{fn this.addVariantOption variant}} />
|
|
94
|
+
</div>
|
|
95
|
+
<div class="space-y-2">
|
|
96
|
+
{{#each variant.options as |variantOption index|}}
|
|
97
|
+
<div class="grid grid-cols-9 gap-1 px-3 py-2 rounded-md dark:bg-gray-900 bg-gray-50">
|
|
98
|
+
<div class="col-span-2">
|
|
99
|
+
<Input @type="text" @value={{variantOption.name}} class="form-input w-full" placeholder="Option Name" />
|
|
100
|
+
</div>
|
|
101
|
+
<div class="col-span-4">
|
|
102
|
+
<Input @type="text" @value={{variantOption.description}} class="form-input w-full" placeholder="Option Description" />
|
|
103
|
+
</div>
|
|
104
|
+
<div class="col-span-2">
|
|
105
|
+
<MoneyInput class="w-full" @currency={{this.product.currency}} @canSelectCurrency={{false}} @value={{variantOption.additional_cost}} />
|
|
106
|
+
</div>
|
|
107
|
+
<div class="flex items-center justify-center text-center text-sm">
|
|
108
|
+
<a href="javascript:;" {{on "click" (fn this.removeVariantOption variant index)}}>Remove</a>
|
|
109
|
+
</div>
|
|
110
|
+
</div>
|
|
111
|
+
{{/each}}
|
|
112
|
+
</div>
|
|
113
|
+
</div>
|
|
114
|
+
</Tab>
|
|
115
|
+
{{/each}}
|
|
116
|
+
</Tabs>
|
|
117
|
+
</ContentPanel>
|
|
118
|
+
|
|
119
|
+
<ContentPanel @title="Add-Ons" @open={{this.product.addon_categories.length}} @pad={{false}} @panelBodyWrapperClass="px-0 py-4" @panelBodyClass="bg-white dark:bg-gray-800">
|
|
120
|
+
<div class="px-4 py-3">
|
|
121
|
+
<div class="flex items-center justify-end mb-3">
|
|
122
|
+
<Button @text="Select Addon Categories" @icon="plus" @iconPrefix="fas" @onClick={{this.selectAddonCategory}} />
|
|
123
|
+
</div>
|
|
124
|
+
<div class="space-y-2">
|
|
125
|
+
{{#each this.product.addon_categories as |addonCategory index|}}
|
|
126
|
+
<div>
|
|
127
|
+
<div class="flex items-center rounded-md shadow-sm px-3 py-2 font-semibold bg-gray-200 dark:bg-gray-900 dark:text-gray-100 mb-2">
|
|
128
|
+
<div class="flex-1 flex items-center">
|
|
129
|
+
<FaIcon @icon="pencil" class="mr-1 dark:text-gray-100" />
|
|
130
|
+
<div class="w-full px-2 m-0 border-none bg-transparent dark:text-gray-100">
|
|
131
|
+
{{addonCategory.name}}
|
|
132
|
+
</div>
|
|
133
|
+
</div>
|
|
134
|
+
<div class="flex items-center">
|
|
135
|
+
<a href="javascript:;" class="destroy-action opacity-50 hover:opacity-100 text-sm" {{on "click" (fn this.removeAddonCategory index)}}>Remove</a>
|
|
136
|
+
</div>
|
|
137
|
+
</div>
|
|
138
|
+
<div class="space-y-2 mb-2">
|
|
139
|
+
{{#each addonCategory.category.addons as |addon|}}
|
|
140
|
+
<div class="grid grid-cols-10 gap-1 px-3 py-2 rounded-md border border-gray-200 dark:border-gray-900 dark:text-gray-100 dark:bg-gray-800 bg-gray-200">
|
|
141
|
+
<div class="flex items-center">
|
|
142
|
+
<Checkbox @value={{not-in-array addon.id addonCategory.excluded_addons}} @onToggle={{fn this.excludeAddon index addon}} />
|
|
143
|
+
</div>
|
|
144
|
+
<div class="col-span-3 flex items-center">
|
|
145
|
+
{{addon.name}}
|
|
146
|
+
</div>
|
|
147
|
+
<div class="col-span-4">
|
|
148
|
+
{{addon.description}}
|
|
149
|
+
</div>
|
|
150
|
+
<div class="col-span-2">
|
|
151
|
+
{{format-currency addon.price}}
|
|
152
|
+
</div>
|
|
153
|
+
</div>
|
|
154
|
+
{{/each}}
|
|
155
|
+
</div>
|
|
156
|
+
</div>
|
|
157
|
+
{{/each}}
|
|
158
|
+
</div>
|
|
159
|
+
</div>
|
|
160
|
+
</ContentPanel>
|
|
161
|
+
|
|
162
|
+
<ContentPanel @title="Availability" @open={{this.product.hours.length}} @pad={{false}} @panelBodyWrapperClass="px-0 py-4" @panelBodyClass="bg-white dark:bg-gray-800">
|
|
163
|
+
<div class="px-4 py-3">
|
|
164
|
+
<ScheduleManager @subject={{this.product}} @subjectKey="product_uuid" @hourModelType="product-hour" class="grid grid-cols-1 gap-4 lg:grid-cols-2 lg:gap-2" />
|
|
165
|
+
</div>
|
|
166
|
+
</ContentPanel>
|
|
167
|
+
|
|
168
|
+
<ContentPanel @title="Images & Videos" @open={{this.product.files.length}} @pad={{false}} @panelBodyWrapperClass="px-0 py-4" @panelBodyClass="bg-white dark:bg-gray-800">
|
|
169
|
+
<div class="px-6 space-y-4">
|
|
170
|
+
{{#if this.isUploading}}
|
|
171
|
+
<div class="min-h-56 dropzone w-full rounded-lg px-4 py-8 min-h bg-gray-50 dark:bg-gray-900 bg-opacity-25 text-gray-900 dark:text-white text-center flex flex-col items-center justify-center border-2 border-dashed border-gray-200 dark:border-indigo-500">
|
|
172
|
+
<div class="flex items-center justify-center py-5">
|
|
173
|
+
<Spinner class="text-sm dar:text-gray-100" @loadingMessage="Uploading..." />
|
|
174
|
+
</div>
|
|
175
|
+
</div>
|
|
176
|
+
{{else}}
|
|
177
|
+
{{#let (file-queue name="files" onFileAdded=this.queueFile accept=(join "," this.acceptedFileTypes)) as |queue|}}
|
|
178
|
+
<FileDropzone @queue={{queue}} class="dropzone file-dropzone" as |dropzone|>
|
|
179
|
+
{{#if dropzone.active}}
|
|
180
|
+
{{#if dropzone.valid}}
|
|
181
|
+
Drop to upload
|
|
182
|
+
{{else}}
|
|
183
|
+
Invalid
|
|
184
|
+
{{/if}}
|
|
185
|
+
{{else if queue.files.length}}
|
|
186
|
+
<div class="my-2">
|
|
187
|
+
<FaIcon @icon="photo-video" class="text-indigo-500 mr-2" />
|
|
188
|
+
{{pluralize queue.files.length "file"}} ready for upload.
|
|
189
|
+
</div>
|
|
190
|
+
<div class="my-2">({{queue.progress}}%)</div>
|
|
191
|
+
{{else}}
|
|
192
|
+
<h4 class="font-semibold mb-8">
|
|
193
|
+
<FaIcon @icon="photo-video" @size="2x" class="text-indigo-500 mr-2" /> Upload Images & Videos
|
|
194
|
+
</h4>
|
|
195
|
+
<div>
|
|
196
|
+
{{#if dropzone.supported}}
|
|
197
|
+
<p class="text-base font-semibold my-5">Drag and drop image and video files onto this dropzone</p>
|
|
198
|
+
{{/if}}
|
|
199
|
+
<FileUpload @name="files" @for="files" @accept={{join "," this.acceptedFileTypes}} @multiple={{true}} @onFileAdded={{fn this.queueFile}}>
|
|
200
|
+
<a tabindex={{0}} class="btn btn-magic cursor-pointer ml-1">or select files to upload.</a>
|
|
201
|
+
</FileUpload>
|
|
202
|
+
</div>
|
|
203
|
+
{{/if}}
|
|
204
|
+
</FileDropzone>
|
|
205
|
+
{{/let}}
|
|
206
|
+
{{#if this.uploadQueue}}
|
|
207
|
+
<div class="mx-4">
|
|
208
|
+
<div class="flex items-center justify-between mb-4">
|
|
209
|
+
<span class="leading-6 dark:text-gray-100">Upload Queue</span>
|
|
210
|
+
</div>
|
|
211
|
+
<div class="space-y-2 mb-4">
|
|
212
|
+
{{#each this.uploadQueue as |file|}}
|
|
213
|
+
<div class="flex items-center justify-between bg-green-100 border border-green-800 dark:border-green-800 py-1.5 shadow-sm rounded-lg px-4">
|
|
214
|
+
<div class="text-sm text-green-900">{{file.name}}</div>
|
|
215
|
+
<div class="flex items-center text-sm">
|
|
216
|
+
<Spinner class="text-green-900 mr-2" />
|
|
217
|
+
<span class="font-bold text-green-900">{{round file.progress}}%</span>
|
|
218
|
+
</div>
|
|
219
|
+
</div>
|
|
220
|
+
{{/each}}
|
|
221
|
+
</div>
|
|
222
|
+
</div>
|
|
223
|
+
{{/if}}
|
|
224
|
+
<div>
|
|
225
|
+
<div class="grid grid-cols-2 md:grid-cols-4 gap-2 md:gap-4">
|
|
226
|
+
{{#each this.product.files as |file|}}
|
|
227
|
+
<FileRecord @file={{file}} @fileIconClass={{if (eq this.product.primary_image_uuid file.id) 'border-blue-400'}} @onDelete={{this.removeFile}}>
|
|
228
|
+
<div class="flex items-center justify-evenly">
|
|
229
|
+
<Button @icon="magic" @text="Make Primary" @size="xs" @textClass="text-xs truncate" @onClick={{fn this.makePrimaryFile file}} @disabled={{eq this.product.primary_image_uuid file.id}} />
|
|
230
|
+
</div>
|
|
231
|
+
</FileRecord>
|
|
232
|
+
{{/each}}
|
|
233
|
+
</div>
|
|
234
|
+
</div>
|
|
235
|
+
{{/if}}
|
|
236
|
+
</div>
|
|
237
|
+
</ContentPanel>
|
|
238
|
+
|
|
239
|
+
<ContentPanel @title="Youtube Videos" @open={{this.product.youtube_urls.length}} @wrapperClass="mb-12" @panelBodyWrapperClass="p-4" @panelBodyClass="bg-white dark:bg-gray-800">
|
|
240
|
+
<p class="text-sm">Add YouTube video urls to assosciate with this product or service.</p>
|
|
241
|
+
<div class="input-group">
|
|
242
|
+
<ArrayInput @data={{this.product.youtube_urls}} @placeholder="Enter youtube video url" @onDataChanged={{fn (mut this.product.youtube_urls)}}>
|
|
243
|
+
<InputLabel @labelText="Youtube Video URLs" @helpText="Input product youtube video urls if applicable." />
|
|
244
|
+
</ArrayInput>
|
|
245
|
+
</div>
|
|
246
|
+
</ContentPanel>
|
|
247
|
+
</Overlay::Body>
|
|
248
|
+
</Overlay>
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<Layout::Section::Header @title={{concat this.category.name " Products"}} @searchQuery={{this.query}} @onSearch={{perform this.search}}>
|
|
2
|
+
<Button @type="default" @text="Edit this category" @icon="edit" @onClick={{fn this.editCategory this.category}} @disabled={{not this.category}} @wrapperClass="mr-2" />
|
|
3
|
+
<Button @type="danger" @text="Delete this category" @icon="trash" @onClick={{this.deleteCategory}} @disabled={{not this.category}} />
|
|
4
|
+
</Layout::Section::Header>
|
|
5
|
+
|
|
6
|
+
<div class="h-screen overflow-y-scroll p-6">
|
|
7
|
+
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
|
|
8
|
+
{{#each @model as |product|}}
|
|
9
|
+
<div class="border border-gray-200 bg-white dark:bg-gray-900 dark:text-gray-100 dark:border-gray-700 text-center rounded-md px-2 py-3">
|
|
10
|
+
<div class="flex flex-col items-center justify-center overflow-hidden">
|
|
11
|
+
<div class="mb-3 flex items-center justify-center">
|
|
12
|
+
<img src={{product.primary_image_url}} alt={{product.name}} class="w-24 h-24" />
|
|
13
|
+
</div>
|
|
14
|
+
<h4 class="font-semibold mb-1">{{product.name}}</h4>
|
|
15
|
+
<p class="text-sm truncate">{{product.description}}</p>
|
|
16
|
+
<p class="mb-2 text-sm text-green-400">{{format-currency product.price product.currency}}</p>
|
|
17
|
+
<div class="flex items-center justify-evenly space-x-4">
|
|
18
|
+
<LinkTo @route="products.index.category.edit" @model={{product}} class="text-sm">
|
|
19
|
+
<FaIcon @icon="pencil" class="mr-1" />
|
|
20
|
+
<span class="destroy-action">Edit</span>
|
|
21
|
+
</LinkTo>
|
|
22
|
+
<a href="javascript:;" class="destroy-action text-sm" {{on "click" (fn this.deleteProduct product)}}>
|
|
23
|
+
<FaIcon @icon="trash" class="text-red-500 mr-1" />
|
|
24
|
+
<span class="destroy-action">Delete</span>
|
|
25
|
+
</a>
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
|
+
{{else}}
|
|
30
|
+
<div>
|
|
31
|
+
<h3 class="dark:text-gray-100 text-opacity-75 text-sm">No products</h3>
|
|
32
|
+
</div>
|
|
33
|
+
{{/each}}
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
|
|
37
|
+
<Layout::Section::Footer>
|
|
38
|
+
<Pagination @meta={{@model.meta}} @currentPage={{this.page}} @onPageChange={{fn (mut this.page)}} />
|
|
39
|
+
</Layout::Section::Footer>
|
|
40
|
+
|
|
41
|
+
{{outlet}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{{outlet}}
|