@fleetbase/storefront-engine 0.4.0 → 0.4.2
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/addon/components/customer-panel/orders.hbs +2 -2
- package/addon/components/modals/create-gateway.hbs +33 -12
- package/addon/components/network-category-picker.js +1 -1
- package/addon/components/order-panel.hbs +1 -1
- package/addon/components/widget/customers.hbs +5 -2
- package/addon/components/widget/customers.js +14 -6
- package/addon/components/widget/orders.hbs +31 -10
- package/addon/components/widget/orders.js +7 -1
- package/addon/components/widget/storefront-key-metrics.js +2 -2
- package/addon/components/widget/storefront-metrics.hbs +11 -1
- package/addon/components/widget/storefront-metrics.js +103 -1
- package/addon/controllers/networks/index/network/index.js +2 -0
- package/addon/controllers/networks/index/network/stores.js +0 -1
- package/addon/controllers/products/index/category/new.js +13 -2
- package/addon/controllers/settings/gateways.js +6 -1
- package/addon/controllers/settings/index.js +1 -0
- package/addon/controllers/settings/notifications.js +4 -5
- package/addon/models/network.js +1 -0
- package/addon/models/store.js +1 -0
- package/addon/routes/networks/index/network/index.js +5 -0
- package/addon/routes/settings/index.js +5 -0
- package/addon/services/order-actions.js +31 -0
- package/addon/styles/storefront-engine.css +22 -0
- package/addon/templates/home.hbs +2 -2
- package/addon/templates/networks/index/network/index.hbs +21 -8
- package/addon/templates/networks/index/network/stores.hbs +8 -1
- package/addon/templates/products/index/category/new.hbs +149 -134
- package/addon/templates/settings/gateways.hbs +15 -4
- package/addon/templates/settings/index.hbs +13 -0
- package/addon/templates/settings/notifications.hbs +2 -2
- package/addon/utils/commerce-date-ranges.js +263 -0
- package/app/utils/commerce-date-ranges.js +1 -0
- package/composer.json +1 -1
- package/extension.json +1 -1
- package/package.json +4 -4
- package/server/migrations/2025_09_01_041353_add_default_order_config_column.php +110 -0
- package/server/src/Console/Commands/MigrateStripeSandboxCustomers.php +165 -0
- package/server/src/Expansions/OrderExpansion.php +43 -0
- package/server/src/Http/Controllers/NetworkController.php +1 -1
- package/server/src/Http/Controllers/OrderController.php +62 -9
- package/server/src/Http/Controllers/v1/CheckoutController.php +57 -48
- package/server/src/Http/Controllers/v1/ServiceQuoteController.php +19 -3
- package/server/src/Http/Middleware/SetStorefrontSession.php +8 -6
- package/server/src/Http/Resources/Customer.php +41 -17
- package/server/src/Http/Resources/Gateway.php +16 -11
- package/server/src/Http/Resources/Network.php +35 -34
- package/server/src/Http/Resources/NotificationChannel.php +17 -10
- package/server/src/Http/Resources/Product.php +1 -0
- package/server/src/Http/Resources/Store.php +36 -35
- package/server/src/Models/Customer.php +18 -2
- package/server/src/Models/FoodTruck.php +29 -2
- package/server/src/Models/Network.php +63 -1
- package/server/src/Models/Store.php +71 -9
- package/server/src/Notifications/StorefrontOrderAccepted.php +164 -0
- package/server/src/Notifications/StorefrontOrderCanceled.php +11 -1
- package/server/src/Notifications/StorefrontOrderCompleted.php +11 -1
- package/server/src/Notifications/StorefrontOrderDriverAssigned.php +12 -4
- package/server/src/Notifications/StorefrontOrderEnroute.php +12 -4
- package/server/src/Notifications/StorefrontOrderNearby.php +12 -4
- package/server/src/Notifications/StorefrontOrderPreparing.php +12 -4
- package/server/src/Notifications/StorefrontOrderReadyForPickup.php +12 -4
- package/server/src/Observers/OrderObserver.php +6 -4
- package/server/src/Providers/StorefrontServiceProvider.php +1 -0
- package/server/src/Rules/IsValidLocation.php +12 -0
- package/server/src/Support/PushNotification.php +20 -4
- package/server/src/Support/Storefront.php +283 -37
- package/server/src/routes.php +1 -0
- package/translations/{ar-ae.yml → ar-ae.yaml} +313 -253
- package/translations/bg-bg.yaml +734 -0
- package/translations/en-us.yaml +5 -0
- package/translations/es-es.yaml +732 -0
- package/translations/fr-fr.yaml +748 -0
- package/translations/mn-mn.yaml +725 -0
- package/translations/pt-br.yaml +732 -0
- package/translations/ru-ru.yaml +726 -0
- package/translations/vi-vn.yaml +412 -338
- package/translations/zh-cn.yaml +659 -0
|
@@ -40,12 +40,14 @@
|
|
|
40
40
|
max-width: 100%;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
.status-badge.accepted-status-badge > span,
|
|
43
44
|
.status-badge.pickup-ready-status-badge > span {
|
|
44
45
|
background-color: #166534;
|
|
45
46
|
border: 1px solid #15803d;
|
|
46
47
|
color: #dcfce7;
|
|
47
48
|
}
|
|
48
49
|
|
|
50
|
+
.status-badge.accepted-status-badge > span svg,
|
|
49
51
|
.status-badge.pickup-ready-status-badge > span svg {
|
|
50
52
|
color: #86efac;
|
|
51
53
|
}
|
|
@@ -60,12 +62,16 @@
|
|
|
60
62
|
color: #fca5a5;
|
|
61
63
|
}
|
|
62
64
|
|
|
65
|
+
.status-badge.driver-picked-up-status-badge > span,
|
|
66
|
+
.status-badge.driver-enroute-to-store-status-badge > span,
|
|
63
67
|
.status-badge.draft-status-badge > span {
|
|
64
68
|
background-color: #a16207;
|
|
65
69
|
border: 1px solid #a16207;
|
|
66
70
|
color: #fef9c3;
|
|
67
71
|
}
|
|
68
72
|
|
|
73
|
+
.status-badge.driver-picked-up-status-badge > span svg,
|
|
74
|
+
.status-badge.driver-enroute-to-store-status-badge > span svg,
|
|
69
75
|
.status-badge.draft-status-badge > span svg {
|
|
70
76
|
color: #fef9c3;
|
|
71
77
|
}
|
|
@@ -84,3 +90,19 @@ td.network-store-name-column > div > svg {
|
|
|
84
90
|
height: 0.5rem;
|
|
85
91
|
width: 0.5rem;
|
|
86
92
|
}
|
|
93
|
+
|
|
94
|
+
.storefront-datepicker .air-datepicker-buttons {
|
|
95
|
+
animation: slideIn 0.3s ease-out;
|
|
96
|
+
display: flex;
|
|
97
|
+
flex-wrap: wrap;
|
|
98
|
+
gap: 8px;
|
|
99
|
+
padding: 0.5rem;
|
|
100
|
+
max-height: 235px;
|
|
101
|
+
overflow-y: auto;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.storefront-datepicker .air-datepicker-buttons .quick-select-btn {
|
|
105
|
+
display: flex;
|
|
106
|
+
align-items: center;
|
|
107
|
+
width: 48%;
|
|
108
|
+
}
|
package/addon/templates/home.hbs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
<Layout::Section::Body class="space-y-4 h-full overflow-y-scroll" @padded={{true}}>
|
|
4
4
|
<Widget::StorefrontMetrics />
|
|
5
|
-
<Widget::Orders />
|
|
6
|
-
<Widget::Customers />
|
|
5
|
+
<Widget::Orders @wrapperClass="bordered-classic" />
|
|
6
|
+
<Widget::Customers @wrapperClass="bordered-classic" />
|
|
7
7
|
<Spacer @height="300px" />
|
|
8
8
|
</Layout::Section::Body>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
<div class="space-y-
|
|
2
|
-
<ContentPanel @title={{t "storefront.networks.index.network.index.general-network-settings-title"}} @open={{true}} @pad={{
|
|
1
|
+
<div class="space-y-2">
|
|
2
|
+
<ContentPanel @title={{t "storefront.networks.index.network.index.general-network-settings-title"}} @open={{true}} @pad={{false}} @wrapperClass="bordered-top">
|
|
3
3
|
<div class="space-y-4">
|
|
4
4
|
<div>
|
|
5
5
|
<h1 class="text-lg leading-6 font-bold text-gray-900 dark:text-gray-100">
|
|
@@ -22,11 +22,24 @@
|
|
|
22
22
|
@placeholder={{t "storefront.networks.index.network.index.general-network-settings-form.description-placeholder"}}
|
|
23
23
|
@helpText={{t "storefront.networks.index.network.index.general-network-settings-form.description-help-text"}}
|
|
24
24
|
/>
|
|
25
|
+
|
|
25
26
|
<InputGroup @name={{t "storefront.networks.index.network.index.general-network-settings-form.currency"}}>
|
|
26
27
|
<CurrencySelect @currency={{@model.currency}} @onCurrencyChange={{fn (mut @model.currency)}} @triggerClass="w-full form-select" />
|
|
27
28
|
</InputGroup>
|
|
28
29
|
|
|
29
|
-
<
|
|
30
|
+
<InputGroup @name="Default Order Config" @helpText="Select the order config which will apply to all orders created for this network.">
|
|
31
|
+
<Select
|
|
32
|
+
@value={{@model.order_config_uuid}}
|
|
33
|
+
@options={{this.orderConfigs}}
|
|
34
|
+
@optionValue="id"
|
|
35
|
+
@optionLabel="name"
|
|
36
|
+
@onSelect={{fn (mut @model.order_config_uuid)}}
|
|
37
|
+
@placeholder="Select default order config"
|
|
38
|
+
class="w-full"
|
|
39
|
+
/>
|
|
40
|
+
</InputGroup>
|
|
41
|
+
|
|
42
|
+
<ContentPanel @title={{t "storefront.networks.index.network.index.general-network-settings-form.contact-social-panel.panel-title"}} @open={{false}} @pad={{false}} @wrapperClass="bordered-top">
|
|
30
43
|
<InputGroup @name={{t "storefront.networks.index.network.index.general-network-settings-form.contact-social-panel.phone"}}>
|
|
31
44
|
<PhoneInput @value={{@model.phone}} @onInput={{fn (mut @model.phone)}} class="form-input w-full" />
|
|
32
45
|
</InputGroup>
|
|
@@ -62,7 +75,7 @@
|
|
|
62
75
|
/>
|
|
63
76
|
</ContentPanel>
|
|
64
77
|
|
|
65
|
-
<ContentPanel @title={{t "storefront.networks.index.network.index.general-network-settings-form.logo-backdrop-panel.panel-title"}} @open={{false}} @pad={{
|
|
78
|
+
<ContentPanel @title={{t "storefront.networks.index.network.index.general-network-settings-form.logo-backdrop-panel.panel-title"}} @open={{false}} @pad={{false}} @wrapperClass="bordered-top">
|
|
66
79
|
<InputGroup
|
|
67
80
|
@name={{t "storefront.networks.index.network.index.general-network-settings-form.logo-backdrop-panel.logo-label"}}
|
|
68
81
|
@helpText={{t "storefront.networks.index.network.index.general-network-settings-form.logo-backdrop-panel.logo-help-text"}}
|
|
@@ -255,7 +268,7 @@
|
|
|
255
268
|
</div>
|
|
256
269
|
</ContentPanel>
|
|
257
270
|
|
|
258
|
-
<ContentPanel @title={{t "storefront.networks.index.network.index.api-panel.panel-title"}} @open={{false}} @pad={{
|
|
271
|
+
<ContentPanel @title={{t "storefront.networks.index.network.index.api-panel.panel-title"}} @open={{false}} @pad={{false}} @wrapperClass="bordered-top">
|
|
259
272
|
<div class="space-y-6">
|
|
260
273
|
<div>
|
|
261
274
|
<h1 class="text-lg leading-6 font-bold text-gray-900 dark:text-gray-100">
|
|
@@ -275,7 +288,7 @@
|
|
|
275
288
|
</div>
|
|
276
289
|
</ContentPanel>
|
|
277
290
|
|
|
278
|
-
<ContentPanel @title={{t "storefront.networks.index.network.index.payment-gateways-panel.panel-title"}} @open={{false}} @pad={{
|
|
291
|
+
<ContentPanel @title={{t "storefront.networks.index.network.index.payment-gateways-panel.panel-title"}} @open={{false}} @pad={{false}} @wrapperClass="bordered-top">
|
|
279
292
|
<div class="space-y-6">
|
|
280
293
|
<div class="flex justify-between">
|
|
281
294
|
<div>
|
|
@@ -298,7 +311,7 @@
|
|
|
298
311
|
</div>
|
|
299
312
|
|
|
300
313
|
{{#each this.gateways as |gateway|}}
|
|
301
|
-
<ContentPanel @title={{gateway.name}} @open={{true}} @pad={{
|
|
314
|
+
<ContentPanel @title={{gateway.name}} @open={{true}} @pad={{false}} @wrapperClass="bordered-top">
|
|
302
315
|
<InputGroup
|
|
303
316
|
@name={{t "storefront.networks.index.network.index.payment-gateways-panel.gateway-form.name"}}
|
|
304
317
|
@value={{gateway.name}}
|
|
@@ -355,7 +368,7 @@
|
|
|
355
368
|
</div>
|
|
356
369
|
</ContentPanel>
|
|
357
370
|
|
|
358
|
-
<ContentPanel @title={{t "storefront.networks.index.network.index.notification-channels-panel.panel-title"}} @open={{false}} @pad={{
|
|
371
|
+
<ContentPanel @title={{t "storefront.networks.index.network.index.notification-channels-panel.panel-title"}} @open={{false}} @pad={{false}} @wrapperClass="bordered-top">
|
|
359
372
|
<div class="space-y-6">
|
|
360
373
|
<div class="flex justify-between">
|
|
361
374
|
<div class="w-3/4">
|
|
@@ -20,7 +20,14 @@
|
|
|
20
20
|
|
|
21
21
|
<Layout::Section::Body>
|
|
22
22
|
<div class="flex flex-row items-center space-x-2">
|
|
23
|
-
<NetworkCategoryPicker
|
|
23
|
+
<NetworkCategoryPicker
|
|
24
|
+
@network={{this.network}}
|
|
25
|
+
@category={{this.category}}
|
|
26
|
+
@onCreateNewCategory={{this.createNewCategory}}
|
|
27
|
+
@onSelect={{this.selectCategory}}
|
|
28
|
+
@onReady={{this.setCategoryPickerContext}}
|
|
29
|
+
@wrapperClass="w-64 my-4 ml-9"
|
|
30
|
+
/>
|
|
24
31
|
{{#if this.categoryModel}}
|
|
25
32
|
<Button @icon="arrow-left" @size="xs" @onClick={{this.categoryPicker.loadParentCategories}} />
|
|
26
33
|
<Button @icon="cog" @text="Edit Category" @size="xs" @onClick={{fn this.editCategory this.categoryModel}} />
|
|
@@ -7,79 +7,100 @@
|
|
|
7
7
|
@headerLeftInnerClass="w-full flex-1"
|
|
8
8
|
@onPressCancel={{this.transitionBack}}
|
|
9
9
|
>
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
10
|
+
<:actions>
|
|
11
|
+
<Button
|
|
12
|
+
@icon={{this.overlayActionButtonIcon}}
|
|
13
|
+
@type="primary"
|
|
14
|
+
@text={{this.overlayActionButtonTitle}}
|
|
15
|
+
@onClick={{perform this.saveProduct}}
|
|
16
|
+
@isLoading={{not this.saveProduct.isIdle}}
|
|
17
|
+
@permission={{this.abilityPermission}}
|
|
18
|
+
/>
|
|
19
|
+
</:actions>
|
|
18
20
|
</Overlay::Header>
|
|
19
21
|
|
|
20
|
-
<Overlay::Body
|
|
22
|
+
<Overlay::Body>
|
|
21
23
|
{{#let (cannot this.abilityPermission) as |unauthorized|}}
|
|
22
|
-
<
|
|
23
|
-
|
|
24
|
-
<
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
<
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
<InputGroup @name="Product SKU" @value={{this.product.sku}} @helpText="Enter product SKU if applicable" @disabled={{unauthorized}} />
|
|
51
|
-
<div class="grid grid-cols-2 gap-2">
|
|
52
|
-
<InputGroup @name="Price" @helpText="Enter a price users will pay to purchase this product">
|
|
53
|
-
<MoneyInput
|
|
24
|
+
<ContentPanel @title={{t "common.details"}} @open={{true}} @wrapperClass="bordered-top">
|
|
25
|
+
<InputGroup @name="Product Name" @value={{this.product.name}} @helpText="Enter your product's name" @disabled={{unauthorized}} />
|
|
26
|
+
<InputGroup @name="Product Description" @helpText="Enter a description of your product">
|
|
27
|
+
<Textarea @value={{this.product.description}} class="form-input w-full" placeholder="Enter a description of your product...." disabled={{unauthorized}} rows={{4}} />
|
|
28
|
+
</InputGroup>
|
|
29
|
+
<InputGroup @name="Product Category">
|
|
30
|
+
<ModelSelect
|
|
31
|
+
@modelName="category"
|
|
32
|
+
@selectedModel={{this.product.category}}
|
|
33
|
+
@query={{hash for="storefront_product" owner_uuid=this.activeStore.id}}
|
|
34
|
+
@placeholder="Select Product Category"
|
|
35
|
+
@triggerClass="form-select form-input"
|
|
36
|
+
@infiniteScroll={{false}}
|
|
37
|
+
@renderInPlace={{true}}
|
|
38
|
+
@allowClear={{true}}
|
|
39
|
+
@onChange={{fn (mut this.product.category)}}
|
|
40
|
+
@onChangeId={{fn (mut this.product.category_uuid)}}
|
|
41
|
+
as |model|
|
|
42
|
+
>
|
|
43
|
+
<div class="flex items-center">
|
|
44
|
+
<span class="uppercase">
|
|
45
|
+
{{model.name}}
|
|
46
|
+
</span>
|
|
47
|
+
</div>
|
|
48
|
+
</ModelSelect>
|
|
49
|
+
</InputGroup>
|
|
50
|
+
<InputGroup @name="Product Status">
|
|
51
|
+
<Select
|
|
54
52
|
class="w-full"
|
|
55
|
-
@
|
|
56
|
-
@
|
|
57
|
-
@
|
|
58
|
-
@
|
|
59
|
-
@
|
|
53
|
+
@value={{this.product.status}}
|
|
54
|
+
@placeholder="Select product status"
|
|
55
|
+
@options={{this.statusOptions}}
|
|
56
|
+
@onSelect={{fn (mut this.product.status)}}
|
|
57
|
+
@humanize={{true}}
|
|
60
58
|
/>
|
|
61
59
|
</InputGroup>
|
|
62
|
-
<InputGroup @name="
|
|
63
|
-
<
|
|
64
|
-
class="
|
|
65
|
-
@
|
|
66
|
-
@
|
|
67
|
-
@
|
|
68
|
-
@
|
|
60
|
+
<InputGroup @name="Product Tags">
|
|
61
|
+
<TagInput
|
|
62
|
+
class="form-input"
|
|
63
|
+
@placeholder="Add tags"
|
|
64
|
+
@allowSpacesInTags={{true}}
|
|
65
|
+
@tags={{this.product.tags}}
|
|
66
|
+
@addTag={{this.addTag}}
|
|
67
|
+
@removeTagAtIndex={{this.removeTag}}
|
|
69
68
|
@disabled={{unauthorized}}
|
|
70
|
-
|
|
69
|
+
as |tag|
|
|
70
|
+
>
|
|
71
|
+
{{tag}}
|
|
72
|
+
</TagInput>
|
|
71
73
|
</InputGroup>
|
|
72
|
-
|
|
74
|
+
<InputGroup @name="Product SKU" @value={{this.product.sku}} @helpText="Enter product SKU if applicable" @disabled={{unauthorized}} />
|
|
75
|
+
<div class="grid grid-cols-2 gap-2">
|
|
76
|
+
<InputGroup @name="Price" @helpText="Enter a price users will pay to purchase this product">
|
|
77
|
+
<MoneyInput
|
|
78
|
+
class="w-full"
|
|
79
|
+
@currency={{if this.product.currency this.product.currency this.activeStore.currency}}
|
|
80
|
+
@value={{this.product.price}}
|
|
81
|
+
@canSelectCurrency={{false}}
|
|
82
|
+
@onCurrencyChange={{fn (mut this.product.currency)}}
|
|
83
|
+
@disabled={{unauthorized}}
|
|
84
|
+
/>
|
|
85
|
+
</InputGroup>
|
|
86
|
+
<InputGroup @name="Sale Price" @helpText="Optionally add a sale price for the product if the product is put on sale">
|
|
87
|
+
<MoneyInput
|
|
88
|
+
class="w-full"
|
|
89
|
+
@currency={{if this.product.currency this.product.currency this.activeStore.currency}}
|
|
90
|
+
@value={{this.product.sale_price}}
|
|
91
|
+
@canSelectCurrency={{false}}
|
|
92
|
+
@onCurrencyChange={{fn (mut this.product.currency)}}
|
|
93
|
+
@disabled={{unauthorized}}
|
|
94
|
+
/>
|
|
95
|
+
</InputGroup>
|
|
96
|
+
</div>
|
|
97
|
+
</ContentPanel>
|
|
73
98
|
|
|
74
|
-
<ContentPanel
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
@panelBodyWrapperClass="px-0 py-4"
|
|
80
|
-
@panelBodyClass="bg-white dark:bg-gray-800"
|
|
81
|
-
>
|
|
82
|
-
{{#each this.product.meta_array as |metaField index|}}
|
|
99
|
+
<ContentPanel @title={{t "common.metadata"}} @open={{true}} @wrapperClass="bordered-top">
|
|
100
|
+
<div>
|
|
101
|
+
<MetadataEditor @value={{this.product.meta}} @onChange={{fn (mut this.product.meta)}} />
|
|
102
|
+
</div>
|
|
103
|
+
{{!-- {{#each this.product.meta_array as |metaField index|}}
|
|
83
104
|
<div class="px-4 py-3 border-b border-gray-200 dark:border-gray-700">
|
|
84
105
|
<div class="input-group">
|
|
85
106
|
<div class="flex justify-between items-center mb-1">
|
|
@@ -97,7 +118,7 @@
|
|
|
97
118
|
<Input class="w-full form-input" @value={{metaField.value}} placeholder={{metaField.label}} disabled={{unauthorized}} />
|
|
98
119
|
</div>
|
|
99
120
|
</div>
|
|
100
|
-
{{/each}}
|
|
121
|
+
{{/each}} --}}
|
|
101
122
|
</ContentPanel>
|
|
102
123
|
|
|
103
124
|
<InputGroup>
|
|
@@ -143,11 +164,9 @@
|
|
|
143
164
|
</div>
|
|
144
165
|
</div>
|
|
145
166
|
|
|
146
|
-
<ContentPanel @title="Variants" @open={{true}} @
|
|
147
|
-
<div class="
|
|
148
|
-
<
|
|
149
|
-
<Button @text="New Variant" @icon="plus" @iconPrefix="fas" @onClick={{this.createProductVariant}} @permission="storefront create product-variant" />
|
|
150
|
-
</div>
|
|
167
|
+
<ContentPanel @title="Variants" @open={{true}} @wrapperClass="bordered-top">
|
|
168
|
+
<div class="flex items-center justify-end">
|
|
169
|
+
<Button @text="New Variant" @icon="plus" @iconPrefix="fas" @onClick={{this.createProductVariant}} @permission="storefront create product-variant" />
|
|
151
170
|
</div>
|
|
152
171
|
<Tabs class="overlay-content-panel" as |Tab|>
|
|
153
172
|
{{#each this.product.variants as |variant|}}
|
|
@@ -224,78 +243,74 @@
|
|
|
224
243
|
</Tabs>
|
|
225
244
|
</ContentPanel>
|
|
226
245
|
|
|
227
|
-
<ContentPanel @title="Add-Ons" @open={{true}} @
|
|
228
|
-
<div class="
|
|
229
|
-
<
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
<div>
|
|
241
|
-
<div class="flex items-center
|
|
242
|
-
<
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
{{addonCategory.name}}
|
|
246
|
-
</div>
|
|
247
|
-
</div>
|
|
248
|
-
<div class="flex items-center">
|
|
249
|
-
<a
|
|
250
|
-
href="javascript:;"
|
|
251
|
-
class="destroy-action opacity-50 hover:opacity-100 text-sm"
|
|
252
|
-
{{on "click" (fn this.removeAddonCategory index)}}
|
|
253
|
-
disabled={{cannot "storefront delete product-addon"}}
|
|
254
|
-
>Remove</a>
|
|
246
|
+
<ContentPanel @title="Add-Ons" @open={{true}} @wrapperClass="bordered-top">
|
|
247
|
+
<div class="flex items-center justify-end mb-2">
|
|
248
|
+
<Button
|
|
249
|
+
@text="Select Addon Categories"
|
|
250
|
+
@icon="plus"
|
|
251
|
+
@iconPrefix="fas"
|
|
252
|
+
@onClick={{perform this.promptSelectAddonCategories}}
|
|
253
|
+
@permission="storefront list product-addon"
|
|
254
|
+
/>
|
|
255
|
+
</div>
|
|
256
|
+
<div class="space-y-2">
|
|
257
|
+
{{#each this.product.addon_categories as |addonCategory index|}}
|
|
258
|
+
<div>
|
|
259
|
+
<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">
|
|
260
|
+
<div class="flex-1 flex items-center">
|
|
261
|
+
<FaIcon @icon="pencil" class="mr-1 dark:text-gray-100" />
|
|
262
|
+
<div class="w-full px-2 m-0 border-none bg-transparent dark:text-gray-100">
|
|
263
|
+
{{addonCategory.name}}
|
|
255
264
|
</div>
|
|
256
265
|
</div>
|
|
257
|
-
<div class="
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
disabled={{cannot "storefront update product-addon"}}
|
|
265
|
-
/>
|
|
266
|
-
</div>
|
|
267
|
-
<div class="col-span-3 flex items-center">
|
|
268
|
-
{{addon.name}}
|
|
269
|
-
</div>
|
|
270
|
-
<div class="col-span-4">
|
|
271
|
-
{{addon.description}}
|
|
272
|
-
</div>
|
|
273
|
-
<div class="col-span-2">
|
|
274
|
-
{{format-currency addon.price this.product.currency}}
|
|
275
|
-
</div>
|
|
276
|
-
</div>
|
|
277
|
-
{{/each}}
|
|
266
|
+
<div class="flex items-center">
|
|
267
|
+
<a
|
|
268
|
+
href="javascript:;"
|
|
269
|
+
class="destroy-action opacity-50 hover:opacity-100 text-sm"
|
|
270
|
+
{{on "click" (fn this.removeAddonCategory index)}}
|
|
271
|
+
disabled={{cannot "storefront delete product-addon"}}
|
|
272
|
+
>Remove</a>
|
|
278
273
|
</div>
|
|
279
274
|
</div>
|
|
280
|
-
|
|
281
|
-
|
|
275
|
+
<div class="space-y-2 mb-2">
|
|
276
|
+
{{#each addonCategory.category.addons as |addon|}}
|
|
277
|
+
<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">
|
|
278
|
+
<div class="flex items-center">
|
|
279
|
+
<Checkbox
|
|
280
|
+
@value={{not (in-array addon.id addonCategory.excluded_addons)}}
|
|
281
|
+
@onToggle={{fn this.excludeAddon index addon}}
|
|
282
|
+
disabled={{cannot "storefront update product-addon"}}
|
|
283
|
+
/>
|
|
284
|
+
</div>
|
|
285
|
+
<div class="col-span-3 flex items-center">
|
|
286
|
+
{{addon.name}}
|
|
287
|
+
</div>
|
|
288
|
+
<div class="col-span-4">
|
|
289
|
+
{{addon.description}}
|
|
290
|
+
</div>
|
|
291
|
+
<div class="col-span-2">
|
|
292
|
+
{{format-currency addon.price this.product.currency}}
|
|
293
|
+
</div>
|
|
294
|
+
</div>
|
|
295
|
+
{{/each}}
|
|
296
|
+
</div>
|
|
297
|
+
</div>
|
|
298
|
+
{{/each}}
|
|
282
299
|
</div>
|
|
283
300
|
</ContentPanel>
|
|
284
301
|
|
|
285
|
-
<ContentPanel @title="Availability" @open={{
|
|
286
|
-
<
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
/>
|
|
294
|
-
</div>
|
|
302
|
+
<ContentPanel @title="Availability" @open={{true}} @wrapperClass="bordered-top">
|
|
303
|
+
<ScheduleManager
|
|
304
|
+
@subject={{this.product}}
|
|
305
|
+
@subjectKey="product_uuid"
|
|
306
|
+
@hourModelType="product-hour"
|
|
307
|
+
@disabled={{unauthorized}}
|
|
308
|
+
class="grid grid-cols-1 gap-4 lg:grid-cols-2 lg:gap-2"
|
|
309
|
+
/>
|
|
295
310
|
</ContentPanel>
|
|
296
311
|
|
|
297
|
-
<ContentPanel @title="Images & Videos" @open={{
|
|
298
|
-
<div class="
|
|
312
|
+
<ContentPanel @title="Images & Videos" @open={{true}} @wrapperClass="bordered-top">
|
|
313
|
+
<div class="space-y-2">
|
|
299
314
|
{{#if this.isUploading}}
|
|
300
315
|
<div
|
|
301
316
|
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"
|
|
@@ -382,7 +397,7 @@
|
|
|
382
397
|
</div>
|
|
383
398
|
</ContentPanel>
|
|
384
399
|
|
|
385
|
-
<ContentPanel @title="Youtube Videos" @open={{
|
|
400
|
+
<ContentPanel @title="Youtube Videos" @open={{true}} @wrapperClass="bordered-top">
|
|
386
401
|
<p class="text-sm">Add YouTube video urls to assosciate with this product or service.</p>
|
|
387
402
|
<div class="input-group">
|
|
388
403
|
<ArrayInput @data={{this.product.youtube_urls}} @placeholder="Enter youtube video url" @onDataChanged={{fn (mut this.product.youtube_urls)}} @disabled={{unauthorized}}>
|
|
@@ -38,17 +38,28 @@
|
|
|
38
38
|
{{#each-in gateway.config as |key value|}}
|
|
39
39
|
{{#if (is-bool-value value)}}
|
|
40
40
|
<div class="input-group">
|
|
41
|
-
<Checkbox @value={{value}} @label={{humanize key}} />
|
|
41
|
+
<Checkbox @value={{value}} @label={{humanize key}} @disabled={{true}} />
|
|
42
42
|
</div>
|
|
43
43
|
{{else}}
|
|
44
44
|
<InputGroup @name={{humanize key}}>
|
|
45
|
-
<Input
|
|
45
|
+
<Input
|
|
46
|
+
@type={{if (can "storefront update gateway") "text" "password"}}
|
|
47
|
+
class="form-input w-full"
|
|
48
|
+
placeholder={{humanize key}}
|
|
49
|
+
@value={{value}}
|
|
50
|
+
disabled
|
|
51
|
+
/>
|
|
46
52
|
</InputGroup>
|
|
47
53
|
{{/if}}
|
|
48
54
|
{{/each-in}}
|
|
49
55
|
</div>
|
|
50
|
-
<div>
|
|
51
|
-
|
|
56
|
+
<div class="flex flex-row items-center space-x-2">
|
|
57
|
+
{{#if (can "storefront update gateway")}}
|
|
58
|
+
<Button @size="sm" @type="primary" @icon="pencil" @text="Edit Gateway" @onClick={{fn this.editGateway gateway}} />
|
|
59
|
+
{{/if}}
|
|
60
|
+
{{#if (can "storefront delete gateway")}}
|
|
61
|
+
<Button @size="sm" @type="danger" @icon="trash" @text={{t "storefront.settings.gateways.delete-payment-gateway"}} @onClick={{fn this.deleteGateway gateway}} />
|
|
62
|
+
{{/if}}
|
|
52
63
|
</div>
|
|
53
64
|
</ContentPanel>
|
|
54
65
|
{{/each}}
|
|
@@ -36,10 +36,23 @@
|
|
|
36
36
|
{{tag}}
|
|
37
37
|
</TagInput>
|
|
38
38
|
</InputGroup>
|
|
39
|
+
|
|
39
40
|
<InputGroup @name={{t "storefront.common.currency"}}>
|
|
40
41
|
<CurrencySelect @currency={{@model.currency}} @onCurrencyChange={{fn (mut @model.currency)}} @triggerClass="w-full form-select" />
|
|
41
42
|
</InputGroup>
|
|
42
43
|
|
|
44
|
+
<InputGroup @name="Default Order Config" @helpText="Select the order config which will apply to all orders created for this store">
|
|
45
|
+
<Select
|
|
46
|
+
@value={{@model.order_config_uuid}}
|
|
47
|
+
@options={{this.orderConfigs}}
|
|
48
|
+
@optionValue="id"
|
|
49
|
+
@optionLabel="name"
|
|
50
|
+
@onSelect={{fn (mut @model.order_config_uuid)}}
|
|
51
|
+
@placeholder="Select default order config"
|
|
52
|
+
class="w-full"
|
|
53
|
+
/>
|
|
54
|
+
</InputGroup>
|
|
55
|
+
|
|
43
56
|
<ContentPanel @title={{t "storefront.settings.index.contact-social"}} @open={{false}} @pad={{true}}>
|
|
44
57
|
<InputGroup @name={{t "storefront.common.phone"}}>
|
|
45
58
|
<PhoneInput @value={{@model.phone}} @onInput={{fn (mut @model.phone)}} class="form-input w-full" />
|
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
</div>
|
|
17
17
|
|
|
18
18
|
<div class="space-y-3">
|
|
19
|
-
{{#each
|
|
20
|
-
<div class="flex px-4 py-2 items-center justify-between shadow-sm rounded-md dark:bg-gray-900 bg-gray-200">
|
|
19
|
+
{{#each @model as |notificationChannel|}}
|
|
20
|
+
<div class="flex px-4 py-2 items-center justify-between shadow-sm rounded-md dark:bg-gray-900 bg-gray-200 border border-gray-200 dark:border-gray-700">
|
|
21
21
|
<div>
|
|
22
22
|
<span class="dark:text-gray-50">{{notificationChannel.name}}</span>
|
|
23
23
|
</div>
|