@meeovi/layer-departments 1.0.0

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 (32) hide show
  1. package/app/components/categories/adultstore.vue +123 -0
  2. package/app/components/categories/chart/[id].vue +254 -0
  3. package/app/components/categories/chart/add-chart.vue +142 -0
  4. package/app/components/categories/chart/chart.vue +82 -0
  5. package/app/components/categories/chart/monthlyChart.vue +46 -0
  6. package/app/components/categories/chart/musicchart.vue +35 -0
  7. package/app/components/categories/chart/update-chart.vue +278 -0
  8. package/app/components/categories/chart/weeklyChart.vue +46 -0
  9. package/app/components/categories/chart/yearlyChart.vue +46 -0
  10. package/app/components/categories/charts.vue +118 -0
  11. package/app/components/categories/deals.vue +101 -0
  12. package/app/components/categories/eats.vue +49 -0
  13. package/app/components/categories/restaurants.vue +77 -0
  14. package/app/components/categories/station/[id].vue +72 -0
  15. package/app/components/categories/stations.vue +124 -0
  16. package/app/components/categories/time/features/alarms.vue +276 -0
  17. package/app/components/categories/time/features/bedtime.vue +12 -0
  18. package/app/components/categories/time/features/stopwatch.vue +109 -0
  19. package/app/components/categories/time/features/timer.vue +191 -0
  20. package/app/components/categories/time/time.vue +63 -0
  21. package/app/components/categories/travel.vue +75 -0
  22. package/app/components/categories/weather/weather.vue +44 -0
  23. package/app/components/related/relatedcharts.vue +39 -0
  24. package/app/components/related/short.vue +207 -0
  25. package/app/components/related/space.vue +79 -0
  26. package/app/pages/departments/[...slug].vue +385 -0
  27. package/app/pages/departments/category/[...slug].vue +135 -0
  28. package/dist/nuxt.config.d.ts +2 -0
  29. package/dist/nuxt.config.js +7 -0
  30. package/nuxt.config.ts +11 -0
  31. package/package.json +35 -0
  32. package/tsconfig.json +14 -0
@@ -0,0 +1,79 @@
1
+ <template>
2
+ <div>
3
+ <div class="card card-1 col-12 col-lg-6" :style="`backgroundImage: url(${$directus.url}assets/${space?.image?.filename_disk})`">
4
+ <div class="card-wrap">
5
+ <div class="item-content">
6
+ <h5 class="card-title-1 mbr-fonts-style align-center display-7">
7
+ <strong>{{ space?.type }}</strong>
8
+ </h5>
9
+ <h6 class="card-subtitle-1 mb-0 mbr-fonts-style align-center display-2">
10
+ <strong>
11
+ {{ space?.name }}
12
+ </strong>
13
+ </h6>
14
+ <p class="card-text-1 mbr-fonts-style align-center mb-0 display-7">Created: {{ new Date(space?.date_created).toLocaleDateString() }}</p>
15
+ <p class="card-text-1 mbr-fonts-style align-center mb-0 display-7">
16
+ {{ space?.description }}
17
+ </p>
18
+ <div class="mbr-section-btn mbr-section-btn-1 align-center">
19
+ <NuxtLink :href="`/social/group/${space?.id}`" class="btn btn-danger display-7" target="_blank">
20
+ <span class="mobi-mbri mobi-mbri-arrow-next mbr-iconfont mbr-iconfont-btn"></span>
21
+ Learn More
22
+ </NuxtLink>
23
+ </div>
24
+ </div>
25
+ </div>
26
+ </div>
27
+ </div>
28
+ </template>
29
+
30
+ <script setup>
31
+ import {
32
+ ref
33
+ } from 'vue'
34
+
35
+ const {
36
+ $directus
37
+ } = useNuxtApp()
38
+
39
+ const props = defineProps({
40
+ space: {
41
+ type: Object,
42
+ required: true,
43
+ },
44
+ })
45
+
46
+ const {
47
+ space
48
+ } = props
49
+
50
+ const getTypeColor = (type) => {
51
+ const colors = {
52
+ 'Audio': 'purple',
53
+ 'Video': 'red',
54
+ 'Text': 'blue',
55
+ 'Mixed': 'green'
56
+ }
57
+ return colors[type] || 'grey'
58
+ }
59
+
60
+ const formatDate = (dateString) => {
61
+ if (!dateString) return 'Unknown date'
62
+ return new Date(dateString).toLocaleDateString('en-US', {
63
+ year: 'numeric',
64
+ month: 'short',
65
+ day: 'numeric'
66
+ })
67
+ }
68
+
69
+ const joinSpace = async () => {
70
+ // TODO: Implement join space functionality
71
+ console.log('Joining space:', space.id)
72
+ }
73
+
74
+ const shareSpace = () => {
75
+ const url = `${window.location.origin}/social/group/${space.id}`
76
+ navigator.clipboard.writeText(url)
77
+ console.log('Space link copied to clipboard')
78
+ }
79
+ </script>
@@ -0,0 +1,385 @@
1
+ <template>
2
+ <div>
3
+ <div v-if="department?.name === 'Deals'">
4
+ <v-toolbar :style="`background-color: ${department?.color}; color: ${department?.colortext}`"
5
+ :title="department?.name"></v-toolbar>
6
+ <deals :category="department?.id" />
7
+ </div>
8
+
9
+ <div v-else>
10
+ <v-card variant="text">
11
+ <v-toolbar :style="`background-color: ${department?.color}; color: ${department?.colortext}`"
12
+ :title="department?.name">
13
+ <v-slide-group show-arrows v-if="department?.categories?.length">
14
+ <v-slide-group-item v-slot="{ isSelected, toggle }">
15
+ <v-menu>
16
+ <template v-slot:activator="{ props }">
17
+ <v-btn :color="isSelected ? 'primary' : undefined" class="ma-2" @click="toggle"
18
+ v-bind="props" append-icon="fas:fa fa-caret-down" variant="text">
19
+ Categories
20
+ </v-btn>
21
+ </template>
22
+ <v-list class="departmentMenu">
23
+ <v-row>
24
+ <v-col cols="3" v-for="categories in department?.categories"
25
+ :key="categories?.id">
26
+ <v-list-item>
27
+ <v-chip><NuxtLink
28
+ :to="`/departments/category/${categories?.categories_id?.slug}`">
29
+ {{ categories?.categories_id?.name }}</NuxtLink></v-chip>
30
+ </v-list-item>
31
+ </v-col>
32
+ </v-row>
33
+ </v-list>
34
+ </v-menu>
35
+ </v-slide-group-item>
36
+
37
+ <v-slide-group-item v-if="department?.menus?.length" v-for="menu in department?.menus"
38
+ :key="menu" v-slot="{ isSelected, toggle }">
39
+ <v-btn :color="isSelected ? 'primary' : undefined" class="ma-2" @click="toggle"
40
+ :href="`${menu?.url}`">
41
+ {{ menu?.name }}
42
+ </v-btn>
43
+ </v-slide-group-item>
44
+ </v-slide-group>
45
+ </v-toolbar>
46
+
47
+ <!--Department Top Banner Section-->
48
+ <section data-bs-version="5.1" class="pricing6 shopm5 cid-tZY31Y2JxZ" id="apricing6-6g">
49
+
50
+ <div class="mbr-overlay"></div>
51
+ <div class="container-fluid">
52
+ <div class="row align-items-stretch items-row justify-content-center">
53
+
54
+ <div class="col-lg-6">
55
+ <div v-if="department?.name === 'Travel'">
56
+ <travel :category="department?.name" />
57
+ </div>
58
+ <!--<div v-else-if="department?.name === 'Appstore'">
59
+ <appstore :category="department?.name" />
60
+ </div>-->
61
+ <div v-else-if="department?.name === 'Weather'">
62
+ <weather :category="department?.name" />
63
+ </div>
64
+
65
+ <div v-else-if="department?.name === 'Time'">
66
+ <timeComponent :category="department?.name" />
67
+ </div>
68
+
69
+ <div v-else class="mbr-section-head" :style="`background-color: ${department?.color}`">
70
+ <h4 class="mbr-section-title mbr-fonts-style mb-0 display-7"
71
+ :style="`color: ${department?.colortext}`">
72
+ <strong>Meeovi</strong>
73
+ </h4>
74
+ <h5 class="mbr-section-subtitle mbr-fonts-style mb-0 display-2"
75
+ :style="`color: ${department?.colortext}`">
76
+ <strong>{{ department?.name }}</strong>
77
+ </h5>
78
+ <h5 class="main-text mbr-fonts-style mb-0 display-7"
79
+ :style="`color: ${department?.colortext}`">
80
+ {{ department?.description }}
81
+ </h5>
82
+ </div>
83
+ </div>
84
+
85
+ <v-sheet
86
+ class="mx-auto col-lg-6" style="background-color: transparent; box-shadow: none;">
87
+ <h4 style="left: 15px; position: relative;">{{ callouts?.menus?.[1]?.name }}</h4>
88
+ <v-slide-group v-model="model" class="pa-4" selected-class="bg-success" show-arrows>
89
+ <v-slide-group-item v-slot="{ isSelected, toggle, selectedClass }"
90
+ v-for="products in department?.products" :key="products">
91
+ <productCard :product="products?.products_id" :class="['ma-4', selectedClass]"
92
+ @click="toggle" />
93
+ <div class="d-flex fill-height align-center justify-center">
94
+ <v-scale-transition>
95
+ <v-icon v-if="isSelected" color="white" icon="mdi-close-circle-outline"
96
+ size="48"></v-icon>
97
+ </v-scale-transition>
98
+ </div>
99
+ </v-slide-group-item>
100
+ </v-slide-group>
101
+ </v-sheet>
102
+ </div>
103
+ </div>
104
+ </section>
105
+
106
+ <!--Department Content Section-->
107
+ <section data-bs-version="5.1" class="gallery2 shopm5 cid-uW1BojE78S" id="agallery2-0" v-if="department?.shorts?.length && department?.products?.products_id?.type === 'department'"
108
+ :style="`background-image: url(${$directus?.url}assets/${department?.image?.filename_disk})`">
109
+ <div class="mbr-overlay" style="opacity: 0.8; background-color: rgb(255, 255, 255);">
110
+ </div>
111
+
112
+ <div class="container-fluid">
113
+ <div class="row">
114
+ <!--Vibez Slider-->
115
+ <v-sheet
116
+ class="mx-auto sliderProducts row align-items-stretch items-row justify-content-center">
117
+ <v-slide-group v-model="model" class="pa-4" selected-class="bg-success" show-arrows>
118
+ <v-slide-group-item v-slot="{ isSelected, toggle, selectedClass }"
119
+ v-for="shorts in department?.shorts" :key="shorts">
120
+ <shorts :short="shorts?.shorts_id" :class="['ma-4', selectedClass]"
121
+ @click="toggle" />
122
+ <div class="d-flex fill-height align-center justify-center">
123
+ <v-scale-transition>
124
+ <v-icon v-if="isSelected" color="white" icon="mdi-close-circle-outline"
125
+ size="48"></v-icon>
126
+ </v-scale-transition>
127
+ </div>
128
+ </v-slide-group-item>
129
+ </v-slide-group>
130
+ </v-sheet>
131
+ </div>
132
+ </div>
133
+ </section>
134
+
135
+ <v-row class="departmentRow">
136
+ <!--Best Seller Product Slider-->
137
+ <v-sheet class="mx-auto sliderProducts row align-items-stretch items-row justify-content-center">
138
+ <h4 style="left: 15px; position: relative;">{{ callouts?.menus?.[1]?.name }}</h4>
139
+ <v-slide-group v-model="model" class="pa-4" selected-class="bg-success" show-arrows>
140
+ <v-slide-group-item v-slot="{ isSelected, toggle, selectedClass }"
141
+ v-for="products in best?.products" :key="products">
142
+ <productCard :product="products?.products_id" :class="['ma-4', selectedClass]"
143
+ @click="toggle" />
144
+ <div class="d-flex fill-height align-center justify-center">
145
+ <v-scale-transition>
146
+ <v-icon v-if="isSelected" color="white" icon="mdi-close-circle-outline"
147
+ size="48"></v-icon>
148
+ </v-scale-transition>
149
+ </div>
150
+ </v-slide-group-item>
151
+ </v-slide-group>
152
+ </v-sheet>
153
+
154
+ <!--List of latest products in the department-->
155
+ <v-sheet class="mx-auto sliderProducts row align-items-stretch items-row justify-content-center">
156
+ <h4 style="left: 15px; position: relative;">{{ callouts?.menus?.[2]?.name }}</h4>
157
+ <v-slide-group v-model="model" class="pa-4" selected-class="bg-success" show-arrows>
158
+ <v-slide-group-item v-slot="{ isSelected, toggle, selectedClass }"
159
+ v-for="products in latestProducts?.products" :key="products">
160
+ <productCard :product="products?.products_id" :class="['ma-4', selectedClass]"
161
+ @click="toggle" />
162
+ <div class="d-flex fill-height align-center justify-center">
163
+ <v-scale-transition>
164
+ <v-icon v-if="isSelected" color="white" icon="mdi-close-circle-outline"
165
+ size="48"></v-icon>
166
+ </v-scale-transition>
167
+ </div>
168
+ </v-slide-group-item>
169
+ </v-slide-group>
170
+ </v-sheet>
171
+
172
+ <!--List of products in the department-->
173
+ <v-sheet class="mx-auto sliderProducts row align-items-stretch items-row justify-content-center">
174
+ <v-slide-group v-model="model" class="pa-4" selected-class="bg-success" show-arrows>
175
+ <v-slide-group-item v-slot="{ isSelected, toggle, selectedClass }"
176
+ v-for="products in department?.products" :key="products">
177
+ <productCard :product="products?.products_id" :class="['ma-4', selectedClass]"
178
+ @click="toggle" />
179
+ <div class="d-flex fill-height align-center justify-center">
180
+ <v-scale-transition>
181
+ <v-icon v-if="isSelected" color="white" icon="mdi-close-circle-outline"
182
+ size="48"></v-icon>
183
+ </v-scale-transition>
184
+ </div>
185
+ </v-slide-group-item>
186
+ </v-slide-group>
187
+ </v-sheet>
188
+
189
+ <!--List of events in this department-->
190
+ <v-sheet class="mx-auto sliderProducts row align-items-stretch items-row justify-content-center"
191
+ v-if="department?.products?.products_id?.type === 'department' && events?.length">
192
+ <h4 style="left: 15px; position: relative;">{{ callouts?.menus?.[3]?.name }}
193
+ {{ department?.name }}</h4>
194
+ <v-slide-group v-model="model" class="pa-4" selected-class="bg-success" show-arrows>
195
+ <v-slide-group-item v-slot="{ isSelected, toggle, selectedClass }"
196
+ v-for="products in events" :key="products">
197
+ <productCard :product="products?.events_id" :class="['ma-4', selectedClass]"
198
+ @click="toggle" />
199
+ <div class="d-flex fill-height align-center justify-center">
200
+ <v-scale-transition>
201
+ <v-icon v-if="isSelected" color="white" icon="mdi-close-circle-outline"
202
+ size="48"></v-icon>
203
+ </v-scale-transition>
204
+ </div>
205
+ </v-slide-group-item>
206
+ </v-slide-group>
207
+ </v-sheet>
208
+ <!---->
209
+
210
+ <!--List of spaces in the department-->
211
+ <v-sheet class="mx-auto sliderProducts row align-items-stretch items-row justify-content-center"
212
+ v-if="department?.spaces?.length">
213
+ <h4 style="left: 15px; position: relative;">{{ callouts?.menus?.[4]?.name }}
214
+ {{ department?.name }}</h4>
215
+ <v-slide-group v-model="model" class="pa-4" selected-class="bg-success" show-arrows>
216
+ <v-slide-group-item v-slot="{ isSelected, toggle, selectedClass }"
217
+ v-for="spaces in department?.spaces" :key="spaces">
218
+ <spaces :space="spaces?.spaces_id" :class="['ma-4', selectedClass]" @click="toggle" />
219
+ <div class="d-flex fill-height align-center justify-center">
220
+ <v-scale-transition>
221
+ <v-icon v-if="isSelected" color="white" icon="mdi-close-circle-outline"
222
+ size="48"></v-icon>
223
+ </v-scale-transition>
224
+ </div>
225
+ </v-slide-group-item>
226
+ </v-slide-group>
227
+ </v-sheet>
228
+ </v-row>
229
+ </v-card>
230
+ </div>
231
+ </div>
232
+ </template>
233
+
234
+ <script setup>
235
+ import shorts from '#social/app/components/related/short.vue'
236
+ import spaces from '#social/app/components/related/space.vue'
237
+ import productCard from '#commerce/app/components/catalog/product/productCard.vue'
238
+ import travel from '@/components/categories/travel.vue'
239
+ import deals from '@/components/categories/deals.vue'
240
+ import timeComponent from '@/components/categories/time/time.vue'
241
+ import weather from '@/components/categories/weather/weather.vue'
242
+
243
+ const route = useRoute()
244
+ const model = ref(null)
245
+ const {
246
+ $directus,
247
+ $readItem,
248
+ $readItems
249
+ } = useNuxtApp()
250
+
251
+ const slug = computed(() => {
252
+ const s = route.params.slug
253
+ return Array.isArray(s) ? s[0] : s
254
+ })
255
+
256
+ const {
257
+ data: departmentRaw
258
+ } = await useAsyncData('department', () => {
259
+ return $directus.request(
260
+ $readItems('departments', {
261
+ fields: [
262
+ '*',
263
+ 'categories.categories_id.*',
264
+ 'spaces.spaces_id.*',
265
+ 'products.products_id.*',
266
+ 'products.products_id.image.*',
267
+ 'shorts.shorts_id.*',
268
+ 'shops.shops_id.*',
269
+ 'image.*'
270
+ ],
271
+ filter: {
272
+ slug: {
273
+ _eq: slug.value
274
+ }
275
+ },
276
+ limit: 1
277
+ })
278
+ )
279
+ })
280
+
281
+ const department = computed(() => departmentRaw.value?.[0] || null)
282
+
283
+ const {
284
+ data: introProducts
285
+ } = await useAsyncData('introProducts', () => {
286
+ return $directus.request($readItems('departments', {
287
+ fields: ['*', { '*': ['*'] }],
288
+ limit: 2,
289
+ }))
290
+ })
291
+
292
+ const {
293
+ data: best
294
+ } = await useAsyncData('best', () => {
295
+ return $directus.request($readItems('departments', {
296
+ fields: ['*',
297
+ 'products.products_id.*',
298
+ 'images.*'
299
+ ],
300
+ limit: 10,
301
+ filter: {
302
+ showcases: {
303
+ showcases_id: {
304
+ name: {
305
+ _eq: "Best Sellers"
306
+ }
307
+ }
308
+ },
309
+ }
310
+ }))
311
+ })
312
+
313
+ const {
314
+ data: latestProducts
315
+ } = await useAsyncData('latestProducts', () => {
316
+ return $directus.request($readItems('departments', {
317
+ fields: ['*',
318
+ 'products.products_id.*',
319
+ 'images.*'
320
+ ],
321
+ limit: 10,
322
+ filter: {
323
+ products: {
324
+ products_id: {
325
+ status: {
326
+ _eq: "published"
327
+ }
328
+ }
329
+ },
330
+ }
331
+ }))
332
+ })
333
+
334
+ const {
335
+ data: limitProducts
336
+ } = await useAsyncData('limitProducts', () => {
337
+ return $directus.request($readItems('departments', {
338
+ fields: ['*',
339
+ 'products.products_id.*',
340
+ 'images.*'
341
+ ],
342
+ limit: 2,
343
+ filter: {
344
+ products: {
345
+ products_id: {
346
+ status: {
347
+ _eq: "published"
348
+ }
349
+ }
350
+ },
351
+ }
352
+ }))
353
+ })
354
+
355
+ const {
356
+ data: events
357
+ } = await useAsyncData('events', () => {
358
+ return $directus.request($readItems('departments', {
359
+ fields: ['*',
360
+ 'products.products_id.*',
361
+ 'images.*'
362
+ ],
363
+ limit: 10,
364
+ filter: {
365
+ products: {
366
+ products_id: {
367
+ type: {
368
+ _eq: "event"
369
+ }
370
+ }
371
+ },
372
+ }
373
+ }))
374
+ })
375
+
376
+ const {
377
+ data: callouts
378
+ } = await useAsyncData('callouts', () => {
379
+ return $directus.request($readItem('callouts', '2'))
380
+ })
381
+
382
+ useHead({
383
+ title: computed(() => department?.value?.name || 'Department Page')
384
+ });
385
+ </script>
@@ -0,0 +1,135 @@
1
+ <template>
2
+ <div v-if="category">
3
+
4
+ <!-- Special Categories -->
5
+ <div v-if="category.slug === 'charts'">
6
+ <charts />
7
+ </div>
8
+
9
+ <div v-else-if="category.slug === 'radio-stations'">
10
+ <stations />
11
+ </div>
12
+
13
+ <div v-else-if="category.slug === 'eats'">
14
+ <eats />
15
+ </div>
16
+
17
+ <div v-else-if="category.slug === 'restaurants'">
18
+ <div v-for="(shop, i) in restaurantsList" :key="i">
19
+ <restaurants :restaurant="shop" />
20
+ </div>
21
+ </div>
22
+
23
+ <!-- Default Category Layout -->
24
+ <v-card variant="text" v-else>
25
+ <v-toolbar :style="`background-color: ${category?.color}; color: ${category?.colortext}`">
26
+ <v-toolbar-title><NuxtLink :to="`/departments/${category?.departments?.[0]?.departments_id?.name}`">Meeovi {{ category?.departments?.[0]?.departments_id?.name }}</NuxtLink> - {{ category?.name }}</v-toolbar-title>
27
+ <v-slide-group show-arrows v-if="category?.categories?.length">
28
+ <v-slide-group-item v-slot="{ isSelected, toggle }">
29
+ <v-menu>
30
+ <template #activator="{ props }">
31
+ <v-btn :color="isSelected ? 'primary' : undefined" class="ma-2" v-bind="props"
32
+ variant="text">
33
+ Categories
34
+ </v-btn>
35
+ </template>
36
+
37
+ <v-list class="departmentMenu">
38
+ <v-row>
39
+ <v-col cols="3" v-for="sub in category.categories" :key="sub?.categories_id?.id">
40
+ <v-list-item>
41
+ <NuxtLink :to="`/departments/categories/${sub.categories_id.id}`">
42
+ {{ sub.categories_id.name }}
43
+ </NuxtLink>
44
+ </v-list-item>
45
+ </v-col>
46
+ </v-row>
47
+ </v-list>
48
+ </v-menu>
49
+ </v-slide-group-item>
50
+
51
+ <v-slide-group-item v-for="menu in category.menus" :key="menu.id" v-slot="{ isSelected, toggle }">
52
+ <v-btn :color="isSelected ? 'primary' : undefined" class="ma-2" :href="menu.url">
53
+ {{ menu.name }}
54
+ </v-btn>
55
+ </v-slide-group-item>
56
+ </v-slide-group>
57
+ </v-toolbar>
58
+ </v-card>
59
+
60
+ <!-- Product List -->
61
+ <v-row>
62
+ <v-col cols="3" v-for="productRel in category.products" :key="productRel.products_id.id">
63
+ <productCard :product="productRel.products_id" />
64
+ </v-col>
65
+ </v-row>
66
+
67
+ </div>
68
+
69
+ <!-- Loading / Not Found -->
70
+ <div v-else class="p-10 text-center text-xl text-neutral-700">
71
+ Loading category...
72
+ </div>
73
+ </template>
74
+
75
+ <script setup>
76
+ import charts from '~/components/categories/charts.vue'
77
+ import stations from '~/components/categories/stations.vue'
78
+ import eats from '~/components/categories/eats.vue'
79
+ import restaurants from '~/components/categories/restaurants.vue'
80
+ import productCard from '#commerce/app/components/catalog/product/productCard.vue'
81
+
82
+ const route = useRoute()
83
+ const {
84
+ $directus,
85
+ $readItem,
86
+ $readItems
87
+ } = useNuxtApp()
88
+
89
+ const slug = computed(() => {
90
+ const s = route.params.slug
91
+ return Array.isArray(s) ? s[0] : s
92
+ })
93
+
94
+ const {
95
+ data: categoryRaw
96
+ } = await useAsyncData('categoryRaw', () => {
97
+ return $directus.request(
98
+ $readItems('categories', {
99
+ fields: [
100
+ '*',
101
+ 'tags.tags_id.*',
102
+ 'departments.departments_id.*',
103
+ 'products.products_id.*',
104
+ 'products.products_id.image.*',
105
+ 'menus.*',
106
+ 'image.*'
107
+ ],
108
+ filter: {
109
+ slug: {
110
+ _eq: slug.value
111
+ }
112
+ },
113
+ limit: 1
114
+ })
115
+ )
116
+ })
117
+
118
+ // Unwrap array cleanly
119
+ const category = computed(() => categoryRaw.value?.[0] || null)
120
+
121
+
122
+ // FETCH SHOPS FOR RESTAURANTS CATEGORY
123
+ const {
124
+ data: restaurantsList
125
+ } = await useAsyncData('restaurantsList', () => {
126
+ return $directus.request($readItems('shops', {
127
+ fields: ['*']
128
+ }))
129
+ })
130
+
131
+ // SEO
132
+ useHead({
133
+ title: computed(() => category.value?.name || 'Category Page')
134
+ })
135
+ </script>
@@ -0,0 +1,2 @@
1
+ declare const _default: import("c12").InputConfig<import("@nuxt/schema").NuxtConfig, import("c12").ConfigLayerMeta>;
2
+ export default _default;
@@ -0,0 +1,7 @@
1
+ import { defineNuxtConfig } from 'nuxt/config';
2
+ export default defineNuxtConfig({
3
+ $meta: {
4
+ name: 'departments',
5
+ },
6
+ runtimeConfig: {}
7
+ });
package/nuxt.config.ts ADDED
@@ -0,0 +1,11 @@
1
+ import {
2
+ defineNuxtConfig
3
+ } from 'nuxt/config'
4
+
5
+ export default defineNuxtConfig({
6
+ $meta: {
7
+ name: 'departments',
8
+ },
9
+
10
+ runtimeConfig: {}
11
+ })
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@meeovi/layer-departments",
3
+ "version": "1.0.0",
4
+ "description": "Departments Layer for the Alternate Framework",
5
+ "keywords": [
6
+ "departments",
7
+ "alternate-framework",
8
+ "nuxt",
9
+ "layer"
10
+ ],
11
+ "license": "MIT",
12
+ "author": "Meeovi",
13
+ "main": "dist/index.js",
14
+ "module": "dist/index.js",
15
+ "types": "dist/index.d.ts",
16
+ "exports": {
17
+ ".": {
18
+ "import": "./dist/index.js",
19
+ "types": "./dist/index.d.ts"
20
+ }
21
+ },
22
+ "type": "module",
23
+ "scripts": {
24
+ "test": "vitest",
25
+ "build": "tsc -p tsconfig.json",
26
+ "typecheck": "tsc -p tsconfig.json --noEmit",
27
+ "lint": "eslint 'src/**/*.{ts,tsx}' || true",
28
+ "clean": "rimraf dist",
29
+ "prepare": "npm run build",
30
+ "prepublishOnly": "npm run typecheck && npm run build"
31
+ },
32
+ "devDependencies": {
33
+ "nuxt": "^4.3.0"
34
+ }
35
+ }