@fleetbase/storefront-engine 0.3.5 → 0.3.6
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/context-panel.hbs +5 -0
- package/addon/components/context-panel.js +6 -0
- package/addon/components/customer-panel/details.hbs +34 -0
- package/addon/components/customer-panel/details.js +3 -0
- package/addon/components/customer-panel/orders.hbs +140 -0
- package/addon/components/customer-panel/orders.js +78 -0
- package/addon/components/customer-panel.hbs +70 -0
- package/addon/components/customer-panel.js +171 -0
- package/addon/components/display-place.hbs +52 -0
- package/addon/components/display-place.js +11 -0
- package/addon/components/modals/manage-addons.hbs +15 -52
- package/addon/components/modals/manage-addons.js +93 -43
- package/addon/components/modals/select-addon-category.hbs +1 -1
- package/addon/components/order-panel/details.hbs +245 -0
- package/addon/components/order-panel/details.js +189 -0
- package/addon/components/order-panel.hbs +1 -0
- package/addon/components/order-panel.js +38 -0
- package/addon/components/storefront-order-summary.hbs +9 -2
- package/addon/components/widget/customers.hbs +3 -1
- package/addon/components/widget/customers.js +5 -0
- package/addon/components/widget/orders.js +8 -146
- package/addon/controllers/customers/index/view.js +43 -0
- package/addon/controllers/customers/index.js +10 -6
- package/addon/controllers/networks/index/network/customers.js +68 -2
- package/addon/controllers/networks/index/network/orders.js +324 -1
- package/addon/controllers/networks/index/network/stores.js +0 -2
- package/addon/controllers/orders/index/view.js +13 -0
- package/addon/controllers/orders/index.js +10 -7
- package/addon/controllers/products/index/category/edit.js +12 -16
- package/addon/controllers/products/index/category/new.js +40 -45
- package/addon/controllers/products/index.js +8 -2
- package/addon/helpers/avatar-url.js +9 -0
- package/addon/models/product-variant-option.js +8 -1
- package/addon/models/product-variant.js +12 -2
- package/addon/models/product.js +62 -0
- package/addon/routes/customers/index/view.js +14 -0
- package/addon/routes/networks/index/network/customers.js +29 -0
- package/addon/routes/networks/index/network/orders.js +5 -0
- package/addon/routes/networks/index.js +1 -1
- package/addon/routes/orders/index/view.js +22 -1
- package/addon/routes/products/index/category/edit.js +6 -0
- package/addon/routes/products/index/category/new.js +3 -1
- package/addon/routes.js +1 -0
- package/addon/serializers/product-variant-option.js +14 -0
- package/addon/serializers/product-variant.js +27 -0
- package/addon/serializers/product.js +26 -4
- package/addon/services/context-panel.js +210 -0
- package/addon/styles/storefront-engine.css +6 -0
- package/addon/templates/application.hbs +3 -1
- package/addon/templates/customers/index/view.hbs +1 -0
- package/addon/templates/networks/index/network/customers.hbs +18 -1
- package/addon/templates/networks/index/network/orders.hbs +18 -1
- package/addon/templates/networks/index/network.hbs +1 -1
- package/addon/templates/orders/index/view.hbs +1 -1
- package/addon/templates/products/index/category/new.hbs +12 -67
- package/app/components/context-panel.js +1 -0
- package/app/components/customer-panel/details.js +1 -0
- package/app/components/customer-panel/orders.js +1 -0
- package/app/components/customer-panel.js +1 -0
- package/app/components/display-place.js +1 -0
- package/app/components/order-panel/details.js +1 -0
- package/app/components/order-panel.js +1 -0
- package/app/controllers/customers/index/view.js +1 -0
- package/app/controllers/orders/index/view.js +1 -0
- package/app/helpers/avatar-url.js +1 -0
- package/app/routes/customers/index/view.js +1 -0
- package/app/serializers/product-variant-option.js +1 -0
- package/app/services/context-panel.js +1 -0
- package/app/templates/customers/index/view.js +1 -0
- package/composer.json +3 -3
- package/extension.json +1 -1
- package/package.json +9 -3
- package/server/src/Http/Controllers/AddonCategoryController.php +90 -0
- package/server/src/Http/Controllers/v1/ReviewController.php +43 -52
- package/server/src/Http/Resources/Network.php +34 -32
- package/server/src/Http/Resources/NotificationChannel.php +32 -0
- package/server/src/Http/Resources/Product.php +10 -8
- package/server/src/Models/AddonCategory.php +37 -0
- package/server/src/Models/Product.php +6 -7
- package/server/src/Models/ProductAddon.php +3 -0
- package/server/src/Models/ProductAddonCategory.php +12 -2
- package/server/src/Providers/StorefrontServiceProvider.php +1 -1
- package/translations/en-us.yaml +101 -39
|
@@ -1,20 +1,6 @@
|
|
|
1
1
|
<Overlay @position="right" @noBackdrop={{true}} @isResizable={{true}} @width="570px" @fullHeight={{true}} @containerClass="border-l border-transparent dark:border-gray-700">
|
|
2
|
-
<Overlay::Header
|
|
3
|
-
@
|
|
4
|
-
@titleClass="truncate"
|
|
5
|
-
@titleWrapperClass="w-3/4"
|
|
6
|
-
@headerLeftClass="w-70pc"
|
|
7
|
-
@headerLeftInnerClass="w-full flex-1"
|
|
8
|
-
@onPressCancel={{this.transitionBack}}
|
|
9
|
-
>
|
|
10
|
-
<Button
|
|
11
|
-
@icon={{this.overlayActionButtonIcon}}
|
|
12
|
-
@type="primary"
|
|
13
|
-
@text={{this.overlayActionButtonTitle}}
|
|
14
|
-
@onClick={{this.saveProduct}}
|
|
15
|
-
@isLoading={{this.isSaving}}
|
|
16
|
-
@isSubscriptionRequired={{true}}
|
|
17
|
-
/>
|
|
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={{perform this.saveProduct}} @isLoading={{not this.saveProduct.isIdle}} />
|
|
18
4
|
</Overlay::Header>
|
|
19
5
|
|
|
20
6
|
<Overlay::Body @increaseInnerBodyHeightBy="0" @wrapperClass="new-order-overlay-body px-4 space-y-4 pt-4">
|
|
@@ -23,48 +9,21 @@
|
|
|
23
9
|
<Textarea @value={{this.product.description}} class="form-input w-full" placeholder="Enter a description of your product...." rows={{4}} />
|
|
24
10
|
</InputGroup>
|
|
25
11
|
<InputGroup @name="Product Tags">
|
|
26
|
-
<TagInput
|
|
27
|
-
class="form-input"
|
|
28
|
-
@placeholder="Add tags"
|
|
29
|
-
@allowSpacesInTags={{true}}
|
|
30
|
-
@tags={{this.product.tags}}
|
|
31
|
-
@addTag={{this.addTag}}
|
|
32
|
-
@removeTagAtIndex={{this.removeTag}}
|
|
33
|
-
as |tag|
|
|
34
|
-
>
|
|
12
|
+
<TagInput class="form-input" @placeholder="Add tags" @allowSpacesInTags={{true}} @tags={{this.product.tags}} @addTag={{this.addTag}} @removeTagAtIndex={{this.removeTag}} as |tag|>
|
|
35
13
|
{{tag}}
|
|
36
14
|
</TagInput>
|
|
37
15
|
</InputGroup>
|
|
38
16
|
<InputGroup @name="Product SKU" @value={{this.product.sku}} @helpText="Enter product SKU if applicable" />
|
|
39
17
|
<div class="grid grid-cols-2 gap-2">
|
|
40
18
|
<InputGroup @name="Price" @helpText="Enter a price users will pay to purchase this product">
|
|
41
|
-
<MoneyInput
|
|
42
|
-
class="w-full"
|
|
43
|
-
@currency={{if this.product.currency this.product.currency this.activeStore.currency}}
|
|
44
|
-
@value={{this.product.price}}
|
|
45
|
-
@canSelectCurrency={{false}}
|
|
46
|
-
@onCurrencyChange={{fn (mut this.product.currency)}}
|
|
47
|
-
/>
|
|
19
|
+
<MoneyInput class="w-full" @currency={{if this.product.currency this.product.currency this.activeStore.currency}} @value={{this.product.price}} @canSelectCurrency={{false}} @onCurrencyChange={{fn (mut this.product.currency)}} />
|
|
48
20
|
</InputGroup>
|
|
49
21
|
<InputGroup @name="Sale Price" @helpText="Optionally add a sale price for the product if the product is put on sale">
|
|
50
|
-
<MoneyInput
|
|
51
|
-
class="w-full"
|
|
52
|
-
@currency={{if this.product.currency this.product.currency this.activeStore.currency}}
|
|
53
|
-
@value={{this.product.sale_price}}
|
|
54
|
-
@canSelectCurrency={{false}}
|
|
55
|
-
@onCurrencyChange={{fn (mut this.product.currency)}}
|
|
56
|
-
/>
|
|
22
|
+
<MoneyInput class="w-full" @currency={{if this.product.currency this.product.currency this.activeStore.currency}} @value={{this.product.sale_price}} @canSelectCurrency={{false}} @onCurrencyChange={{fn (mut this.product.currency)}} />
|
|
57
23
|
</InputGroup>
|
|
58
24
|
</div>
|
|
59
25
|
|
|
60
|
-
<ContentPanel
|
|
61
|
-
@title="Metadata"
|
|
62
|
-
@open={{this.product.meta_array.length}}
|
|
63
|
-
@actionButtons={{this.metadataButtons}}
|
|
64
|
-
@pad={{true}}
|
|
65
|
-
@panelBodyWrapperClass="px-0 py-4"
|
|
66
|
-
@panelBodyClass="bg-white dark:bg-gray-800"
|
|
67
|
-
>
|
|
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">
|
|
68
27
|
{{#each this.product.meta_array as |metaField index|}}
|
|
69
28
|
<div class="px-4 py-3 border-b border-gray-200 dark:border-gray-700">
|
|
70
29
|
<div class="input-group">
|
|
@@ -119,7 +78,7 @@
|
|
|
119
78
|
</div>
|
|
120
79
|
</div>
|
|
121
80
|
|
|
122
|
-
<ContentPanel @title="Variants" @open={{
|
|
81
|
+
<ContentPanel @title="Variants" @open={{true}} @pad={{false}} @panelBodyWrapperClass="px-0 py-4" @panelBodyClass="bg-white dark:bg-gray-800">
|
|
123
82
|
<div class="content-panel-body p-4">
|
|
124
83
|
<div class="flex items-center justify-end">
|
|
125
84
|
<Button @text="New Variant" @icon="plus" @iconPrefix="fas" @onClick={{this.createProductVariant}} />
|
|
@@ -144,12 +103,7 @@
|
|
|
144
103
|
<Input @type="text" @value={{variantOption.description}} class="form-input w-full" placeholder="Option Description" />
|
|
145
104
|
</div>
|
|
146
105
|
<div class="col-span-2">
|
|
147
|
-
<MoneyInput
|
|
148
|
-
class="w-full"
|
|
149
|
-
@currency={{if this.product.currency this.product.currency this.activeStore.currency}}
|
|
150
|
-
@canSelectCurrency={{false}}
|
|
151
|
-
@value={{variantOption.additional_cost}}
|
|
152
|
-
/>
|
|
106
|
+
<MoneyInput class="w-full" @currency={{if this.product.currency this.product.currency this.activeStore.currency}} @canSelectCurrency={{false}} @value={{variantOption.additional_cost}} />
|
|
153
107
|
</div>
|
|
154
108
|
<div class="flex items-center justify-center text-center text-sm">
|
|
155
109
|
<a href="javascript:;" {{on "click" (fn this.removeVariantOption variant index)}}>Remove</a>
|
|
@@ -163,10 +117,10 @@
|
|
|
163
117
|
</Tabs>
|
|
164
118
|
</ContentPanel>
|
|
165
119
|
|
|
166
|
-
<ContentPanel @title="Add-Ons" @open={{
|
|
120
|
+
<ContentPanel @title="Add-Ons" @open={{true}} @pad={{false}} @panelBodyWrapperClass="px-0 py-4" @panelBodyClass="bg-white dark:bg-gray-800">
|
|
167
121
|
<div class="px-4">
|
|
168
122
|
<div class="flex items-center justify-end mb-3">
|
|
169
|
-
<Button @text="Select Addon Categories" @icon="plus" @iconPrefix="fas" @onClick={{this.
|
|
123
|
+
<Button @text="Select Addon Categories" @icon="plus" @iconPrefix="fas" @onClick={{perform this.promptSelectAddonCategories}} />
|
|
170
124
|
</div>
|
|
171
125
|
<div class="space-y-2">
|
|
172
126
|
{{#each this.product.addon_categories as |addonCategory index|}}
|
|
@@ -215,9 +169,7 @@
|
|
|
215
169
|
<ContentPanel @title="Images & Videos" @open={{this.product.files.length}} @pad={{false}} @panelBodyWrapperClass="px-0 py-4" @panelBodyClass="bg-white dark:bg-gray-800">
|
|
216
170
|
<div class="px-6 space-y-4">
|
|
217
171
|
{{#if this.isUploading}}
|
|
218
|
-
<div
|
|
219
|
-
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"
|
|
220
|
-
>
|
|
172
|
+
<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">
|
|
221
173
|
<div class="flex items-center justify-center py-5">
|
|
222
174
|
<Spinner class="text-sm dar:text-gray-100" @loadingMessage={{t "component.dropzone.uploading"}} />
|
|
223
175
|
</div>
|
|
@@ -276,14 +228,7 @@
|
|
|
276
228
|
{{#each this.product.files as |file|}}
|
|
277
229
|
<FileRecord @file={{file}} @fileIconClass={{if (eq this.product.primary_image_uuid file.id) "border-blue-400"}} @onDelete={{this.removeFile}}>
|
|
278
230
|
<div class="flex items-center justify-evenly">
|
|
279
|
-
<Button
|
|
280
|
-
@icon="magic"
|
|
281
|
-
@text="Make Primary"
|
|
282
|
-
@size="xs"
|
|
283
|
-
@textClass="text-xs truncate"
|
|
284
|
-
@onClick={{fn this.makePrimaryFile file}}
|
|
285
|
-
@disabled={{eq this.product.primary_image_uuid file.id}}
|
|
286
|
-
/>
|
|
231
|
+
<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}} />
|
|
287
232
|
</div>
|
|
288
233
|
</FileRecord>
|
|
289
234
|
{{/each}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/storefront-engine/components/context-panel';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/storefront-engine/components/customer-panel/details';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/storefront-engine/components/customer-panel/orders';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/storefront-engine/components/customer-panel';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/storefront-engine/components/display-place';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/storefront-engine/components/order-panel/details';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/storefront-engine/components/order-panel';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/storefront-engine/controllers/customers/index/view';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/storefront-engine/controllers/orders/index/view';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/storefront-engine/helpers/avatar-url';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/storefront-engine/routes/customers/index/view';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/storefront-engine/serializers/product-variant-option';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/storefront-engine/services/context-panel';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/storefront-engine/templates/customers/index/view';
|
package/composer.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fleetbase/storefront-api",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.6",
|
|
4
4
|
"description": "Headless Commerce & Marketplace Extension for Fleetbase",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"fleetbase-extension",
|
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
],
|
|
23
23
|
"require": {
|
|
24
24
|
"php": "^8.0",
|
|
25
|
-
"fleetbase/core-api": "^1.4.
|
|
26
|
-
"fleetbase/fleetops-api": "^0.4.
|
|
25
|
+
"fleetbase/core-api": "^1.4.15",
|
|
26
|
+
"fleetbase/fleetops-api": "^0.4.23",
|
|
27
27
|
"geocoder-php/google-maps-places-provider": "^1.4",
|
|
28
28
|
"laravel-notification-channels/apn": "^5.0",
|
|
29
29
|
"laravel-notification-channels/fcm": "^4.1",
|
package/extension.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fleetbase/storefront-engine",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.6",
|
|
4
4
|
"description": "Headless Commerce & Marketplace Extension for Fleetbase",
|
|
5
5
|
"fleetbase": {
|
|
6
6
|
"route": "storefront",
|
|
@@ -43,9 +43,9 @@
|
|
|
43
43
|
"publish:github": "npm config set '@fleetbase:registry' https://npm.pkg.github.com/ && npm publish"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@fleetbase/ember-core": "^0.2.
|
|
46
|
+
"@fleetbase/ember-core": "^0.2.8",
|
|
47
47
|
"@fleetbase/ember-ui": "^0.2.11",
|
|
48
|
-
"@fleetbase/fleetops-data": "^0.1.
|
|
48
|
+
"@fleetbase/fleetops-data": "^0.1.14",
|
|
49
49
|
"@babel/core": "^7.23.2",
|
|
50
50
|
"@fortawesome/ember-fontawesome": "^0.4.1",
|
|
51
51
|
"@fortawesome/fontawesome-svg-core": "^6.4.0",
|
|
@@ -130,6 +130,12 @@
|
|
|
130
130
|
"options": {
|
|
131
131
|
"singleQuote": false
|
|
132
132
|
}
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"files": "*.{yml,yaml}",
|
|
136
|
+
"options": {
|
|
137
|
+
"tabWidth": 2
|
|
138
|
+
}
|
|
133
139
|
}
|
|
134
140
|
]
|
|
135
141
|
}
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
namespace Fleetbase\Storefront\Http\Controllers;
|
|
4
4
|
|
|
5
|
+
use Fleetbase\Storefront\Models\AddonCategory;
|
|
6
|
+
use Fleetbase\Support\Http;
|
|
7
|
+
use Illuminate\Http\Request;
|
|
8
|
+
|
|
5
9
|
class AddonCategoryController extends StorefrontController
|
|
6
10
|
{
|
|
7
11
|
/**
|
|
@@ -10,4 +14,90 @@ class AddonCategoryController extends StorefrontController
|
|
|
10
14
|
* @var string
|
|
11
15
|
*/
|
|
12
16
|
public $resource = 'addon_category';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Creates a new record based on the provided request data.
|
|
20
|
+
*
|
|
21
|
+
* This method handles the creation of a new record using data from the request.
|
|
22
|
+
* It includes a validation step, creation of the record, and an optional closure
|
|
23
|
+
* to perform additional operations on the model and request data. The method
|
|
24
|
+
* returns an instance of a resource, which wraps the created record. Error handling
|
|
25
|
+
* is implemented to catch and respond to various exceptions that might occur during the process.
|
|
26
|
+
*
|
|
27
|
+
* @param Request $request the incoming HTTP request containing data for the new record
|
|
28
|
+
*
|
|
29
|
+
* @return mixed an instance of the resource class containing the created record, or an error response
|
|
30
|
+
*
|
|
31
|
+
* @throws \Exception general exceptions with a message
|
|
32
|
+
* @throws \Illuminate\Database\QueryException database query exceptions with a message
|
|
33
|
+
* @throws \Fleetbase\Exceptions\FleetbaseRequestValidationException custom validation exceptions with error details
|
|
34
|
+
*/
|
|
35
|
+
public function createRecord(Request $request)
|
|
36
|
+
{
|
|
37
|
+
try {
|
|
38
|
+
$this->validateRequest($request);
|
|
39
|
+
|
|
40
|
+
$record = $this->model->createRecordFromRequest($request, null, function (&$request, AddonCategory &$addonCategory) {
|
|
41
|
+
$addons = $request->array('addonCategory.addons');
|
|
42
|
+
$addonCategory->setAddons($addons);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
if (Http::isInternalRequest($request)) {
|
|
46
|
+
$this->resource::wrap($this->resourceSingularlName);
|
|
47
|
+
|
|
48
|
+
return new $this->resource($record);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return new $this->resource($record);
|
|
52
|
+
} catch (\Exception $e) {
|
|
53
|
+
return response()->error($e->getMessage());
|
|
54
|
+
} catch (\Illuminate\Database\QueryException $e) {
|
|
55
|
+
return response()->error($e->getMessage());
|
|
56
|
+
} catch (\Fleetbase\Exceptions\FleetbaseRequestValidationException $e) {
|
|
57
|
+
return response()->error($e->getErrors());
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Updates an existing record based on the provided request data.
|
|
63
|
+
*
|
|
64
|
+
* This method updates a record identified by the provided ID using data from the request.
|
|
65
|
+
* It includes a validation step, updating of the record, and an optional closure
|
|
66
|
+
* to perform additional operations on the model and request data. The method returns
|
|
67
|
+
* an instance of a resource, which wraps the updated record. Error handling is implemented
|
|
68
|
+
* to catch and respond to various exceptions that might occur during the update process.
|
|
69
|
+
*
|
|
70
|
+
* @param Request $request the incoming HTTP request containing data for updating the record
|
|
71
|
+
* @param string $id the identifier of the record to be updated
|
|
72
|
+
*
|
|
73
|
+
* @return mixed an instance of the resource class containing the updated record, or an error response
|
|
74
|
+
*
|
|
75
|
+
* @throws \Exception general exceptions with a message
|
|
76
|
+
* @throws \Illuminate\Database\QueryException database query exceptions with a message
|
|
77
|
+
* @throws \Fleetbase\Exceptions\FleetbaseRequestValidationException custom validation exceptions with error details
|
|
78
|
+
*/
|
|
79
|
+
public function updateRecord(Request $request, string $id)
|
|
80
|
+
{
|
|
81
|
+
try {
|
|
82
|
+
$this->validateRequest($request);
|
|
83
|
+
$record = $this->model->updateRecordFromRequest($request, $id, function (&$request, AddonCategory &$addonCategory) {
|
|
84
|
+
$addons = $request->array('addonCategory.addons');
|
|
85
|
+
$addonCategory->setAddons($addons);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
if (Http::isInternalRequest($request)) {
|
|
89
|
+
$this->resource::wrap($this->resourceSingularlName);
|
|
90
|
+
|
|
91
|
+
return new $this->resource($record);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return new $this->resource($record);
|
|
95
|
+
} catch (\Exception $e) {
|
|
96
|
+
return response()->error($e->getMessage());
|
|
97
|
+
} catch (\Illuminate\Database\QueryException $e) {
|
|
98
|
+
return response()->error($e->getMessage());
|
|
99
|
+
} catch (\Fleetbase\Exceptions\FleetbaseRequestValidationException $e) {
|
|
100
|
+
return response()->error($e->getErrors());
|
|
101
|
+
}
|
|
102
|
+
}
|
|
13
103
|
}
|
|
@@ -28,40 +28,20 @@ class ReviewController extends Controller
|
|
|
28
28
|
$offset = $request->input('offset', false);
|
|
29
29
|
$sort = $request->input('sort');
|
|
30
30
|
|
|
31
|
+
if ($sort) {
|
|
32
|
+
$this->applySort($request, $sort);
|
|
33
|
+
}
|
|
34
|
+
|
|
31
35
|
if (session('storefront_store')) {
|
|
32
|
-
$results = Review::queryWithRequest($request, function (&$query) use ($
|
|
33
|
-
$query->where('subject_uuid',
|
|
36
|
+
$results = Review::queryWithRequest($request, function (&$query) use ($store, $limit, $offset) {
|
|
37
|
+
$query->where('subject_uuid', $store->uuid);
|
|
34
38
|
|
|
35
39
|
if ($limit) {
|
|
36
40
|
$query->limit($limit);
|
|
37
41
|
}
|
|
38
42
|
|
|
39
43
|
if ($offset) {
|
|
40
|
-
$query->
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
if ($sort) {
|
|
44
|
-
switch ($sort) {
|
|
45
|
-
case 'highest':
|
|
46
|
-
case 'highest rated':
|
|
47
|
-
$query->orderByDesc('rating');
|
|
48
|
-
break;
|
|
49
|
-
|
|
50
|
-
case 'lowest':
|
|
51
|
-
case 'lowest rated':
|
|
52
|
-
$query->orderBy('rating');
|
|
53
|
-
break;
|
|
54
|
-
|
|
55
|
-
case 'newest':
|
|
56
|
-
case 'newest first':
|
|
57
|
-
$query->orderByDesc('created_at');
|
|
58
|
-
break;
|
|
59
|
-
|
|
60
|
-
case 'oldest':
|
|
61
|
-
case 'oldest first':
|
|
62
|
-
$query->orderBy('created_at');
|
|
63
|
-
break;
|
|
64
|
-
}
|
|
44
|
+
$query->offset($offset);
|
|
65
45
|
}
|
|
66
46
|
});
|
|
67
47
|
}
|
|
@@ -79,7 +59,7 @@ class ReviewController extends Controller
|
|
|
79
59
|
return response()->json(['error' => 'Cannot find reviews for store'], 400);
|
|
80
60
|
}
|
|
81
61
|
|
|
82
|
-
$results = Review::queryWithRequest($request, function (&$query) use ($store, $
|
|
62
|
+
$results = Review::queryWithRequest($request, function (&$query) use ($store, $limit, $offset) {
|
|
83
63
|
$query->where('subject_uuid', $store->uuid);
|
|
84
64
|
|
|
85
65
|
if ($limit) {
|
|
@@ -89,30 +69,6 @@ class ReviewController extends Controller
|
|
|
89
69
|
if ($offset) {
|
|
90
70
|
$query->limit($offset);
|
|
91
71
|
}
|
|
92
|
-
|
|
93
|
-
if ($sort) {
|
|
94
|
-
switch ($sort) {
|
|
95
|
-
case 'highest':
|
|
96
|
-
case 'highest rated':
|
|
97
|
-
$query->orderByDesc('rating');
|
|
98
|
-
break;
|
|
99
|
-
|
|
100
|
-
case 'lowest':
|
|
101
|
-
case 'lowest rated':
|
|
102
|
-
$query->orderBy('rating');
|
|
103
|
-
break;
|
|
104
|
-
|
|
105
|
-
case 'newest':
|
|
106
|
-
case 'newest first':
|
|
107
|
-
$query->orderByDesc('created_at');
|
|
108
|
-
break;
|
|
109
|
-
|
|
110
|
-
case 'oldest':
|
|
111
|
-
case 'oldest first':
|
|
112
|
-
$query->orderBy('created_at');
|
|
113
|
-
break;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
72
|
});
|
|
117
73
|
}
|
|
118
74
|
}
|
|
@@ -120,6 +76,41 @@ class ReviewController extends Controller
|
|
|
120
76
|
return StorefrontReview::collection($results);
|
|
121
77
|
}
|
|
122
78
|
|
|
79
|
+
public function applySort($request, $sort)
|
|
80
|
+
{
|
|
81
|
+
if ($sort) {
|
|
82
|
+
switch ($sort) {
|
|
83
|
+
case 'highest':
|
|
84
|
+
case 'highest rated':
|
|
85
|
+
$request->merge(['sort' => 'rating', 'sort_direction' => 'desc']);
|
|
86
|
+
|
|
87
|
+
break;
|
|
88
|
+
|
|
89
|
+
case 'lowest':
|
|
90
|
+
case 'lowest rated':
|
|
91
|
+
$request->merge(['sort' => 'rating', 'sort_direction' => 'asc']);
|
|
92
|
+
|
|
93
|
+
break;
|
|
94
|
+
|
|
95
|
+
case 'newest':
|
|
96
|
+
case 'newest first':
|
|
97
|
+
$request->merge(['sort' => 'created_at', 'sort_direction' => 'desc']);
|
|
98
|
+
|
|
99
|
+
break;
|
|
100
|
+
|
|
101
|
+
case 'oldest':
|
|
102
|
+
case 'oldest first':
|
|
103
|
+
$request->merge(['sort' => 'created_at', 'sort_direction' => 'asc']);
|
|
104
|
+
|
|
105
|
+
break;
|
|
106
|
+
|
|
107
|
+
default:
|
|
108
|
+
// Handle unknown sorting criteria
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
123
114
|
/**
|
|
124
115
|
* Coutns the number of ratings between 1-5 for a store.
|
|
125
116
|
*
|
|
@@ -17,38 +17,40 @@ class Network extends FleetbaseResource
|
|
|
17
17
|
public function toArray($request)
|
|
18
18
|
{
|
|
19
19
|
return [
|
|
20
|
-
'id'
|
|
21
|
-
'uuid'
|
|
22
|
-
'public_id'
|
|
23
|
-
'key'
|
|
24
|
-
'company_uuid'
|
|
25
|
-
'created_by_uuid'
|
|
26
|
-
'logo_uuid'
|
|
27
|
-
'backdrop_uuid'
|
|
28
|
-
'name'
|
|
29
|
-
'description'
|
|
30
|
-
'translations'
|
|
31
|
-
'website'
|
|
32
|
-
'facebook'
|
|
33
|
-
'instagram'
|
|
34
|
-
'twitter'
|
|
35
|
-
'email'
|
|
36
|
-
'phone'
|
|
37
|
-
'tags'
|
|
38
|
-
'currency'
|
|
39
|
-
'options'
|
|
40
|
-
'alertable'
|
|
41
|
-
'logo_url'
|
|
42
|
-
'backdrop_url'
|
|
43
|
-
'rating'
|
|
44
|
-
'online'
|
|
45
|
-
'stores'
|
|
46
|
-
'categories'
|
|
47
|
-
'
|
|
48
|
-
'
|
|
49
|
-
'
|
|
50
|
-
'
|
|
51
|
-
'
|
|
20
|
+
'id' => $this->when(Http::isInternalRequest(), $this->id, $this->public_id),
|
|
21
|
+
'uuid' => $this->when(Http::isInternalRequest(), $this->uuid),
|
|
22
|
+
'public_id' => $this->when(Http::isInternalRequest(), $this->public_id),
|
|
23
|
+
'key' => $this->when(Http::isInternalRequest(), $this->key),
|
|
24
|
+
'company_uuid' => $this->when(Http::isInternalRequest(), $this->company_uuid),
|
|
25
|
+
'created_by_uuid' => $this->when(Http::isInternalRequest(), $this->created_by_uuid),
|
|
26
|
+
'logo_uuid' => $this->when(Http::isInternalRequest(), $this->logo_uuid),
|
|
27
|
+
'backdrop_uuid' => $this->when(Http::isInternalRequest(), $this->backdrop_uuid),
|
|
28
|
+
'name' => $this->name,
|
|
29
|
+
'description' => $this->description,
|
|
30
|
+
'translations' => $this->translations ?? [],
|
|
31
|
+
'website' => $this->website,
|
|
32
|
+
'facebook' => $this->facebook,
|
|
33
|
+
'instagram' => $this->instagram,
|
|
34
|
+
'twitter' => $this->twitter,
|
|
35
|
+
'email' => $this->email,
|
|
36
|
+
'phone' => $this->phone,
|
|
37
|
+
'tags' => $this->tags ?? [],
|
|
38
|
+
'currency' => $this->currency ?? 'USD',
|
|
39
|
+
'options' => $this->options ?? [],
|
|
40
|
+
'alertable' => $this->alertable,
|
|
41
|
+
'logo_url' => $this->logo_url,
|
|
42
|
+
'backdrop_url' => $this->backdrop_url,
|
|
43
|
+
'rating' => $this->rating,
|
|
44
|
+
'online' => $this->online,
|
|
45
|
+
'stores' => $this->when($request->boolean('with_stores') || $request->inArray('with', 'stores'), Store::collection($this->stores)),
|
|
46
|
+
'categories' => $this->when($request->boolean('with_categories') || $request->inArray('with', 'categories'), Category::collection($this->categories)),
|
|
47
|
+
'gateways' => $this->when($request->boolean('with_gateways') || $request->inArray('with', 'gateways'), Gateway::collection($this->gateways)),
|
|
48
|
+
'notification_channels' => $this->when($request->boolean('with_notification_channels') || $request->inArray('with', 'notification_channels'), NotificationChannel::collection($this->notificationChannels)),
|
|
49
|
+
'is_network' => true,
|
|
50
|
+
'is_store' => false,
|
|
51
|
+
'slug' => $this->slug,
|
|
52
|
+
'created_at' => $this->created_at,
|
|
53
|
+
'updated_at' => $this->updated_at,
|
|
52
54
|
];
|
|
53
55
|
}
|
|
54
56
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\Storefront\Http\Resources;
|
|
4
|
+
|
|
5
|
+
use Fleetbase\Http\Resources\FleetbaseResource;
|
|
6
|
+
use Fleetbase\Support\Http;
|
|
7
|
+
|
|
8
|
+
class NotificationChannel extends FleetbaseResource
|
|
9
|
+
{
|
|
10
|
+
/**
|
|
11
|
+
* Transform the resource into an array.
|
|
12
|
+
*
|
|
13
|
+
* @param \Illuminate\Http\Request $request
|
|
14
|
+
*
|
|
15
|
+
* @return array
|
|
16
|
+
*/
|
|
17
|
+
public function toArray($request)
|
|
18
|
+
{
|
|
19
|
+
return [
|
|
20
|
+
'id' => $this->when(Http::isInternalRequest(), $this->id, $this->public_id),
|
|
21
|
+
'uuid' => $this->when(Http::isInternalRequest(), $this->uuid),
|
|
22
|
+
'public_id' => $this->when(Http::isInternalRequest(), $this->public_id),
|
|
23
|
+
'name' => $this->name,
|
|
24
|
+
'scheme' => $this->scheme,
|
|
25
|
+
'options' => $this->options,
|
|
26
|
+
'is_apn_gateway' => $this->is_apn_gateway,
|
|
27
|
+
'is_fcm_gateway' => $this->is_fcm_gateway,
|
|
28
|
+
'created_at' => $this->created_at,
|
|
29
|
+
'updated_at' => $this->updated_at,
|
|
30
|
+
];
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -97,14 +97,16 @@ class Product extends FleetbaseResource
|
|
|
97
97
|
|
|
98
98
|
if (Http::isInternalRequest()) {
|
|
99
99
|
return [
|
|
100
|
-
'uuid'
|
|
101
|
-
'
|
|
102
|
-
'
|
|
103
|
-
'
|
|
104
|
-
'
|
|
105
|
-
'
|
|
106
|
-
'
|
|
107
|
-
'
|
|
100
|
+
'uuid' => $addonCategory->uuid,
|
|
101
|
+
'product_uuid' => $addonCategory->product_uuid,
|
|
102
|
+
'category_uuid' => $addonCategory->category_uuid,
|
|
103
|
+
'public_id' => data_get($addonCategory, 'category.public_id'),
|
|
104
|
+
'id' => $addonCategory->id,
|
|
105
|
+
'name' => $addonCategory->name,
|
|
106
|
+
'excluded_addons' => $addonCategory->excluded_addons,
|
|
107
|
+
'category' => $addonCategory->category,
|
|
108
|
+
'created_at' => $addonCategory->created_at,
|
|
109
|
+
'updated_at' => $addonCategory->updated_at,
|
|
108
110
|
];
|
|
109
111
|
} else {
|
|
110
112
|
return [
|