Light mode improvements, empty state on search page

This commit is contained in:
2024-11-26 20:58:10 +01:00
parent 1a4b438191
commit 1f6ebf5b2e
19 changed files with 135 additions and 86 deletions

View File

@@ -613,25 +613,25 @@
"image": "concerts/will-of-the-people-tour.jpg", "image": "concerts/will-of-the-people-tour.jpg",
"concerts": [ "concerts": [
{ {
"date": "32", "date": "2",
"price": 67.90, "price": 67.90,
"inStock": 847, "inStock": 847,
"location": "ZAG Arena" "location": "ZAG Arena"
}, },
{ {
"date": "39", "date": "17",
"price": 67.90, "price": 67.90,
"inStock": 847, "inStock": 847,
"location": "ZAG Arena" "location": "ZAG Arena"
}, },
{ {
"date": "41", "date": "31",
"price": 64.90, "price": 64.90,
"inStock": 245, "inStock": 245,
"location": "Olympiastadion Berlin" "location": "Olympiastadion Berlin"
}, },
{ {
"date": "45", "date": "43",
"price": 64.90, "price": 64.90,
"inStock": 245, "inStock": 245,
"location": "Astra Kulturhaus" "location": "Astra Kulturhaus"

View File

@@ -40,12 +40,16 @@ defineProps({
type="image" type="image"
:loading="loading" :loading="loading"
> >
<v-img <v-sheet
:src="image" color="sheet"
:height="height" >
:width="height" <v-img
cover :src="image"
/> :height="height"
:width="height"
cover
/>
</v-sheet>
</v-skeleton-loader> </v-skeleton-loader>
<v-skeleton-loader <v-skeleton-loader
@@ -55,6 +59,7 @@ defineProps({
> >
<v-sheet <v-sheet
:height="height" :height="height"
color="sheet"
width="100%" width="100%"
class="text-center d-flex justify-center align-center" class="text-center d-flex justify-center align-center"
> >
@@ -75,6 +80,8 @@ defineProps({
> >
<v-sheet <v-sheet
:height="height" :height="height"
color="sheet"
class="w-100"
> >
<div> <div>
<div class="text-h4 font-weight-black pt-2 h-100"> <div class="text-h4 font-weight-black pt-2 h-100">

View File

@@ -30,67 +30,58 @@ loadLicense(props.image)
</script> </script>
<template> <template>
<v-tooltip <v-card
:text="license" variant="tonal"
location="top" :link="link"
open-delay="200"
> >
<template #activator="{ props }"> <v-skeleton-loader
<v-card :loading="loading"
variant="tonal" type="image"
:link="link" height="150"
v-bind="props" >
<v-img
:src="image"
aspect-ratio="1"
max-height="200"
cover
> >
<v-skeleton-loader <template #error>
:loading="loading"
type="image"
height="150"
>
<v-img <v-img
:src="image" :src="'http://localhost:3000/static/' + errorImage"
aspect-ratio="1" aspect-ratio="1"
max-height="200" style="background-color: aliceblue;"
cover />
> </template>
<template #error> </v-img>
<v-img </v-skeleton-loader>
:src="'http://localhost:3000/static/' + errorImage"
aspect-ratio="1"
style="background-color: aliceblue;"
/>
</template>
</v-img>
</v-skeleton-loader>
<v-skeleton-loader <v-skeleton-loader
:loading="loading" :loading="loading"
type="heading" type="heading"
> >
<div v-if="title"> <div v-if="title">
<v-card-title v-if="!smallerTitle"> <v-card-title v-if="!smallerTitle">
{{ title }} {{ title }}
</v-card-title> </v-card-title>
<v-card-title v-else style="font-size: medium"> <v-card-title v-else style="font-size: medium">
{{ title }} {{ title }}
</v-card-title> </v-card-title>
</div> </div>
</v-skeleton-loader> </v-skeleton-loader>
<v-skeleton-loader <v-skeleton-loader
type="sentences" type="sentences"
:loading="loading" :loading="loading"
> >
<div class="px-4 pb-4 text-disabled" v-if="$slots.default"> <div class="px-4 pb-4 text-disabled" v-if="$slots.default">
<slot></slot> <slot></slot>
</div> </div>
</v-skeleton-loader> </v-skeleton-loader>
<v-card-actions v-if="$slots.actions" class="card-actions position-absolute bottom-0 right-0"> <v-card-actions v-if="$slots.actions" class="card-actions position-absolute bottom-0 right-0">
<v-spacer /> <v-spacer />
<slot name="actions"></slot> <slot name="actions"></slot>
</v-card-actions> </v-card-actions>
</v-card> </v-card>
</template>
</v-tooltip>
</template> </template>

View File

@@ -20,7 +20,7 @@ function confirmPressed() {
<template> <template>
<action-dialog <action-dialog
:title="title" :title="title"
max-width="400" max-width="500"
v-model="showDialog" v-model="showDialog"
persistent persistent
> >

View File

@@ -8,20 +8,28 @@ defineProps({
<template> <template>
<v-row class="pt-3 d-none d-md-flex"> <v-row class="pt-3 d-none d-md-flex">
<!-- Left line -->
<v-col class="d-flex justify-center align-center"> <v-col class="d-flex justify-center align-center">
<v-sheet height="12" width="100%" color="primary" class="rounded-s-lg" /> <v-sheet height="12" width="100%" color="primary" class="rounded-s-lg" />
</v-col> </v-col>
<!-- Title -->
<v-col class="v-col-auto"> <v-col class="v-col-auto">
<v-skeleton-loader <v-skeleton-loader
type="heading" type="heading"
:loading="loading" :loading="loading"
width="300" width="300"
> >
<span class="text-h4">{{ title }}</span> <v-sheet
class="text-h4"
color="sheet"
>
{{ title }}
</v-sheet>
</v-skeleton-loader> </v-skeleton-loader>
</v-col> </v-col>
<!-- Right line -->
<v-col class="d-flex justify-center align-center"> <v-col class="d-flex justify-center align-center">
<v-sheet height="12" width="100%" color="primary" class="rounded-e-lg" /> <v-sheet height="12" width="100%" color="primary" class="rounded-e-lg" />
</v-col> </v-col>

View File

@@ -56,6 +56,7 @@ defineProps({
type="heading" type="heading"
:loading="loading" :loading="loading"
width="500" width="500"
class="text-white"
> >
<span class="text-h3 font-weight-bold"> <span class="text-h3 font-weight-bold">
{{ title }} {{ title }}
@@ -77,11 +78,18 @@ defineProps({
<!-- Description --> <!-- Description -->
<p class="text-h6 text-medium-emphasis" v-if="!$slots.description"> <p
class="text-h6 text-white"
style="opacity: 0.7;"
v-if="!$slots.description"
>
{{ description }} {{ description }}
</p> </p>
<p class="text-h6 text-medium-emphasis"> <p
class="text-h6 text-white"
style="opacity: 0.7;"
>
<slot name="description"></slot> <slot name="description"></slot>
</p> </p>
</v-skeleton-loader> </v-skeleton-loader>

View File

@@ -249,7 +249,13 @@
"chooseDestinationFolder": "Zielordner auswählen", "chooseDestinationFolder": "Zielordner auswählen",
"upload": "Hochladen", "upload": "Hochladen",
"fulfillYourPersonalDataFirst": "Gehe zu den Einstellungen und fülle deinen Namen und deine Matrikelnummer aus", "fulfillYourPersonalDataFirst": "Gehe zu den Einstellungen und fülle deinen Namen und deine Matrikelnummer aus",
"testEnvironment": "Testumgebung" "testEnvironment": "Testumgebung",
"search": {
"empty": {
"headline": "So leer hier..."
},
"searchterm": "Suchbegriff"
}
}, },
"genre": { "genre": {
"withoutBand": "ohne Band" "withoutBand": "ohne Band"

View File

@@ -249,7 +249,13 @@
"chooseDestinationFolder": "Choose destination folder", "chooseDestinationFolder": "Choose destination folder",
"upload": "Upload", "upload": "Upload",
"fulfillYourPersonalDataFirst": "Go to settings and enter your name and the right register number", "fulfillYourPersonalDataFirst": "Go to settings and enter your name and the right register number",
"testEnvironment": "Test Environment" "testEnvironment": "Test Environment",
"search": {
"empty": {
"headline": "So empty here..."
},
"searchterm": "Search term"
}
}, },
"genre": { "genre": {
"withoutBand": "without Band" "withoutBand": "without Band"

View File

@@ -46,8 +46,10 @@ defineProps({
</v-col> </v-col>
<v-col> <v-col>
<v-list> <v-list style="background-color: transparent;">
<v-list-item v-for="ratingValue in ratings"> <v-list-item
v-for="ratingValue in ratings"
>
<template v-slot:prepend> <template v-slot:prepend>
<span>{{ ratingValue.value }}</span> <span>{{ ratingValue.value }}</span>
<v-icon class="ml-3 mr-n3" icon="mdi-star" /> <v-icon class="ml-3 mr-n3" icon="mdi-star" />

View File

@@ -94,7 +94,7 @@ watch(() => router.currentRoute.value.params.date, () => {
<v-row> <v-row>
<v-col> <v-col>
<v-list > <v-list style="background-color: transparent;">
<v-list-item v-for="seat in basketStore.selectedSeats" > <v-list-item v-for="seat in basketStore.selectedSeats" >
<ticket-list-item <ticket-list-item
:concert="concertStore.concert" :concert="concertStore.concert"

View File

@@ -18,7 +18,6 @@ const showOrderingDialog = ref()
<v-col> <v-col>
<v-alert <v-alert
color="info" color="info"
closable
> >
{{ $t('account.login.pleaseLoginToOrder') }} {{ $t('account.login.pleaseLoginToOrder') }}
</v-alert> </v-alert>

View File

@@ -2,6 +2,7 @@
import { useBasketStore } from '@/stores/basket.store'; import { useBasketStore } from '@/stores/basket.store';
import { BasketItemModel } from '@/data/models/ordering/basketItemModel'; import { BasketItemModel } from '@/data/models/ordering/basketItemModel';
import { calcPrice } from '@/scripts/concertScripts'; import { calcPrice } from '@/scripts/concertScripts';
import moment from 'moment';
const basketStore = useBasketStore() const basketStore = useBasketStore()
@@ -11,9 +12,10 @@ function removeFromBasket(basketItem: BasketItemModel) {
</script> </script>
<template> <template>
<v-table> <v-table style="background-color: transparent;">
<thead> <thead>
<tr> <tr>
<th>{{ $t('concert.date') }}</th>
<th>{{ $t('band.band') }}</th> <th>{{ $t('band.band') }}</th>
<th>{{ $t('concert.concert') }}</th> <th>{{ $t('concert.concert') }}</th>
<th class="text-center">{{ $t('misc.quantity') }}</th> <th class="text-center">{{ $t('misc.quantity') }}</th>
@@ -25,6 +27,11 @@ function removeFromBasket(basketItem: BasketItemModel) {
<tbody> <tbody>
<tr v-for="basketItem in basketStore.itemsInBasket"> <tr v-for="basketItem in basketStore.itemsInBasket">
<!-- Concert date -->
<td>
{{ moment(basketItem.concert.date).format("DD.MM.YYYY") }}
</td>
<!-- Band name --> <!-- Band name -->
<td> <td>
{{ basketItem.band.name }} {{ basketItem.band.name }}
@@ -43,7 +50,7 @@ function removeFromBasket(basketItem: BasketItemModel) {
<!-- Price per event --> <!-- Price per event -->
<td class="text-right"> <td class="text-right">
<div v-if="basketItem.seats"> <div v-if="basketItem.seats">
{{ basketItem.price }} {{ basketItem.price.toFixed(2) }}
</div> </div>
</td> </td>

View File

@@ -67,6 +67,7 @@ preferenceStore.getServerState()
v-model="preferenceStore.showDeleteDbDialog" v-model="preferenceStore.showDeleteDbDialog"
:onConfirm="preferenceStore.resetDb" :onConfirm="preferenceStore.resetDb"
:loading="preferenceStore.fetchInProgress" :loading="preferenceStore.fetchInProgress"
icon="mdi-database-refresh"
/> />
<!-- Confirm delete exercise progress --> <!-- Confirm delete exercise progress -->
@@ -76,12 +77,14 @@ preferenceStore.getServerState()
v-model="preferenceStore.showDeleteExerciseDialog" v-model="preferenceStore.showDeleteExerciseDialog"
:onConfirm="preferenceStore.resetExerciseProg" :onConfirm="preferenceStore.resetExerciseProg"
:loading="preferenceStore.fetchInProgress" :loading="preferenceStore.fetchInProgress"
icon="mdi-progress-close"
/> />
<confirm-dialog <confirm-dialog
:title="$t('preferences.factoryReset.dialog.title')" :title="$t('preferences.factoryReset.dialog.title')"
:description="$t('preferences.factoryReset.dialog.description')" :description="$t('preferences.factoryReset.dialog.description')"
v-model="preferenceStore.showFactoryResetDialog" v-model="preferenceStore.showFactoryResetDialog"
icon="mdi-factory"
:onConfirm="() => { :onConfirm="() => {
preferenceStore.resetToFactorySettings() preferenceStore.resetToFactorySettings()
router.push('/') router.push('/')

View File

@@ -23,7 +23,17 @@ const searchStore = useSearchStore()
</v-col> </v-col>
</v-row> </v-row>
<div v-if="searchStore.alreadySearched"> <v-row v-if="!searchStore.alreadySearched">
<v-col>
<v-empty-state
icon="mdi-magnify"
:headline="$t('misc.search.empty.headline')"
:title="$t('misc.enterSomeKeywords')"
/>
</v-col>
</v-row>
<div v-else>
<v-row> <v-row>
<v-col> <v-col>
<section-divider :title="$t('band.band', 2)" /> <section-divider :title="$t('band.band', 2)" />
@@ -41,7 +51,8 @@ const searchStore = useSearchStore()
<v-row <v-row
v-else-if="searchStore.bands.length > 0" v-else-if="searchStore.bands.length > 0"
v-for="band in searchStore.bands"> v-for="band in searchStore.bands"
>
<v-col> <v-col>
<band-list-item <band-list-item
:band="band" :band="band"

View File

@@ -11,7 +11,7 @@ const searchStore = useSearchStore()
variant="outlined" variant="outlined"
hide-details hide-details
v-model="searchStore.searchTerm" v-model="searchStore.searchTerm"
:placeholder="$t('misc.enterSomeKeywords')" :label="$t('misc.search.searchterm')"
@keyup.enter="searchStore.startSearch" @keyup.enter="searchStore.startSearch"
> >
<template #append-inner> <template #append-inner>

View File

@@ -30,7 +30,7 @@ const vuetify = createVuetify({
colors: { colors: {
primary: colors.blue.darken4, primary: colors.blue.darken4,
secondary: colors.yellow.darken3, secondary: colors.yellow.darken3,
sheet: colors.grey.lighten3, sheet: colors.grey.lighten4,
warning: colors.amber.darken4, warning: colors.amber.darken4,
success: colors.green.darken2, success: colors.green.darken2,
error: colors.red.darken4, error: colors.red.darken4,

View File

@@ -33,8 +33,10 @@ export const useAccountStore = defineStore("accountStore", {
/** Request to server sent, waiting for data response */ /** Request to server sent, waiting for data response */
fetchInProgress: ref(false), fetchInProgress: ref(false),
/** Flag to show or hide admin icon in navigation bar */
adminPanelVisible: ref(false), adminPanelVisible: ref(false),
/** Flag to activate buy option on basket page */
privilegeBuy: ref(false) privilegeBuy: ref(false)
}), }),

View File

@@ -19,10 +19,10 @@ export const useBasketStore = defineStore('basketStore', {
itemsInBasket: useLocalStorage<Array<BasketItemModel>>("hackmycart/basketStore/itemsInBasket", []), itemsInBasket: useLocalStorage<Array<BasketItemModel>>("hackmycart/basketStore/itemsInBasket", []),
/** Address used in the order dialog */ /** Address used in the order dialog */
usedAddress: ref(new AddressModel()), usedAddress: ref<AddressModel>(null),
/** Payment method used in the order dialog */ /** Payment method used in the order dialog */
usedPayment: ref(new PaymentModel()), usedPayment: ref<PaymentModel>(null),
/** Selected seats in the booking page */ /** Selected seats in the booking page */
selectedSeats: ref<Array<SelectedSeatModel>>([]) selectedSeats: ref<Array<SelectedSeatModel>>([])

View File

@@ -5,11 +5,10 @@ import { fetchLocationsBySearchTerm } from "../data/api/locationApi";
import { fetchConcertsBySearchTerm } from "../data/api/concertApi"; import { fetchConcertsBySearchTerm } from "../data/api/concertApi";
import { ConcertApiModel } from "@/data/models/acts/concertApiModel"; import { ConcertApiModel } from "@/data/models/acts/concertApiModel";
import { useExerciseStore } from "./exercise.store"; import { useExerciseStore } from "./exercise.store";
import { AccountApiModel } from "@/data/models/user/accountApiModel";
import { LocationApiModel } from "@/data/models/locations/locationApiModel";
import { BandApiModel } from "@/data/models/acts/bandApiModel"; import { BandApiModel } from "@/data/models/acts/bandApiModel";
import { useBandStore } from "./band.store"; import { useBandStore } from "./band.store";
import { useAccountStore } from "./account.store"; import { useAccountStore } from "./account.store";
import { LocationDetailsApiModel } from "@/data/models/locations/locationDetailsApiModel";
export const useSearchStore = defineStore("searchStore", { export const useSearchStore = defineStore("searchStore", {
state: () => ({ state: () => ({
@@ -20,7 +19,7 @@ export const useSearchStore = defineStore("searchStore", {
bands: ref<Array<BandApiModel>>([]), bands: ref<Array<BandApiModel>>([]),
/** Location results */ /** Location results */
locations: ref<Array<LocationApiModel>>([]), locations: ref<Array<LocationDetailsApiModel>>([]),
/** Concert results */ /** Concert results */
concerts: ref<Array<ConcertApiModel>>([]), concerts: ref<Array<ConcertApiModel>>([]),