Filterable tours
This commit is contained in:
@@ -23,5 +23,5 @@ export class Tour extends Model {
|
|||||||
band: Band
|
band: Band
|
||||||
|
|
||||||
@HasMany(() => Concert)
|
@HasMany(() => Concert)
|
||||||
shows: Concert[]
|
concerts: Concert[]
|
||||||
}
|
}
|
||||||
@@ -7,6 +7,7 @@ import navigationPrependItems from './components/navigation/navigationPrependIte
|
|||||||
import { usePreferencesStore } from './data/stores/preferencesStore';
|
import { usePreferencesStore } from './data/stores/preferencesStore';
|
||||||
import { useFeedbackStore } from './data/stores/feedbackStore';
|
import { useFeedbackStore } from './data/stores/feedbackStore';
|
||||||
import { useConcertStore } from './data/stores/concertStore';
|
import { useConcertStore } from './data/stores/concertStore';
|
||||||
|
import { LocationModel } from './data/models/acts/locationModel';
|
||||||
|
|
||||||
const preferencesStore = usePreferencesStore()
|
const preferencesStore = usePreferencesStore()
|
||||||
const concertStore = useConcertStore()
|
const concertStore = useConcertStore()
|
||||||
@@ -22,6 +23,19 @@ concertStore.fetchAllTours()
|
|||||||
watch(() => preferencesStore.language, () => {
|
watch(() => preferencesStore.language, () => {
|
||||||
i18n.global.locale = preferencesStore.language
|
i18n.global.locale = preferencesStore.language
|
||||||
}, { immediate: true })
|
}, { immediate: true })
|
||||||
|
|
||||||
|
watch(() => concertStore.cityFilter, () => {
|
||||||
|
concertStore.locationFilter = new LocationModel()
|
||||||
|
concertStore.filterTours()
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(() => concertStore.locationFilter, () => {
|
||||||
|
concertStore.filterTours()
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(() => concertStore.genreFilter, () => {
|
||||||
|
concertStore.filterTours()
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -64,8 +78,8 @@ watch(() => preferencesStore.language, () => {
|
|||||||
</v-snackbar>
|
</v-snackbar>
|
||||||
|
|
||||||
<!-- Here changes the router the content -->
|
<!-- Here changes the router the content -->
|
||||||
<v-container max-width="1400" class="pt-0 pb-5">
|
<v-container max-width="1400" class="py-0" height="100%">
|
||||||
<v-sheet color="sheet">
|
<v-sheet color="sheet" height="100%">
|
||||||
<router-view></router-view>
|
<router-view></router-view>
|
||||||
</v-sheet>
|
</v-sheet>
|
||||||
</v-container>
|
</v-container>
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
<v-divider vertical />
|
<v-divider vertical />
|
||||||
|
|
||||||
<v-btn
|
<v-btn
|
||||||
to="/shows/concerts"
|
to="/shows/tours"
|
||||||
prepend-icon="mdi-ticket"
|
prepend-icon="mdi-ticket"
|
||||||
height="100%"
|
height="100%"
|
||||||
:rounded="false"
|
:rounded="false"
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import { GenreModel } from "./genreModel"
|
|
||||||
import { MemberModel } from "./memberModel"
|
|
||||||
import { RatingModel } from "./ratingModel"
|
import { RatingModel } from "./ratingModel"
|
||||||
|
|
||||||
export class BandModel {
|
export class BandModel {
|
||||||
@@ -11,8 +9,11 @@ export class BandModel {
|
|||||||
images: Array<string>
|
images: Array<string>
|
||||||
logo: string
|
logo: string
|
||||||
ratings: Array<RatingModel>
|
ratings: Array<RatingModel>
|
||||||
members: Array<MemberModel>
|
members: Array<{
|
||||||
genres: {
|
name: string,
|
||||||
|
image: string
|
||||||
|
}>
|
||||||
|
genres: Array<{
|
||||||
name: string
|
name: string
|
||||||
}
|
}>
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
import { MemberModel } from "./memberModel"
|
|
||||||
import { RatingModel } from "./ratingModel"
|
import { RatingModel } from "./ratingModel"
|
||||||
|
|
||||||
export class GenreModel {
|
export class GenreModel {
|
||||||
@@ -7,13 +6,9 @@ export class GenreModel {
|
|||||||
bands: Array<
|
bands: Array<
|
||||||
{
|
{
|
||||||
name: string
|
name: string
|
||||||
foundingYear: number
|
|
||||||
descriptionEn: string
|
|
||||||
descriptionDe: string
|
|
||||||
images: Array<string>
|
images: Array<string>
|
||||||
logo: string
|
logo: string
|
||||||
ratings: Array<RatingModel>
|
ratings: Array<RatingModel>
|
||||||
members: Array<MemberModel>
|
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
}
|
}
|
||||||
@@ -4,7 +4,6 @@ export class LocationModel {
|
|||||||
address: string
|
address: string
|
||||||
image: string
|
image: string
|
||||||
city: {
|
city: {
|
||||||
id: number
|
|
||||||
name: string
|
name: string
|
||||||
country: string
|
country: string
|
||||||
}
|
}
|
||||||
@@ -7,5 +7,5 @@ export class TourModel {
|
|||||||
offered: boolean
|
offered: boolean
|
||||||
band: BandModel
|
band: BandModel
|
||||||
image: string
|
image: string
|
||||||
shows: Array<ConcertModel>
|
concerts: Array<ConcertModel>
|
||||||
}
|
}
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
import { BandModel } from "./bandModel"
|
|
||||||
|
|
||||||
export class MemberModel {
|
|
||||||
id: Number
|
|
||||||
name: string
|
|
||||||
image: string
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { ConcertModel } from "./concertModel"
|
import { ConcertModel } from "../acts/concertModel"
|
||||||
|
|
||||||
export class BasketItemModel {
|
export class BasketItemModel {
|
||||||
id: number = -1
|
id: number = -1
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { ConcertModel } from "./concertModel"
|
import { ConcertModel } from "../acts/concertModel"
|
||||||
|
|
||||||
export class OrderItemModel {
|
export class OrderItemModel {
|
||||||
orderId: number = -1
|
orderId: number = -1
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { AddressModel } from "./addressModel"
|
import { AddressModel } from "../user/addressModel"
|
||||||
import { OrderItemModel } from "./orderItemModel"
|
import { OrderItemModel } from "./orderItemModel"
|
||||||
import { PaymentModel } from "./paymentModel"
|
import { PaymentModel } from "../user/paymentModel"
|
||||||
|
|
||||||
export class OrderModel {
|
export class OrderModel {
|
||||||
id: number
|
id: number
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
import { useLocalStorage } from "@vueuse/core";
|
import { useLocalStorage } from "@vueuse/core";
|
||||||
import { defineStore } from "pinia";
|
import { defineStore } from "pinia";
|
||||||
import { AccountModel } from "../models/accountModel";
|
import { AccountModel } from "../models/user/accountModel";
|
||||||
import { OrderModel } from "../models/orderModel";
|
import { OrderModel } from "../models/ordering/orderModel";
|
||||||
import { useFeedbackStore } from "./feedbackStore";
|
import { useFeedbackStore } from "./feedbackStore";
|
||||||
import { loginAccount, registerAccount, updateAccount } from "../api/accountApi";
|
import { loginAccount, registerAccount, updateAccount } from "../api/accountApi";
|
||||||
import { getUserOrders } from "../api/orderApi";
|
import { getUserOrders } from "../api/orderApi";
|
||||||
import { BannerStateEnum } from "../enums/bannerStateEnum";
|
import { BannerStateEnum } from "../enums/bannerStateEnum";
|
||||||
import { AddressModel } from "../models/addressModel";
|
import { AddressModel } from "../models/user/addressModel";
|
||||||
import { PaymentModel } from "../models/paymentModel";
|
import { PaymentModel } from "../models/user/paymentModel";
|
||||||
|
|
||||||
export const useAccountStore = defineStore("accountStore", {
|
export const useAccountStore = defineStore("accountStore", {
|
||||||
state: () => ({
|
state: () => ({
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import { defineStore } from "pinia";
|
import { defineStore } from "pinia";
|
||||||
import { useLocalStorage } from "@vueuse/core";
|
import { useLocalStorage } from "@vueuse/core";
|
||||||
import { BasketItemModel } from "../models/basketItemModel";
|
import { BasketItemModel } from "../models/ordering/basketItemModel";
|
||||||
import { useFeedbackStore } from "./feedbackStore";
|
import { useFeedbackStore } from "./feedbackStore";
|
||||||
import { BannerStateEnum } from "../enums/bannerStateEnum";
|
import { BannerStateEnum } from "../enums/bannerStateEnum";
|
||||||
import { addOrder } from "../api/orderApi";
|
import { addOrder } from "../api/orderApi";
|
||||||
import { useAccountStore } from "./accountStore";
|
import { useAccountStore } from "./accountStore";
|
||||||
import { ConcertModel } from "../models/concertModel";
|
import { ConcertModel } from "../models/acts/concertModel";
|
||||||
import { AddressModel } from "../models/addressModel";
|
import { AddressModel } from "../models/user/addressModel";
|
||||||
import { PaymentModel } from "../models/paymentModel";
|
import { PaymentModel } from "../models/user/paymentModel";
|
||||||
|
|
||||||
export const useBasketStore = defineStore('basketStore', {
|
export const useBasketStore = defineStore('basketStore', {
|
||||||
state: () => ({
|
state: () => ({
|
||||||
|
|||||||
@@ -1,23 +1,28 @@
|
|||||||
import { useLocalStorage } from "@vueuse/core";
|
import { useLocalStorage } from "@vueuse/core";
|
||||||
import { defineStore } from "pinia";
|
import { defineStore } from "pinia";
|
||||||
import { TourModel } from "../models/tourModel";
|
import { TourModel } from "../models/acts/tourModel";
|
||||||
import { getAllTours } from "../api/tourApi";
|
import { getAllTours } from "../api/tourApi";
|
||||||
import { GenreModel } from "../models/genreModel";
|
import { GenreModel } from "../models/acts/genreModel";
|
||||||
import { getAllBands } from "../api/bandApi";
|
import { getAllBands } from "../api/bandApi";
|
||||||
import { BandModel } from "../models/bandModel";
|
import { BandModel } from "../models/acts/bandModel";
|
||||||
import { LocationModel } from "../models/locationModel";
|
import { LocationModel } from "../models/acts/locationModel";
|
||||||
import { getAllLocations } from "../api/locationApi";
|
import { getAllLocations } from "../api/locationApi";
|
||||||
import { getAllGenres } from "../api/genreApi";
|
import { getAllGenres } from "../api/genreApi";
|
||||||
import { CityModel } from "../models/cityModel";
|
import { CityModel } from "../models/acts/cityModel";
|
||||||
import { getAllCities } from "../api/cityApi";
|
import { getAllCities } from "../api/cityApi";
|
||||||
|
|
||||||
export const useConcertStore = defineStore("concertStore", {
|
export const useConcertStore = defineStore("concertStore", {
|
||||||
state: () => ({
|
state: () => ({
|
||||||
tours: useLocalStorage<Array<TourModel>>("hackmycart/concertStore/tours", []),
|
tours: useLocalStorage<Array<TourModel>>("hackmycart/concertStore/tours", []),
|
||||||
|
filteredTours: useLocalStorage<Array<TourModel>>("hackmycart/concertStore/filteredTours", []),
|
||||||
bands: useLocalStorage<Array<BandModel>>("hackmycart/concertStore/bands", []),
|
bands: useLocalStorage<Array<BandModel>>("hackmycart/concertStore/bands", []),
|
||||||
locations: useLocalStorage<Array<LocationModel>>("hackmycart/concertStore/locations", []),
|
locations: useLocalStorage<Array<LocationModel>>("hackmycart/concertStore/locations", []),
|
||||||
|
filteredLocations: useLocalStorage<Array<LocationModel>>("hackmycart/concertStore/filteredLocations", []),
|
||||||
cities: useLocalStorage<Array<CityModel>>("hackmycart/concertStore/cities", []),
|
cities: useLocalStorage<Array<CityModel>>("hackmycart/concertStore/cities", []),
|
||||||
genres: useLocalStorage<Array<GenreModel>>("hackmycart/concertStore/genres", [])
|
genres: useLocalStorage<Array<GenreModel>>("hackmycart/concertStore/genres", []),
|
||||||
|
cityFilter: useLocalStorage<CityModel>("hackmycart/concertStore/cityFilter", new CityModel()),
|
||||||
|
locationFilter: useLocalStorage<LocationModel>("hackmycart/concertStore/locationFilter", new LocationModel),
|
||||||
|
genreFilter: useLocalStorage<GenreModel>("hackmycart/concertStore/genreFilter", new GenreModel())
|
||||||
}),
|
}),
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
@@ -27,8 +32,12 @@ export const useConcertStore = defineStore("concertStore", {
|
|||||||
this.tours = result.data
|
this.tours = result.data
|
||||||
|
|
||||||
this.tours.sort((a, b) => {
|
this.tours.sort((a, b) => {
|
||||||
return new Date(a.shows[0].date) < new Date(b.shows[0].date) ? -1 : 1
|
return new Date(a.concerts[0].date) < new Date(b.concerts[0].date) ? -1 : 1
|
||||||
})
|
})
|
||||||
|
|
||||||
|
this.filteredTours = this.tours
|
||||||
|
|
||||||
|
this.filterTours()
|
||||||
})
|
})
|
||||||
|
|
||||||
await getAllBands()
|
await getAllBands()
|
||||||
@@ -50,6 +59,60 @@ export const useConcertStore = defineStore("concertStore", {
|
|||||||
.then(result => {
|
.then(result => {
|
||||||
this.cities = result.data
|
this.cities = result.data
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
filterTours() {
|
||||||
|
this.filteredTours = []
|
||||||
|
|
||||||
|
// Filter tours by city, location and genre
|
||||||
|
for (let tour of this.tours) {
|
||||||
|
let rightGenre = false
|
||||||
|
let rightCity = false
|
||||||
|
let rightLocation = false
|
||||||
|
|
||||||
|
// Genre filter
|
||||||
|
if (this.genreFilter == null || this.genreFilter.id == undefined) {
|
||||||
|
rightGenre = true
|
||||||
|
} else {
|
||||||
|
for (let genre of tour.band.genres) {
|
||||||
|
if (genre.name == this.genreFilter.name) {
|
||||||
|
rightGenre = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// City filter
|
||||||
|
if (this.cityFilter == null || this.cityFilter.id == undefined) {
|
||||||
|
rightCity = true
|
||||||
|
} else {
|
||||||
|
for (let concert of tour.concerts) {
|
||||||
|
if (concert.location.city.name == this.cityFilter.name) {
|
||||||
|
rightCity = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter locations by city
|
||||||
|
this.filteredLocations = this.cities.find(city =>
|
||||||
|
city.id == this.cityFilter.id
|
||||||
|
).locations
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Location filter
|
||||||
|
if (this.locationFilter == null || this.locationFilter.id == undefined) {
|
||||||
|
rightLocation = true
|
||||||
|
} else {
|
||||||
|
for (let concert of tour.concerts) {
|
||||||
|
if (concert.location.id == this.locationFilter.id) {
|
||||||
|
rightLocation = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rightGenre && rightCity && rightLocation) {
|
||||||
|
this.filteredTours.push(tour)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -11,17 +11,9 @@
|
|||||||
"topBands": "Top Bands",
|
"topBands": "Top Bands",
|
||||||
"topLocations": "Top Veranstaltungsorte"
|
"topLocations": "Top Veranstaltungsorte"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"tours": {
|
"tours": {
|
||||||
"concert": "Konzert | Konzerte"
|
"concert": "Konzert | Konzerte"
|
||||||
},
|
},
|
||||||
|
|
||||||
"preferences": {
|
"preferences": {
|
||||||
"pageSetup": "Seiteneinstellungen",
|
"pageSetup": "Seiteneinstellungen",
|
||||||
"selectedTheme": "Ausgewähltes Theme",
|
"selectedTheme": "Ausgewähltes Theme",
|
||||||
@@ -148,5 +140,8 @@
|
|||||||
"wrongIban": "Falsches IBAN Format, nur deutsche IBAN-Nummern erlaubt!",
|
"wrongIban": "Falsches IBAN Format, nur deutsche IBAN-Nummern erlaubt!",
|
||||||
"save": "Speichern",
|
"save": "Speichern",
|
||||||
"editProduct": "Produkt bearbeiten",
|
"editProduct": "Produkt bearbeiten",
|
||||||
"brand": "Marke | Marken"
|
"brand": "Marke | Marken",
|
||||||
|
"concerts": {
|
||||||
|
"location": "Veranstaltungsort"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,18 +11,9 @@
|
|||||||
"topBands": "Top Bands",
|
"topBands": "Top Bands",
|
||||||
"topLocations": "Top Locations"
|
"topLocations": "Top Locations"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"tours": {
|
"tours": {
|
||||||
"concert": "Concert | Concerts"
|
"concert": "Concert | Concerts"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
"preferences": {
|
"preferences": {
|
||||||
"pageSetup": "Page setup",
|
"pageSetup": "Page setup",
|
||||||
"selectedTheme": "Selected theme",
|
"selectedTheme": "Selected theme",
|
||||||
@@ -149,5 +140,8 @@
|
|||||||
"wrongIban": "Wrong IBAN format, only German IBANs are allowed!",
|
"wrongIban": "Wrong IBAN format, only German IBANs are allowed!",
|
||||||
"save": "Save",
|
"save": "Save",
|
||||||
"editProduct": "Edit product",
|
"editProduct": "Edit product",
|
||||||
"brand": "Brand | Brands"
|
"brand": "Brand | Brands",
|
||||||
|
"concerts": {
|
||||||
|
"location": "Locations"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import cardView from '@/components/cardView.vue';
|
import cardView from '@/components/cardView.vue';
|
||||||
import { useAccountStore } from '@/data/stores/accountStore';
|
import { useAccountStore } from '@/data/stores/accountStore';
|
||||||
import outlinedButton from '@/components/outlinedButton.vue';
|
import outlinedButton from '@/components/outlinedButton.vue';
|
||||||
import { AddressModel } from '@/data/models/addressModel';
|
import { AddressModel } from '@/data/models/user/addressModel';
|
||||||
import { useFeedbackStore } from '@/data/stores/feedbackStore';
|
import { useFeedbackStore } from '@/data/stores/feedbackStore';
|
||||||
import { getNumberStartRules, getPostalRules, getStringRules } from '@/scripts/validationRules';
|
import { getNumberStartRules, getPostalRules, getStringRules } from '@/scripts/validationRules';
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import cardView from '@/components/cardView.vue';
|
import cardView from '@/components/cardView.vue';
|
||||||
import { useAccountStore } from '@/data/stores/accountStore';
|
import { useAccountStore } from '@/data/stores/accountStore';
|
||||||
import outlinedButton from '@/components/outlinedButton.vue';
|
import outlinedButton from '@/components/outlinedButton.vue';
|
||||||
import { PaymentModel } from '@/data/models/paymentModel';
|
import { PaymentModel } from '@/data/models/user/paymentModel';
|
||||||
import { getIbanRules, getStringRules } from '@/scripts/validationRules';
|
import { getIbanRules, getStringRules } from '@/scripts/validationRules';
|
||||||
|
|
||||||
const accountStore = useAccountStore()
|
const accountStore = useAccountStore()
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { AccountModel } from '@/data/models/accountModel';
|
import { AccountModel } from '@/data/models/user/accountModel';
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import cardView from '@/components/cardView.vue';
|
import cardView from '@/components/cardView.vue';
|
||||||
import outlinedButton from '@/components/outlinedButton.vue';
|
import outlinedButton from '@/components/outlinedButton.vue';
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import cardView from '@/components/cardView.vue';
|
import cardView from '@/components/cardView.vue';
|
||||||
import { OrderModel } from '@/data/models/orderModel';
|
import { OrderModel } from '@/data/models/ordering/orderModel';
|
||||||
import { useAccountStore } from '@/data/stores/accountStore';
|
import { useAccountStore } from '@/data/stores/accountStore';
|
||||||
|
|
||||||
const accountStore = useAccountStore()
|
const accountStore = useAccountStore()
|
||||||
|
|||||||
@@ -2,5 +2,5 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
Tour Detail
|
||||||
</template>
|
</template>
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { SortOrder } from '@/data/enums/sortOrderEnum';
|
import { SortOrder } from '@/data/enums/sortOrderEnum';
|
||||||
import { useTourStore } from '@/data/stores/tourStore';
|
|
||||||
|
|
||||||
const tourStore = useTourStore()
|
|
||||||
const sortOrderItems = Object.values(SortOrder)
|
const sortOrderItems = Object.values(SortOrder)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -2,9 +2,7 @@
|
|||||||
import tourCard from "./tourCard.vue"
|
import tourCard from "./tourCard.vue"
|
||||||
import { ref, watch } from "vue";
|
import { ref, watch } from "vue";
|
||||||
import filterNavDrawer from "./filterNavDrawer.vue";
|
import filterNavDrawer from "./filterNavDrawer.vue";
|
||||||
import { useTourStore } from "@/data/stores/tourStore";
|
|
||||||
|
|
||||||
const tourStore = useTourStore()
|
|
||||||
|
|
||||||
const showProductDetails = ref(false)
|
const showProductDetails = ref(false)
|
||||||
// const dialogProduct = ref(new ProductModel())
|
// const dialogProduct = ref(new ProductModel())
|
||||||
@@ -20,7 +18,7 @@ const showProductDetails = ref(false)
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<v-container max-width="1200">
|
<!-- <v-container max-width="1200">
|
||||||
<v-row dense>
|
<v-row dense>
|
||||||
<v-col
|
<v-col
|
||||||
v-if="tourStore.tours.length > 0"
|
v-if="tourStore.tours.length > 0"
|
||||||
@@ -39,7 +37,7 @@ const showProductDetails = ref(false)
|
|||||||
/>
|
/>
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
</v-container>
|
</v-container> -->
|
||||||
|
|
||||||
<filter-nav-drawer />
|
<filter-nav-drawer />
|
||||||
|
|
||||||
|
|||||||
@@ -2,43 +2,40 @@
|
|||||||
import { VNumberInput } from 'vuetify/labs/VNumberInput'
|
import { VNumberInput } from 'vuetify/labs/VNumberInput'
|
||||||
import { ModelRef, ref, watch } from 'vue';
|
import { ModelRef, ref, watch } from 'vue';
|
||||||
import { useBasketStore } from '@/data/stores/basketStore';
|
import { useBasketStore } from '@/data/stores/basketStore';
|
||||||
import { calcPrice } from '@/scripts/productScripts';
|
|
||||||
import ActionDialog from '@/components/actionDialog.vue'
|
import ActionDialog from '@/components/actionDialog.vue'
|
||||||
import { ProductModel } from '@/data/models/productModel';
|
|
||||||
import outlinedButton from '@/components/outlinedButton.vue';
|
import outlinedButton from '@/components/outlinedButton.vue';
|
||||||
|
|
||||||
const props = defineProps({
|
// const props = defineProps({
|
||||||
product: {
|
// product: {
|
||||||
type: ProductModel,
|
// type: ProductModel,
|
||||||
default: new ProductModel()
|
// default: new ProductModel()
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
|
|
||||||
const showDialog: ModelRef<boolean> = defineModel()
|
// const showDialog: ModelRef<boolean> = defineModel()
|
||||||
const nrOfArticles = ref(1)
|
// const nrOfArticles = ref(1)
|
||||||
const basketStore = useBasketStore()
|
// const basketStore = useBasketStore()
|
||||||
const selectedImage = ref("")
|
// const selectedImage = ref("")
|
||||||
|
|
||||||
function addProductToBasket() {
|
// function addProductToBasket() {
|
||||||
basketStore.addItemToBasket(props.product, nrOfArticles.value)
|
// basketStore.addItemToBasket(props.product, nrOfArticles.value)
|
||||||
nrOfArticles.value = 1
|
// nrOfArticles.value = 1
|
||||||
showDialog.value = false
|
// showDialog.value = false
|
||||||
}
|
// }
|
||||||
|
|
||||||
watch(() => props.product.images, () => {
|
// watch(() => props.product.images, () => {
|
||||||
selectedImage.value = 'http://localhost:3000/static/' + props.product.images[0]
|
// selectedImage.value = 'http://localhost:3000/static/' + props.product.images[0]
|
||||||
})
|
// })
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<action-dialog
|
<!-- <action-dialog
|
||||||
:title="product.brand.name + ': ' + product.name"
|
:title="product.brand.name + ': ' + product.name"
|
||||||
:icon="product.category.icon"
|
:icon="product.category.icon"
|
||||||
:subtitle="product.category.name"
|
:subtitle="product.category.name"
|
||||||
v-model="showDialog"
|
v-model="showDialog"
|
||||||
>
|
>
|
||||||
<v-row>
|
<v-row>
|
||||||
<!-- Image col -->
|
|
||||||
<v-col>
|
<v-col>
|
||||||
<v-row>
|
<v-row>
|
||||||
<v-col class="py-0">
|
<v-col class="py-0">
|
||||||
@@ -66,7 +63,6 @@ watch(() => props.product.images, () => {
|
|||||||
</v-col>
|
</v-col>
|
||||||
|
|
||||||
|
|
||||||
<!-- Product description col -->
|
|
||||||
<v-col>
|
<v-col>
|
||||||
<v-row>
|
<v-row>
|
||||||
<v-col class="text-h6 pt-0">
|
<v-col class="text-h6 pt-0">
|
||||||
@@ -157,5 +153,5 @@ watch(() => props.product.images, () => {
|
|||||||
{{ $t('addToBasket') }}
|
{{ $t('addToBasket') }}
|
||||||
</outlined-button>
|
</outlined-button>
|
||||||
</template>
|
</template>
|
||||||
</action-dialog>
|
</action-dialog> -->
|
||||||
</template>
|
</template>
|
||||||
@@ -1,18 +1,17 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { TourModel } from '@/data/models/tourModel';
|
|
||||||
import cardView from '@/components/cardView.vue';
|
import cardView from '@/components/cardView.vue';
|
||||||
import OutlinedButton from '@/components/outlinedButton.vue';
|
import OutlinedButton from '@/components/outlinedButton.vue';
|
||||||
|
|
||||||
defineProps({
|
// defineProps({
|
||||||
tour: {
|
// tour: {
|
||||||
required: true,
|
// required: true,
|
||||||
type: TourModel
|
// type: TourModel
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<card-view
|
<!-- <card-view
|
||||||
:title="tour.band.name"
|
:title="tour.band.name"
|
||||||
:subtitle="tour.name"
|
:subtitle="tour.name"
|
||||||
:prepend-image="'http://127.0.0.1:3000/static/bands/' + tour.band.images[0]"
|
:prepend-image="'http://127.0.0.1:3000/static/bands/' + tour.band.images[0]"
|
||||||
@@ -24,7 +23,7 @@ defineProps({
|
|||||||
<OutlinedButton>
|
<OutlinedButton>
|
||||||
{{ tour.shows.length }} {{ $t('tours.concert', tour.shows.length) }}
|
{{ tour.shows.length }} {{ $t('tours.concert', tour.shows.length) }}
|
||||||
</OutlinedButton>
|
</OutlinedButton>
|
||||||
</template>
|
</template> -->
|
||||||
|
|
||||||
<!-- <template> -->
|
<!-- <template> -->
|
||||||
<!-- <div>
|
<!-- <div>
|
||||||
@@ -75,7 +74,7 @@ defineProps({
|
|||||||
</div>
|
</div>
|
||||||
</div> -->
|
</div> -->
|
||||||
<!-- </template> -->
|
<!-- </template> -->
|
||||||
</card-view>
|
<!-- </card-view> -->
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
87
software/src/pages/shows/toursPage/filterBar.vue
Normal file
87
software/src/pages/shows/toursPage/filterBar.vue
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import cardView from '@/components/cardView.vue';
|
||||||
|
import { useConcertStore } from '@/data/stores/concertStore';
|
||||||
|
|
||||||
|
const concertStore = useConcertStore()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<card-view
|
||||||
|
variant="tonal"
|
||||||
|
>
|
||||||
|
<v-row>
|
||||||
|
<v-col cols="3">
|
||||||
|
<v-select
|
||||||
|
variant="outlined"
|
||||||
|
:items="concertStore.cities"
|
||||||
|
v-model="concertStore.cityFilter"
|
||||||
|
label="Stadt"
|
||||||
|
density="compact"
|
||||||
|
class="mb-n5"
|
||||||
|
:clearable="concertStore.cityFilter != null && concertStore.cityFilter.id != undefined"
|
||||||
|
base-color="secondary"
|
||||||
|
color="secondary"
|
||||||
|
>
|
||||||
|
<template #item="{ props, item }">
|
||||||
|
<v-list-item v-bind="props" :title="item.raw.name" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #selection="{ item }">
|
||||||
|
<v-list-item :title="item.raw.name" />
|
||||||
|
</template>
|
||||||
|
</v-select>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col cols="auto" class="d-flex justify-center align-center px-0">
|
||||||
|
<v-icon icon="mdi-chevron-right" />
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col cols="4">
|
||||||
|
<v-select
|
||||||
|
variant="outlined"
|
||||||
|
:items="concertStore.filteredLocations"
|
||||||
|
v-model="concertStore.locationFilter"
|
||||||
|
:label="$t('concerts.location')"
|
||||||
|
density="compact"
|
||||||
|
:clearable="concertStore.locationFilter != null && concertStore.locationFilter.id != undefined"
|
||||||
|
:disabled="concertStore.cityFilter == null || concertStore.cityFilter.id == undefined"
|
||||||
|
class="mb-n5"
|
||||||
|
base-color="secondary"
|
||||||
|
color="secondary"
|
||||||
|
>
|
||||||
|
<template #item="{ props, item }">
|
||||||
|
<v-list-item v-bind="props" :title="item.raw.name" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #selection="{ item }">
|
||||||
|
<v-list-item :title="item.raw.name" />
|
||||||
|
</template>
|
||||||
|
</v-select>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-divider vertical />
|
||||||
|
|
||||||
|
<v-col cols="4">
|
||||||
|
<v-select
|
||||||
|
variant="outlined"
|
||||||
|
:items="concertStore.genres"
|
||||||
|
v-model="concertStore.genreFilter"
|
||||||
|
label="Genre"
|
||||||
|
density="compact"
|
||||||
|
:clearable="concertStore.genreFilter != null && concertStore.genreFilter.id != undefined"
|
||||||
|
class="mb-n5"
|
||||||
|
base-color="secondary"
|
||||||
|
color="secondary"
|
||||||
|
>
|
||||||
|
<template #item="{ props, item }">
|
||||||
|
<v-list-item v-bind="props" :title="item.raw.name" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #selection="{ item }">
|
||||||
|
<v-list-item :title="item.raw.name" />
|
||||||
|
</template>
|
||||||
|
</v-select>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</card-view>
|
||||||
|
</template>
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
import cardWithLeftImage from '@/components/cardWithLeftImage.vue';
|
import cardWithLeftImage from '@/components/cardWithLeftImage.vue';
|
||||||
import { useConcertStore } from '@/data/stores/concertStore';
|
import { useConcertStore } from '@/data/stores/concertStore';
|
||||||
import { createDateRangeString, lowestTicketPrice } from '@/scripts/concertScripts';
|
import { createDateRangeString, lowestTicketPrice } from '@/scripts/concertScripts';
|
||||||
|
import filterBar from './filterBar.vue';
|
||||||
|
|
||||||
const concertStore = useConcertStore()
|
const concertStore = useConcertStore()
|
||||||
</script>
|
</script>
|
||||||
@@ -12,14 +13,23 @@ const concertStore = useConcertStore()
|
|||||||
<v-spacer />
|
<v-spacer />
|
||||||
|
|
||||||
<v-col cols="10">
|
<v-col cols="10">
|
||||||
<v-row v-for="tour of concertStore.tours">
|
<v-row>
|
||||||
|
<v-col>
|
||||||
|
<filter-bar />
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
|
||||||
|
<v-row
|
||||||
|
v-if="concertStore.filteredTours.length > 0"
|
||||||
|
v-for="tour of concertStore.filteredTours"
|
||||||
|
>
|
||||||
<v-col>
|
<v-col>
|
||||||
<card-with-left-image
|
<card-with-left-image
|
||||||
:title="tour.band.name + ' - ' + tour.name"
|
:title="tour.band.name + ' - ' + tour.name"
|
||||||
:image="'http://localhost:3000/static/tours/' + tour.image"
|
:image="'http://localhost:3000/static/tours/' + tour.image"
|
||||||
>
|
>
|
||||||
{{ createDateRangeString(tour) }}
|
{{ createDateRangeString(tour) }}
|
||||||
<div>{{ tour.shows.length }} {{ $t('tours.concert', tour.shows.length) }}</div>
|
<div>{{ tour.concerts.length }} {{ $t('tours.concert', tour.concerts.length) }}</div>
|
||||||
|
|
||||||
<template #append>
|
<template #append>
|
||||||
<div class="d-flex justify-center align-center text-h5" style="height: 100%;">
|
<div class="d-flex justify-center align-center text-h5" style="height: 100%;">
|
||||||
@@ -29,6 +39,15 @@ const concertStore = useConcertStore()
|
|||||||
</card-with-left-image>
|
</card-with-left-image>
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
|
|
||||||
|
<v-row v-else>
|
||||||
|
<v-col>
|
||||||
|
<v-empty-state
|
||||||
|
title="Keine Konzerte gefunden"
|
||||||
|
icon="mdi-magnify"
|
||||||
|
/>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
</v-col>
|
</v-col>
|
||||||
|
|
||||||
<v-spacer />
|
<v-spacer />
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
import ConcertsPage from "@/pages/shows/concertsPage/index.vue";
|
import ToursPage from "@/pages/shows/toursPage/index.vue";
|
||||||
import BandsPage from "@/pages/shows/bandsPage/index.vue";
|
import BandsPage from "@/pages/shows/bandsPage/index.vue";
|
||||||
import LocationsPage from "@/pages/shows/locationsPage/index.vue"
|
import LocationsPage from "@/pages/shows/locationsPage/index.vue"
|
||||||
import SearchPage from "@/pages/shows/searchPage/index.vue"
|
import SearchPage from "@/pages/shows/searchPage/index.vue"
|
||||||
|
|
||||||
export const showRoutes = [
|
export const showRoutes = [
|
||||||
{ path: '/shows/concerts', component: ConcertsPage },
|
{ path: '/shows/tours', component: ToursPage },
|
||||||
{ path: '/shows/bands', component: BandsPage },
|
{ path: '/shows/bands', component: BandsPage },
|
||||||
{ path: '/shows/locations', component: LocationsPage },
|
{ path: '/shows/locations', component: LocationsPage },
|
||||||
{ path: '/shows/search', component: SearchPage },
|
{ path: '/shows/search', component: SearchPage },
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { RatingModel } from "@/data/models/ratingModel"
|
import { RatingModel } from "@/data/models/acts/ratingModel"
|
||||||
import { dateToHumanReadableString } from "./dateTimeScripts"
|
import { dateToHumanReadableString } from "./dateTimeScripts"
|
||||||
import { TourModel } from "@/data/models/tourModel"
|
import { TourModel } from "@/data/models/acts/tourModel"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate a price based on parameters
|
* Calculate a price based on parameters
|
||||||
@@ -35,7 +35,7 @@ export function calcRating(ratings: Array<RatingModel>) {
|
|||||||
export function createDateRangeString(tour: TourModel) {
|
export function createDateRangeString(tour: TourModel) {
|
||||||
const dateArray = []
|
const dateArray = []
|
||||||
|
|
||||||
for (let concert of tour.shows) {
|
for (let concert of tour.concerts) {
|
||||||
dateArray.push(new Date(concert.date))
|
dateArray.push(new Date(concert.date))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ export function createDateRangeString(tour: TourModel) {
|
|||||||
export function lowestTicketPrice(tour: TourModel): string {
|
export function lowestTicketPrice(tour: TourModel): string {
|
||||||
const priceArray : Array<number> = []
|
const priceArray : Array<number> = []
|
||||||
|
|
||||||
for (let concert of tour.shows) {
|
for (let concert of tour.concerts) {
|
||||||
priceArray.push(concert.price)
|
priceArray.push(concert.price)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user