Implement global search
This commit is contained in:
@@ -59,7 +59,7 @@ band.get("/", (req: Request, res: Response) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Get all information about one band
|
// Get all information about one band
|
||||||
band.get("/:name", (req: Request, res: Response) => {
|
band.get("/band/:name", (req: Request, res: Response) => {
|
||||||
Band.findOne({
|
Band.findOne({
|
||||||
where: {
|
where: {
|
||||||
name: { [Op.like]: req.params.name }
|
name: { [Op.like]: req.params.name }
|
||||||
@@ -110,3 +110,18 @@ band.get("/:name", (req: Request, res: Response) => {
|
|||||||
res.status(200).json(band)
|
res.status(200).json(band)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
// Band search
|
||||||
|
band.get("/search", (req: Request, res: Response) => {
|
||||||
|
Band.findAll({
|
||||||
|
where: {
|
||||||
|
name: {
|
||||||
|
[Op.substring]: req.query.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(bands => {
|
||||||
|
res.status(200).json(bands)
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -8,10 +8,11 @@ import { SeatRow } from "../models/locations/seatRow.model";
|
|||||||
import { Seat } from "../models/locations/seat.model";
|
import { Seat } from "../models/locations/seat.model";
|
||||||
import { Ticket } from "../models/ordering/ticket.model";
|
import { Ticket } from "../models/ordering/ticket.model";
|
||||||
import { Band } from "../models/acts/band.model";
|
import { Band } from "../models/acts/band.model";
|
||||||
|
import { Op } from "sequelize";
|
||||||
|
|
||||||
export const concert = Router()
|
export const concert = Router()
|
||||||
|
|
||||||
concert.get("/:id", (req: Request, res: Response) => {
|
concert.get("/concert/:id", (req: Request, res: Response) => {
|
||||||
Concert.findByPk(req.params.id, {
|
Concert.findByPk(req.params.id, {
|
||||||
include: [
|
include: [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { Request, Response, Router } from "express";
|
|||||||
import { Location } from "../models/locations/location.model";
|
import { Location } from "../models/locations/location.model";
|
||||||
import { Genre } from "../models/acts/genre.model";
|
import { Genre } from "../models/acts/genre.model";
|
||||||
import { City } from "../models/locations/city.model";
|
import { City } from "../models/locations/city.model";
|
||||||
|
import { Op } from "sequelize";
|
||||||
|
|
||||||
export const events = Router()
|
export const events = Router()
|
||||||
|
|
||||||
@@ -80,5 +81,33 @@ events.get("/", async (req: Request, res: Response) => {
|
|||||||
|
|
||||||
res.status(200).json(events)
|
res.status(200).json(events)
|
||||||
})
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
// Event search
|
||||||
|
events.get("/search", (req: Request, res: Response) => {
|
||||||
|
Event.findAll({
|
||||||
|
where: {
|
||||||
|
name: {
|
||||||
|
[Op.substring]: req.query.value
|
||||||
|
}
|
||||||
|
},
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: Concert,
|
||||||
|
required: true,
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: Location,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
model: Band,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
.then(events => {
|
||||||
|
res.status(200).json(events)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
@@ -7,6 +7,7 @@ import { Band } from "../models/acts/band.model";
|
|||||||
import { SeatGroup } from "../models/locations/seatGroup.model";
|
import { SeatGroup } from "../models/locations/seatGroup.model";
|
||||||
import { Seat } from "../models/locations/seat.model";
|
import { Seat } from "../models/locations/seat.model";
|
||||||
import { SeatRow } from "../models/locations/seatRow.model";
|
import { SeatRow } from "../models/locations/seatRow.model";
|
||||||
|
import { Op } from "sequelize";
|
||||||
|
|
||||||
export const location = Router()
|
export const location = Router()
|
||||||
|
|
||||||
@@ -69,7 +70,7 @@ location.get("/", (req: Request, res: Response) => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
location.get("/:urlName", (req: Request, res: Response) => {
|
location.get("/location/:urlName", (req: Request, res: Response) => {
|
||||||
Location.findOne({
|
Location.findOne({
|
||||||
where: { urlName: req.params.urlName },
|
where: { urlName: req.params.urlName },
|
||||||
include: [
|
include: [
|
||||||
@@ -118,3 +119,18 @@ location.get("/:urlName", (req: Request, res: Response) => {
|
|||||||
res.status(200).json(location)
|
res.status(200).json(location)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
// Location search
|
||||||
|
location.get("/search", (req: Request, res: Response) => {
|
||||||
|
Location.findAll({
|
||||||
|
where: {
|
||||||
|
name: {
|
||||||
|
[Op.substring]: req.query.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(locations => {
|
||||||
|
res.status(200).json(locations)
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -6,38 +6,21 @@ import navigationAppendItems from './components/navigation/navigationAppendItems
|
|||||||
import navigationPrependItems from './components/navigation/navigationPrependItems.vue';
|
import navigationPrependItems from './components/navigation/navigationPrependItems.vue';
|
||||||
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 { LocationModel } from './data/models/locations/locationModel';
|
|
||||||
import { useShoppingStore } from './data/stores/shoppingStore';
|
import { useShoppingStore } from './data/stores/shoppingStore';
|
||||||
import footerItems from './components/navigation/footerItems.vue';
|
import footerItems from './components/navigation/footerItems.vue';
|
||||||
|
|
||||||
const preferencesStore = usePreferencesStore()
|
const preferencesStore = usePreferencesStore()
|
||||||
const concertStore = useConcertStore()
|
|
||||||
const feedbackStore = useFeedbackStore()
|
const feedbackStore = useFeedbackStore()
|
||||||
const shoppingStore = useShoppingStore()
|
const shoppingStore = useShoppingStore()
|
||||||
const theme = useTheme()
|
const theme = useTheme()
|
||||||
|
|
||||||
theme.global.name.value = preferencesStore.theme
|
theme.global.name.value = preferencesStore.theme
|
||||||
|
|
||||||
concertStore.fetchAllTours()
|
|
||||||
|
|
||||||
// Global watcher
|
// Global watcher
|
||||||
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>
|
||||||
|
|||||||
@@ -5,22 +5,10 @@ import router from '@/plugins/router';
|
|||||||
|
|
||||||
const accountStore = useAccountStore()
|
const accountStore = useAccountStore()
|
||||||
const basketStore = useBasketStore()
|
const basketStore = useBasketStore()
|
||||||
|
|
||||||
function startSearch() {
|
|
||||||
// todo
|
|
||||||
router.push("/shows/search")
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<v-text-field
|
<v-btn variant="plain" icon="mdi-magnify" to="/search" />
|
||||||
variant="outlined"
|
|
||||||
append-inner-icon="mdi-magnify"
|
|
||||||
density="compact"
|
|
||||||
class="mt-5 mr-5"
|
|
||||||
@click:append-inner="startSearch"
|
|
||||||
width="400"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<v-btn v-if="accountStore.userAccount.id == 0" variant="plain" icon="mdi-account" to="/account/login" />
|
<v-btn v-if="accountStore.userAccount.id == 0" variant="plain" icon="mdi-account" to="/account/login" />
|
||||||
<v-btn v-else variant="plain" icon="mdi-account" to="/account/home" />
|
<v-btn v-else variant="plain" icon="mdi-account" to="/account/home" />
|
||||||
|
|||||||
23
software/src/components/pageParts/locationListItem.vue
Normal file
23
software/src/components/pageParts/locationListItem.vue
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import cardViewTopImage from '../basics/cardViewTopImage.vue';
|
||||||
|
import { LocationModel } from '@/data/models/locations/locationModel';
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
defineProps({
|
||||||
|
location: LocationModel
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<card-view-top-image
|
||||||
|
:image="location.imageOutdoor"
|
||||||
|
:title="location.name"
|
||||||
|
@click="router.push('locations/' + location.name.replaceAll(' ', '-').toLowerCase())"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
{{ location.concerts.length }} {{ $t('concert', location.concerts.length) }}
|
||||||
|
</div>
|
||||||
|
</card-view-top-image>
|
||||||
|
</template>
|
||||||
@@ -7,5 +7,9 @@ export async function getAllBands() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function getBand(bandName: string) {
|
export async function getBand(bandName: string) {
|
||||||
return await axios.get(BASE_URL + '/' + bandName)
|
return await axios.get(BASE_URL + '/band/' + bandName)
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function searchBand(searchTerm: string) {
|
||||||
|
return await axios.get(BASE_URL + '/search?value=' + searchTerm)
|
||||||
}
|
}
|
||||||
@@ -2,13 +2,9 @@ import axios from "axios"
|
|||||||
|
|
||||||
let BASE_URL = "http://localhost:3000/concerts"
|
let BASE_URL = "http://localhost:3000/concerts"
|
||||||
|
|
||||||
export async function getAllConcerts() {
|
|
||||||
return await axios.get(BASE_URL)
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getConcert(id: number) {
|
export async function getConcert(id: number) {
|
||||||
if (id != undefined) {
|
if (id != undefined) {
|
||||||
return await axios.get(BASE_URL + "/" + id)
|
return await axios.get(BASE_URL + "/concert/" + id)
|
||||||
} else {
|
} else {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,3 +15,7 @@ export async function getTopEvents(nrOfEvents) {
|
|||||||
|
|
||||||
return await axios.get(url)
|
return await axios.get(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function searchEvent(searchTerm: string) {
|
||||||
|
return await axios.get(BASE_URL + "/search?value=" + searchTerm)
|
||||||
|
}
|
||||||
@@ -7,7 +7,7 @@ export async function getAllLocations() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function getLocation(locationName: string) {
|
export async function getLocation(locationName: string) {
|
||||||
return await axios.get(BASE_URL + "/" + locationName)
|
return await axios.get(BASE_URL + "/location/" + locationName)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getTopLocations(nrOfLocations: number) {
|
export async function getTopLocations(nrOfLocations: number) {
|
||||||
@@ -15,3 +15,7 @@ export async function getTopLocations(nrOfLocations: number) {
|
|||||||
|
|
||||||
return await axios.get(url)
|
return await axios.get(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function searchLocation(searchTerm: string) {
|
||||||
|
return await axios.get(BASE_URL + "/search?value=" + searchTerm)
|
||||||
|
}
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
import axios from "axios"
|
|
||||||
|
|
||||||
let BASE_URL = "http://localhost:3000/tours"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetch all tours from API
|
|
||||||
*/
|
|
||||||
export async function getAllTours() {
|
|
||||||
//return await axios.get(BASE_URL)
|
|
||||||
}
|
|
||||||
@@ -1,122 +0,0 @@
|
|||||||
import { useLocalStorage } from "@vueuse/core";
|
|
||||||
import { defineStore } from "pinia";
|
|
||||||
import { TourModel } from "../models/acts/tourModel";
|
|
||||||
import { getAllTours } from "../api/tourApi";
|
|
||||||
import { GenreModel } from "../models/acts/genreModel";
|
|
||||||
import { getAllBands } from "../api/bandApi";
|
|
||||||
import { BandModel } from "../models/acts/bandModel";
|
|
||||||
import { LocationModel } from "../models/locations/locationModel";
|
|
||||||
import { getAllLocations } from "../api/locationApi";
|
|
||||||
import { getAllGenres } from "../api/genreApi";
|
|
||||||
import { CityModel } from "../models/locations/cityModel";
|
|
||||||
import { getAllCities } from "../api/cityApi";
|
|
||||||
|
|
||||||
export const useConcertStore = defineStore("concertStore", {
|
|
||||||
state: () => ({
|
|
||||||
tours: useLocalStorage<Array<TourModel>>("hackmycart/concertStore/tours", []),
|
|
||||||
filteredTours: useLocalStorage<Array<TourModel>>("hackmycart/concertStore/filteredTours", []),
|
|
||||||
bands: useLocalStorage<Array<BandModel>>("hackmycart/concertStore/bands", []),
|
|
||||||
locations: useLocalStorage<Array<LocationModel>>("hackmycart/concertStore/locations", []),
|
|
||||||
filteredLocations: useLocalStorage<Array<LocationModel>>("hackmycart/concertStore/filteredLocations", []),
|
|
||||||
cities: useLocalStorage<Array<CityModel>>("hackmycart/concertStore/cities", []),
|
|
||||||
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: {
|
|
||||||
async fetchAllTours() {
|
|
||||||
await getAllTours()
|
|
||||||
.then(result => {
|
|
||||||
// this.tours = result.data
|
|
||||||
|
|
||||||
// this.tours.sort((a, b) => {
|
|
||||||
// return new Date(a.concerts[0].date) < new Date(b.concerts[0].date) ? -1 : 1
|
|
||||||
// })
|
|
||||||
|
|
||||||
// this.filteredTours = this.tours
|
|
||||||
|
|
||||||
// this.filterTours()
|
|
||||||
})
|
|
||||||
|
|
||||||
await getAllBands()
|
|
||||||
.then(result => {
|
|
||||||
this.bands = result.data
|
|
||||||
})
|
|
||||||
|
|
||||||
await getAllLocations()
|
|
||||||
.then(result => {
|
|
||||||
this.locations = result.data
|
|
||||||
})
|
|
||||||
|
|
||||||
await getAllGenres()
|
|
||||||
.then(result => {
|
|
||||||
this.genres = result.data
|
|
||||||
|
|
||||||
this.genres.sort((a, b) => {
|
|
||||||
return a.name > b.name
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
await getAllCities()
|
|
||||||
.then(result => {
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
import { useLocalStorage } from "@vueuse/core";
|
|
||||||
import { defineStore } from "pinia";
|
|
||||||
|
|
||||||
const useScoreStore = defineStore("scoreStore", {
|
|
||||||
state: () => ({
|
|
||||||
progressGroup0: useLocalStorage("hackmycart/scoreStore/progressGroup0", 0),
|
|
||||||
progressGroup1: useLocalStorage("hackmycart/scoreStore/progressGroup1", 0),
|
|
||||||
progressGroup2: useLocalStorage("hackmycart/scoreStore/progressGroup2", 0),
|
|
||||||
progressGroup3: useLocalStorage("hackmycart/scoreStore/progressGroup3", 0),
|
|
||||||
})
|
|
||||||
})
|
|
||||||
43
software/src/data/stores/searchStore.ts
Normal file
43
software/src/data/stores/searchStore.ts
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
import { defineStore } from "pinia";
|
||||||
|
import { ref } from "vue";
|
||||||
|
import { searchBand } from "../api/bandApi";
|
||||||
|
import { searchLocation } from "../api/locationApi";
|
||||||
|
import { searchEvent } from "../api/eventApi";
|
||||||
|
|
||||||
|
export const useSearchStore = defineStore("searchStore", {
|
||||||
|
state: () => ({
|
||||||
|
searchTerm: ref(""),
|
||||||
|
bands: ref(),
|
||||||
|
locations: ref(),
|
||||||
|
events: ref(),
|
||||||
|
alreadySearched: ref(false),
|
||||||
|
searchInProgress: ref(false)
|
||||||
|
}),
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
/**
|
||||||
|
* Search for the termin in all bands, locations, events
|
||||||
|
*/
|
||||||
|
async startSearch() {
|
||||||
|
this.alreadySearched = true
|
||||||
|
this.searchInProgress = true
|
||||||
|
|
||||||
|
await searchBand(this.searchTerm)
|
||||||
|
.then(result => {
|
||||||
|
this.bands = result.data
|
||||||
|
})
|
||||||
|
|
||||||
|
await searchLocation(this.searchTerm)
|
||||||
|
.then(result => {
|
||||||
|
this.locations = result.data
|
||||||
|
})
|
||||||
|
|
||||||
|
await searchEvent(this.searchTerm)
|
||||||
|
.then(result => {
|
||||||
|
this.events = result.data
|
||||||
|
})
|
||||||
|
|
||||||
|
this.searchInProgress = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
@@ -170,5 +170,6 @@
|
|||||||
"description": "Soll der Bearbeitungsfortschritt der Übungen wirklich zurückgesetzt werden? Dies kann nicht rückgänig gemacht werden!"
|
"description": "Soll der Bearbeitungsfortschritt der Übungen wirklich zurückgesetzt werden? Dies kann nicht rückgänig gemacht werden!"
|
||||||
},
|
},
|
||||||
"goToTheConcert": "Zum Konzert",
|
"goToTheConcert": "Zum Konzert",
|
||||||
"selectedConcert": "Ausgewähltes Konzert"
|
"selectedConcert": "Ausgewähltes Konzert",
|
||||||
|
"enterSomeKeywords": "Füge Schlagworte ein um nach Bands, Events, Konzerten und Veranstaltungsorten zu suchen"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -170,5 +170,6 @@
|
|||||||
"description": "Do you really want to reset the exercise progress? This can't be undone!"
|
"description": "Do you really want to reset the exercise progress? This can't be undone!"
|
||||||
},
|
},
|
||||||
"goToTheConcert": "To the concert",
|
"goToTheConcert": "To the concert",
|
||||||
"selectedConcert": "Selected Concert"
|
"selectedConcert": "Selected Concert",
|
||||||
|
"enterSomeKeywords": "Enter keywords to search for bands, events, concerts and locations"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
Search
|
|
||||||
</template>
|
|
||||||
@@ -1,10 +1,12 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import OutlinedButton from '@/components/basics/outlinedButton.vue';
|
import OutlinedButton from '@/components/basics/outlinedButton.vue';
|
||||||
import { useConcertStore } from '@/data/stores/concertStore';
|
import { useShoppingStore } from '@/data/stores/shoppingStore';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
|
|
||||||
const concertStore = useConcertStore()
|
const shoppingStore = useShoppingStore()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
|
shoppingStore.getEvents()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -31,27 +33,27 @@ const router = useRouter()
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<v-carousel-item
|
<v-carousel-item
|
||||||
v-for="band in concertStore.bands"
|
v-for="event in shoppingStore.events"
|
||||||
:src="'http://localhost:3000/static/' + band.imageMembers"
|
:src="'http://localhost:3000/static/' + event.band.imageMembers"
|
||||||
cover
|
cover
|
||||||
>
|
>
|
||||||
<v-card
|
<v-card
|
||||||
class="position-absolute bottom-0"
|
class="position-absolute bottom-0"
|
||||||
:title="band.name"
|
:title="event.name"
|
||||||
width="100%"
|
width="100%"
|
||||||
:rounded="false"
|
:rounded="false"
|
||||||
background-opacity="50%"
|
background-opacity="50%"
|
||||||
>
|
>
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
<div>
|
<div>
|
||||||
{{ band.descriptionDe }}
|
{{ event.band.descriptionDe }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<outlined-button
|
<outlined-button
|
||||||
append-icon="mdi-arrow-right"
|
append-icon="mdi-arrow-right"
|
||||||
class="mt-2"
|
class="mt-2"
|
||||||
color="primary"
|
color="primary"
|
||||||
@click="router.push('bands/' + band.name.replaceAll(' ', '-').toLowerCase())"
|
@click="router.push('bands/' + event.name.replaceAll(' ', '-').toLowerCase())"
|
||||||
>
|
>
|
||||||
{{ $t('tickets', 2) }}
|
{{ $t('tickets', 2) }}
|
||||||
</outlined-button>
|
</outlined-button>
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useConcertStore } from '@/data/stores/concertStore';
|
|
||||||
import highlightCarousel from './highlightCarousel.vue';
|
import highlightCarousel from './highlightCarousel.vue';
|
||||||
import sectionDivider from '@/components/basics/sectionDivider.vue';
|
import sectionDivider from '@/components/basics/sectionDivider.vue';
|
||||||
import cardWithTopImage from '@/components/basics/cardViewTopImage.vue';
|
import cardWithTopImage from '@/components/basics/cardViewTopImage.vue';
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import cardWithTopImage from '@/components/basics/cardViewTopImage.vue';
|
|||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import { useShoppingStore } from '@/data/stores/shoppingStore';
|
import { useShoppingStore } from '@/data/stores/shoppingStore';
|
||||||
import { useFeedbackStore } from '@/data/stores/feedbackStore';
|
import { useFeedbackStore } from '@/data/stores/feedbackStore';
|
||||||
|
import locationListItem from '@/components/pageParts/locationListItem.vue';
|
||||||
|
|
||||||
const shoppingStore = useShoppingStore()
|
const shoppingStore = useShoppingStore()
|
||||||
const feedbackStore = useFeedbackStore()
|
const feedbackStore = useFeedbackStore()
|
||||||
@@ -51,15 +52,7 @@ shoppingStore.getCities()
|
|||||||
|
|
||||||
<v-row>
|
<v-row>
|
||||||
<v-col v-for="location in city.locations" cols="3">
|
<v-col v-for="location in city.locations" cols="3">
|
||||||
<card-with-top-image
|
<location-list-item :location="location" />
|
||||||
:image="location.imageOutdoor"
|
|
||||||
:title="location.name"
|
|
||||||
@click="router.push('locations/' + location.name.replaceAll(' ', '-').toLowerCase())"
|
|
||||||
>
|
|
||||||
<div>
|
|
||||||
{{ location.nrOfConcerts }} {{ $t('concert', location.nrOfConcerts) }}
|
|
||||||
</div>
|
|
||||||
</card-with-top-image>
|
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
75
software/src/pages/searchPage/index.vue
Normal file
75
software/src/pages/searchPage/index.vue
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import searchBar from './searchBar.vue';
|
||||||
|
import eventListItem from '@/components/pageParts/eventListItem.vue';
|
||||||
|
import sectionDivider from '@/components/basics/sectionDivider.vue';
|
||||||
|
import { useSearchStore } from '@/data/stores/searchStore';
|
||||||
|
|
||||||
|
const searchStore = useSearchStore()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<v-container>
|
||||||
|
<v-row>
|
||||||
|
<v-spacer />
|
||||||
|
|
||||||
|
<v-col cols="10">
|
||||||
|
<v-row>
|
||||||
|
<v-col>
|
||||||
|
<search-bar />
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
|
||||||
|
<v-row>
|
||||||
|
<v-col>
|
||||||
|
{{ searchStore.bands }}
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
|
||||||
|
<v-row>
|
||||||
|
<v-col>
|
||||||
|
{{ searchStore.locations }}
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
|
||||||
|
|
||||||
|
<v-row>
|
||||||
|
<v-col>
|
||||||
|
<section-divider
|
||||||
|
v-if="searchStore.alreadySearched"
|
||||||
|
:title="$t('event', 2)"
|
||||||
|
/>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
|
||||||
|
<v-row
|
||||||
|
v-if="searchStore.alreadySearched && !searchStore.searchInProgress"
|
||||||
|
v-for="event in searchStore.events"
|
||||||
|
>
|
||||||
|
<v-col>
|
||||||
|
<event-list-item :event="event" :loading="searchStore.searchInProgress" />
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
|
||||||
|
<v-row
|
||||||
|
v-else-if="searchStore.alreadySearched && searchStore.searchInProgress"
|
||||||
|
v-for="i in 3"
|
||||||
|
>
|
||||||
|
<v-col>
|
||||||
|
<event-list-item :loading="searchStore.searchInProgress" />
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
|
||||||
|
<v-row>
|
||||||
|
<v-col>
|
||||||
|
<v-empty-state
|
||||||
|
:title="$t('noEventsFound')"
|
||||||
|
icon="mdi-magnify"
|
||||||
|
/>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-spacer />
|
||||||
|
</v-row>
|
||||||
|
</v-container>
|
||||||
|
</template>
|
||||||
25
software/src/pages/searchPage/searchBar.vue
Normal file
25
software/src/pages/searchPage/searchBar.vue
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import cardView from '@/components/basics/cardView.vue';
|
||||||
|
import { useSearchStore } from '@/data/stores/searchStore';
|
||||||
|
|
||||||
|
const searchStore = useSearchStore()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<card-view >
|
||||||
|
<v-text-field
|
||||||
|
variant="outlined"
|
||||||
|
hide-details
|
||||||
|
v-model="searchStore.searchTerm"
|
||||||
|
:placeholder="$t('enterSomeKeywords')"
|
||||||
|
>
|
||||||
|
<template #append-inner>
|
||||||
|
<v-btn
|
||||||
|
icon="mdi-magnify"
|
||||||
|
variant="plain"
|
||||||
|
@click="searchStore.startSearch"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</v-text-field>
|
||||||
|
</card-view>
|
||||||
|
</template>
|
||||||
@@ -5,7 +5,7 @@ import { accountRoutes } from "./account.routes";
|
|||||||
import { systemRoutes } from "./system.routes";
|
import { systemRoutes } from "./system.routes";
|
||||||
import EventsPage from "@/pages/events/eventsPage/index.vue";
|
import EventsPage from "@/pages/events/eventsPage/index.vue";
|
||||||
import LocationsPage from "@/pages/locations/locationsPage/index.vue"
|
import LocationsPage from "@/pages/locations/locationsPage/index.vue"
|
||||||
import SearchPage from "@/pages/events/searchPage/index.vue"
|
import SearchPage from "@/pages/searchPage/index.vue"
|
||||||
import BandDetailPage from "@/pages/events/bandDetailPage/index.vue"
|
import BandDetailPage from "@/pages/events/bandDetailPage/index.vue"
|
||||||
import LocationDetailPage from "@/pages/locations/locationDetailPage/index.vue"
|
import LocationDetailPage from "@/pages/locations/locationDetailPage/index.vue"
|
||||||
import TicketOrderPage from "@/pages/events/ticketOrderPage/index.vue"
|
import TicketOrderPage from "@/pages/events/ticketOrderPage/index.vue"
|
||||||
|
|||||||
Reference in New Issue
Block a user