New section on homepage: popular genres

This commit is contained in:
2025-08-31 11:33:25 +02:00
parent 57a036bea2
commit 2fd045c590
5 changed files with 76 additions and 7 deletions

View File

@@ -3,17 +3,33 @@ defineProps({
/** Displayed smaller text on the left side */
descriptionText: {
type: String,
default: ""
default: "",
},
loading: {
type: Boolean,
default: false,
},
/** Displayed bigger text on the right side */
valueText: [ String, Number ]
})
valueText: [String, Number],
});
</script>
<template>
<v-card variant="outlined" class="my-1 px-2">
<v-row class="d-flex justify-center align-center">
<v-row v-if="loading">
<v-col>
<v-skeleton-loader
type="heading"
:loading="loading"
style="background-color: transparent"
>
sdasd
</v-skeleton-loader>
</v-col>
</v-row>
<v-row class="d-flex justify-center align-center" v-else>
<v-col class="text-caption text-left" v-if="descriptionText.length > 0">
{{ descriptionText }}
</v-col>

View File

@@ -296,7 +296,8 @@
"projectPage": "Projektseite"
},
"genre": {
"withoutBand": "ohne Band"
"withoutBand": "ohne Band",
"popular": "Beliebte Genres"
},
"admin": {
"adminpanel": "Admin Panel"

View File

@@ -296,7 +296,8 @@
"projectPage": "Project page"
},
"genre": {
"withoutBand": "without Band"
"withoutBand": "without Band",
"popular": "Popular Genres"
},
"admin": {
"adminpanel": "Admin Panel"

View File

@@ -0,0 +1,48 @@
<script setup lang="ts">
import CardView from "@/components/basics/cardView.vue";
import CardViewOneLine from "@/components/basics/cardViewOneLine.vue";
import SectionDivider from "@/components/basics/sectionDivider.vue";
import { GenreApiModel } from "@/data/models/acts/genreApiModel";
import { useGenreStore } from "@/stores/genre.store";
import { ref, watch } from "vue";
import { useRouter } from "vue-router";
const genreStore = useGenreStore();
const genresByNumberOfBands = ref<Array<GenreApiModel>>([]);
const router = useRouter();
genreStore.getGenres();
watch(
() => genreStore.genres,
() => {
genresByNumberOfBands.value = genreStore.genres;
genresByNumberOfBands.value.sort((a, b) => {
return b.bands.length - a.bands.length;
});
}
);
</script>
<template>
<v-row>
<v-col>
<section-divider :title="$t('genre.popular')" />
</v-col>
</v-row>
<v-row>
<v-col v-if="genreStore.fetchInProgress" v-for="n in 4" cols="6" md="">
<v-skeleton-loader :loading="true" type="card" />
</v-col>
<v-col v-else v-for="genre in genresByNumberOfBands" cols="6" md="3">
<card-view
@click="router.push({ path: '/bands', query: { genreName: genre.name }})"
:title="genre.name"
:subtitle="genre.bands.length + ' ' + $t('band.band', genre.bands.length)"
/>
</v-col>
</v-row>
</template>

View File

@@ -7,6 +7,7 @@ import TopLocationsSection from "./topLocationsSection.vue";
import { usePreferencesStore } from "@/stores/preferences.store";
import welcomeDialog from "./welcomeDialog/dialog.vue";
import { ref } from "vue";
import genresSection from "./genresSection.vue";
const concertStore = useConcertStore();
const locationStore = useLocationStore();
@@ -34,6 +35,8 @@ if (preferencesStore.firstStartup) {
<v-col cols="10">
<upcoming-concerts-section />
<genres-section />
<top-locations-section />
</v-col>