@shopbite-de/storefront 1.18.2 → 1.18.4

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/app/app.vue CHANGED
@@ -89,14 +89,8 @@ if (import.meta.client) {
89
89
  }
90
90
  }
91
91
 
92
- const { refresh: refreshToppings } = useShopBiteConfig();
93
-
94
92
  onMounted(async () => {
95
- await Promise.all([
96
- refreshHolidays(),
97
- refreshBusinessHours(),
98
- refreshToppings(),
99
- ]);
93
+ await Promise.all([refreshHolidays(), refreshBusinessHours()]);
100
94
  refreshCart();
101
95
  displayStoreStatus();
102
96
  });
@@ -159,61 +159,61 @@ const moreThanOneFilterAndOption = computed<boolean>(
159
159
  :items="getSortingOrders"
160
160
  placeholder="Sortierung"
161
161
  />
162
- <UDrawer
163
- v-if="moreThanOneFilterAndOption"
164
- class="lg:hidden"
165
- title="Filter"
166
- direction="right"
167
- >
168
- <UButton
169
- label="Filter"
170
- icon="i-lucide-sliders-horizontal"
171
- color="neutral"
172
- variant="subtle"
173
- />
162
+ <ClientOnly v-if="moreThanOneFilterAndOption">
163
+ <UDrawer class="lg:hidden" title="Filter" direction="right">
164
+ <UButton
165
+ label="Filter"
166
+ icon="i-lucide-sliders-horizontal"
167
+ color="neutral"
168
+ variant="subtle"
169
+ />
174
170
 
175
- <template #body>
176
- <div class="flex flex-col gap-4">
177
- <div
178
- v-for="filter in propertyFilters"
179
- :key="filter.id"
180
- class="flex flex-col gap-4"
181
- >
182
- <UCollapsible
183
- class="flex flex-col gap-2 w-48"
184
- :default-open="true"
171
+ <template #body>
172
+ <div class="flex flex-col gap-4">
173
+ <div
174
+ v-for="filter in propertyFilters"
175
+ :key="filter.id"
176
+ class="flex flex-col gap-4"
185
177
  >
186
- <UButton
187
- :label="filter.translated.name"
188
- color="neutral"
189
- variant="subtle"
190
- trailing-icon="i-lucide-chevron-down"
191
- block
192
- :ui="{
193
- trailingIcon:
194
- 'group-data-[state=open]:rotate-180 transition-transform duration-200',
195
- }"
196
- />
197
-
198
- <template #content>
199
- <UCheckboxGroup
200
- v-model="selectedPropertyFilters"
201
- :items="filter.options"
202
- value-key="id"
203
- label-key="translated.name"
178
+ <UCollapsible
179
+ class="flex flex-col gap-2 w-48"
180
+ :default-open="true"
181
+ >
182
+ <UButton
183
+ :label="filter.translated.name"
184
+ color="neutral"
185
+ variant="subtle"
186
+ trailing-icon="i-lucide-chevron-down"
187
+ block
188
+ :ui="{
189
+ trailingIcon:
190
+ 'group-data-[state=open]:rotate-180 transition-transform duration-200',
191
+ }"
204
192
  />
205
- </template>
206
- </UCollapsible>
193
+
194
+ <template #content>
195
+ <UCheckboxGroup
196
+ v-model="selectedPropertyFilters"
197
+ :items="filter.options"
198
+ value-key="id"
199
+ label-key="translated.name"
200
+ />
201
+ </template>
202
+ </UCollapsible>
203
+ </div>
204
+ <UButton
205
+ label="Zurücksetzen"
206
+ variant="outline"
207
+ block
208
+ @click="handleFilterRest"
209
+ />
207
210
  </div>
208
- <UButton
209
- label="Zurücksetzten"
210
- variant="outline"
211
- block
212
- @click="handleFilterRest"
213
- />
214
- </div>
211
+ </template>
212
+ </UDrawer>
213
+ <template #fallback>
214
+ <USkeleton class="h-8 w-20 lg:hidden" />
215
215
  </template>
216
- </UDrawer>
216
+ </ClientOnly>
217
217
  </div>
218
218
 
219
219
  <div
@@ -243,46 +243,64 @@ const moreThanOneFilterAndOption = computed<boolean>(
243
243
 
244
244
  <template #right>
245
245
  <UPageAside>
246
- <div v-if="moreThanOneFilterAndOption" class="flex flex-col gap-4">
247
- <h2 class="text-3xl md:text-4xl mb-3 pb-2">Filter</h2>
248
- <div
249
- v-for="filter in propertyFilters"
250
- :key="filter.id"
251
- class="flex flex-col gap-4"
252
- >
253
- <UCollapsible
254
- class="flex flex-col gap-2 w-48"
255
- :default-open="true"
246
+ <ClientOnly v-if="moreThanOneFilterAndOption">
247
+ <div class="flex flex-col gap-4">
248
+ <h2 class="text-3xl md:text-4xl mb-3 pb-2">Filter</h2>
249
+ <div
250
+ v-for="filter in propertyFilters"
251
+ :key="filter.id"
252
+ class="flex flex-col gap-4"
256
253
  >
257
- <UButton
258
- :label="filter.translated.name"
259
- color="neutral"
260
- variant="subtle"
261
- trailing-icon="i-lucide-chevron-down"
262
- block
263
- :ui="{
264
- trailingIcon:
265
- 'group-data-[state=open]:rotate-180 transition-transform duration-200',
266
- }"
267
- />
268
-
269
- <template #content>
270
- <UCheckboxGroup
271
- v-model="selectedPropertyFilters"
272
- :items="filter.options"
273
- value-key="id"
274
- label-key="translated.name"
254
+ <UCollapsible
255
+ class="flex flex-col gap-2 w-48"
256
+ :default-open="true"
257
+ >
258
+ <UButton
259
+ :label="filter.translated.name"
260
+ color="neutral"
261
+ variant="subtle"
262
+ trailing-icon="i-lucide-chevron-down"
263
+ block
264
+ :ui="{
265
+ trailingIcon:
266
+ 'group-data-[state=open]:rotate-180 transition-transform duration-200',
267
+ }"
275
268
  />
276
- </template>
277
- </UCollapsible>
269
+
270
+ <template #content>
271
+ <UCheckboxGroup
272
+ v-model="selectedPropertyFilters"
273
+ :items="filter.options"
274
+ value-key="id"
275
+ label-key="translated.name"
276
+ />
277
+ </template>
278
+ </UCollapsible>
279
+ </div>
280
+ <UButton
281
+ label="Zurücksetzen"
282
+ variant="outline"
283
+ block
284
+ @click="handleFilterRest"
285
+ />
278
286
  </div>
279
- <UButton
280
- label="Zurücksetzten"
281
- variant="outline"
282
- block
283
- @click="handleFilterRest"
284
- />
285
- </div>
287
+ <template #fallback>
288
+ <div class="flex flex-col gap-4">
289
+ <USkeleton class="h-9 w-20" />
290
+ <div class="flex flex-col gap-2">
291
+ <USkeleton class="h-8 w-48" />
292
+ <USkeleton class="h-4 w-36" />
293
+ <USkeleton class="h-4 w-32" />
294
+ <USkeleton class="h-4 w-40" />
295
+ </div>
296
+ <div class="flex flex-col gap-2">
297
+ <USkeleton class="h-8 w-48" />
298
+ <USkeleton class="h-4 w-36" />
299
+ <USkeleton class="h-4 w-32" />
300
+ </div>
301
+ </div>
302
+ </template>
303
+ </ClientOnly>
286
304
  </UPageAside>
287
305
  </template>
288
306
  </UPage>
@@ -110,7 +110,7 @@ const dropDownMenu = computed<DropdownMenuItem[][]>(() => {
110
110
  />
111
111
  </UChip>
112
112
  </div>
113
- <UDrawer
113
+ <LazyUDrawer
114
114
  v-if="isCheckoutEnabled"
115
115
  v-model:open="cartQuickViewOpen"
116
116
  title="Warenkorb"
@@ -140,5 +140,5 @@ const dropDownMenu = computed<DropdownMenuItem[][]>(() => {
140
140
  @go-to-cart="cartQuickViewOpen = false"
141
141
  />
142
142
  </template>
143
- </UDrawer>
143
+ </LazyUDrawer>
144
144
  </template>
@@ -26,19 +26,32 @@ defineProps<{
26
26
  :links="links"
27
27
  >
28
28
  <template #body>
29
- <UCarousel
30
- v-slot="{ item, index }"
31
- arrows
32
- :items="images"
33
- class="w-full max-w-2xl mx-auto"
34
- >
35
- <img
36
- :src="item.image"
37
- :alt="item.alt"
38
- :fetchpriority="index === 0 ? 'high' : 'auto'"
39
- class="rounded-lg"
40
- />
41
- </UCarousel>
29
+ <ClientOnly>
30
+ <UCarousel
31
+ v-slot="{ item, index }"
32
+ arrows
33
+ :items="images"
34
+ class="w-full max-w-2xl mx-auto"
35
+ >
36
+ <img
37
+ :src="item.image"
38
+ :alt="item.alt"
39
+ :fetchpriority="index === 0 ? 'high' : 'auto'"
40
+ class="rounded-lg"
41
+ />
42
+ </UCarousel>
43
+ <template #fallback>
44
+ <div class="w-full max-w-2xl mx-auto">
45
+ <img
46
+ v-if="images?.[0]"
47
+ :src="images[0].image"
48
+ :alt="images[0].alt"
49
+ fetchpriority="high"
50
+ class="rounded-lg"
51
+ />
52
+ </div>
53
+ </template>
54
+ </ClientOnly>
42
55
  </template>
43
56
  </UPageSection>
44
57
  </template>
@@ -1,31 +1,16 @@
1
- import { useContext, useShopwareContext } from "#imports";
2
- import type { Schemas } from "#shopware";
3
-
4
- type useShopBiteConfigReturn = {
5
- deliveryTime: ComputedRef<number>;
6
- isCheckoutEnabled: ComputedRef<boolean>;
7
- refresh(): Promise<Schemas["ShopBiteConfig"]>;
8
- };
9
-
10
- export function useShopBiteConfig(): useShopBiteConfigReturn {
1
+ export function useShopBiteConfig() {
11
2
  const { apiClient } = useShopwareContext();
12
3
 
13
- const _deliveryTime = useContext<number>("deliveryTime");
14
- const _isCheckoutEnabled = useContext<boolean>("isCheckoutActive");
15
-
16
- async function refresh(): Promise<Schemas["ShopBiteConfig"]> {
4
+ const { data, refresh } = useAsyncData("shopbite-config", async () => {
17
5
  const { data } = await apiClient.invoke(
18
6
  "shopbite.config.get get /shopbite/config",
19
7
  );
20
- _deliveryTime.value = data.deliveryTime;
21
- _isCheckoutEnabled.value = data.isCheckoutEnabled;
22
-
23
8
  return data;
24
- }
9
+ });
25
10
 
26
11
  return {
27
- deliveryTime: computed(() => _deliveryTime.value),
28
- isCheckoutEnabled: computed(() => _isCheckoutEnabled.value),
12
+ deliveryTime: computed(() => data.value?.deliveryTime ?? 30),
13
+ isCheckoutEnabled: computed(() => data.value?.isCheckoutEnabled ?? false),
29
14
  refresh,
30
15
  };
31
16
  }
package/nuxt.config.ts CHANGED
@@ -104,7 +104,6 @@ export default defineNuxtConfig({
104
104
  "nuxt-vitalizer",
105
105
  "@nuxt/eslint",
106
106
  "@pinia/nuxt",
107
- "@nuxt/hints",
108
107
  ],
109
108
 
110
109
  content: {
@@ -202,6 +201,7 @@ export default defineNuxtConfig({
202
201
  "@nuxt/scripts",
203
202
  "@nuxt/test-utils/module",
204
203
  "@nuxt/eslint",
204
+ "@nuxt/hints",
205
205
  ],
206
206
  },
207
207
  $production: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shopbite-de/storefront",
3
- "version": "1.18.2",
3
+ "version": "1.18.4",
4
4
  "main": "nuxt.config.ts",
5
5
  "description": "Shopware storefront for food delivery shops",
6
6
  "keywords": [
@@ -23,7 +23,6 @@
23
23
  "@iconify-json/lucide": "^1.2.97",
24
24
  "@iconify-json/simple-icons": "^1.2.73",
25
25
  "@nuxt/content": "3.12.0",
26
- "@nuxt/hints": "1.0.2",
27
26
  "@nuxt/image": "^2.0.0",
28
27
  "@nuxt/scripts": "0.13.2",
29
28
  "@nuxt/ui": "^4.5.1",
@@ -45,6 +44,7 @@
45
44
  "uuid": "^13.0.0"
46
45
  },
47
46
  "devDependencies": {
47
+ "@nuxt/hints": "1.0.2",
48
48
  "@iconify-json/heroicons": "^1.2.3",
49
49
  "@iconify-json/hugeicons": "^1.2.23",
50
50
  "@nuxt/devtools-kit": "^3.2.3",
@@ -1,14 +1,11 @@
1
1
  import { describe, it, expect, vi, beforeEach } from "vitest";
2
2
  import { mockNuxtImport } from "@nuxt/test-utils/runtime";
3
+ import { ref } from "vue";
3
4
  import { useShopBiteConfig } from "~/composables/useShopBiteConfig";
4
5
 
5
- const { mockInvoke, mockDeliveryTime, mockIsCheckoutEnabled } = vi.hoisted(
6
- () => ({
7
- mockInvoke: vi.fn(),
8
- mockDeliveryTime: { value: 0 },
9
- mockIsCheckoutEnabled: { value: false },
10
- }),
11
- );
6
+ const { mockInvoke } = vi.hoisted(() => ({
7
+ mockInvoke: vi.fn(),
8
+ }));
12
9
 
13
10
  mockNuxtImport("useShopwareContext", () => () => ({
14
11
  apiClient: {
@@ -16,25 +13,26 @@ mockNuxtImport("useShopwareContext", () => () => ({
16
13
  },
17
14
  }));
18
15
 
19
- mockNuxtImport("useContext", () => (key: string) => {
20
- if (key === "deliveryTime") return mockDeliveryTime;
21
- if (key === "isCheckoutActive") return mockIsCheckoutEnabled;
22
- return { value: null };
23
- });
16
+ mockNuxtImport(
17
+ "useAsyncData",
18
+ () => (_key: string, fetcher: () => Promise<unknown>) => {
19
+ const data = ref<unknown>(null);
20
+ const refresh = async () => {
21
+ data.value = await fetcher();
22
+ };
23
+ return { data, refresh };
24
+ },
25
+ );
24
26
 
25
27
  describe("useShopBiteConfig", () => {
26
28
  beforeEach(() => {
27
29
  vi.clearAllMocks();
28
- mockDeliveryTime.value = 0;
29
- mockIsCheckoutEnabled.value = false;
30
30
  });
31
31
 
32
- it("should initialize with values from context", () => {
33
- mockDeliveryTime.value = 30;
34
- mockIsCheckoutEnabled.value = true;
32
+ it("should return default values when no data is loaded", () => {
35
33
  const { deliveryTime, isCheckoutEnabled } = useShopBiteConfig();
36
34
  expect(deliveryTime.value).toBe(30);
37
- expect(isCheckoutEnabled.value).toBe(true);
35
+ expect(isCheckoutEnabled.value).toBe(false);
38
36
  });
39
37
 
40
38
  it("should refresh values from API", async () => {
@@ -53,7 +51,5 @@ describe("useShopBiteConfig", () => {
53
51
  );
54
52
  expect(deliveryTime.value).toBe(45);
55
53
  expect(isCheckoutEnabled.value).toBe(true);
56
- expect(mockDeliveryTime.value).toBe(45);
57
- expect(mockIsCheckoutEnabled.value).toBe(true);
58
54
  });
59
55
  });