@fleetbase/storefront-engine 0.3.17 → 0.3.20
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 +107 -104
- package/addon/components/customer-panel/orders.js +52 -45
- package/addon/components/modals/incoming-order.hbs +208 -199
- package/addon/components/modals/manage-addons.js +6 -2
- package/addon/components/modals/order-ready-assign-driver.hbs +1 -1
- package/addon/components/order-panel/details.js +0 -2
- package/addon/components/order-panel.hbs +314 -1
- package/addon/components/order-panel.js +51 -3
- package/addon/components/widget/customers.hbs +75 -51
- package/addon/components/widget/customers.js +29 -41
- package/addon/components/widget/orders.hbs +278 -119
- package/addon/components/widget/orders.js +75 -80
- package/addon/components/widget/storefront-metrics.hbs +3 -6
- package/addon/components/widget/storefront-metrics.js +25 -41
- package/addon/controllers/orders/index.js +214 -105
- package/addon/controllers/products/index/category/new.js +2 -1
- package/addon/controllers/products/index/index.js +0 -23
- package/addon/controllers/settings/gateways.js +14 -18
- package/addon/helpers/get-tip-amount.js +13 -2
- package/addon/models/product-addon-category.js +3 -0
- package/addon/routes/application.js +2 -4
- package/addon/services/order-actions.js +248 -0
- package/addon/services/storefront.js +2 -0
- package/addon/styles/storefront-engine.css +55 -0
- package/addon/templates/home.hbs +2 -1
- package/addon/templates/orders/index/view.hbs +1 -1
- package/addon/templates/orders/index.hbs +26 -3
- package/addon/templates/products/index/category/new.hbs +4 -1
- package/addon/templates/products/index/index.hbs +28 -28
- package/addon/templates/settings/gateways.hbs +1 -1
- package/addon/templates/settings/index.hbs +2 -2
- package/addon/templates/settings.hbs +1 -1
- package/app/services/order-actions.js +1 -0
- package/composer.json +1 -1
- package/extension.json +1 -1
- package/package.json +1 -1
- package/server/migrations/2023_05_03_025307_create_carts_table.php +1 -1
- package/server/migrations/2023_05_03_025307_create_checkouts_table.php +1 -1
- package/server/migrations/2023_05_03_025307_create_gateways_table.php +1 -1
- package/server/migrations/2023_05_03_025307_create_network_stores_table.php +1 -1
- package/server/migrations/2023_05_03_025307_create_networks_table.php +1 -1
- package/server/migrations/2023_05_03_025307_create_notification_channels_table.php +1 -1
- package/server/migrations/2023_05_03_025307_create_payment_methods_table.php +1 -1
- package/server/migrations/2023_05_03_025307_create_product_addon_categories_table.php +1 -1
- package/server/migrations/2023_05_03_025307_create_product_addons_table.php +1 -1
- package/server/migrations/2023_05_03_025307_create_product_hours_table.php +1 -1
- package/server/migrations/2023_05_03_025307_create_product_store_locations_table.php +1 -1
- package/server/migrations/2023_05_03_025307_create_product_variant_options_table.php +1 -1
- package/server/migrations/2023_05_03_025307_create_product_variants_table.php +1 -1
- package/server/migrations/2023_05_03_025307_create_products_table.php +1 -1
- package/server/migrations/2023_05_03_025307_create_reviews_table.php +1 -1
- package/server/migrations/2023_05_03_025307_create_store_hours_table.php +1 -1
- package/server/migrations/2023_05_03_025307_create_store_locations_table.php +1 -1
- package/server/migrations/2023_05_03_025307_create_stores_table.php +1 -1
- package/server/migrations/2023_05_03_025307_create_votes_table.php +1 -1
- package/server/migrations/2023_05_03_025310_add_foreign_keys_to_carts_table.php +1 -1
- package/server/migrations/2023_05_03_025310_add_foreign_keys_to_checkouts_table.php +1 -1
- package/server/migrations/2023_05_03_025310_add_foreign_keys_to_gateways_table.php +1 -1
- package/server/migrations/2023_05_03_025310_add_foreign_keys_to_network_stores_table.php +1 -1
- package/server/migrations/2023_05_03_025310_add_foreign_keys_to_networks_table.php +1 -1
- package/server/migrations/2023_05_03_025310_add_foreign_keys_to_notification_channels_table.php +1 -1
- package/server/migrations/2023_05_03_025310_add_foreign_keys_to_payment_methods_table.php +1 -1
- package/server/migrations/2023_05_03_025310_add_foreign_keys_to_product_addon_categories_table.php +1 -1
- package/server/migrations/2023_05_03_025310_add_foreign_keys_to_product_addons_table.php +1 -1
- package/server/migrations/2023_05_03_025310_add_foreign_keys_to_product_hours_table.php +1 -1
- package/server/migrations/2023_05_03_025310_add_foreign_keys_to_product_store_locations_table.php +1 -1
- package/server/migrations/2023_05_03_025310_add_foreign_keys_to_product_variant_options_table.php +1 -1
- package/server/migrations/2023_05_03_025310_add_foreign_keys_to_product_variants_table.php +1 -1
- package/server/migrations/2023_05_03_025310_add_foreign_keys_to_products_table.php +1 -1
- package/server/migrations/2023_05_03_025310_add_foreign_keys_to_reviews_table.php +1 -1
- package/server/migrations/2023_05_03_025310_add_foreign_keys_to_store_hours_table.php +1 -1
- package/server/migrations/2023_05_03_025310_add_foreign_keys_to_store_locations_table.php +1 -1
- package/server/migrations/2023_05_03_025310_add_foreign_keys_to_stores_table.php +1 -1
- package/server/migrations/2023_05_03_025310_add_foreign_keys_to_votes_table.php +1 -1
- package/server/src/Http/Controllers/ActionController.php +2 -1
- package/server/src/Http/Controllers/OrderController.php +15 -2
- package/server/src/Http/Controllers/ProductController.php +2 -0
- package/server/src/Http/Controllers/v1/CheckoutController.php +337 -40
- package/server/src/Http/Controllers/v1/CustomerController.php +88 -3
- package/server/src/Http/Controllers/v1/ServiceQuoteController.php +5 -5
- package/server/src/Http/Controllers/v1/StoreController.php +35 -5
- package/server/src/Http/Requests/CreateCustomerRequest.php +4 -0
- package/server/src/Http/Requests/CreateStripeSetupIntentRequest.php +31 -0
- package/server/src/Http/Requests/CustomerRequest.php +31 -0
- package/server/src/Http/Requests/InitializeCheckoutRequest.php +2 -1
- package/server/src/Http/Resources/Cart.php +18 -1
- package/server/src/Http/Resources/Customer.php +19 -14
- package/server/src/Http/Resources/Store.php +5 -1
- package/server/src/Models/AddonCategory.php +14 -16
- package/server/src/Models/Cart.php +10 -5
- package/server/src/Models/Customer.php +2 -2
- package/server/src/Models/Gateway.php +9 -4
- package/server/src/Models/Product.php +9 -10
- package/server/src/Models/ProductAddonCategory.php +2 -0
- package/server/src/Models/Store.php +2 -2
- package/server/src/Observers/OrderObserver.php +7 -1
- package/server/src/Rules/IsValidLocation.php +2 -2
- package/server/src/Support/QPay.php +35 -1
- package/server/src/Support/Storefront.php +34 -0
- package/server/src/Support/StripeUtils.php +38 -0
- package/server/src/routes.php +19 -0
- package/translations/en-us.yaml +8 -2
|
@@ -1,58 +1,103 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
>
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
1
|
+
{{#if (and this.loadOrders.isRunning (not this.loaded))}}
|
|
2
|
+
<div class="next-content-panel-wrapper">
|
|
3
|
+
<div class="next-content-panel-container">
|
|
4
|
+
<div class="next-content-panel next-content-panel-is-closed">
|
|
5
|
+
<div class="next-content-panel-header next-content-panel-toggle next-content-panel-is-closed">
|
|
6
|
+
<a href="javascript:;" class="next-content-panel-header-left">
|
|
7
|
+
<span class="icon-container">
|
|
8
|
+
<Spinner class="text-sky-400" @height="13" @width="13" />
|
|
9
|
+
</span>
|
|
10
|
+
<div class="next-content-panel-title-container">
|
|
11
|
+
<div class="panel-title flex-shrink-0">
|
|
12
|
+
<div class="flex flex-col">
|
|
13
|
+
<span>{{this.title}}</span>
|
|
14
|
+
</div>
|
|
15
|
+
</div>
|
|
16
|
+
</div>
|
|
17
|
+
</a>
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
14
20
|
</div>
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
<tbody>
|
|
21
|
+
</div>
|
|
22
|
+
{{else}}
|
|
23
|
+
<ContentPanel
|
|
24
|
+
@title={{this.title}}
|
|
25
|
+
@titleStatusRight={{this.orders.length}}
|
|
26
|
+
@titleStatuRightClass="info-status-badge"
|
|
27
|
+
@hideStatusDot={{true}}
|
|
28
|
+
@open={{gt this.orders.length 0}}
|
|
29
|
+
@isLoading={{this.loadOrders.isRunning}}
|
|
30
|
+
@pad={{false}}
|
|
31
|
+
@wrapperClass={{@wrapperClass}}
|
|
32
|
+
>
|
|
33
|
+
{{#if (media "isMobile")}}
|
|
34
|
+
<div class="flex flex-col p-3 space-y-3">
|
|
30
35
|
{{#each this.orders as |order|}}
|
|
31
|
-
<
|
|
32
|
-
<
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
<
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
<div class="py-2 px-3 rounded-md border border-gray-400 dark:border-gray-700">
|
|
37
|
+
<div class="flex flex-row mb-2">
|
|
38
|
+
<div class="flex-1">
|
|
39
|
+
<a href="javascript:;" {{on "click" (fn this.viewOrder order)}} class="text-sm font-semibold">{{order.public_id}}</a>
|
|
40
|
+
<div class="text-xs">{{order.createdAt}}</div>
|
|
41
|
+
<div class="text-xs">{{order.createdAgo}}</div>
|
|
42
|
+
</div>
|
|
43
|
+
<div class="flex-shrink-0 flex flex-col text-right">
|
|
44
|
+
<Badge class="mb-1" @status={{order.status}} />
|
|
45
|
+
{{#if order.meta.is_pickup}}
|
|
46
|
+
<Badge class="mb-1" @hideStatusDot={{true}} @status="info"><FaIcon @icon="hand-holding-dollar" class="mr-1" />{{t
|
|
47
|
+
"storefront.component.widget.orders.pickup-order"
|
|
48
|
+
}}</Badge>
|
|
49
|
+
{{/if}}
|
|
50
|
+
<div class="text-sm">{{format-currency order.meta.total order.meta.currency}}</div>
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
<div class="flex flex-col space-y-2 flex-wrap mb-2">
|
|
54
|
+
<Button
|
|
55
|
+
@wrapperClass="w-full"
|
|
56
|
+
class="btn-block w-full"
|
|
57
|
+
@size="xs"
|
|
58
|
+
@type="primary"
|
|
59
|
+
@icon="eye"
|
|
60
|
+
@text={{t "storefront.common.view"}}
|
|
61
|
+
@onClick={{fn this.viewOrder order}}
|
|
62
|
+
/>
|
|
63
|
+
{{#unless order.meta.is_pickup}}
|
|
64
|
+
<Button
|
|
65
|
+
@wrapperClass="w-full"
|
|
66
|
+
class="btn-block w-full"
|
|
67
|
+
@size="xs"
|
|
68
|
+
@type="default"
|
|
69
|
+
@icon="id-card"
|
|
70
|
+
@text={{if order.has_driver_assigned (t "storefront.component.widget.orders.change-driver") (t "storefront.component.widget.orders.assign-driver")}}
|
|
71
|
+
@onClick={{fn this.assignDriver order}}
|
|
72
|
+
/>
|
|
73
|
+
{{/unless}}
|
|
41
74
|
{{#if order.isFresh}}
|
|
42
75
|
<Button
|
|
76
|
+
@wrapperClass="w-full"
|
|
77
|
+
class="btn-block w-full"
|
|
43
78
|
@size="xs"
|
|
44
79
|
@type="success"
|
|
45
80
|
@iconPrefix="fas"
|
|
46
81
|
@icon="check"
|
|
47
|
-
@text={{
|
|
82
|
+
@text={{t "storefront.component.widget.orders.accept-order"}}
|
|
48
83
|
@onClick={{fn this.acceptOrder order}}
|
|
49
84
|
/>
|
|
50
85
|
{{/if}}
|
|
51
86
|
{{#if order.isPreparing}}
|
|
52
|
-
<Button
|
|
87
|
+
<Button
|
|
88
|
+
@wrapperClass="w-full"
|
|
89
|
+
class="btn-block w-full"
|
|
90
|
+
@size="xs"
|
|
91
|
+
@type="success"
|
|
92
|
+
@icon="bell-concierge"
|
|
93
|
+
@text={{t "storefront.component.widget.orders.mark-as-ready"}}
|
|
94
|
+
@onClick={{fn this.markAsReady order}}
|
|
95
|
+
/>
|
|
53
96
|
{{/if}}
|
|
54
97
|
{{#if order.isPickupReady}}
|
|
55
98
|
<Button
|
|
99
|
+
@wrapperClass="w-full"
|
|
100
|
+
class="btn-block w-full"
|
|
56
101
|
@size="xs"
|
|
57
102
|
@type="success"
|
|
58
103
|
@icon="check"
|
|
@@ -60,87 +105,201 @@
|
|
|
60
105
|
@onClick={{fn this.markAsCompleted order}}
|
|
61
106
|
/>
|
|
62
107
|
{{/if}}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
<a href="javascript:;" {{on "click" (fn this.viewOrder order)}} class="font-semibold">{{order.public_id}}</a>
|
|
75
|
-
<div>{{order.createdAt}}</div>
|
|
76
|
-
<div>{{order.createdAgo}}</div>
|
|
77
|
-
</div>
|
|
78
|
-
<div class="flex-shrink-0 flex flex-col text-right">
|
|
79
|
-
<Badge class="mb-1" @status={{order.status}} />
|
|
80
|
-
<div>{{format-currency order.meta.total order.meta.currency}}</div>
|
|
81
|
-
</div>
|
|
82
|
-
</div>
|
|
83
|
-
<div class="flex flex-row space-x-2 flex-wrap">
|
|
84
|
-
<Button @size="xs" @type="primary" @icon="eye" @text={{t "storefront.common.view"}} @onClick={{fn this.viewOrder order}} />
|
|
85
|
-
<Button
|
|
86
|
-
@size="xs"
|
|
87
|
-
@type="default"
|
|
88
|
-
@icon="steering-wheel"
|
|
89
|
-
@text={{if order.has_driver_assigned (t "storefront.component.widget.order.change-driver") (t "storefront.component.widget.order.assign-driver")}}
|
|
90
|
-
@onClick={{fn this.assignDriver order}}
|
|
91
|
-
/>
|
|
92
|
-
{{#if order.isFresh}}
|
|
93
|
-
<Button
|
|
94
|
-
@size="xs"
|
|
95
|
-
@type="success"
|
|
96
|
-
@iconPrefix="fas"
|
|
97
|
-
@icon="check"
|
|
98
|
-
@text={{concat (t "storefront.component.widget.orders.accept-order") "!"}}
|
|
99
|
-
@onClick={{fn this.acceptOrder order}}
|
|
100
|
-
/>
|
|
101
|
-
{{/if}}
|
|
102
|
-
{{#if order.isPreparing}}
|
|
103
|
-
<Button @size="xs" @type="success" @icon="bells" @text={{t "storefront.component.widget.orders.mark-as-mark"}} @onClick={{fn this.markAsReady order}} />
|
|
104
|
-
{{/if}}
|
|
105
|
-
{{#if order.isPickupReady}}
|
|
106
|
-
<Button @size="xs" @type="success" @icon="check" @text={{t "storefront.component.widget.orders.mark-as-completed"}} @onClick={{fn this.markAsCompleted order}} />
|
|
107
|
-
{{/if}}
|
|
108
|
-
</div>
|
|
109
|
-
<ContentPanel @title={{t "storefront.component.widget.orders.title"}} class="mt-2">
|
|
110
|
-
<div class="flex flex-col py-2 border-t dark:border-gray-800">
|
|
111
|
-
<div>{{t "storefront.component.widget.orders.customer"}}: {{n-a order.customer_name}}</div>
|
|
112
|
-
<div>{{t "storefront.component.widget.orders.driver"}}: {{n-a order.driver_name}}</div>
|
|
113
|
-
</div>
|
|
114
|
-
<div class="py-2 space-y-2 border-t dark:border-gray-800">
|
|
115
|
-
<div class="flex items-center justify-between">
|
|
116
|
-
<span class="dark:text-gray-50">{{t "storefront.component.widget.orders.subtotal"}}</span>
|
|
117
|
-
<span class="dark:text-gray-50">{{format-currency order.meta.subtotal order.meta.currency}}</span>
|
|
108
|
+
{{#unless order.isCanceled}}
|
|
109
|
+
<Button
|
|
110
|
+
@wrapperClass="w-full"
|
|
111
|
+
class="btn-block w-full"
|
|
112
|
+
@size="xs"
|
|
113
|
+
@type="danger"
|
|
114
|
+
@icon="ban"
|
|
115
|
+
@text={{t "storefront.component.widget.orders.cancel-order"}}
|
|
116
|
+
@onClick={{fn this.cancelOrder order}}
|
|
117
|
+
/>
|
|
118
|
+
{{/unless}}
|
|
118
119
|
</div>
|
|
119
|
-
{{
|
|
120
|
-
<div class="
|
|
121
|
-
|
|
122
|
-
|
|
120
|
+
<ContentPanel @title={{t "storefront.component.widget.orders.more-details"}}>
|
|
121
|
+
<div class="p-2 space-y-2">
|
|
122
|
+
{{#unless order.meta.is_pickup}}
|
|
123
|
+
<div class="bg-gray-100 border border-gray-200 dark:bg-gray-800 dark:border-gray-700 rounded-md px-4 py-2 space-y-2 h-full">
|
|
124
|
+
<h5 class="dark:text-gray-100 font-semibold">{{t "storefront.component.modals.incoming-order.assigned"}}</h5>
|
|
125
|
+
<div class="flex flex-col space-y-4">
|
|
126
|
+
{{#if order.driver_assigned.id}}
|
|
127
|
+
<div class="flex items-center">
|
|
128
|
+
<Image src={{order.driver_assigned.photoUrl}} class="w-12 h-12 rounded-md shadow-sm mr-4" alt={{order.driver_assigned.name}} />
|
|
129
|
+
<div>
|
|
130
|
+
<h5 class="font-semibold dark:text-white text-xs">{{n-a order.driver_assigned.displayName}}</h5>
|
|
131
|
+
<div class="font-semibold dark:text-gray-100 text-xs">{{n-a
|
|
132
|
+
order.driver_assigned.phone
|
|
133
|
+
(t "storefront.component.modals.incoming-order.no-phone")
|
|
134
|
+
}}</div>
|
|
135
|
+
</div>
|
|
136
|
+
</div>
|
|
137
|
+
{{else}}
|
|
138
|
+
<div>
|
|
139
|
+
<h5 class="text-red-500 text-sm">{{t "storefront.component.modals.incoming-order.not-assigned"}}</h5>
|
|
140
|
+
</div>
|
|
141
|
+
{{/if}}
|
|
142
|
+
<div>
|
|
143
|
+
<Button
|
|
144
|
+
@size="xs"
|
|
145
|
+
@type="default"
|
|
146
|
+
@icon="id-card"
|
|
147
|
+
@text={{if
|
|
148
|
+
order.has_driver_assigned
|
|
149
|
+
(t "storefront.component.modals.incoming-order.change-driver")
|
|
150
|
+
(t "storefront.component.modals.incoming-order.assign-driver")
|
|
151
|
+
}}
|
|
152
|
+
@onClick={{this.assignDriver order}}
|
|
153
|
+
/>
|
|
154
|
+
</div>
|
|
155
|
+
</div>
|
|
156
|
+
</div>
|
|
157
|
+
{{/unless}}
|
|
158
|
+
<div class="bg-gray-100 border border-gray-200 dark:bg-gray-800 dark:border-gray-700 rounded-md px-4 py-2 space-y-2 h-full">
|
|
159
|
+
<h5 class="dark:text-gray-100 font-semibold">{{t "storefront.common.customer"}}</h5>
|
|
160
|
+
<div class="">
|
|
161
|
+
<div class="flex flex-row">
|
|
162
|
+
<div>
|
|
163
|
+
<Image src={{avatar-url order.customer.photo_url}} class="w-12 h-12 rounded-md shadow-sm mr-4" alt={{order.customer.name}} />
|
|
164
|
+
</div>
|
|
165
|
+
<div>
|
|
166
|
+
<div class="text-xs font-bold dark:text-gray-100">{{order.customer.name}}</div>
|
|
167
|
+
<div class="text-xs dark:text-gray-100">{{order.customer.email}}</div>
|
|
168
|
+
<div class="text-xs dark:text-gray-100">{{order.customer.phone}}</div>
|
|
169
|
+
</div>
|
|
170
|
+
</div>
|
|
171
|
+
{{#unless order.meta.is_pickup}}
|
|
172
|
+
<div class="mt-2">
|
|
173
|
+
<h5 class="dark:text-gray-100 font-semibold text-xs truncate">{{t "storefront.component.modals.incoming-order.address"}}</h5>
|
|
174
|
+
<div class="flex flex-row mt-1">
|
|
175
|
+
<div class="flex items-center justify-center rounded-full bg-blue-500 w-8 h-8 mr-3">
|
|
176
|
+
<FaIcon @icon="map-marker-alt" class="text-white" />
|
|
177
|
+
</div>
|
|
178
|
+
<div class="truncate">
|
|
179
|
+
<DisplayPlace @place={{order.payload.dropoff}} @type="dropoff" @addressClass="text-xs dark:text-gray-100" @noAddressClass="text-xs" />
|
|
180
|
+
</div>
|
|
181
|
+
</div>
|
|
182
|
+
</div>
|
|
183
|
+
{{/unless}}
|
|
184
|
+
</div>
|
|
185
|
+
</div>
|
|
123
186
|
</div>
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
187
|
+
<div class="py-2 mt-2 space-y-2 border-t dark:border-gray-800">
|
|
188
|
+
<div class="flex items-center justify-between px-3 text-xs">
|
|
189
|
+
<span class="dark:text-gray-50">{{t "storefront.component.widget.orders.subtotal"}}</span>
|
|
190
|
+
<span class="dark:text-gray-50">{{format-currency order.meta.subtotal order.meta.currency}}</span>
|
|
191
|
+
</div>
|
|
192
|
+
{{#unless order.meta.is_pickup}}
|
|
193
|
+
<div class="flex items-center justify-between px-3 text-xs">
|
|
194
|
+
<span class="dark:text-gray-50">{{t "storefront.component.widget.orders.delivery-fee"}}</span>
|
|
195
|
+
<span class="dark:text-gray-50">{{format-currency order.meta.delivery_fee order.meta.currency}}</span>
|
|
196
|
+
</div>
|
|
197
|
+
{{/unless}}
|
|
198
|
+
{{#if order.meta.tip}}
|
|
199
|
+
<div class="flex items-center justify-between px-3 py-2 text-xs">
|
|
200
|
+
<span class="dark:text-gray-50">{{t "storefront.component.widget.orders.tip"}}</span>
|
|
201
|
+
<span class="dark:text-gray-50">{{get-tip-amount order.meta.tip order.meta.subtotal order.meta.currency}}</span>
|
|
202
|
+
</div>
|
|
203
|
+
{{/if}}
|
|
204
|
+
{{#if order.meta.delivery_tip}}
|
|
205
|
+
<div class="flex items-center justify-between px-3 text-xs">
|
|
206
|
+
<span class="dark:text-gray-50">{{t "storefront.component.widget.orders.delivery-tip"}}</span>
|
|
207
|
+
<span class="dark:text-gray-50">{{get-tip-amount order.meta.delivery_tip order.meta.subtotal order.meta.currency}}</span>
|
|
208
|
+
</div>
|
|
209
|
+
{{/if}}
|
|
210
|
+
<div class="flex items-center justify-between px-3 text-xs">
|
|
211
|
+
<span class="dark:text-gray-50 font-bold">{{t "storefront.component.widget.orders.total"}}</span>
|
|
212
|
+
<span class="dark:text-gray-50 font-bold">{{format-currency order.meta.total order.meta.currency}}</span>
|
|
213
|
+
</div>
|
|
129
214
|
</div>
|
|
130
|
-
|
|
131
|
-
{{#if order.meta.delivery_tip}}
|
|
132
|
-
<div class="flex items-center justify-between">
|
|
133
|
-
<span class="dark:text-gray-50">{{t "storefront.component.widget.order.delivery-tip"}}</span>
|
|
134
|
-
<span class="dark:text-gray-50">{{get-tip-amount order.meta.delivery_tip order.meta.subtotal order.meta.currency}}</span>
|
|
135
|
-
</div>
|
|
136
|
-
{{/if}}
|
|
137
|
-
<div class="flex items-center justify-between">
|
|
138
|
-
<span class="dark:text-gray-50 font-bold">{{t "storefront.component.widget.order.tip"}}</span>
|
|
139
|
-
<span class="dark:text-gray-50 font-bold">{{format-currency order.meta.total order.meta.currency}}</span>
|
|
140
|
-
</div>
|
|
215
|
+
</ContentPanel>
|
|
141
216
|
</div>
|
|
142
|
-
|
|
217
|
+
{{/each}}
|
|
143
218
|
</div>
|
|
144
|
-
{{
|
|
145
|
-
|
|
146
|
-
|
|
219
|
+
{{else}}
|
|
220
|
+
<div class="table-wrapper table-fluid">
|
|
221
|
+
<table class="storefront-widget-table">
|
|
222
|
+
<thead>
|
|
223
|
+
<tr class="h-12 text-left py-1">
|
|
224
|
+
<th style={{"width: 15%"}}>{{t "storefront.component.widget.orders.id-column"}}</th>
|
|
225
|
+
<th style={{"width: 10%"}}>{{t "storefront.common.amount"}}</th>
|
|
226
|
+
<th style={{"width: 15%"}}>{{t "storefront.common.customer"}}</th>
|
|
227
|
+
<th style={{"width: 15%"}}>{{t "storefront.common.driver"}}</th>
|
|
228
|
+
<th style={{"width: 10%"}}>{{t "storefront.common.created"}}</th>
|
|
229
|
+
<th style={{"width: 15%"}}>{{t "storefront.common.status"}}</th>
|
|
230
|
+
<th style={{"width: 22%"}}></th>
|
|
231
|
+
</tr>
|
|
232
|
+
</thead>
|
|
233
|
+
<tbody>
|
|
234
|
+
{{#each this.orders as |order|}}
|
|
235
|
+
<tr class="h-12">
|
|
236
|
+
<td><a href="javascript:;" {{on "click" (fn this.viewOrder order)}}>{{order.public_id}}</a></td>
|
|
237
|
+
<td>{{format-currency order.meta.total order.meta.currency}}</td>
|
|
238
|
+
<td>{{n-a order.customer.name}}</td>
|
|
239
|
+
<td>
|
|
240
|
+
{{#if order.meta.is_pickup}}
|
|
241
|
+
<Badge @hideStatusDot={{true}} @status="info"><FaIcon @icon="hand-holding-dollar" class="mr-1" />{{t
|
|
242
|
+
"storefront.component.widget.orders.pickup-order"
|
|
243
|
+
}}</Badge>
|
|
244
|
+
{{else}}
|
|
245
|
+
{{n-a order.driver_assigned.name}}
|
|
246
|
+
{{/if}}
|
|
247
|
+
</td>
|
|
248
|
+
<td>{{order.createdAgo}}</td>
|
|
249
|
+
<td>
|
|
250
|
+
<Badge @status={{order.status}} />
|
|
251
|
+
</td>
|
|
252
|
+
<td>
|
|
253
|
+
<div class="flex flex-row justify-end space-x-2">
|
|
254
|
+
{{#if order.isFresh}}
|
|
255
|
+
<Button
|
|
256
|
+
@size="xs"
|
|
257
|
+
@type="success"
|
|
258
|
+
@iconPrefix="fas"
|
|
259
|
+
@icon="check"
|
|
260
|
+
@text={{t "storefront.component.widget.orders.accept-order"}}
|
|
261
|
+
@onClick={{fn this.acceptOrder order}}
|
|
262
|
+
/>
|
|
263
|
+
{{/if}}
|
|
264
|
+
{{#if order.isPreparing}}
|
|
265
|
+
<Button
|
|
266
|
+
@size="xs"
|
|
267
|
+
@type="success"
|
|
268
|
+
@icon="bell-concierge"
|
|
269
|
+
@text={{t "storefront.component.widget.orders.mark-as-ready"}}
|
|
270
|
+
@onClick={{fn this.markAsReady order}}
|
|
271
|
+
/>
|
|
272
|
+
{{/if}}
|
|
273
|
+
{{#if order.isPickupReady}}
|
|
274
|
+
<Button
|
|
275
|
+
@size="xs"
|
|
276
|
+
@type="success"
|
|
277
|
+
@icon="check"
|
|
278
|
+
@text={{t "storefront.component.widget.orders.mark-as-completed"}}
|
|
279
|
+
@onClick={{fn this.markAsCompleted order}}
|
|
280
|
+
/>
|
|
281
|
+
{{/if}}
|
|
282
|
+
{{#unless order.isCanceled}}
|
|
283
|
+
<Button
|
|
284
|
+
@size="xs"
|
|
285
|
+
@type="danger"
|
|
286
|
+
@icon="ban"
|
|
287
|
+
@helpText={{t "storefront.component.widget.orders.cancel-order"}}
|
|
288
|
+
@onClick={{fn this.cancelOrder order}}
|
|
289
|
+
/>
|
|
290
|
+
{{/unless}}
|
|
291
|
+
</div>
|
|
292
|
+
</td>
|
|
293
|
+
</tr>
|
|
294
|
+
{{/each}}
|
|
295
|
+
|
|
296
|
+
<tr class="h-12">
|
|
297
|
+
<td><div class="font-semibold text-green-500">TOTAL</div></td>
|
|
298
|
+
<td colspan="6"><div class="flex justify-start text-green-500 font-semibold">{{format-currency this.total this.currency}}</div></td>
|
|
299
|
+
</tr>
|
|
300
|
+
</tbody>
|
|
301
|
+
</table>
|
|
302
|
+
</div>
|
|
303
|
+
{{/if}}
|
|
304
|
+
</ContentPanel>
|
|
305
|
+
{{/if}}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import Component from '@glimmer/component';
|
|
2
2
|
import { tracked } from '@glimmer/tracking';
|
|
3
3
|
import { inject as service } from '@ember/service';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
4
|
+
import { action, get } from '@ember/object';
|
|
5
|
+
import { debug } from '@ember/debug';
|
|
6
|
+
import { task } from 'ember-concurrency';
|
|
7
7
|
|
|
8
8
|
export default class WidgetOrdersComponent extends Component {
|
|
9
9
|
@service store;
|
|
@@ -13,35 +13,24 @@ export default class WidgetOrdersComponent extends Component {
|
|
|
13
13
|
@service appCache;
|
|
14
14
|
@service modalsManager;
|
|
15
15
|
@service contextPanel;
|
|
16
|
-
@
|
|
16
|
+
@service orderActions;
|
|
17
|
+
@service notifications;
|
|
17
18
|
@tracked orders = [];
|
|
18
|
-
@
|
|
19
|
+
@tracked title = this.intl.t('storefront.component.widget.orders.widget-title');
|
|
20
|
+
@tracked loaded = false;
|
|
21
|
+
@tracked total = 0;
|
|
19
22
|
|
|
20
|
-
|
|
21
|
-
return this.args.title ?? this.intl.t('storefront.component.widget.orders.widget-title');
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
constructor() {
|
|
23
|
+
constructor(owner, { title }) {
|
|
25
24
|
super(...arguments);
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
this,
|
|
31
|
-
() => {
|
|
32
|
-
this.reloadOrders();
|
|
33
|
-
},
|
|
34
|
-
100
|
|
35
|
-
);
|
|
36
|
-
|
|
37
|
-
// reload orders when new order income
|
|
25
|
+
this.title = title ?? this.intl.t('storefront.component.widget.orders.widget-title');
|
|
26
|
+
this.currency = get(this.storefront, 'activeStore.currency');
|
|
27
|
+
// this.orders = this.getCachedOrders();
|
|
28
|
+
this.loadOrders.perform();
|
|
38
29
|
this.storefront.on('order.broadcasted', () => {
|
|
39
|
-
this.
|
|
30
|
+
this.loadOrders.perform();
|
|
40
31
|
});
|
|
41
|
-
|
|
42
|
-
// reload orders when store changes
|
|
43
32
|
this.storefront.on('storefront.changed', () => {
|
|
44
|
-
this.
|
|
33
|
+
this.loadOrders.perform();
|
|
45
34
|
});
|
|
46
35
|
}
|
|
47
36
|
|
|
@@ -49,61 +38,53 @@ export default class WidgetOrdersComponent extends Component {
|
|
|
49
38
|
this.orders = await this.fetchOrders(params);
|
|
50
39
|
}
|
|
51
40
|
|
|
52
|
-
@
|
|
53
|
-
|
|
41
|
+
@task *loadOrders(params = {}) {
|
|
42
|
+
const storefront = get(this.storefront, 'activeStore.public_id');
|
|
43
|
+
const queryParams = {
|
|
44
|
+
storefront,
|
|
45
|
+
limit: 14,
|
|
46
|
+
sort: '-created_at',
|
|
47
|
+
...params,
|
|
48
|
+
};
|
|
54
49
|
|
|
55
50
|
try {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
51
|
+
const orders = yield this.fetch.get('orders', queryParams, { namespace: 'storefront/int/v1', normalizeToEmberData: true });
|
|
52
|
+
this.loaded = true;
|
|
53
|
+
this.updateCachedOrders(orders);
|
|
54
|
+
this.total = this.calculateTotal(orders);
|
|
55
|
+
this.orders = orders;
|
|
56
|
+
|
|
57
|
+
return orders;
|
|
58
|
+
} catch (err) {
|
|
59
|
+
debug('Error loading orders for widget:', err);
|
|
61
60
|
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
calculateTotal(orders = []) {
|
|
64
|
+
let total = 0;
|
|
65
|
+
orders.forEach((order) => {
|
|
66
|
+
total += get(order, 'meta.total');
|
|
67
|
+
});
|
|
62
68
|
|
|
63
|
-
|
|
64
|
-
|
|
69
|
+
return total;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
getCachedOrders() {
|
|
73
|
+
let cachedOrders = [];
|
|
74
|
+
if (this.appCache.has('storefront_recent_orders')) {
|
|
75
|
+
cachedOrders = this.appCache.getEmberData('storefront_recent_orders', 'order');
|
|
65
76
|
}
|
|
66
77
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
const queryParams = {
|
|
78
|
-
storefront,
|
|
79
|
-
limit: 14,
|
|
80
|
-
sort: '-created_at',
|
|
81
|
-
...params,
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
this.fetch
|
|
85
|
-
.get('orders', queryParams, {
|
|
86
|
-
namespace: 'storefront/int/v1',
|
|
87
|
-
normalizeToEmberData: true,
|
|
88
|
-
})
|
|
89
|
-
.then((orders) => {
|
|
90
|
-
this.isLoading = false;
|
|
91
|
-
|
|
92
|
-
try {
|
|
93
|
-
this.appCache.setEmberData('storefront_recent_orders', orders, ['tracking_statuses', 'tracking_number']);
|
|
94
|
-
} catch (exception) {
|
|
95
|
-
// silent exception just clear from cache if not able to set
|
|
96
|
-
this.appCache.set('storefront_recent_orders', undefined);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
resolve(orders);
|
|
100
|
-
})
|
|
101
|
-
.catch(() => {
|
|
102
|
-
this.isLoading = false;
|
|
103
|
-
|
|
104
|
-
resolve(this.orders);
|
|
105
|
-
});
|
|
106
|
-
});
|
|
78
|
+
return cachedOrders;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
updateCachedOrders(orders = []) {
|
|
82
|
+
try {
|
|
83
|
+
this.appCache.setEmberData('storefront_recent_orders', orders, ['tracking_statuses', 'tracking_number']);
|
|
84
|
+
} catch (err) {
|
|
85
|
+
this.appCache.set('storefront_recent_orders', undefined);
|
|
86
|
+
debug('Error updating orders widget cache:', err);
|
|
87
|
+
}
|
|
107
88
|
}
|
|
108
89
|
|
|
109
90
|
@action async viewOrder(order) {
|
|
@@ -111,18 +92,32 @@ export default class WidgetOrdersComponent extends Component {
|
|
|
111
92
|
}
|
|
112
93
|
|
|
113
94
|
@action async acceptOrder(order) {
|
|
114
|
-
await this.
|
|
95
|
+
await this.orderActions.acceptOrder(order, () => {
|
|
96
|
+
this.loadOrders.perform();
|
|
97
|
+
});
|
|
115
98
|
}
|
|
116
99
|
|
|
117
100
|
@action markAsReady(order) {
|
|
118
|
-
this.
|
|
101
|
+
this.orderActions.markAsReady(order, () => {
|
|
102
|
+
this.loadOrders.perform();
|
|
103
|
+
});
|
|
119
104
|
}
|
|
120
105
|
|
|
121
106
|
@action markAsCompleted(order) {
|
|
122
|
-
this.
|
|
107
|
+
this.orderActions.markAsCompleted(order, () => {
|
|
108
|
+
this.loadOrders.perform();
|
|
109
|
+
});
|
|
123
110
|
}
|
|
124
111
|
|
|
125
|
-
@action
|
|
126
|
-
|
|
112
|
+
@action assignDriver(order) {
|
|
113
|
+
this.orderActions.assignDriver(order, () => {
|
|
114
|
+
this.loadOrders.perform();
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
@action cancelOrder(order) {
|
|
119
|
+
this.orderActions.cancelOrder(order, () => {
|
|
120
|
+
this.loadOrders.perform();
|
|
121
|
+
});
|
|
127
122
|
}
|
|
128
123
|
}
|