@fleetbase/storefront-engine 0.3.24 → 0.3.26

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 (115) hide show
  1. package/addon/adapters/catalog.js +1 -0
  2. package/addon/adapters/food-truck.js +1 -0
  3. package/addon/components/customer-panel/orders.hbs +7 -1
  4. package/addon/components/modals/assign-food-truck-catalogs.hbs +14 -0
  5. package/addon/components/modals/create-catalog.hbs +96 -0
  6. package/addon/components/modals/create-first-store.hbs +6 -1
  7. package/addon/components/modals/create-food-truck.hbs +69 -0
  8. package/addon/components/modals/manage-addons.js +1 -15
  9. package/addon/components/order-panel.hbs +2 -2
  10. package/addon/components/widget/customers.hbs +5 -5
  11. package/addon/components/widget/orders.hbs +7 -4
  12. package/addon/components/widget/orders.js +11 -1
  13. package/addon/controllers/catalogs/index.js +121 -0
  14. package/addon/controllers/food-trucks/index.js +100 -0
  15. package/addon/models/catalog-category.js +6 -0
  16. package/addon/models/catalog-hour.js +72 -0
  17. package/addon/models/catalog.js +45 -0
  18. package/addon/models/food-truck.js +47 -0
  19. package/addon/models/product.js +1 -0
  20. package/addon/routes/catalogs/index.js +22 -0
  21. package/addon/routes/catalogs.js +3 -0
  22. package/addon/routes/food-trucks/index.js +22 -0
  23. package/addon/routes/food-trucks.js +3 -0
  24. package/addon/routes.js +6 -0
  25. package/addon/serializers/catalog-category.js +15 -0
  26. package/addon/serializers/catalog.js +16 -0
  27. package/addon/serializers/food-truck.js +18 -0
  28. package/addon/serializers/product-variant.js +0 -1
  29. package/addon/styles/storefront-engine.css +15 -5
  30. package/addon/templates/application.hbs +14 -0
  31. package/addon/templates/catalogs/index.hbs +46 -0
  32. package/addon/templates/catalogs.hbs +1 -0
  33. package/addon/templates/customers/index.hbs +1 -1
  34. package/addon/templates/food-trucks/index.hbs +52 -0
  35. package/addon/templates/food-trucks.hbs +1 -0
  36. package/addon/templates/networks/index.hbs +14 -2
  37. package/addon/templates/products/index/category/new.hbs +10 -3
  38. package/addon/templates/products/index/index.hbs +1 -2
  39. package/addon/templates/products/index.hbs +16 -2
  40. package/app/adapters/catalog.js +1 -0
  41. package/app/adapters/food-truck.js +1 -0
  42. package/app/components/modals/assign-food-truck-catalogs.js +1 -0
  43. package/app/components/modals/create-catalog.js +1 -0
  44. package/app/components/modals/create-food-truck.js +1 -0
  45. package/app/controllers/catalogs/index.js +1 -0
  46. package/app/controllers/food-trucks/index.js +1 -0
  47. package/app/models/catalog-category.js +1 -0
  48. package/app/models/catalog-hour.js +1 -0
  49. package/app/models/catalog.js +1 -0
  50. package/app/models/food-truck.js +1 -0
  51. package/app/routes/catalogs/index.js +1 -0
  52. package/app/routes/catalogs.js +1 -0
  53. package/app/routes/food-trucks/index.js +1 -0
  54. package/app/routes/food-trucks.js +1 -0
  55. package/app/serializers/catalog-category.js +1 -0
  56. package/app/serializers/catalog.js +1 -0
  57. package/app/serializers/food-truck.js +1 -0
  58. package/app/templates/catalogs/index.js +1 -0
  59. package/app/templates/catalogs.js +1 -0
  60. package/app/templates/food-trucks/index.js +1 -0
  61. package/app/templates/food-trucks.js +1 -0
  62. package/composer.json +1 -1
  63. package/extension.json +1 -1
  64. package/package.json +1 -1
  65. package/server/migrations/2025_01_30_042853_create_catalogs_table.php +41 -0
  66. package/server/migrations/2025_01_30_044728_create_catalog_category_products_table.php +35 -0
  67. package/server/migrations/2025_01_30_050611_create_food_trucks_table.php +72 -0
  68. package/server/migrations/2025_01_30_052157_create_catalog_subjects_table.php +54 -0
  69. package/server/migrations/2025_01_30_052402_create_catalog_hours_table.php +39 -0
  70. package/server/src/Auth/Schemas/Storefront.php +16 -0
  71. package/server/src/Console/Commands/PurgeExpiredCarts.php +13 -3
  72. package/server/src/Http/Controllers/CatalogCategoryController.php +13 -0
  73. package/server/src/Http/Controllers/CatalogController.php +13 -0
  74. package/server/src/Http/Controllers/CatalogHourController.php +13 -0
  75. package/server/src/Http/Controllers/FoodTruckController.php +13 -0
  76. package/server/src/Http/Controllers/v1/CatalogController.php +38 -0
  77. package/server/src/Http/Controllers/v1/CategoryController.php +1 -1
  78. package/server/src/Http/Controllers/v1/CheckoutController.php +4 -0
  79. package/server/src/Http/Controllers/v1/CustomerController.php +5 -1
  80. package/server/src/Http/Controllers/v1/FoodTruckController.php +39 -0
  81. package/server/src/Http/Controllers/v1/ProductController.php +1 -1
  82. package/server/src/Http/Controllers/v1/ReviewController.php +8 -6
  83. package/server/src/Http/Controllers/v1/StoreController.php +10 -0
  84. package/server/src/Http/Filter/FoodTruckFilter.php +37 -0
  85. package/server/src/Http/Resources/Catalog.php +34 -0
  86. package/server/src/Http/Resources/CatalogCategory.php +38 -0
  87. package/server/src/Http/Resources/CatalogProduct.php +55 -0
  88. package/server/src/Http/Resources/FoodTruck.php +42 -0
  89. package/server/src/Http/Resources/Product.php +1 -0
  90. package/server/src/Http/Resources/ReviewCustomer.php +2 -0
  91. package/server/src/Models/AddonCategory.php +12 -0
  92. package/server/src/Models/Cart.php +6 -0
  93. package/server/src/Models/Catalog.php +213 -0
  94. package/server/src/Models/CatalogCategory.php +118 -0
  95. package/server/src/Models/CatalogHour.php +46 -0
  96. package/server/src/Models/CatalogProduct.php +25 -0
  97. package/server/src/Models/CatalogSubject.php +70 -0
  98. package/server/src/Models/FoodTruck.php +182 -0
  99. package/server/src/Models/Product.php +29 -2
  100. package/server/src/Models/Review.php +2 -2
  101. package/server/src/Notifications/StorefrontOrderCanceled.php +80 -121
  102. package/server/src/Notifications/StorefrontOrderCompleted.php +86 -131
  103. package/server/src/Notifications/StorefrontOrderCreated.php +29 -15
  104. package/server/src/Notifications/StorefrontOrderDriverAssigned.php +96 -130
  105. package/server/src/Notifications/StorefrontOrderEnroute.php +89 -129
  106. package/server/src/Notifications/StorefrontOrderNearby.php +103 -132
  107. package/server/src/Notifications/StorefrontOrderPreparing.php +84 -134
  108. package/server/src/Notifications/StorefrontOrderReadyForPickup.php +89 -134
  109. package/server/src/Observers/CatalogObserver.php +40 -0
  110. package/server/src/Observers/FoodTruckObserver.php +24 -0
  111. package/server/src/Observers/ProductObserver.php +23 -41
  112. package/server/src/Providers/StorefrontServiceProvider.php +5 -3
  113. package/server/src/Support/PushNotification.php +127 -0
  114. package/server/src/routes.php +10 -0
  115. package/translations/en-us.yaml +5 -0
@@ -0,0 +1,45 @@
1
+ import Model, { attr, hasMany } from '@ember-data/model';
2
+ import { format, formatDistanceToNow } from 'date-fns';
3
+
4
+ export default class CatalogModel extends Model {
5
+ /** @ids */
6
+ @attr('string') store_uuid;
7
+ @attr('string') created_by_uuid;
8
+ @attr('string') company_uuid;
9
+
10
+ /** @relationships */
11
+ @hasMany('catalog-category', { async: false }) categories;
12
+ @hasMany('catalog-hour', { async: false }) hours;
13
+
14
+ /** @attributes */
15
+ @attr('string') name;
16
+ @attr('string') description;
17
+ @attr('raw') meta;
18
+ @attr('string') status;
19
+
20
+ /** @dates */
21
+ @attr('date') created_at;
22
+ @attr('date') updated_at;
23
+
24
+ /** @methods */
25
+ toJSON() {
26
+ return this.serialize();
27
+ }
28
+
29
+ /** @computed */
30
+ get updatedAgo() {
31
+ return formatDistanceToNow(this.updated_at);
32
+ }
33
+
34
+ get updatedAt() {
35
+ return format(this.updated_at, 'PPP');
36
+ }
37
+
38
+ get createdAgo() {
39
+ return formatDistanceToNow(this.created_at);
40
+ }
41
+
42
+ get createdAt() {
43
+ return format(this.created_at, 'PPP p');
44
+ }
45
+ }
@@ -0,0 +1,47 @@
1
+ import Model, { attr, belongsTo, hasMany } from '@ember-data/model';
2
+ import { format, formatDistanceToNow } from 'date-fns';
3
+
4
+ export default class FoodTruckModel extends Model {
5
+ /** @ids */
6
+ @attr('string') company_uuid;
7
+ @attr('string') created_by_uuid;
8
+ @attr('string') vehicle_uuid;
9
+ @attr('string') store_uuid;
10
+
11
+ /** @relationships */
12
+ @belongsTo('vehicle') vehicle;
13
+ @belongsTo('service-area') service_area;
14
+ @belongsTo('zone') zone;
15
+ @hasMany('catalog') catalogs;
16
+
17
+ /** @attributes */
18
+ @attr('string', { defaultValue: 'storefront:store' }) subject_type;
19
+ @attr('raw') meta;
20
+ @attr('string') status;
21
+
22
+ /** @dates */
23
+ @attr('date') created_at;
24
+ @attr('date') updated_at;
25
+
26
+ /** @methods */
27
+ toJSON() {
28
+ return this.serialize();
29
+ }
30
+
31
+ /** @computed */
32
+ get updatedAgo() {
33
+ return formatDistanceToNow(this.updated_at);
34
+ }
35
+
36
+ get updatedAt() {
37
+ return format(this.updated_at, 'PPP');
38
+ }
39
+
40
+ get createdAgo() {
41
+ return formatDistanceToNow(this.created_at);
42
+ }
43
+
44
+ get createdAt() {
45
+ return format(this.created_at, 'PPP p');
46
+ }
47
+ }
@@ -24,6 +24,7 @@ export default class ProductModel extends Model {
24
24
  @hasMany('product-variant', { async: false }) variants;
25
25
  @hasMany('product-addon-category', { async: false }) addon_categories;
26
26
  @hasMany('product-hour') hours;
27
+ @hasMany('catalog-category', { inverse: 'products' }) catalogCategories;
27
28
 
28
29
  /** @attributes */
29
30
  @attr('string', { defaultValue: '' }) name;
@@ -0,0 +1,22 @@
1
+ import Route from '@ember/routing/route';
2
+ import { inject as service } from '@ember/service';
3
+
4
+ export default class CatalogsIndexRoute extends Route {
5
+ @service store;
6
+ @service storefront;
7
+ @service intl;
8
+ @service abilities;
9
+ @service hostRouter;
10
+ @service notifications;
11
+
12
+ beforeModel() {
13
+ if (this.abilities.cannot('storefront list catalog')) {
14
+ this.notifications.warning(this.intl.t('common.unauthorized-access'));
15
+ return this.hostRouter.transitionTo('console.storefront');
16
+ }
17
+ }
18
+
19
+ model(params) {
20
+ return this.store.query('catalog', { ...params, store_uuid: this.storefront.getActiveStore('id') });
21
+ }
22
+ }
@@ -0,0 +1,3 @@
1
+ import Route from '@ember/routing/route';
2
+
3
+ export default class CatalogsRoute extends Route {}
@@ -0,0 +1,22 @@
1
+ import Route from '@ember/routing/route';
2
+ import { inject as service } from '@ember/service';
3
+
4
+ export default class FoodTrucksIndexRoute extends Route {
5
+ @service store;
6
+ @service storefront;
7
+ @service intl;
8
+ @service abilities;
9
+ @service hostRouter;
10
+ @service notifications;
11
+
12
+ beforeModel() {
13
+ if (this.abilities.cannot('storefront list food-truck')) {
14
+ this.notifications.warning(this.intl.t('common.unauthorized-access'));
15
+ return this.hostRouter.transitionTo('console.storefront');
16
+ }
17
+ }
18
+
19
+ model(params) {
20
+ return this.store.query('food-truck', { ...params, store_uuid: this.storefront.getActiveStore('id') });
21
+ }
22
+ }
@@ -0,0 +1,3 @@
1
+ import Route from '@ember/routing/route';
2
+
3
+ export default class FoodTrucksRoute extends Route {}
package/addon/routes.js CHANGED
@@ -13,6 +13,9 @@ export default buildRoutes(function () {
13
13
  });
14
14
  });
15
15
  });
16
+ this.route('catalogs', function () {
17
+ this.route('index', { path: '/' }, function () {});
18
+ });
16
19
  this.route('customers', function () {
17
20
  this.route('index', { path: '/' }, function () {
18
21
  this.route('edit', { path: '/:public_id' });
@@ -35,6 +38,9 @@ export default buildRoutes(function () {
35
38
  });
36
39
  });
37
40
  });
41
+ this.route('food-trucks', function () {
42
+ this.route('index', { path: '/' }, function () {});
43
+ });
38
44
  this.route('promotions');
39
45
  this.route('coupons');
40
46
  this.route('broadcast');
@@ -0,0 +1,15 @@
1
+ import ApplicationSerializer from '@fleetbase/ember-core/serializers/application';
2
+ import { EmbeddedRecordsMixin } from '@ember-data/serializer/rest';
3
+
4
+ export default class CatalogCategorySerializer extends ApplicationSerializer.extend(EmbeddedRecordsMixin) {
5
+ /**
6
+ * Embedded relationship attributes
7
+ *
8
+ * @var {Object}
9
+ */
10
+ get attrs() {
11
+ return {
12
+ products: { embedded: 'always' },
13
+ };
14
+ }
15
+ }
@@ -0,0 +1,16 @@
1
+ import ApplicationSerializer from '@fleetbase/ember-core/serializers/application';
2
+ import { EmbeddedRecordsMixin } from '@ember-data/serializer/rest';
3
+
4
+ export default class CatalogSerializer extends ApplicationSerializer.extend(EmbeddedRecordsMixin) {
5
+ /**
6
+ * Embedded relationship attributes
7
+ *
8
+ * @var {Object}
9
+ */
10
+ get attrs() {
11
+ return {
12
+ categories: { embedded: 'always' },
13
+ hours: { embedded: 'always' },
14
+ };
15
+ }
16
+ }
@@ -0,0 +1,18 @@
1
+ import ApplicationSerializer from '@fleetbase/ember-core/serializers/application';
2
+ import { EmbeddedRecordsMixin } from '@ember-data/serializer/rest';
3
+
4
+ export default class FoodTruckSerializer extends ApplicationSerializer.extend(EmbeddedRecordsMixin) {
5
+ /**
6
+ * Embedded relationship attributes
7
+ *
8
+ * @var {Object}
9
+ */
10
+ get attrs() {
11
+ return {
12
+ catalogs: { embedded: 'always' },
13
+ vehicle: { embedded: 'always' },
14
+ serviceArea: { embedded: 'always' },
15
+ zone: { embedded: 'always' },
16
+ };
17
+ }
18
+ }
@@ -34,7 +34,6 @@ export default class ProductVariantSerializer extends ApplicationSerializer.exte
34
34
  if (key === 'options') {
35
35
  const options = snapshot.record.get('options');
36
36
  json.options = isArray(options) ? Array.from(options) : [];
37
- console.log('[ProductVariantSerializer #json.options]', json.options);
38
37
  }
39
38
 
40
39
  return super.serializeHasMany(...arguments);
@@ -60,10 +60,20 @@
60
60
  color: #fca5a5;
61
61
  }
62
62
 
63
+ .status-badge.draft-status-badge > span {
64
+ background-color: #a16207;
65
+ border: 1px solid #a16207;
66
+ color: #fef9c3;
67
+ }
68
+
69
+ .status-badge.draft-status-badge > span svg {
70
+ color: #fef9c3;
71
+ }
72
+
63
73
  /** hotfix nav tab */
64
- body[data-theme='dark'] .ui-tabs.overlay-content-panel > ul .nav-item.active,
65
- body[data-theme='dark'] .ui-tabs.overlay-content-panel > nav .nav-item.active,
66
- body[data-theme='dark'] .ui-tabs.overlay-content-panel > ul .ui-tab.active,
74
+ body[data-theme='dark'] .ui-tabs.overlay-content-panel > ul .nav-item.active,
75
+ body[data-theme='dark'] .ui-tabs.overlay-content-panel > nav .nav-item.active,
76
+ body[data-theme='dark'] .ui-tabs.overlay-content-panel > ul .ui-tab.active,
67
77
  body[data-theme='dark'] .ui-tabs.overlay-content-panel > nav .ui-tab.active {
68
- background-color: #202A37;
69
- }
78
+ background-color: #202a37;
79
+ }
@@ -9,6 +9,13 @@
9
9
  @visible="storefront see product"
10
10
  disabled={{not this.activeStore.id}}
11
11
  >{{t "storefront.sidebar.products"}}</Layout::Sidebar::Item>
12
+ <Layout::Sidebar::Item
13
+ @route="console.storefront.catalogs"
14
+ @icon="book-open"
15
+ @permission="storefront list catalog"
16
+ @visible="storefront see catalog"
17
+ disabled={{not this.activeStore.id}}
18
+ >{{t "storefront.sidebar.catalogs"}}</Layout::Sidebar::Item>
12
19
  <Layout::Sidebar::Item @route="console.storefront.customers" @icon="users" @permission="storefront list user" @visible="storefront see user" disabled={{not this.activeStore.id}}>{{t
13
20
  "storefront.sidebar.customers"
14
21
  }}</Layout::Sidebar::Item>
@@ -26,6 +33,13 @@
26
33
  @visible="storefront see network"
27
34
  disabled={{not this.activeStore.id}}
28
35
  >{{t "storefront.sidebar.networks"}}</Layout::Sidebar::Item>
36
+ <Layout::Sidebar::Item
37
+ @route="console.storefront.food-trucks"
38
+ @icon="truck"
39
+ @permission="storefront list food-truck"
40
+ @visible="storefront see food-truck"
41
+ disabled={{not this.activeStore.id}}
42
+ >{{t "storefront.sidebar.food-trucks"}}</Layout::Sidebar::Item>
29
43
  <Layout::Sidebar::Item
30
44
  @route="console.storefront.settings"
31
45
  @icon="cogs"
@@ -0,0 +1,46 @@
1
+ <Layout::Section::Header @title={{t "storefront.common.catalogs"}}>
2
+ <Button @type="primary" @icon="plus" @text={{t "storefront.common.new"}} @permission="storefront create catalog" @onClick={{this.createCatalog}} class="mr-2" />
3
+ <Button @icon="long-arrow-up" @iconClass="rotate-icon-45" @text={{t "storefront.common.export"}} @permission="storefront export catalog" />
4
+ </Layout::Section::Header>
5
+
6
+ <Layout::Section::Body>
7
+ <div class="p-4">
8
+ <div class="grid grid-cols-3 gap-4">
9
+ {{#each @model as |catalog|}}
10
+ <div class="px-2 py-2 border rounded-lg dark:bg-gray-800 dark:border-gray-700 border-gray-200 bg-gray-100">
11
+ <div class="flex flex-row mb-2">
12
+ <div class="flex flex-col flex-1">
13
+ <div class="text-sm font-semibold">{{catalog.name}}</div>
14
+ <div class="mt-1 flex flex-row">
15
+ <div class="text-sm">{{n-a catalog.description}}</div>
16
+ </div>
17
+ <div>
18
+ <Badge @status={{catalog.status}} @hideStatusDot={{true}} />
19
+ </div>
20
+ </div>
21
+ </div>
22
+ <div class="mt-2 flex flex-row space-x-2">
23
+ <Button
24
+ @type="default"
25
+ @icon="pencil"
26
+ @text={{t "storefront.common.edit"}}
27
+ @onClick={{fn this.editCatalog catalog}}
28
+ @permission="storefront update food-truck"
29
+ @size="sm"
30
+ />
31
+ <Button
32
+ @type="danger"
33
+ @icon="trash"
34
+ @text={{t "storefront.common.delete"}}
35
+ @onClick={{fn this.deleteCatalog catalog}}
36
+ @permission="storefront delete food-truck"
37
+ @size="sm"
38
+ />
39
+ </div>
40
+ </div>
41
+ {{/each}}
42
+ </div>
43
+ </div>
44
+ </Layout::Section::Body>
45
+
46
+ {{outlet}}
@@ -0,0 +1 @@
1
+ {{outlet}}
@@ -1,4 +1,4 @@
1
- <Layout::Section::Header @title={{t "storefront.common.customer"}} @searchQuery={{this.query}} @onSearch={{perform this.search}}>
1
+ <Layout::Section::Header @title={{t "storefront.common.customers"}} @searchQuery={{this.query}} @onSearch={{perform this.search}}>
2
2
  <FiltersPicker
3
3
  @columns={{this.columns}}
4
4
  @onApply={{fn this.filters.apply this}}
@@ -0,0 +1,52 @@
1
+ <Layout::Section::Header @title={{t "storefront.common.food-trucks"}}>
2
+ <Button @type="primary" @icon="plus" @text={{t "storefront.common.new"}} @onClick={{this.createFoodTruck}} @permission="storefront create food-truck" class="mr-2" />
3
+ <Button @icon="long-arrow-up" @iconClass="rotate-icon-45" @text={{t "storefront.common.export"}} @permission="storefront export food-truck" />
4
+ </Layout::Section::Header>
5
+
6
+ <Layout::Section::Body>
7
+ <div class="p-4">
8
+ <div class="grid grid-cols-3 gap-4">
9
+ {{#each @model as |foodTruck|}}
10
+ <div class="px-2 py-2 border rounded-lg dark:bg-gray-800 dark:border-gray-700 border-gray-200 bg-gray-100">
11
+ <div class="flex flex-row mb-2">
12
+ <div class="mr-2">
13
+ <Image src={{foodTruck.vehicle.photo_url}} class="w-14 h-14 rounded-md shadow-sm" />
14
+ </div>
15
+ <div class="flex flex-col flex-1">
16
+ <div class="text-sm font-semibold mb-0.5">{{foodTruck.vehicle.display_name}}</div>
17
+ <div class="flex flex-row items-center space-x-1">
18
+ <FaIcon @icon="draw-polygon" class="mr-1" />
19
+ <div class="text-sm">{{n-a foodTruck.service_area.name}}</div>
20
+ <div>•</div>
21
+ <div class="text-sm">{{n-a foodTruck.zone.name}}</div>
22
+ </div>
23
+ {{!-- <div>{{format-point foodTruck.vehicle.location}}</div> --}}
24
+ <Badge @status={{foodTruck.status}} @hideStatusDot={{true}} />
25
+ </div>
26
+ </div>
27
+ <div class="mt-2 flex flex-row space-x-2">
28
+ <Button
29
+ @type="default"
30
+ @icon="pencil"
31
+ @text={{t "storefront.common.edit"}}
32
+ @onClick={{fn this.editFoodTruck foodTruck}}
33
+ @permission="storefront update food-truck"
34
+ @size="xs"
35
+ />
36
+ <Button @type="default" @icon="square-check" @text="Catalogs" @onClick={{fn this.assignCatalogs foodTruck}} @permission="storefront update food-truck" @size="xs" />
37
+ <Button
38
+ @type="danger"
39
+ @icon="trash"
40
+ @text={{t "storefront.common.delete"}}
41
+ @onClick={{fn this.deleteFoodTruck foodTruck}}
42
+ @permission="storefront delete food-truck"
43
+ @size="xs"
44
+ />
45
+ </div>
46
+ </div>
47
+ {{/each}}
48
+ </div>
49
+ </div>
50
+ </Layout::Section::Body>
51
+
52
+ {{outlet}}
@@ -0,0 +1 @@
1
+ {{outlet}}
@@ -26,13 +26,25 @@
26
26
  </div>
27
27
  <div class="next-dd-menu-seperator"></div>
28
28
  <div role="group" class="px-1">
29
- <a href="javascript:;" class="next-dd-item" role="menuitem" {{on "click" (dropdown-fn dd this.manageNetwork network)}} disabled={{cannot "storefront view network"}}>
29
+ <a
30
+ href="javascript:;"
31
+ class="next-dd-item"
32
+ role="menuitem"
33
+ {{on "click" (dropdown-fn dd this.manageNetwork network)}}
34
+ disabled={{cannot "storefront view network"}}
35
+ >
30
36
  <div class="w-7">
31
37
  <FaIcon @icon="network-wired" class="mr-2" />
32
38
  </div>
33
39
  <span>{{t "storefront.networks.index.manage-network"}}</span>
34
40
  </a>
35
- <a href="javascript:;" class="next-dd-item" role="menuitem" {{on "click" (dropdown-fn dd this.sendInvites network)}} disabled={{cannot "storefront update network"}}>
41
+ <a
42
+ href="javascript:;"
43
+ class="next-dd-item"
44
+ role="menuitem"
45
+ {{on "click" (dropdown-fn dd this.sendInvites network)}}
46
+ disabled={{cannot "storefront update network"}}
47
+ >
36
48
  <div class="w-7">
37
49
  <FaIcon @icon="envelope-open-text" class="mr-2" />
38
50
  </div>
@@ -24,7 +24,14 @@
24
24
  <Textarea @value={{this.product.description}} class="form-input w-full" placeholder="Enter a description of your product...." disabled={{unauthorized}} rows={{4}} />
25
25
  </InputGroup>
26
26
  <InputGroup @name="Product Status">
27
- <Select class="w-full" @value={{this.product.status}} @placeholder="Select product status" @options={{this.statusOptions}} @onSelect={{fn (mut this.product.status)}} @humanize={{true}} />
27
+ <Select
28
+ class="w-full"
29
+ @value={{this.product.status}}
30
+ @placeholder="Select product status"
31
+ @options={{this.statusOptions}}
32
+ @onSelect={{fn (mut this.product.status)}}
33
+ @humanize={{true}}
34
+ />
28
35
  </InputGroup>
29
36
  <InputGroup @name="Product Tags">
30
37
  <TagInput
@@ -275,8 +282,8 @@
275
282
  </div>
276
283
  </ContentPanel>
277
284
 
278
- <ContentPanel @title="Availability" @open={{this.product.hours.length}} @pad={{false}} @panelBodyWrapperClass="px-0 py-4" @panelBodyClass="bg-white dark:bg-gray-800">
279
- <div class="px-4 py-3">
285
+ <ContentPanel @title="Availability" @open={{this.product.hours.length}} @pad={{false}} @panelBodyClass="bg-white dark:bg-gray-800">
286
+ <div class="p-2">
280
287
  <ScheduleManager
281
288
  @subject={{this.product}}
282
289
  @subjectKey="product_uuid"
@@ -1,13 +1,12 @@
1
1
  <Layout::Section::Header @title="All Products" @searchQuery={{this.query}} @onSearch={{perform this.search}} />
2
2
 
3
3
  <Layout::Section::Body class="h-full overflow-y-scroll p-6">
4
-
5
4
  <div class="grid grid-cols-2 md:grid-cols-4 gap-4">
6
5
  {{#each @model as |product|}}
7
6
  <div class="border border-gray-200 bg-white dark:bg-gray-900 dark:text-gray-100 dark:border-gray-700 text-center rounded-md px-2 py-3">
8
7
  <div class="flex flex-col items-center justify-center overflow-hidden">
9
8
  <div class="mb-3 flex items-center justify-center">
10
- <img src={{product.primary_image_url}} alt={{product.name}} class="w-24 h-24" />
9
+ <Image src={{product.primary_image_url}} alt={{product.name}} class="w-24 h-24" />
11
10
  </div>
12
11
  <h4 class="font-semibold mb-1">{{product.name}}</h4>
13
12
  <p class="text-sm truncate">{{product.description}}</p>
@@ -1,5 +1,12 @@
1
1
  <Layout::Section::Header @title={{t "storefront.common.product"}}>
2
- <Button @type="magic" @icon="tags" @text={{t "storefront.products.index.manage-addons"}} class="mr-2 flex-shrink-0" @permission="storefront list product-addon" @onClick={{this.manageAddons}} />
2
+ <Button
3
+ @type="magic"
4
+ @icon="tags"
5
+ @text={{t "storefront.products.index.manage-addons"}}
6
+ class="mr-2 flex-shrink-0"
7
+ @permission="storefront list product-addon"
8
+ @onClick={{this.manageAddons}}
9
+ />
3
10
  <Button
4
11
  @type="primary"
5
12
  @icon="plus"
@@ -11,7 +18,14 @@
11
18
  @permission="storefront create product"
12
19
  class="mr-2 flex-shrink-0"
13
20
  />
14
- <Button @icon="file-import" @text={{t "storefront.common.import"}} class="mr-2" @wrapperClass="hidden lg:flex flex-shrink-0" @permission="storefront import product" @onClick={{this.importProducts}} />
21
+ <Button
22
+ @icon="file-import"
23
+ @text={{t "storefront.common.import"}}
24
+ class="mr-2"
25
+ @wrapperClass="hidden lg:flex flex-shrink-0"
26
+ @permission="storefront import product"
27
+ @onClick={{this.importProducts}}
28
+ />
15
29
  <Button @icon="long-arrow-up" @iconClass="rotate-icon-45" @wrapperClass="hidden lg:flex flex-shrink-0" @permission="storefront export product" @text={{t "storefront.common.export"}} />
16
30
  </Layout::Section::Header>
17
31
 
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/storefront-engine/adapters/catalog';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/storefront-engine/adapters/food-truck';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/storefront-engine/components/modals/assign-food-truck-catalogs';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/storefront-engine/components/modals/create-catalog';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/storefront-engine/components/modals/create-food-truck';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/storefront-engine/controllers/catalogs/index';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/storefront-engine/controllers/food-trucks/index';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/storefront-engine/models/catalog-category';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/storefront-engine/models/catalog-hour';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/storefront-engine/models/catalog';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/storefront-engine/models/food-truck';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/storefront-engine/routes/catalogs/index';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/storefront-engine/routes/catalogs';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/storefront-engine/routes/food-trucks/index';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/storefront-engine/routes/food-trucks';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/storefront-engine/serializers/catalog-category';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/storefront-engine/serializers/catalog';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/storefront-engine/serializers/food-truck';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/storefront-engine/templates/catalogs/index';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/storefront-engine/templates/catalogs';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/storefront-engine/templates/food-trucks/index';
@@ -0,0 +1 @@
1
+ export { default } from '@fleetbase/storefront-engine/templates/food-trucks';
package/composer.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fleetbase/storefront-api",
3
- "version": "0.3.24",
3
+ "version": "0.3.26",
4
4
  "description": "Headless Commerce & Marketplace Extension for Fleetbase",
5
5
  "keywords": [
6
6
  "fleetbase-extension",
package/extension.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "Storefront",
3
- "version": "0.3.24",
3
+ "version": "0.3.26",
4
4
  "description": "Headless Commerce & Marketplace Extension for Fleetbase",
5
5
  "repository": "https://github.com/fleetbase/storefront",
6
6
  "license": "AGPL-3.0-or-later",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fleetbase/storefront-engine",
3
- "version": "0.3.24",
3
+ "version": "0.3.26",
4
4
  "description": "Headless Commerce & Marketplace Extension for Fleetbase",
5
5
  "fleetbase": {
6
6
  "route": "storefront",