@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.
- package/app/components/categories/adultstore.vue +123 -0
- package/app/components/categories/chart/[id].vue +254 -0
- package/app/components/categories/chart/add-chart.vue +142 -0
- package/app/components/categories/chart/chart.vue +82 -0
- package/app/components/categories/chart/monthlyChart.vue +46 -0
- package/app/components/categories/chart/musicchart.vue +35 -0
- package/app/components/categories/chart/update-chart.vue +278 -0
- package/app/components/categories/chart/weeklyChart.vue +46 -0
- package/app/components/categories/chart/yearlyChart.vue +46 -0
- package/app/components/categories/charts.vue +118 -0
- package/app/components/categories/deals.vue +101 -0
- package/app/components/categories/eats.vue +49 -0
- package/app/components/categories/restaurants.vue +77 -0
- package/app/components/categories/station/[id].vue +72 -0
- package/app/components/categories/stations.vue +124 -0
- package/app/components/categories/time/features/alarms.vue +276 -0
- package/app/components/categories/time/features/bedtime.vue +12 -0
- package/app/components/categories/time/features/stopwatch.vue +109 -0
- package/app/components/categories/time/features/timer.vue +191 -0
- package/app/components/categories/time/time.vue +63 -0
- package/app/components/categories/travel.vue +75 -0
- package/app/components/categories/weather/weather.vue +44 -0
- package/app/components/related/relatedcharts.vue +39 -0
- package/app/components/related/short.vue +207 -0
- package/app/components/related/space.vue +79 -0
- package/app/pages/departments/[...slug].vue +385 -0
- package/app/pages/departments/category/[...slug].vue +135 -0
- package/dist/nuxt.config.d.ts +2 -0
- package/dist/nuxt.config.js +7 -0
- package/nuxt.config.ts +11 -0
- package/package.json +35 -0
- package/tsconfig.json +14 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<AgeVerification />
|
|
4
|
+
<section data-bs-version="5.1" class="formulam5 header1 cid-uwd6B8oI8u mbr-parallax-background" id="header1-a7">
|
|
5
|
+
|
|
6
|
+
<div class="mbr-overlay"></div>
|
|
7
|
+
<div class="container-fluid">
|
|
8
|
+
<div class="row">
|
|
9
|
+
<div class="content-wrap col-12 col-md-12 col-lg-12">
|
|
10
|
+
<h1 class="mbr-section-title mbr-fonts-style mbr-white mb-4 display-1"><strong>{{ adult?.name }}</strong>
|
|
11
|
+
</h1>
|
|
12
|
+
|
|
13
|
+
<p class="mbr-fonts-style mbr-text mbr-white mb-4 display-7">
|
|
14
|
+
{{ adult?.description }}
|
|
15
|
+
</p>
|
|
16
|
+
<div class="mbr-section-btn"><NuxtLink class="btn btn-white display-4" href="#"><span
|
|
17
|
+
class="mobi-mbri mobi-mbri-right mbr-iconfont mbr-iconfont-btn"></span>START
|
|
18
|
+
SHOPPING</NuxtLink>
|
|
19
|
+
</div>
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
23
|
+
</section>
|
|
24
|
+
|
|
25
|
+
<section data-bs-version="5.1" class="formulam5 features4 cid-uwd7HtZZXP" id="features4-a9">
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
<div class="container-fluid">
|
|
29
|
+
<div class="row justify-content-center">
|
|
30
|
+
<div class="col-12 content-head">
|
|
31
|
+
|
|
32
|
+
</div>
|
|
33
|
+
</div>
|
|
34
|
+
<div class="row justify-content-center">
|
|
35
|
+
<div class="item features-image col-12 col-md-6 col-lg-4">
|
|
36
|
+
<div class="item-wrapper">
|
|
37
|
+
<div class="item-img">
|
|
38
|
+
<img src="assets/images/features2.jpg" alt="" />
|
|
39
|
+
<div class="item-content">
|
|
40
|
+
<h5 class="item-title mbr-fonts-style display-2">
|
|
41
|
+
<strong>Сream</strong>
|
|
42
|
+
</h5>
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
<div class="mbr-section-btn item-footer"><NuxtLink to=""
|
|
46
|
+
class="btn item-btn btn-white display-4"><span
|
|
47
|
+
class="mobi-mbri mobi-mbri-right mbr-iconfont mbr-iconfont-btn"></span>Learn
|
|
48
|
+
More</NuxtLink></div>
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
<div class="item features-image col-12 col-md-6 col-lg-4">
|
|
56
|
+
<div class="item-wrapper">
|
|
57
|
+
<div class="item-img">
|
|
58
|
+
<img src="assets/images/features1.jpg" alt="" />
|
|
59
|
+
<div class="item-content">
|
|
60
|
+
<h5 class="item-title mbr-fonts-style display-2">
|
|
61
|
+
<strong>Soap</strong>
|
|
62
|
+
</h5>
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
<div class="mbr-section-btn item-footer"><NuxtLink to=""
|
|
66
|
+
class="btn item-btn btn-white display-4"><span
|
|
67
|
+
class="mobi-mbri mobi-mbri-right mbr-iconfont mbr-iconfont-btn"></span>Learn
|
|
68
|
+
More</NuxtLink></div>
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
<div class="item features-image col-12 col-md-6 col-lg-4">
|
|
76
|
+
<div class="item-wrapper">
|
|
77
|
+
<div class="item-img">
|
|
78
|
+
<img src="assets/images/features4.jpg" alt="" />
|
|
79
|
+
<div class="item-content">
|
|
80
|
+
<h5 class="item-title mbr-fonts-style display-2">
|
|
81
|
+
<strong>Lotion</strong>
|
|
82
|
+
</h5>
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
<div class="mbr-section-btn item-footer"><NuxtLink to=""
|
|
86
|
+
class="btn item-btn btn-white display-4"><span
|
|
87
|
+
class="mobi-mbri mobi-mbri-right mbr-iconfont mbr-iconfont-btn"></span>Learn
|
|
88
|
+
More</NuxtLink></div>
|
|
89
|
+
</div>
|
|
90
|
+
</div>
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
</div>
|
|
94
|
+
</div>
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
</div>
|
|
98
|
+
</div>
|
|
99
|
+
</section>
|
|
100
|
+
</div>
|
|
101
|
+
</template>
|
|
102
|
+
|
|
103
|
+
<script setup>
|
|
104
|
+
import AgeVerification from '~/app/components/partials/globals/ageverification.vue'
|
|
105
|
+
|
|
106
|
+
const {
|
|
107
|
+
$directus,
|
|
108
|
+
$readItem
|
|
109
|
+
} = useNuxtApp()
|
|
110
|
+
|
|
111
|
+
const {
|
|
112
|
+
data: adult
|
|
113
|
+
} = await useAsyncData('adult', () => {
|
|
114
|
+
return $directus.request($readItem('departments', '64'))
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
const props = defineProps({
|
|
118
|
+
category: {
|
|
119
|
+
type: String,
|
|
120
|
+
required: true,
|
|
121
|
+
},
|
|
122
|
+
});
|
|
123
|
+
</script>
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="contentPage">
|
|
3
|
+
<v-row>
|
|
4
|
+
<v-col cols="12">
|
|
5
|
+
<v-card :color="chartbar?.color">
|
|
6
|
+
<div class="d-flex flex-no-wrap justify-space-between">
|
|
7
|
+
<div>
|
|
8
|
+
<v-card-title class="text-h5">
|
|
9
|
+
{{ chart?.name }}
|
|
10
|
+
</v-card-title>
|
|
11
|
+
|
|
12
|
+
<v-card-subtitle>{{ chart?.description }}</v-card-subtitle>
|
|
13
|
+
</div>
|
|
14
|
+
|
|
15
|
+
<v-avatar class="ma-3" rounded="0" size="125">
|
|
16
|
+
<NuxtImg :src="`${$directus.url}/assets/${chart?.image?.filename_disk}`" />
|
|
17
|
+
</v-avatar>
|
|
18
|
+
</div>
|
|
19
|
+
</v-card>
|
|
20
|
+
</v-col>
|
|
21
|
+
|
|
22
|
+
<v-col cols="12">
|
|
23
|
+
<v-card elevation="0">
|
|
24
|
+
<v-tabs v-model="tab" :bg-color="chartbar?.color">
|
|
25
|
+
<div v-for="(menu, index) in spacebar?.menus" :key="index">
|
|
26
|
+
<v-tab :value="menu?.value">{{ menu?.name }}</v-tab>
|
|
27
|
+
</div>
|
|
28
|
+
</v-tabs>
|
|
29
|
+
|
|
30
|
+
<v-card-text>
|
|
31
|
+
<v-tabs-window v-model="tab">
|
|
32
|
+
<v-tabs-window-item :value="chartbar?.menus[0]?.value">
|
|
33
|
+
<!-- Weekly Chart Table -->
|
|
34
|
+
<WeeklyChart :data="topProducts" />
|
|
35
|
+
</v-tabs-window-item>
|
|
36
|
+
<v-tabs-window-item :value="chartbar?.menus[1]?.value">
|
|
37
|
+
<!-- Monthly Chart Table -->
|
|
38
|
+
<MonthlyChart :data="topProducts" />
|
|
39
|
+
</v-tabs-window-item>
|
|
40
|
+
<v-tabs-window-item :value="chartbar?.menus[2]?.value">
|
|
41
|
+
<!-- Yearly Chart Table -->
|
|
42
|
+
<YearlyChart :data="topProducts" />
|
|
43
|
+
</v-tabs-window-item>
|
|
44
|
+
|
|
45
|
+
<v-tabs-window-item :value="chartbar?.menus[3]?.value">
|
|
46
|
+
<v-row>
|
|
47
|
+
<v-col v-for="charts in charts" :key="charts">
|
|
48
|
+
<charts :chart="charts" />
|
|
49
|
+
</v-col>
|
|
50
|
+
</v-row>
|
|
51
|
+
</v-tabs-window-item>
|
|
52
|
+
</v-tabs-window>
|
|
53
|
+
</v-card-text>
|
|
54
|
+
</v-card>
|
|
55
|
+
</v-col>
|
|
56
|
+
</v-row>
|
|
57
|
+
</div>
|
|
58
|
+
</template>
|
|
59
|
+
|
|
60
|
+
<script setup>
|
|
61
|
+
import {
|
|
62
|
+
ref,
|
|
63
|
+
computed
|
|
64
|
+
} from 'vue'
|
|
65
|
+
import WeeklyChart from '@/components/charts/weeklyChart.vue'
|
|
66
|
+
import MonthlyChart from '@/components/charts/monthlyChart.vue'
|
|
67
|
+
import YearlyChart from '@/components/charts/yearlyChart.vue'
|
|
68
|
+
|
|
69
|
+
const tab = ref('weekly')
|
|
70
|
+
const route = useRoute()
|
|
71
|
+
const topProducts = ref([]);
|
|
72
|
+
|
|
73
|
+
// Add new reactive references
|
|
74
|
+
const filterOptions = ref({
|
|
75
|
+
category: null,
|
|
76
|
+
timeRange: 'weekly'
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
const sortOptions = ref({
|
|
80
|
+
field: 'sales',
|
|
81
|
+
order: 'desc'
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
const {
|
|
85
|
+
$directus,
|
|
86
|
+
$readItem,
|
|
87
|
+
$readItems
|
|
88
|
+
} = useNuxtApp()
|
|
89
|
+
|
|
90
|
+
const {
|
|
91
|
+
data: chart
|
|
92
|
+
} = await useAsyncData('chart', () => {
|
|
93
|
+
return $directus.request($readItem('musicchart', route.params.id, {
|
|
94
|
+
fields: ['*', {
|
|
95
|
+
'*': ['*']
|
|
96
|
+
}]
|
|
97
|
+
}))
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
const {
|
|
101
|
+
data: charts
|
|
102
|
+
} = await useAsyncData('charts', () => {
|
|
103
|
+
return $directus.request($readItems('musicchart', {
|
|
104
|
+
fields: ['*', {
|
|
105
|
+
'*': ['*']
|
|
106
|
+
}]
|
|
107
|
+
}))
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
const {
|
|
111
|
+
data: chartbar
|
|
112
|
+
} = await useAsyncData('chartbar', () => {
|
|
113
|
+
return $directus.request($readItem('navigation', '53'))
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
const categories = ref([]) // Will be populated from your products data
|
|
117
|
+
|
|
118
|
+
// Calculate helper functions
|
|
119
|
+
const calculateTrend = (current, previous) => {
|
|
120
|
+
if (current > previous) return 'up';
|
|
121
|
+
if (current < previous) return 'down';
|
|
122
|
+
return 'stable';
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
const calculateWeeksOnChart = (firstAppearance) => {
|
|
126
|
+
const now = new Date();
|
|
127
|
+
const start = new Date(firstAppearance);
|
|
128
|
+
return Math.floor((now - start) / (7 * 24 * 60 * 60 * 1000));
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
// Modify your existing fetchChartData function
|
|
132
|
+
const fetchChartData = async (timeframe) => {
|
|
133
|
+
try {
|
|
134
|
+
const now = new Date();
|
|
135
|
+
let startDate;
|
|
136
|
+
|
|
137
|
+
// Determine the start date based on the timeframe
|
|
138
|
+
if (timeframe === "weekly") {
|
|
139
|
+
startDate = new Date(now.setDate(now.getDate() - 7));
|
|
140
|
+
} else if (timeframe === "monthly") {
|
|
141
|
+
startDate = new Date(now.getFullYear(), now.getMonth(), 1);
|
|
142
|
+
} else if (timeframe === "yearly") {
|
|
143
|
+
startDate = new Date(now.getFullYear(), 0, 1);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const {
|
|
147
|
+
data
|
|
148
|
+
} = await useAsyncData("productChart", () => {
|
|
149
|
+
return $directus.request(
|
|
150
|
+
$readItems("products", {
|
|
151
|
+
sort: ["-sales"],
|
|
152
|
+
limit: 100,
|
|
153
|
+
filter: {
|
|
154
|
+
created_on: {
|
|
155
|
+
_gte: startDate.toISOString(),
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
})
|
|
159
|
+
);
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
// Process the data and calculate fields
|
|
163
|
+
const processedData = data.value.map((product) => ({
|
|
164
|
+
...product,
|
|
165
|
+
trend: calculateTrend(product.currentSales, product.previousSales),
|
|
166
|
+
weeksOnChart: calculateWeeksOnChart(product.firstAppearance),
|
|
167
|
+
}));
|
|
168
|
+
|
|
169
|
+
// Update top products and categories
|
|
170
|
+
topProducts.value = processedData;
|
|
171
|
+
categories.value = [...new Set(processedData.map((p) => p.category))];
|
|
172
|
+
} catch (error) {
|
|
173
|
+
console.error("Error fetching chart data:", error);
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
// Watch for tab changes to update data
|
|
178
|
+
watch(tab, (newValue) => {
|
|
179
|
+
fetchChartData(newValue);
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
// Filter and sort products
|
|
183
|
+
const sortedAndFilteredProducts = computed(() => {
|
|
184
|
+
let filtered = [...topProducts.value];
|
|
185
|
+
|
|
186
|
+
if (filterOptions.value.category) {
|
|
187
|
+
filtered = filtered.filter(
|
|
188
|
+
(product) => product.category === filterOptions.value.category
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return filtered.sort((a, b) => {
|
|
193
|
+
const aValue = a[sortOptions.value.field];
|
|
194
|
+
const bValue = b[sortOptions.value.field];
|
|
195
|
+
|
|
196
|
+
return sortOptions.value.order === 'asc' ?
|
|
197
|
+
aValue - bValue :
|
|
198
|
+
bValue - aValue;
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
watch(tab, (newValue) => {
|
|
203
|
+
fetchChartData(newValue);
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
// Set page title
|
|
207
|
+
useHead({
|
|
208
|
+
title: computed(() => chart.value?.name || 'Chart Page'),
|
|
209
|
+
});
|
|
210
|
+
</script>
|
|
211
|
+
|
|
212
|
+
<style scoped>
|
|
213
|
+
/* Keep existing styles */
|
|
214
|
+
|
|
215
|
+
/* Add animation styles */
|
|
216
|
+
.product-row {
|
|
217
|
+
transition: all 0.3s ease-in-out;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
.position-changed {
|
|
221
|
+
animation: highlightRow 1s ease-in-out;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
@keyframes highlightRow {
|
|
225
|
+
0% {
|
|
226
|
+
background-color: rgba(var(--v-theme-primary), 0.1);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
100% {
|
|
230
|
+
background-color: transparent;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
.position-change-enter-active,
|
|
235
|
+
.position-change-leave-active {
|
|
236
|
+
transition: all 0.3s ease;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
.position-change-enter-from,
|
|
240
|
+
.position-change-leave-to {
|
|
241
|
+
opacity: 0;
|
|
242
|
+
transform: translateY(30px);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/* Add smooth transitions for sorting */
|
|
246
|
+
.v-table tbody tr {
|
|
247
|
+
transition: transform 0.3s ease;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/* Add hover effect */
|
|
251
|
+
.product-row:hover {
|
|
252
|
+
background-color: rgba(var(--v-theme-primary), 0.05);
|
|
253
|
+
}
|
|
254
|
+
</style>
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<form @submit.prevent="createActivityAndRefresh">
|
|
4
|
+
<v-card>
|
|
5
|
+
<v-card-text>
|
|
6
|
+
<v-text-field v-model="chartData.name" id="chartName" label="Chart Name*" required />
|
|
7
|
+
<v-textarea v-model="chartData.description" label="What's happening?*" variant="outlined"
|
|
8
|
+
required></v-textarea>
|
|
9
|
+
<v-row>
|
|
10
|
+
<v-col cols="6">
|
|
11
|
+
<v-select v-model="chartData.type" label="What type of chart is this?"
|
|
12
|
+
:items="['Notes', 'News']" />
|
|
13
|
+
</v-col>
|
|
14
|
+
<v-col cols="6">
|
|
15
|
+
<v-select v-model="chartData.status" label="Is this chart public or private?"
|
|
16
|
+
:items="['Public', 'Private']" />
|
|
17
|
+
</v-col>
|
|
18
|
+
<v-col cols="12">
|
|
19
|
+
<v-file-input @change="handleImageUpload" clearable density="compact"
|
|
20
|
+
prepend-icon="fas fa-image" accept="image/*" label="Image" variant="solo-inverted" />
|
|
21
|
+
</v-col>
|
|
22
|
+
</v-row>
|
|
23
|
+
</v-card-text>
|
|
24
|
+
<v-divider class="mt-12"></v-divider>
|
|
25
|
+
<v-card-actions>
|
|
26
|
+
<v-btn color="blue-darken-1" variant="text" @click="dialog = false">
|
|
27
|
+
Close
|
|
28
|
+
</v-btn>
|
|
29
|
+
<v-spacer></v-spacer>
|
|
30
|
+
<v-btn color="blue-darken-1" variant="text" type="submit" @click="reset = false">
|
|
31
|
+
Reset
|
|
32
|
+
</v-btn>
|
|
33
|
+
<v-btn color="blue-darken-1" variant="text" type="submit" @click="createNewChart">
|
|
34
|
+
Create
|
|
35
|
+
</v-btn>
|
|
36
|
+
</v-card-actions>
|
|
37
|
+
</v-card>
|
|
38
|
+
</form>
|
|
39
|
+
</div>
|
|
40
|
+
</template>
|
|
41
|
+
|
|
42
|
+
<script>
|
|
43
|
+
export default {
|
|
44
|
+
methods: {
|
|
45
|
+
reset() {
|
|
46
|
+
this.$refs.form.reset()
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
}
|
|
50
|
+
</script>
|
|
51
|
+
|
|
52
|
+
<script setup>
|
|
53
|
+
import {
|
|
54
|
+
ref
|
|
55
|
+
} from 'vue';
|
|
56
|
+
import {
|
|
57
|
+
useRoute } from 'vue-router';
|
|
58
|
+
import uploadFiles from '#shared/app/composables/globals/uploadFiles';
|
|
59
|
+
import createChart from '@/composables/charts/createChart';
|
|
60
|
+
|
|
61
|
+
// Make sure your props are properly defined
|
|
62
|
+
// Update props to include spaces_id
|
|
63
|
+
const props = defineProps({
|
|
64
|
+
spaces_id: {
|
|
65
|
+
type: String,
|
|
66
|
+
required: true
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
const { user } = useSupabaseAuth()
|
|
71
|
+
|
|
72
|
+
const route = useRoute();
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
const chartData = ref({
|
|
76
|
+
name: '',
|
|
77
|
+
description: '',
|
|
78
|
+
type: '',
|
|
79
|
+
status: '',
|
|
80
|
+
image: '',
|
|
81
|
+
reactions: '',
|
|
82
|
+
color: '',
|
|
83
|
+
coverFile: null,
|
|
84
|
+
avatarFile: null,
|
|
85
|
+
creator: user?.email,
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
const dialog = ref(false);
|
|
89
|
+
|
|
90
|
+
const imageFile = ref(null);
|
|
91
|
+
const documentFile = ref(null);
|
|
92
|
+
|
|
93
|
+
// Emit event for parent component updates
|
|
94
|
+
const emit = defineEmits(['chart-created']);
|
|
95
|
+
|
|
96
|
+
const handleImageUpload = (event) => {
|
|
97
|
+
imageFile.value = event.target.files[0];
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
const createNewChart = async () => {
|
|
102
|
+
try {
|
|
103
|
+
// Upload files if any
|
|
104
|
+
const uploadedFiles = await uploadFiles({
|
|
105
|
+
imageFile: imageFile.value,
|
|
106
|
+
documentFile: documentFile.value,
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// Update chart data with uploaded files
|
|
110
|
+
if (uploadedFiles) {
|
|
111
|
+
chartData.value.image = uploadedFiles.imageId;
|
|
112
|
+
chartData.value.media = uploadedFiles.documentId;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Set spaces_id in chartData to link chart to the space
|
|
116
|
+
chartData.value.spaces_id = props.spaces_id;
|
|
117
|
+
|
|
118
|
+
// Create the chart with space relationship
|
|
119
|
+
const chart = await createChart(chartData.value);
|
|
120
|
+
|
|
121
|
+
console.log('Created Chart:', chart);
|
|
122
|
+
|
|
123
|
+
// Emit event to refresh parent component
|
|
124
|
+
emit('chart-created', chart);
|
|
125
|
+
|
|
126
|
+
// Close dialog and reset form
|
|
127
|
+
dialog.value = false;
|
|
128
|
+
reset();
|
|
129
|
+
|
|
130
|
+
// Optional: Redirect to the space page
|
|
131
|
+
router.push(`/departments/categories/chart/${props.spaces_id}`);
|
|
132
|
+
} catch (error) {
|
|
133
|
+
console.error('Error creating chart:', error);
|
|
134
|
+
// Add error handling here
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
// Add watch to update spaces_id if props change
|
|
139
|
+
watch(() => props.spaces_id, (newSpaceId) => {
|
|
140
|
+
chartData.value.spaces_id = newSpaceId;
|
|
141
|
+
});
|
|
142
|
+
</script>
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="contentPage">
|
|
3
|
+
<v-toolbar :style="`background-color: ${chart?.color}`" :title="chart?.name"></v-toolbar>
|
|
4
|
+
<v-table class="charttable">
|
|
5
|
+
<thead>
|
|
6
|
+
<tr>
|
|
7
|
+
<th></th>
|
|
8
|
+
<th class="text-left">
|
|
9
|
+
This Week
|
|
10
|
+
</th>
|
|
11
|
+
<th class="text-left">Name</th>
|
|
12
|
+
<th class="text-left">
|
|
13
|
+
Award
|
|
14
|
+
</th>
|
|
15
|
+
<th class="text-left">
|
|
16
|
+
Last Week
|
|
17
|
+
</th>
|
|
18
|
+
<th class="text-left">
|
|
19
|
+
Peak Position
|
|
20
|
+
</th>
|
|
21
|
+
<th class="text-left">
|
|
22
|
+
Weeks on Chart
|
|
23
|
+
</th>
|
|
24
|
+
<th class="text-left">
|
|
25
|
+
Buy
|
|
26
|
+
</th>
|
|
27
|
+
<th class="text-left"><share /></th>
|
|
28
|
+
</tr>
|
|
29
|
+
</thead>
|
|
30
|
+
<tbody>
|
|
31
|
+
<tr v-for="(products, index) in chart?.products?.products_id" :key="index">
|
|
32
|
+
<td class="chartnumber">
|
|
33
|
+
<h1>{{ chart?.thisWeek }}</h1>
|
|
34
|
+
</td>
|
|
35
|
+
<td>
|
|
36
|
+
<v-avatar :image="products?.image?.filename_disk" rounded="0" size="130"></v-avatar>
|
|
37
|
+
</td>
|
|
38
|
+
<td>
|
|
39
|
+
<v-list>
|
|
40
|
+
<v-list-item>
|
|
41
|
+
<v-list-item-title>{{ products?.name }}</v-list-item-title>
|
|
42
|
+
<div v-for="product in products?.product_types?.product_types_id" :key="product">
|
|
43
|
+
<v-list-item-subtitle>{{ product?.name }}</v-list-item-subtitle>
|
|
44
|
+
</div>
|
|
45
|
+
</v-list-item>
|
|
46
|
+
</v-list>
|
|
47
|
+
</td>
|
|
48
|
+
<td>
|
|
49
|
+
<v-avatar icon="fas fa-star" :style="`color: ${chart?.award}`"></v-avatar>
|
|
50
|
+
</td>
|
|
51
|
+
<td>
|
|
52
|
+
<h5>{{ chart?.last_week }}</h5>
|
|
53
|
+
</td>
|
|
54
|
+
<td>
|
|
55
|
+
<h5>{{ chart?.peak_position }}</h5>
|
|
56
|
+
</td>
|
|
57
|
+
<td>
|
|
58
|
+
<h5>{{ chart?.weeks_on_chart }}</h5>
|
|
59
|
+
</td>
|
|
60
|
+
<td>
|
|
61
|
+
<v-btn href="" icon="fas fa-shopping-cart"></v-btn>
|
|
62
|
+
</td>
|
|
63
|
+
</tr>
|
|
64
|
+
</tbody>
|
|
65
|
+
</v-table>
|
|
66
|
+
<relatedchart />
|
|
67
|
+
<relatedproducts /><!---->
|
|
68
|
+
<recentlyviewed /><!---->
|
|
69
|
+
</div>
|
|
70
|
+
</template>
|
|
71
|
+
|
|
72
|
+
<script setup>
|
|
73
|
+
import share from '#social/app/components/blocks/share.vue'
|
|
74
|
+
import relatedchart from '../../related/relatedcharts.vue'
|
|
75
|
+
import relatedproducts from '#commerce/app/components/related/relatedproducts.vue'
|
|
76
|
+
import recentlyviewed from '#commerce/app/components/catalog/product/recentlyviewed.vue'
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
useHead({
|
|
80
|
+
title: computed(() => chart?.value?.name || 'Chart Page')
|
|
81
|
+
});
|
|
82
|
+
</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,35 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<v-card color="#1F7087" :href="`/departments/categories/chart/${chart?.id}`">
|
|
4
|
+
<div class="d-flex flex-no-wrap justify-space-between">
|
|
5
|
+
<div>
|
|
6
|
+
<v-card-title class="text-h5">
|
|
7
|
+
{{ chart?.name }}
|
|
8
|
+
</v-card-title>
|
|
9
|
+
|
|
10
|
+
<v-card-subtitle>{{ chart?.description }}</v-card-subtitle>
|
|
11
|
+
|
|
12
|
+
<v-card-actions>
|
|
13
|
+
<v-btn class="ms-2" size="small" text="VISIT" variant="outlined"></v-btn>
|
|
14
|
+
</v-card-actions>
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
<v-avatar class="ma-3" rounded="0" size="125">
|
|
18
|
+
<v-img :src="`${$directus.url}assets/${chart?.image?.filename_disk}`"></v-img>
|
|
19
|
+
</v-avatar>
|
|
20
|
+
</div>
|
|
21
|
+
</v-card>
|
|
22
|
+
</div>
|
|
23
|
+
</template>
|
|
24
|
+
|
|
25
|
+
<script setup>
|
|
26
|
+
const props = defineProps({
|
|
27
|
+
chart: {
|
|
28
|
+
type: Object,
|
|
29
|
+
required: true,
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
const {
|
|
33
|
+
chart
|
|
34
|
+
} = props;
|
|
35
|
+
</script>
|