@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.
Files changed (83) hide show
  1. package/addon/components/context-panel.hbs +5 -0
  2. package/addon/components/context-panel.js +6 -0
  3. package/addon/components/customer-panel/details.hbs +34 -0
  4. package/addon/components/customer-panel/details.js +3 -0
  5. package/addon/components/customer-panel/orders.hbs +140 -0
  6. package/addon/components/customer-panel/orders.js +78 -0
  7. package/addon/components/customer-panel.hbs +70 -0
  8. package/addon/components/customer-panel.js +171 -0
  9. package/addon/components/display-place.hbs +52 -0
  10. package/addon/components/display-place.js +11 -0
  11. package/addon/components/modals/manage-addons.hbs +15 -52
  12. package/addon/components/modals/manage-addons.js +93 -43
  13. package/addon/components/modals/select-addon-category.hbs +1 -1
  14. package/addon/components/order-panel/details.hbs +245 -0
  15. package/addon/components/order-panel/details.js +189 -0
  16. package/addon/components/order-panel.hbs +1 -0
  17. package/addon/components/order-panel.js +38 -0
  18. package/addon/components/storefront-order-summary.hbs +9 -2
  19. package/addon/components/widget/customers.hbs +3 -1
  20. package/addon/components/widget/customers.js +5 -0
  21. package/addon/components/widget/orders.js +8 -146
  22. package/addon/controllers/customers/index/view.js +43 -0
  23. package/addon/controllers/customers/index.js +10 -6
  24. package/addon/controllers/networks/index/network/customers.js +68 -2
  25. package/addon/controllers/networks/index/network/orders.js +324 -1
  26. package/addon/controllers/networks/index/network/stores.js +0 -2
  27. package/addon/controllers/orders/index/view.js +13 -0
  28. package/addon/controllers/orders/index.js +10 -7
  29. package/addon/controllers/products/index/category/edit.js +12 -16
  30. package/addon/controllers/products/index/category/new.js +40 -45
  31. package/addon/controllers/products/index.js +8 -2
  32. package/addon/helpers/avatar-url.js +9 -0
  33. package/addon/models/product-variant-option.js +8 -1
  34. package/addon/models/product-variant.js +12 -2
  35. package/addon/models/product.js +62 -0
  36. package/addon/routes/customers/index/view.js +14 -0
  37. package/addon/routes/networks/index/network/customers.js +29 -0
  38. package/addon/routes/networks/index/network/orders.js +5 -0
  39. package/addon/routes/networks/index.js +1 -1
  40. package/addon/routes/orders/index/view.js +22 -1
  41. package/addon/routes/products/index/category/edit.js +6 -0
  42. package/addon/routes/products/index/category/new.js +3 -1
  43. package/addon/routes.js +1 -0
  44. package/addon/serializers/product-variant-option.js +14 -0
  45. package/addon/serializers/product-variant.js +27 -0
  46. package/addon/serializers/product.js +26 -4
  47. package/addon/services/context-panel.js +210 -0
  48. package/addon/styles/storefront-engine.css +6 -0
  49. package/addon/templates/application.hbs +3 -1
  50. package/addon/templates/customers/index/view.hbs +1 -0
  51. package/addon/templates/networks/index/network/customers.hbs +18 -1
  52. package/addon/templates/networks/index/network/orders.hbs +18 -1
  53. package/addon/templates/networks/index/network.hbs +1 -1
  54. package/addon/templates/orders/index/view.hbs +1 -1
  55. package/addon/templates/products/index/category/new.hbs +12 -67
  56. package/app/components/context-panel.js +1 -0
  57. package/app/components/customer-panel/details.js +1 -0
  58. package/app/components/customer-panel/orders.js +1 -0
  59. package/app/components/customer-panel.js +1 -0
  60. package/app/components/display-place.js +1 -0
  61. package/app/components/order-panel/details.js +1 -0
  62. package/app/components/order-panel.js +1 -0
  63. package/app/controllers/customers/index/view.js +1 -0
  64. package/app/controllers/orders/index/view.js +1 -0
  65. package/app/helpers/avatar-url.js +1 -0
  66. package/app/routes/customers/index/view.js +1 -0
  67. package/app/serializers/product-variant-option.js +1 -0
  68. package/app/services/context-panel.js +1 -0
  69. package/app/templates/customers/index/view.js +1 -0
  70. package/composer.json +3 -3
  71. package/extension.json +1 -1
  72. package/package.json +9 -3
  73. package/server/src/Http/Controllers/AddonCategoryController.php +90 -0
  74. package/server/src/Http/Controllers/v1/ReviewController.php +43 -52
  75. package/server/src/Http/Resources/Network.php +34 -32
  76. package/server/src/Http/Resources/NotificationChannel.php +32 -0
  77. package/server/src/Http/Resources/Product.php +10 -8
  78. package/server/src/Models/AddonCategory.php +37 -0
  79. package/server/src/Models/Product.php +6 -7
  80. package/server/src/Models/ProductAddon.php +3 -0
  81. package/server/src/Models/ProductAddonCategory.php +12 -2
  82. package/server/src/Providers/StorefrontServiceProvider.php +1 -1
  83. 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
- @title={{this.overlayTitle}}
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={{this.product.variants.length}} @pad={{false}} @panelBodyWrapperClass="px-0 py-4" @panelBodyClass="bg-white dark:bg-gray-800">
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={{this.product.addon_categories.length}} @pad={{false}} @panelBodyWrapperClass="px-0 py-4" @panelBodyClass="bg-white dark:bg-gray-800">
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.selectAddonCategory}} />
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.5",
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.12",
26
- "fleetbase/fleetops-api": "^0.4.18",
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "Storefront",
3
- "version": "0.3.5",
3
+ "version": "0.3.6",
4
4
  "description": "Headless Commerce & Marketplace Extension for Fleetbase",
5
5
  "repository": "https://github.com/fleetbase/storefront",
6
6
  "license": "MIT",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fleetbase/storefront-engine",
3
- "version": "0.3.5",
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.6",
46
+ "@fleetbase/ember-core": "^0.2.8",
47
47
  "@fleetbase/ember-ui": "^0.2.11",
48
- "@fleetbase/fleetops-data": "^0.1.13",
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 ($limit, $offset, $sort) {
33
- $query->where('subject_uuid', session('storefront_store'));
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->limit($offset);
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, $sort, $limit, $offset) {
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' => $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
- 'is_network' => true,
48
- 'is_store' => false,
49
- 'slug' => $this->slug,
50
- 'created_at' => $this->created_at,
51
- 'updated_at' => $this->updated_at,
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' => $addonCategory->uuid,
101
- 'public_id' => data_get($addonCategory, 'category.public_id'),
102
- 'id' => $addonCategory->id,
103
- 'name' => $addonCategory->name,
104
- 'excluded_addons' => $addonCategory->excluded_addons,
105
- 'category' => $addonCategory->category,
106
- 'created_at' => $addonCategory->created_at,
107
- 'updated_at' => $addonCategory->updated_at,
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 [