Remove EventTable in database, redesign frontend URL paths
This commit is contained in:
60
software/src/pages/misc/basketPage/index.vue
Normal file
60
software/src/pages/misc/basketPage/index.vue
Normal file
@@ -0,0 +1,60 @@
|
||||
<script setup lang="ts">
|
||||
import { useBasketStore } from '@/data/stores/basketStore';
|
||||
import cardView from '@/components/basics/cardView.vue';
|
||||
import orderingDialog from './orderingDialog.vue';
|
||||
import outlinedButton from '@/components/basics/outlinedButton.vue';
|
||||
import { ref } from 'vue';
|
||||
import { useAccountStore } from '@/data/stores/accountStore';
|
||||
import ticketsTable from './ticketsTable.vue';
|
||||
|
||||
const basketStore = useBasketStore()
|
||||
const accountStore = useAccountStore()
|
||||
const showOrderingDialog = ref()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<v-container max-width="1000">
|
||||
<v-row>
|
||||
<v-col>
|
||||
<card-view
|
||||
:title="$t('basket')"
|
||||
:subtitle="basketStore.itemsInBasket.length + ' ' +
|
||||
$tc('product.product', basketStore.itemsInBasket.length)"
|
||||
v-model="showOrderingDialog"
|
||||
icon="mdi-cart"
|
||||
>
|
||||
<!-- Display items if basket is not empty -->
|
||||
<div v-if="basketStore.itemsInBasket.length > 0">
|
||||
<tickets-table />
|
||||
</div>
|
||||
|
||||
<!-- Display empty state if card is empty -->
|
||||
<v-empty-state v-else
|
||||
icon="mdi-basket-off"
|
||||
:title="$t('emptyBasketTitle')"
|
||||
:text="$t('emptyBasketText')"
|
||||
/>
|
||||
|
||||
<v-card-text class="text-right text-h5" v-if="basketStore.itemsInBasket.length > 0">
|
||||
{{ $t('totalPrice') }}: {{ (basketStore.getTotalPrice).toFixed(2) }} €
|
||||
</v-card-text>
|
||||
|
||||
|
||||
<template #actions>
|
||||
<outlined-button
|
||||
prepend-icon="mdi-basket-check"
|
||||
:disabled="basketStore.itemsInBasket.length == 0 || accountStore.userAccount.id == null"
|
||||
variant="outlined"
|
||||
color="green"
|
||||
@click="showOrderingDialog = true"
|
||||
>
|
||||
{{ $t('orderNow') }}
|
||||
</outlined-button>
|
||||
</template>
|
||||
</card-view>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
|
||||
<ordering-dialog v-model="showOrderingDialog" />
|
||||
</template>
|
||||
109
software/src/pages/misc/basketPage/orderingDialog.vue
Normal file
109
software/src/pages/misc/basketPage/orderingDialog.vue
Normal file
@@ -0,0 +1,109 @@
|
||||
<script setup lang="ts">
|
||||
import actionDialog from '@/components/basics/actionDialog.vue';
|
||||
import { useBasketStore } from '@/data/stores/basketStore';
|
||||
import outlinedButton from '@/components/basics/outlinedButton.vue';
|
||||
import { ModelRef, ref } from 'vue';
|
||||
import { useAccountStore } from '@/data/stores/accountStore';
|
||||
|
||||
const basketStore = useBasketStore()
|
||||
const accountStore = useAccountStore()
|
||||
const showDialog: ModelRef<boolean> = defineModel()
|
||||
const orderingInProgress = ref(false)
|
||||
const addressError = ref(false)
|
||||
const paymentError = ref(false)
|
||||
|
||||
async function doOrder() {
|
||||
orderingInProgress.value = true
|
||||
addressError.value = false
|
||||
paymentError.value = false
|
||||
|
||||
if (basketStore.usedAddress == null) {
|
||||
addressError.value = true
|
||||
}
|
||||
|
||||
if (basketStore.usedPayment == null){
|
||||
paymentError.value = true
|
||||
}
|
||||
|
||||
if (basketStore.usedAddress != null && basketStore.usedPayment != null) {
|
||||
|
||||
await basketStore.takeOrder()
|
||||
showDialog.value = false
|
||||
}
|
||||
|
||||
orderingInProgress.value = false
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<action-dialog
|
||||
:title="$t('ordering.ordering')"
|
||||
icon="mdi-basket-check"
|
||||
v-model="showDialog"
|
||||
max-width="800"
|
||||
persistent
|
||||
>
|
||||
<v-row>
|
||||
<v-col>
|
||||
{{ $t('account.address', accountStore.userAccount.addresses.length) }}
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col>
|
||||
<v-radio-group
|
||||
v-model="basketStore.usedAddress"
|
||||
:error="addressError"
|
||||
>
|
||||
<v-radio
|
||||
v-for="address in accountStore.userAccount.addresses"
|
||||
:value="address"
|
||||
:label="address.street + ' ' + address.houseNumber + ', ' + address.postalCode + ' ' + address.city"
|
||||
|
||||
/>
|
||||
</v-radio-group>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col>
|
||||
{{ $t('account.payment', accountStore.userAccount.payments.length) }}
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col>
|
||||
<v-radio-group
|
||||
v-model="basketStore.usedPayment"
|
||||
>
|
||||
<v-radio
|
||||
v-for="payment in accountStore.userAccount.payments"
|
||||
:value="payment"
|
||||
:label="payment.bankName + ': ' + payment.iban"
|
||||
:error="paymentError"
|
||||
/>
|
||||
</v-radio-group>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<template #actions>
|
||||
<outlined-button
|
||||
@click="showDialog = false"
|
||||
prepend-icon="mdi-close"
|
||||
color="orange"
|
||||
:disabled="orderingInProgress"
|
||||
>
|
||||
{{ $t('dialog.cancel') }}
|
||||
</outlined-button>
|
||||
|
||||
<outlined-button
|
||||
@click="doOrder"
|
||||
:loading="orderingInProgress"
|
||||
prepend-icon="mdi-send"
|
||||
color="green"
|
||||
>
|
||||
{{ $t('ordering.takeOrder') }}
|
||||
</outlined-button>
|
||||
</template>
|
||||
</action-dialog>
|
||||
</template>
|
||||
67
software/src/pages/misc/basketPage/ticketsTable.vue
Normal file
67
software/src/pages/misc/basketPage/ticketsTable.vue
Normal file
@@ -0,0 +1,67 @@
|
||||
<script setup lang="ts">
|
||||
import { useBasketStore } from '@/data/stores/basketStore';
|
||||
import { BasketItemModel } from '@/data/models/ordering/basketItemModel';
|
||||
import { calcPrice } from '@/scripts/concertScripts';
|
||||
|
||||
const basketStore = useBasketStore()
|
||||
|
||||
function removeFromBasket(basketItem: BasketItemModel) {
|
||||
basketStore.removeItemFromBasket(basketItem)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<v-table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ $t('band') }}</th>
|
||||
<th>{{ $t('event') }}</th>
|
||||
<th class="text-center">{{ $t('quantity') }}</th>
|
||||
<th class="text-right">{{ $t('product.productPrice') }}</th>
|
||||
<th class="text-right">{{ $t('totalPrice') }}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr v-for="basketItem in basketStore.itemsInBasket">
|
||||
<!-- Band name -->
|
||||
<td>
|
||||
{{ basketItem.band.name }}
|
||||
</td>
|
||||
|
||||
<!-- Event name -->
|
||||
<td>
|
||||
{{ basketItem.event.name }}
|
||||
</td>
|
||||
|
||||
<!-- Quantity -->
|
||||
<td class="text-center">
|
||||
{{ basketItem.seats.length }}x
|
||||
</td>
|
||||
|
||||
<!-- Price per event -->
|
||||
<td class="text-right">
|
||||
<div v-if="basketItem.seats">
|
||||
{{ basketItem.price }} €
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<!-- Total price -->
|
||||
<td class="text-right">
|
||||
{{ (calcPrice(basketItem.concert.price, basketItem.seats.length)).toFixed(2) }} €
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<v-btn
|
||||
icon="mdi-delete"
|
||||
@click="removeFromBasket(basketItem)"
|
||||
color="red"
|
||||
variant="text"
|
||||
flat
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</v-table>
|
||||
</template>
|
||||
37
software/src/pages/misc/helpPage/index.vue
Normal file
37
software/src/pages/misc/helpPage/index.vue
Normal file
@@ -0,0 +1,37 @@
|
||||
<script setup lang="ts">
|
||||
import { getAllExerciseGroups } from '@/data/api/exerciseApi';
|
||||
import scoreCard from './scoreCard.vue';
|
||||
import { ref } from 'vue';
|
||||
import { ExerciseGroupModel } from '@/data/models/exercises/exerciseGroupModel';
|
||||
import { useFeedbackStore } from '@/data/stores/feedbackStore';
|
||||
|
||||
const exerciseGroups = ref<Array<ExerciseGroupModel>>([])
|
||||
const feedbackStore = useFeedbackStore()
|
||||
|
||||
feedbackStore.fetchDataFromServerInProgress = true
|
||||
|
||||
getAllExerciseGroups()
|
||||
.then(result => {
|
||||
exerciseGroups.value = result.data
|
||||
feedbackStore.fetchDataFromServerInProgress = false
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<v-container max-width="1000">
|
||||
<v-row v-if="feedbackStore.fetchDataFromServerInProgress" v-for="i in 3">
|
||||
<v-col>
|
||||
<score-card :loading="true"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row v-for="exerciseGroup in exerciseGroups">
|
||||
<v-col>
|
||||
<score-card
|
||||
:exercise-group="exerciseGroup"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
</template>
|
||||
86
software/src/pages/misc/helpPage/scoreCard.vue
Normal file
86
software/src/pages/misc/helpPage/scoreCard.vue
Normal file
@@ -0,0 +1,86 @@
|
||||
<script setup lang="ts">
|
||||
import cardView from '@/components/basics/cardView.vue';
|
||||
import { ExerciseGroupModel } from '@/data/models/exercises/exerciseGroupModel';
|
||||
|
||||
defineProps({
|
||||
exerciseGroup: ExerciseGroupModel,
|
||||
loading: Boolean
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<card-view v-if="loading" :loading="loading" >
|
||||
<v-timeline
|
||||
direction="horizontal"
|
||||
side="start"
|
||||
class="pb-3"
|
||||
>
|
||||
<v-timeline-item
|
||||
v-for="i in 3"
|
||||
dot-color="grey"
|
||||
icon="mdi-pencil"
|
||||
>
|
||||
<v-skeleton-loader
|
||||
type="list-item"
|
||||
:loading="loading"
|
||||
width="200"
|
||||
/>
|
||||
|
||||
<template #opposite>
|
||||
<v-skeleton-loader
|
||||
type="sentences"
|
||||
:loading="loading"
|
||||
width="200"
|
||||
/>
|
||||
</template>
|
||||
</v-timeline-item>
|
||||
</v-timeline>
|
||||
</card-view>
|
||||
|
||||
|
||||
<card-view
|
||||
v-else
|
||||
:title="$t('exerciseGroup') + ' ' + exerciseGroup.groupNr + ': ' + exerciseGroup.nameDe"
|
||||
:loading="loading"
|
||||
>
|
||||
<v-timeline
|
||||
direction="horizontal"
|
||||
side="start"
|
||||
class="pb-3"
|
||||
>
|
||||
<v-timeline-item
|
||||
v-for="exercise in exerciseGroup.exercises"
|
||||
:dot-color="exercise.solved ? 'green' : 'grey'"
|
||||
:icon="exercise.solved ? 'mdi-check' : 'mdi-pencil'"
|
||||
>
|
||||
<v-skeleton-loader
|
||||
type="text"
|
||||
:loading="loading"
|
||||
>
|
||||
<div class="text-h6">
|
||||
{{ $t('exercise') }} {{ exercise.exerciseNr }}
|
||||
</div>
|
||||
</v-skeleton-loader>
|
||||
|
||||
|
||||
<template #opposite>
|
||||
<v-skeleton-loader
|
||||
type="text"
|
||||
:loading="loading"
|
||||
>
|
||||
<div class="text-center">
|
||||
<div class="text-h6">
|
||||
{{ exercise.nameDe }}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
{{ exercise.descriptionDe }}
|
||||
</div>
|
||||
</div>
|
||||
</v-skeleton-loader>
|
||||
</template>
|
||||
|
||||
</v-timeline-item>
|
||||
</v-timeline>
|
||||
</card-view>
|
||||
</template>
|
||||
20
software/src/pages/misc/preferencesPage/index.vue
Normal file
20
software/src/pages/misc/preferencesPage/index.vue
Normal file
@@ -0,0 +1,20 @@
|
||||
<script setup lang="ts">
|
||||
import pageSetup from './pageSetup.vue';
|
||||
import systemSetup from './systemSetup.vue';
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<v-container max-width="800">
|
||||
<v-row>
|
||||
<v-col>
|
||||
<page-setup />
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col>
|
||||
<system-setup />
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
</template>
|
||||
50
software/src/pages/misc/preferencesPage/pageSetup.vue
Normal file
50
software/src/pages/misc/preferencesPage/pageSetup.vue
Normal file
@@ -0,0 +1,50 @@
|
||||
<script setup lang="ts">
|
||||
import { ThemeEnum } from '@/data/enums/themeEnums';
|
||||
import { useTheme } from 'vuetify/lib/framework.mjs';
|
||||
import { i18n } from '@/plugins/i18n';
|
||||
import cardView from '@/components/basics/cardView.vue';
|
||||
import { usePreferencesStore } from '@/data/stores/preferencesStore';
|
||||
|
||||
const preferencesStore = usePreferencesStore()
|
||||
const theme = useTheme()
|
||||
const themeEnums = Object.values(ThemeEnum)
|
||||
|
||||
function changeTheme() {
|
||||
theme.global.name.value = preferencesStore.theme
|
||||
}
|
||||
|
||||
function changeLanguage() {
|
||||
i18n.global.locale = preferencesStore.language
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<card-view
|
||||
:title="$t('preferences.pageSetup')"
|
||||
icon="mdi-view-dashboard"
|
||||
>
|
||||
<v-row>
|
||||
<v-col>
|
||||
<v-select
|
||||
v-model="preferencesStore.theme"
|
||||
:items="themeEnums"
|
||||
:label="$t('preferences.selectedTheme')"
|
||||
@update:model-value="changeTheme"
|
||||
hide-details
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col>
|
||||
<v-select
|
||||
v-model="preferencesStore.language"
|
||||
:items="$i18n.availableLocales"
|
||||
:label="$t('preferences.language')"
|
||||
@update:model-value="changeLanguage"
|
||||
hide-details
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</card-view>
|
||||
</template>
|
||||
132
software/src/pages/misc/preferencesPage/systemSetup.vue
Normal file
132
software/src/pages/misc/preferencesPage/systemSetup.vue
Normal file
@@ -0,0 +1,132 @@
|
||||
<script setup lang="ts">
|
||||
import { BannerStateEnum } from '@/data/enums/bannerStateEnum';
|
||||
import { useFeedbackStore } from '@/data/stores/feedbackStore';
|
||||
import cardView from '@/components/basics/cardView.vue';
|
||||
import outlinedButton from '@/components/basics/outlinedButton.vue';
|
||||
import { ref } from 'vue';
|
||||
import confirmDialog from '@/components/basics/confirmDialog.vue';
|
||||
import { getServerState, resetDatabase, resetExerciseProgress } from '@/data/api/mainApi';
|
||||
import { ServerStateEnum } from '@/data/enums/serverStateEnum';
|
||||
import packageJson from './../../../../package.json'
|
||||
|
||||
const feedbackStore = useFeedbackStore()
|
||||
const showConfirmDeleteDbDialog = ref(false)
|
||||
const showConfirmDeleteExerciseProgressDialog = ref(false)
|
||||
const serverOnline = ref(ServerStateEnum.PENDING)
|
||||
|
||||
getServerState()
|
||||
.then(result => {
|
||||
if (result.status == 200) {
|
||||
serverOnline.value = ServerStateEnum.ONLINE
|
||||
} else {
|
||||
serverOnline.value = ServerStateEnum.OFFLINE
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
serverOnline.value = ServerStateEnum.OFFLINE
|
||||
})
|
||||
|
||||
async function resetDb() {
|
||||
serverOnline.value = ServerStateEnum.PENDING
|
||||
|
||||
await resetDatabase()
|
||||
.then(result => {
|
||||
if (result.status == 200) {
|
||||
feedbackStore.changeBanner(BannerStateEnum.DATABASERESETSUCCESSFUL)
|
||||
serverOnline.value = ServerStateEnum.ONLINE
|
||||
}
|
||||
|
||||
showConfirmDeleteDbDialog.value = false
|
||||
})
|
||||
}
|
||||
|
||||
async function resetExerciseProg() {
|
||||
serverOnline.value = ServerStateEnum.PENDING
|
||||
|
||||
await resetExerciseProgress()
|
||||
.then(result => {
|
||||
if (result.status == 200) {
|
||||
feedbackStore.changeBanner(BannerStateEnum.EXERCISEPROGRESSRESETSUCCESSFUL)
|
||||
serverOnline.value = ServerStateEnum.ONLINE
|
||||
}
|
||||
|
||||
showConfirmDeleteExerciseProgressDialog.value = false
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<card-view
|
||||
:title="$t('preferences.systemSetup')"
|
||||
icon="mdi-engine"
|
||||
>
|
||||
<v-row>
|
||||
<v-col>
|
||||
{{ $t('serverState') }}:
|
||||
<span v-if="serverOnline == ServerStateEnum.ONLINE" class="text-green">
|
||||
<v-icon icon="mdi-check" />
|
||||
Online
|
||||
</span>
|
||||
|
||||
<span v-else-if="serverOnline == ServerStateEnum.OFFLINE" class="text-red">
|
||||
<v-icon icon="mdi-alert-circle" />
|
||||
Offline
|
||||
</span>
|
||||
|
||||
<span v-else-if="serverOnline == ServerStateEnum.PENDING" class="text-orange">
|
||||
<v-icon icon="mdi-clock" />
|
||||
Pending...
|
||||
</span>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col>
|
||||
Software Version: {{ packageJson.version }}
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col class="d-flex justify-center align-center">
|
||||
<outlined-button
|
||||
@click="showConfirmDeleteDbDialog = true"
|
||||
prepend-icon="mdi-database-refresh"
|
||||
color="red"
|
||||
:disabled="serverOnline != ServerStateEnum.ONLINE"
|
||||
>
|
||||
{{ $t('resetDatabase') }}
|
||||
</outlined-button>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col class="d-flex justify-center align-center">
|
||||
<outlined-button
|
||||
@click="showConfirmDeleteExerciseProgressDialog = true"
|
||||
prepend-icon="mdi-progress-close"
|
||||
color="red"
|
||||
:disabled="serverOnline != ServerStateEnum.ONLINE"
|
||||
>
|
||||
{{ $t('resetProgress') }}
|
||||
</outlined-button>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</card-view>
|
||||
|
||||
<!-- Confirm delete database -->
|
||||
<confirm-dialog
|
||||
:title="$t('resetDatabaseConfirm.title')"
|
||||
:description="$t('resetDatabaseConfirm.description')"
|
||||
v-model="showConfirmDeleteDbDialog"
|
||||
:onConfirm="resetDb"
|
||||
/>
|
||||
|
||||
<!-- Confirm delete exercise progress -->
|
||||
<confirm-dialog
|
||||
:title="$t('resetExerciseProgressConfirm.title')"
|
||||
:description="$t('resetExerciseProgressConfirm.description')"
|
||||
v-model="showConfirmDeleteExerciseProgressDialog"
|
||||
:onConfirm="resetExerciseProg"
|
||||
/>
|
||||
</template>
|
||||
151
software/src/pages/misc/searchPage/index.vue
Normal file
151
software/src/pages/misc/searchPage/index.vue
Normal file
@@ -0,0 +1,151 @@
|
||||
<script setup lang="ts">
|
||||
import searchBar from './searchBar.vue';
|
||||
import eventListItem from '@/components/pageParts/eventListItem.vue';
|
||||
import sectionDivider from '@/components/basics/sectionDivider.vue';
|
||||
import cardViewHorizontal from '@/components/basics/cardViewHorizontal.vue';
|
||||
import locationListItem from '@/components/pageParts/locationListItem.vue';
|
||||
import cardViewTopImage from '@/components/basics/cardViewTopImage.vue';
|
||||
import bandListItem from '@/components/pageParts/bandListItem.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>
|
||||
|
||||
<div v-if="searchStore.alreadySearched">
|
||||
<v-row>
|
||||
<v-col>
|
||||
<section-divider :title="$t('band', 2)" />
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row
|
||||
v-if="searchStore.searchInProgress"
|
||||
v-for="i in 2"
|
||||
>
|
||||
<v-col>
|
||||
<card-view-horizontal :loading="true" />
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row
|
||||
v-else-if="searchStore.bands.length > 0"
|
||||
v-for="band in searchStore.bands">
|
||||
<v-col>
|
||||
<band-list-item
|
||||
:band="band"
|
||||
:events="band.events"
|
||||
:genres="band.genres"
|
||||
:loading="searchStore.searchInProgress"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row v-else >
|
||||
<v-col>
|
||||
<v-empty-state
|
||||
:title="$t('noBandFound')"
|
||||
icon="mdi-guitar-electric"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
|
||||
|
||||
<!-- Section Location results -->
|
||||
<v-row>
|
||||
<v-col>
|
||||
<section-divider :title="$t('location', 2)" />
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row
|
||||
v-if="searchStore.searchInProgress"
|
||||
>
|
||||
<v-col v-for="i in 4">
|
||||
<card-view-top-image :loading="true" />
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row
|
||||
v-else-if="searchStore.locations.length > 0"
|
||||
>
|
||||
<v-col
|
||||
cols="3"
|
||||
v-for="locaiton in searchStore.locations"
|
||||
>
|
||||
<location-list-item
|
||||
:location="locaiton"
|
||||
:concerts="locaiton.concerts"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row v-else >
|
||||
<v-col>
|
||||
<v-empty-state
|
||||
:title="$t('noLocationsFound')"
|
||||
icon="mdi-city"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
|
||||
|
||||
<!-- Section Event results -->
|
||||
<v-row>
|
||||
<v-col>
|
||||
<section-divider :title="$t('event', 2)" />
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row
|
||||
v-if="searchStore.searchInProgress"
|
||||
v-for="i in 2"
|
||||
>
|
||||
<v-col>
|
||||
<card-view-horizontal :loading="true" />
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row
|
||||
v-else-if="searchStore.events.length > 0"
|
||||
v-for="event in searchStore.events"
|
||||
>
|
||||
<v-col>
|
||||
<event-list-item
|
||||
:event="event"
|
||||
:band="event.band"
|
||||
:concerts="event.concerts"
|
||||
:loading="searchStore.searchInProgress"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row v-else >
|
||||
<v-col>
|
||||
<v-empty-state
|
||||
:title="$t('noEventsFound')"
|
||||
icon="mdi-party-popper"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</div>
|
||||
|
||||
</v-col>
|
||||
|
||||
<v-spacer />
|
||||
</v-row>
|
||||
</v-container>
|
||||
</template>
|
||||
26
software/src/pages/misc/searchPage/searchBar.vue
Normal file
26
software/src/pages/misc/searchPage/searchBar.vue
Normal file
@@ -0,0 +1,26 @@
|
||||
<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')"
|
||||
@keyup.enter="searchStore.startSearch"
|
||||
>
|
||||
<template #append-inner>
|
||||
<v-btn
|
||||
icon="mdi-magnify"
|
||||
variant="plain"
|
||||
@click="searchStore.startSearch"
|
||||
/>
|
||||
</template>
|
||||
</v-text-field>
|
||||
</card-view>
|
||||
</template>
|
||||
Reference in New Issue
Block a user