Buchdetailseite: Design, Struktur und Features

This commit is contained in:
Michi Tomaschko 2025-04-07 07:13:03 +02:00
parent 876ee84bd7
commit 604facd288

View File

@ -2,29 +2,71 @@
<VContainer class="py-6"> <VContainer class="py-6">
<VCard class="pa-4" elevation="2"> <VCard class="pa-4" elevation="2">
<VRow> <VRow>
<!-- Cover & Shops + Community --> <!-- Cover & Blöcke -->
<VCol cols="12" md="3"> <VCol cols="12" md="3">
<div class="mb-4" style="aspect-ratio: 2/3; overflow: hidden;"> <div class="mb-4" style="aspect-ratio: 2/3; overflow: hidden;">
<VImg :src="book.image" height="100%" width="100%" cover class="elevation-1" /> <VImg :src="book.image" height="100%" width="100%" cover class="elevation-1" />
</div> </div>
<div class="d-flex flex-column gap-2 mb-4"> <!-- Shoplinks mit Farben -->
<VBtn block color="black" variant="outlined" href="https://www.amazon.de" target="_blank"> <VCard class="pa-3 mb-4" variant="outlined">
<VIcon start icon="tabler-brand-amazon" /> Amazon <VCardTitle>Shops</VCardTitle>
</VBtn> <VCardText>
<VBtn block color="blue" variant="outlined"> <div class="d-flex flex-column gap-2">
<VIcon start icon="tabler-book" /> Hugendubel
</VBtn> <VBtn block variant="outlined" style="border-color: #FF9900; background-color: #FFF3E0;" class="text-black shop-btn">
<VBtn block color="grey" variant="outlined"> <VIcon start icon="tabler-brand-amazon" /> Amazon
<VIcon start icon="tabler-brand-apple" /> Apple </VBtn>
</VBtn>
<VBtn block color="green" variant="outlined"> <VBtn block variant="outlined" style="border-color: #005B9F; background-color: #E3F2FD;" class="text-black shop-btn">
<VIcon start icon="tabler-book-2" /> Thalia <VIcon start icon="tabler-book" /> Hugendubel
</VBtn> </VBtn>
</div>
<VBtn block variant="outlined" style="border-color: #333333; background-color: #F5F5F5;" class="text-black shop-btn">
<VIcon start icon="tabler-brand-apple" /> Apple
</VBtn>
<VBtn block variant="outlined" style="border-color: #009245; background-color: #E8F5E9;" class="text-black shop-btn">
<VIcon start icon="tabler-book-2" /> Thalia
</VBtn>
</div>
</VCardText>
</VCard>
<!-- Benutzeraktionen -->
<VCard class="pa-3 mb-4" variant="outlined">
<VCardTitle>Deine Aktionen</VCardTitle>
<VCardText>
<div class="d-flex flex-column gap-2">
<VBtn :color="liked ? 'primary' : 'grey'" @click="toggleLike" variant="outlined">
<VIcon
start
:icon="liked ? 'tabler-heart-filled' : 'tabler-heart'"
class="transition-transform"
:class="liked ? 'scale-125' : ''"
/>
{{ liked ? 'Gefällt mir' : 'Gefällt mir nicht mehr' }}
</VBtn>
<VBtn :color="readingStatus ? 'primary' : 'grey'" @click="toggleReadingStatus" variant="outlined">
<VIcon icon="tabler-book" start />
{{ readingStatus ? 'Gelesen' : 'Noch nicht gelesen' }}
</VBtn>
<VBtn :color="wishlist ? 'primary' : 'grey'" @click="toggleWishlist" variant="outlined">
<VIcon icon="tabler-bookmark" start />
{{ wishlist ? 'Auf der Wunschliste' : 'Zur Wunschliste' }}
</VBtn>
<VBtn :color="collection ? 'primary' : 'grey'" @click="toggleCollection" variant="outlined">
<VIcon icon="tabler-archive" start />
{{ collection ? 'In Sammlung' : 'Zur Sammlung hinzufügen' }}
</VBtn>
</div>
</VCardText>
</VCard>
<!-- Community-Statistik --> <!-- Community-Statistik -->
<VCard class="pa-3" variant="outlined" style="min-height: 220px;"> <VCard class="pa-3" variant="outlined">
<VCardTitle>Community-Statistik</VCardTitle> <VCardTitle>Community-Statistik</VCardTitle>
<VCardText> <VCardText>
<VList density="compact"> <VList density="compact">
@ -57,20 +99,34 @@
</VChip> </VChip>
</div> </div>
<!-- Neue statische Fieberkurve --> <!-- Fieberkurve -->
<Fieberkurve :isStatic="true" :defaultValues="[{ value: 5 }, { value: 2 }, { value: 7 }, { value: 3 }, { value: 5 }]" class="my-4" /> <VCard class="mb-6 elevation-3" variant="outlined" style="border: 2px dashed var(--v-theme-primary);">
<VCardTitle>
<VIcon icon="tabler-activity" start /> Fieberkurve (Lesedynamik)
</VCardTitle>
<VCardText>
<Fieberkurve :isStatic="true" :defaultValues="book.fieberkurve" class="mb-2" />
<!-- <p class="text-caption text-muted">
Die Skoutz-Fieberkurve zeigt, wie emotional spannend das Buch im Verlauf empfunden wird.
</p>-->
</VCardText>
</VCard>
<!-- Inhaltsangabe --> <!-- Inhaltsangabe -->
<VCard class="mb-4" variant="outlined" style="min-height: 180px;"> <VCard class="mb-4 elevation-1" variant="outlined" style="border-left: 6px solid var(--v-theme-primary); background-color: #f9f9ff;">
<VCardTitle>Inhaltsangabe</VCardTitle> <VCardTitle>
<VCardText>{{ book.blurb }}</VCardText> <VIcon icon="tabler-quote" start /> Inhaltsangabe
</VCardTitle>
<VCardText class="text-body-1">{{ book.blurb }}</VCardText>
</VCard> </VCard>
<!-- Buchdetails & Infos --> <!-- Buchdetails & Infos -->
<VRow> <VRow>
<VCol cols="12" md="6"> <VCol cols="12" md="6">
<VCard class="pa-3" variant="outlined" style="min-height: 220px;"> <VCard class="pa-3 elevation-1" variant="outlined" style="border-left: 6px solid var(--v-theme-primary); background-color: #f9f9ff;">
<VCardTitle>Buchdetails</VCardTitle> <VCardTitle>
<VIcon icon="tabler-info-circle" start /> Buchdetails
</VCardTitle>
<VCardText> <VCardText>
<strong>ISBN:</strong> {{ book.isbn || '' }}<br /> <strong>ISBN:</strong> {{ book.isbn || '' }}<br />
<strong>Sprache:</strong> {{ book.language }}<br /> <strong>Sprache:</strong> {{ book.language }}<br />
@ -81,8 +137,10 @@
</VCard> </VCard>
</VCol> </VCol>
<VCol cols="12" md="6"> <VCol cols="12" md="6">
<VCard class="pa-3" variant="outlined" style="min-height: 220px;"> <VCard class="pa-3 elevation-1" variant="outlined">
<VCardTitle>Weitere Informationen</VCardTitle> <VCardTitle>
<VIcon icon="tabler-link" start /> Weitere Informationen
</VCardTitle>
<VCardText> <VCardText>
<ul class="pa-0" style="list-style: none"> <ul class="pa-0" style="list-style: none">
<li><a href="#">Alle Ausgaben in der Übersicht</a></li> <li><a href="#">Alle Ausgaben in der Übersicht</a></li>
@ -97,50 +155,64 @@
</VCol> </VCol>
</VRow> </VRow>
<!-- Weitere Bücher vom Autor --> <!-- Bücher vom gleichen Autor -->
<VCard class="mt-6 mb-6" elevation="0"> <VCard class="mt-6" elevation="0">
<VCardTitle>Bücher von {{ book.authors[0]?.name }}</VCardTitle> <VCardTitle>Weitere Bücher von {{ book.authors[0]?.name }}</VCardTitle>
<VCardText> <VCardText>
<VRow> <VRow>
<VCol v-for="item in authorBooks" :key="item.id" cols="12" sm="6" md="3"> <VCol
<RouterLink :to="`/buchdetailseite/${item.id}`"> v-for="b in authorBooks"
:key="b.id"
cols="12"
sm="6"
md="3"
>
<RouterLink :to="`/buchdetailseite/${b.id}`">
<VCard class="hover:scale-105 transition-transform duration-200"> <VCard class="hover:scale-105 transition-transform duration-200">
<VImg :src="item.image" height="180" cover /> <VImg :src="b.image" height="180" cover />
<VCardText> <VCardText class="text-sm font-semibold">
<div class="text-sm font-semibold">{{ item.title }}</div> {{ b.title }}
</VCardText> </VCardText>
</VCard> </VCard>
</RouterLink> </RouterLink>
</VCol> </VCol>
<!-- Beispielbücher -->
<VCol cols="12" sm="6" md="3">
<VCard>
<VImg src="https://m.media-amazon.com/images/I/81bsw6fnUiL.jpg" height="180" cover />
<VCardText>
<div class="text-sm font-semibold">Rich Dad's Cashflow Quadrant</div>
</VCardText>
</VCard>
</VCol>
<VCol cols="12" sm="6" md="3">
<VCard>
<VImg src="https://m.media-amazon.com/images/I/81eUwF5QzIL.jpg" height="180" cover />
<VCardText>
<div class="text-sm font-semibold">Rich Dad's Guide to Investing</div>
</VCardText>
</VCard>
</VCol>
</VRow> </VRow>
</VCardText> </VCardText>
</VCard> </VCard>
<!-- Rezensionen --> <!-- Rezensionen -->
<VCard elevation="0"> <VCard class="mt-6" variant="outlined">
<VCardTitle>Rezensionen & Bewertungen</VCardTitle> <VCardTitle><VIcon icon="tabler-star" start /> Rezensionen & Bewertungen</VCardTitle>
<VCardText> <VCardText>
<p class="mb-2"> 4,3 / 5 Sterne (15 Stimmen)</p> <VCard
<em>Hier könnten später echte Rezensionen von Nutzern folgen.</em> v-for="(review, index) in reviews"
:key="index"
class="mb-3 pa-3"
variant="outlined"
>
<div class="d-flex justify-space-between align-center">
<span><strong>{{ review.name }}</strong> am {{ review.date }}</span>
<VRating v-model="review.rating" readonly density="compact" size="small" />
</div>
<p class="mt-2">{{ review.text }}</p>
</VCard>
</VCardText> </VCardText>
</VCard> </VCard>
<!-- eigene Rezensionen abgeben -->
<VCardText>
<VTextarea label="Eigene Rezension schreiben" rows="3" variant="outlined" />
<VBtn color="primary" class="mt-2">Absenden</VBtn>
</VCardText>
<!-- Snackbar -->
<VSnackbar v-model="snackbar" :timeout="2000" location="top right" color="success">
{{ snackbarText }}
</VSnackbar>
<!-- Ähnliche Bücher --> <!-- Ähnliche Bücher -->
<VCard class="mt-6" elevation="0"> <VCard class="mt-6" elevation="0">
@ -173,7 +245,7 @@
</template> </template>
<script setup> <script setup>
import { computed } from 'vue' import { ref, computed } from 'vue'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import { books } from '@/components/buecherdatenbank' import { books } from '@/components/buecherdatenbank'
import Fieberkurve from '@/components/Fieberkurve.vue' import Fieberkurve from '@/components/Fieberkurve.vue'
@ -182,6 +254,36 @@ const route = useRoute()
const id = parseInt(route.params.id) const id = parseInt(route.params.id)
const book = books.find(b => b.id === id) || {} const book = books.find(b => b.id === id) || {}
const liked = ref(false)
const readingStatus = ref(false)
const wishlist = ref(false)
const collection = ref(false)
const snackbar = ref(false)
snackbar.value = false
const snackbarText = ref('')
function showFeedback(text) {
snackbarText.value = text
snackbar.value = true
}
function toggleLike() {
liked.value = !liked.value
showFeedback(liked.value ? 'Zur Favoritenliste hinzugefügt ✅' : 'Aus Favoriten entfernt ❌')
}
function toggleReadingStatus() {
readingStatus.value = !readingStatus.value
showFeedback(readingStatus.value ? 'Als gelesen markiert 📘' : 'Markierung entfernt ❌')
}
function toggleWishlist() {
wishlist.value = !wishlist.value
showFeedback(wishlist.value ? 'Zur Wunschliste hinzugefügt 🎁' : 'Von Wunschliste entfernt ❌')
}
function toggleCollection() {
collection.value = !collection.value
showFeedback(collection.value ? 'Zur Sammlung hinzugefügt 📚' : 'Aus Sammlung entfernt ❌')
}
const authorBooks = computed(() => { const authorBooks = computed(() => {
if (!book?.authors?.[0]?.name) return [] if (!book?.authors?.[0]?.name) return []
return books.filter(b => b.authors?.[0]?.name === book.authors[0].name && b.id !== book.id) return books.filter(b => b.authors?.[0]?.name === book.authors[0].name && b.id !== book.id)
@ -195,6 +297,12 @@ const similarBooks = computed(() => {
).slice(0, 4) ).slice(0, 4)
}) })
const reviews = ref([
{ name: 'Anna L.', date: '03.04.2025', rating: 4, text: 'Ein inspirierendes Buch hat mich zum Nachdenken gebracht!' },
{ name: 'Jonas M.', date: '18.02.2025', rating: 3, text: 'Starker Mittelteil, etwas schwaches Ende. Trotzdem lesenswert.' },
{ name: 'LeserIn', date: '22.01.2025', rating: 5, text: 'Ich konnte es nicht aus der Hand legen! Spannung pur.' },
])
const genreIcon = genre => { const genreIcon = genre => {
const icons = { const icons = {
Crime: 'tabler-fingerprint', Crime: 'tabler-fingerprint',
@ -211,3 +319,11 @@ const genreIcon = genre => {
return icons[genre] || 'tabler-book' return icons[genre] || 'tabler-book'
} }
</script> </script>
<style scoped>
.shop-btn:hover {
transform: scale(1.02);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
</style>