@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,278 @@
1
+ <template>
2
+ <div>
3
+ <v-dialog max-width="500">
4
+ <template v-slot:activator="{ props: activatorProps }">
5
+ <v-btn color="primary" v-bind="activatorProps" icon="fas fa-gear" size="medium"
6
+ title="Open Settings"></v-btn>
7
+ </template>
8
+
9
+ <template v-slot:default="{ isActive }">
10
+ <v-card title="Dialog">
11
+ <v-card-text>
12
+ <form @submit.prevent="handleSubmit">
13
+ <v-card>
14
+ <v-card-text>
15
+ <v-text-field v-model="chartData.name" id="chartName" label="Chart Name*" required />
16
+ <v-textarea v-model="chartData.description" label="What's happening?*" variant="outlined"
17
+ required></v-textarea>
18
+ <v-row>
19
+ <v-col cols="6">
20
+ <v-select v-model="chartData.type" label="What type of chart is this?"
21
+ :items="['Notes', 'News']" />
22
+ </v-col>
23
+ <v-col cols="6">
24
+ <v-select v-model="chartData.status" label="Is this chart public or private?"
25
+ :items="['Public', 'Private']" />
26
+ </v-col>
27
+ <v-col cols="12">
28
+ <v-file-input @change="handleImageUpload" clearable density="compact"
29
+ prepend-icon="fas fa-image" accept="image/*" label="Image"
30
+ variant="solo-inverted" />
31
+ </v-col>
32
+ <v-col cols="12">
33
+ <v-file-input @change="handleMediaUpload" chips multiple clearable
34
+ density="compact" prepend-icon="fas fa-video" accept="video/*"
35
+ label="Live Video" variant="solo-inverted">
36
+ </v-file-input>
37
+ </v-col>
38
+ <v-col cols="12">
39
+ <v-file-input @change="handleAudioUpload" chips multiple clearable
40
+ density="compact" prepend-icon="fas fa-microphone" accept="audio/*"
41
+ label="Audio" variant="solo-inverted">
42
+ </v-file-input>
43
+ </v-col>
44
+ </v-row>
45
+ </v-card-text>
46
+ <v-divider class="mt-12"></v-divider>
47
+ <v-card-actions>
48
+ <v-btn color="blue-darken-1" variant="text" @click="isActive.value = false">
49
+ Close
50
+ </v-btn>
51
+ <v-spacer></v-spacer>
52
+ <v-btn color="blue-darken-1" variant="text" type="submit" @click="confirmDelete"
53
+ :loading="deleteLoading">
54
+ Delete Chart
55
+ </v-btn>
56
+ <v-btn color="blue-darken-1" variant="text" type="submit">
57
+ Update Chart
58
+ </v-btn>
59
+ </v-card-actions>
60
+ </v-card>
61
+ </form>
62
+ </v-card-text>
63
+ </v-card>
64
+ </template>
65
+ </v-dialog>
66
+
67
+ <!-- Delete Confirmation Dialog -->
68
+ <v-dialog v-model="deleteDialog" max-width="500px">
69
+ <v-card>
70
+ <v-card-title class="text-h5">Delete Chart</v-card-title>
71
+ <v-card-text>
72
+ Are you sure you want to delete this chart? This action cannot be undone.
73
+ </v-card-text>
74
+ <v-card-actions>
75
+ <v-spacer></v-spacer>
76
+ <v-btn color="blue-darken-1" variant="text" @click="deleteDialog = false">
77
+ Cancel
78
+ </v-btn>
79
+ <v-btn color="error" variant="text" @click="deleteChart" :loading="deleteLoading">
80
+ Delete
81
+ </v-btn>
82
+ </v-card-actions>
83
+ </v-card>
84
+ </v-dialog>
85
+ </div>
86
+ </template>
87
+
88
+ <script setup>
89
+ import {
90
+ ref
91
+ } from 'vue';
92
+ import uploadFiles from '../../../composables/globals/uploadFiles'
93
+ import updateChart from '~/composables/charts/updateChart';
94
+ import { updateItem, deleteItem } from '@meeovi/directus-client';
95
+ import {
96
+ useUserStore
97
+ } from '#auth/app/stores/user'
98
+ import {
99
+ useRouter
100
+ } from 'vue-router'
101
+
102
+ // Make sure your props are properly defined
103
+ // Update props to include space_id
104
+ const props = defineProps({
105
+ space_id: {
106
+ type: String,
107
+ required: true
108
+ }
109
+ });
110
+
111
+ // Add these new refs for delete functionality
112
+ const deleteDialog = ref(false);
113
+ const deleteLoading = ref(false);
114
+
115
+ const { user } = useSupabaseAuth()
116
+
117
+ const route = useRoute();
118
+ const router = useRouter();
119
+
120
+ const chartData = ref({
121
+ id: '', // Add this to store the chart ID
122
+ name: '',
123
+ type: '',
124
+ status: '',
125
+ description: '',
126
+ color: '',
127
+ image: null,
128
+ media: null,
129
+ audio: null,
130
+ username: user?.email,
131
+ space_id: props.space_id, // Initialize with the space_id from props
132
+ });
133
+
134
+ const dialog = ref(false);
135
+ const includeFiles = ref(true);
136
+ const imageFile = ref(null);
137
+ const audioFile = ref(null);
138
+ const loading = ref(false);
139
+
140
+ // Function to fetch existing chart data
141
+ const fetchChartData = async () => {
142
+ try {
143
+ const {
144
+ $directus,
145
+ $readItem,
146
+ } = useNuxtApp();
147
+ const listId = route.params.id; // Assuming you're passing the ID in the route
148
+ const response = await $directus.request($readItem('musicchart', listId));
149
+
150
+ // Populate the form with existing data
151
+ chartData.value = {
152
+ id: response.id,
153
+ name: response.name,
154
+ type: response.type,
155
+ status: response.status,
156
+ description: response.description,
157
+ color: response.color,
158
+ image: response.image,
159
+ audio: response.audio,
160
+ username: response.username
161
+ };
162
+ } catch (error) {
163
+ console.error('Error fetching chart:', error);
164
+ }
165
+ };
166
+
167
+ // Load existing data when component mounts
168
+ onMounted(() => {
169
+ if (route.params.id) {
170
+ fetchChartData();
171
+ }
172
+ });
173
+
174
+ const handleImageUpload = (event) => {
175
+ imageFile.value = event.target.files[0];
176
+ };
177
+
178
+ const handleMediaUpload = (event) => {
179
+ imageFile.value = event.target.files[0];
180
+ };
181
+
182
+ const handleAudioUpload = (event) => {
183
+ audioFile.value = event.target.files[0];
184
+ };
185
+
186
+ const resetForm = () => {
187
+ chartData.value = {
188
+ id: '', // Add this to store the chart ID
189
+ name: '',
190
+ type: '',
191
+ status: '',
192
+ description: '',
193
+ color: '',
194
+ image: null,
195
+ media: null,
196
+ audio: null,
197
+ };
198
+ imageFile.value = null;
199
+ };
200
+
201
+ const handleSubmit = async () => {
202
+ try {
203
+ loading.value = true;
204
+
205
+ const { $directus } = useNuxtApp();
206
+
207
+ // Prepare update data
208
+ const updateData = {
209
+ name: chartData.value.name,
210
+ type: chartData.value.type,
211
+ status: chartData.value.status,
212
+ description: chartData.value.description,
213
+ color: chartData.value.color
214
+ };
215
+
216
+ // Handle image upload if there's a new image
217
+ if (imageFile.value) {
218
+ const uploadedFiles = await uploadFiles({
219
+ imageFile: imageFile.value,
220
+ });
221
+ updateData.image = uploadedFiles.imageId;
222
+ }
223
+
224
+ // Update the chart using Directus updateItem
225
+ const updatedChart = await $directus.request(
226
+ updateItem('charts', route.params.id, updateData)
227
+ );
228
+
229
+ if (updatedChart) {
230
+ // Refresh the chart data
231
+ await fetchChartData();
232
+
233
+ // Show success message
234
+ alert('Chart updated successfully');
235
+ } else {
236
+ throw new Error('Failed to update chart');
237
+ }
238
+
239
+ } catch (error) {
240
+ console.error('Error updating chart:', error);
241
+ alert('Error updating chart: ' + error.message);
242
+ } finally {
243
+ loading.value = false;
244
+ }
245
+ };
246
+
247
+
248
+ // Add these new functions for delete functionality
249
+ const confirmDelete = () => {
250
+ deleteDialog.value = true;
251
+ };
252
+
253
+ const deleteChart = async () => {
254
+ try {
255
+ deleteLoading.value = true;
256
+ const {
257
+ $directus
258
+ } = useNuxtApp();
259
+
260
+ // Delete the chart using the imported deleteItem function
261
+ await $directus.request(deleteItem('musicchart', route.params.id));
262
+
263
+ // Close the delete dialog
264
+ deleteDialog.value = false;
265
+
266
+ // Show success message
267
+ alert('Chart deleted successfully');
268
+
269
+ // Redirect to charts page
270
+ navigateTo('/social/newsfeed');
271
+ } catch (error) {
272
+ console.error('Error deleting chart:', error);
273
+ alert('Error deleting chart: ' + error.message);
274
+ } finally {
275
+ deleteLoading.value = false;
276
+ }
277
+ };
278
+ </script>
@@ -0,0 +1,46 @@
1
+ <template>
2
+ <v-table fixed-header>
3
+ <thead>
4
+ <tr>
5
+ <th class="text-left">Position</th>
6
+ <th class="text-left">Product</th>
7
+ <th class="text-left">Sales</th>
8
+ <th class="text-left">Last Week</th>
9
+ <th class="text-left">Peak Position</th>
10
+ <th class="text-left">Weeks on Chart</th>
11
+ <th class="text-left">Trend</th>
12
+ </tr>
13
+ </thead>
14
+ <tbody>
15
+ <tr v-for="(product, index) in data" :key="product.id">
16
+ <td>{{ index + 1 }}</td>
17
+ <td>
18
+ <div class="d-flex align-center">
19
+ <v-img :src="product.image" width="50" height="50" class="mr-3" />
20
+ <div>
21
+ <div class="font-weight-bold">{{ product.name }}</div>
22
+ <div class="text-caption">{{ product.category }}</div>
23
+ </div>
24
+ </div>
25
+ </td>
26
+ <td>{{ product.sales }}</td>
27
+ <td>
28
+ <v-chip :color="getPositionColor(product.lastWeek, index + 1)" size="small">
29
+ {{ product.lastWeek }}
30
+ </v-chip>
31
+ </td>
32
+ <td>{{ product.peakPosition }}</td>
33
+ <td>{{ product.weeksOnChart }}</td>
34
+ <td>
35
+ <v-icon :color="getTrendColor(product.trend)">{{ getTrendIcon(product.trend) }}</v-icon>
36
+ </td>
37
+ </tr>
38
+ </tbody>
39
+ </v-table>
40
+ </template>
41
+
42
+ <script setup>
43
+ defineProps({
44
+ data: Array, // Accepts the chart data
45
+ });
46
+ </script>
@@ -0,0 +1,46 @@
1
+ <template>
2
+ <v-table fixed-header>
3
+ <thead>
4
+ <tr>
5
+ <th class="text-left">Position</th>
6
+ <th class="text-left">Product</th>
7
+ <th class="text-left">Sales</th>
8
+ <th class="text-left">Last Week</th>
9
+ <th class="text-left">Peak Position</th>
10
+ <th class="text-left">Weeks on Chart</th>
11
+ <th class="text-left">Trend</th>
12
+ </tr>
13
+ </thead>
14
+ <tbody>
15
+ <tr v-for="(product, index) in data" :key="product.id">
16
+ <td>{{ index + 1 }}</td>
17
+ <td>
18
+ <div class="d-flex align-center">
19
+ <v-img :src="product.image" width="50" height="50" class="mr-3" />
20
+ <div>
21
+ <div class="font-weight-bold">{{ product.name }}</div>
22
+ <div class="text-caption">{{ product.category }}</div>
23
+ </div>
24
+ </div>
25
+ </td>
26
+ <td>{{ product.sales }}</td>
27
+ <td>
28
+ <v-chip :color="getPositionColor(product.lastWeek, index + 1)" size="small">
29
+ {{ product.lastWeek }}
30
+ </v-chip>
31
+ </td>
32
+ <td>{{ product.peakPosition }}</td>
33
+ <td>{{ product.weeksOnChart }}</td>
34
+ <td>
35
+ <v-icon :color="getTrendColor(product.trend)">{{ getTrendIcon(product.trend) }}</v-icon>
36
+ </td>
37
+ </tr>
38
+ </tbody>
39
+ </v-table>
40
+ </template>
41
+
42
+ <script setup>
43
+ defineProps({
44
+ data: Array, // Accepts the chart data
45
+ });
46
+ </script>
@@ -0,0 +1,118 @@
1
+ <template>
2
+ <div>
3
+ <!---->
4
+ <v-card elevation="0">
5
+ <v-toolbar :title="chartbar?.name" color="#1F7087">
6
+ <v-dialog min-width="500">
7
+ <template v-slot:activator="{ props: activatorProps }">
8
+ <v-btn v-bind="activatorProps" prepend-icon="fas:fa fa-plus" title="Create a Chart"
9
+ variant="flat">Create a Chart
10
+ </v-btn>
11
+ </template>
12
+
13
+ <template v-slot:default="{ isActive }">
14
+ <createchart />
15
+ </template>
16
+ </v-dialog>
17
+ </v-toolbar>
18
+
19
+ <v-tabs v-model="tab" bg-color="#1F7087">
20
+ <div v-for="(menu, index) in chartbar?.menus" :key="index">
21
+ <v-tab :value="menu?.value">{{ menu?.name }}</v-tab>
22
+ </div>
23
+ </v-tabs>
24
+
25
+ <v-card-text>
26
+ <v-tabs-window v-model="tab">
27
+ <v-tabs-window-item value="one">
28
+ <v-row style="padding-top: 15px;">
29
+ <v-col cols="4" v-for="(charts, index) in charts" :key="index">
30
+ <chart :chart="charts" />
31
+ </v-col>
32
+ </v-row>
33
+ </v-tabs-window-item>
34
+
35
+ <v-tabs-window-item value="two">
36
+ <v-row style="padding-top: 15px;">
37
+ <v-col cols="4" v-for="(charts, index) in videocharts" :key="index">
38
+ <chart :chart="charts" />
39
+ </v-col>
40
+ </v-row>
41
+ </v-tabs-window-item>
42
+
43
+ <v-tabs-window-item value="three">
44
+ <v-row style="padding-top: 15px;">
45
+ <v-col cols="4" v-for="(charts, index) in mycharts" :key="index">
46
+ <chart :chart="charts" />
47
+ </v-col>
48
+ </v-row>
49
+ </v-tabs-window-item>
50
+ </v-tabs-window>
51
+ </v-card-text>
52
+ </v-card>
53
+ </div>
54
+ </template>
55
+
56
+ <script setup>
57
+ import chart from './chart/chart.vue'
58
+ import createchart from './chart/add-chart.vue'
59
+ import { ref } from 'vue'
60
+ import {
61
+ useUserStore
62
+ } from '../../../../auth/app/stores/user'
63
+
64
+ const userStore = useUserStore()
65
+
66
+ const tab = ref(null);
67
+ const {
68
+ $directus,
69
+ $readItems,
70
+ $readItem
71
+ } = useNuxtApp()
72
+
73
+ const {
74
+ data: charts
75
+ } = await useAsyncData('charts', () => {
76
+ return $directus.request($readItems('musicchart', {
77
+ fields: ['*', { '*': ['*'] }]
78
+ }))
79
+ })
80
+
81
+ const {
82
+ data: videocharts
83
+ } = await useAsyncData('videocharts', () => {
84
+ return $directus.request($readItems('musicchart', {
85
+ filter: {
86
+ type: {
87
+ _eq: "Video"
88
+ }
89
+ }
90
+ }))
91
+ })
92
+
93
+ const {
94
+ data: mycharts
95
+ } = await useAsyncData('mycharts', () => {
96
+ return $directus.request($readItems('musicchart', {
97
+ filter: {
98
+ creator: {
99
+ _eq: `${userStore?.email?.value}`
100
+ }
101
+ }
102
+ }))
103
+ })
104
+
105
+ const {
106
+ data: chartbar
107
+ } = await useAsyncData('chartbar', () => {
108
+ return $directus.request($readItem('navigation', '33'))
109
+ })
110
+
111
+ definePageMeta({
112
+ middleware: ['authenticated'],
113
+ })
114
+
115
+ useHead({
116
+ title: 'Charts',
117
+ })
118
+ </script>
@@ -0,0 +1,101 @@
1
+ <template>
2
+ <div>
3
+ <v-card elevation="0" style="min-height: 100vh !important;">
4
+ <v-layout>
5
+ <v-main>
6
+ <v-tabs center-active v-model="tab" bg-color="transparent">
7
+ <div v-for="(menu, index) in dealbar?.menus" :key="index">
8
+ <v-tab :value="menu?.value">{{ menu?.name }}</v-tab>
9
+ </div>
10
+ </v-tabs>
11
+
12
+ <v-card-text>
13
+ <v-tabs-window v-model="tab">
14
+ <v-tabs-window-item :value="dealbar?.menus[0]?.value">
15
+ <v-row>
16
+ <v-col cols="3" v-for="products in dealsProducts" :key="products">
17
+ <productCard :product="products" />
18
+ </v-col>
19
+ </v-row>
20
+ </v-tabs-window-item>
21
+
22
+ <v-tabs-window-item :value="dealbar?.menus[1]?.value">
23
+ <v-row>
24
+ <v-col cols="3" v-for="products in dollar" :key="products">
25
+ <productCard :product="products" />
26
+ </v-col>
27
+ </v-row>
28
+ </v-tabs-window-item>
29
+ </v-tabs-window>
30
+ </v-card-text>
31
+ </v-main>
32
+ </v-layout>
33
+ </v-card>
34
+ </div>
35
+ </template>
36
+
37
+ <script setup>
38
+ import {
39
+ ref
40
+ } from 'vue'
41
+ import productCard from '#commerce/app/components/catalog/product/productCard.vue'
42
+
43
+
44
+ const {
45
+ $directus,
46
+ $readItem,
47
+ $readItems
48
+ } = useNuxtApp()
49
+
50
+ const {
51
+ data: dealbar
52
+ } = await useAsyncData('dealbar', () => {
53
+ return $directus.request($readItem('navigation', '49', {
54
+ fields: ['*', {
55
+ '*': ['*']
56
+ }]
57
+ }))
58
+ })
59
+
60
+ const {
61
+ data: dealsProducts
62
+ } = await useAsyncData('dealsProducts', () => {
63
+ return $directus.request($readItems('products', {
64
+ fields: ['*', {
65
+ '*': ['*']
66
+ }],
67
+ filter: {
68
+ price: {
69
+ _lte: 20
70
+ }
71
+ }
72
+ }))
73
+ })
74
+
75
+ const {
76
+ data: dollar
77
+ } = await useAsyncData('dollar', () => {
78
+ return $directus.request($readItems('products', {
79
+ fields: ['*', {
80
+ '*': ['*']
81
+ }],
82
+ filter: {
83
+ price: {
84
+ _lte: 1
85
+ }
86
+ }
87
+ }))
88
+ })
89
+
90
+ const tab = ref(null)
91
+ const props = defineProps({
92
+ category: {
93
+ type: Number,
94
+ required: true,
95
+ },
96
+ });
97
+
98
+ useHead({
99
+ title: 'Deals',
100
+ })
101
+ </script>
@@ -0,0 +1,49 @@
1
+ <template :style="`background: ${categoryEats?.color}`">
2
+ <div>
3
+ <v-toolbar :title="`Meeovi ${categoryEats?.name}`" :color="categoryEats?.color" :style="`color: ${categoryEats?.colortext}; font: bold;`"></v-toolbar>
4
+ <v-row class="eatsPage">
5
+ <v-col cols="12" v-for="(eats, index) in eats" :key="index">
6
+ <shorts :short="eats" />
7
+ </v-col>
8
+ </v-row>
9
+ </div>
10
+ </template>
11
+
12
+ <script setup>
13
+ import shorts from '#social/app/components/features/vibeSections/shorts.vue'
14
+ //import share from '~/components/partials/globals/share.vue'
15
+
16
+ const {
17
+ $directus,
18
+ $readItems,
19
+ $readItem
20
+ } = useNuxtApp()
21
+
22
+ const {
23
+ data: eats
24
+ } = await useAsyncData('eats', () => {
25
+ return $directus.request($readItems('shorts', {
26
+ filter: {
27
+ type: {
28
+ _eq: 'Eats'
29
+ },
30
+ status: {
31
+ _eq: 'Published'
32
+ }
33
+ },
34
+ fields: ['*', {
35
+ '*': ['*']
36
+ }]
37
+ }))
38
+ })
39
+
40
+ const {
41
+ data: categoryEats
42
+ } = await useAsyncData('categoryEats', () => {
43
+ return $directus.request($readItem('categories', '152', {
44
+ fields: ['*', {
45
+ '*': ['*']
46
+ }]
47
+ }))
48
+ })
49
+ </script>