buchdetailseite: Umsetzung von PowerPoint Layout, sowie zusätliche Idee "Community-Statistik" usw.
This commit is contained in:
parent
2818ec4a60
commit
6679083789
@ -1,102 +1,213 @@
|
|||||||
<template>
|
<template>
|
||||||
<VContainer class="pt-6">
|
<VContainer class="py-6">
|
||||||
<VRow>
|
<VCard class="pa-4" elevation="2">
|
||||||
<VCol cols="12" md="4">
|
<VRow>
|
||||||
<VImg
|
<!-- Cover & Shops + Community -->
|
||||||
:src="book.image"
|
<VCol cols="12" md="3">
|
||||||
max-height="500"
|
<div class="mb-4" style="aspect-ratio: 2/3; overflow: hidden;">
|
||||||
max-width="100%"
|
<VImg :src="book.image" height="100%" width="100%" cover class="elevation-1" />
|
||||||
contain
|
</div>
|
||||||
class="rounded"
|
|
||||||
/>
|
|
||||||
</VCol>
|
|
||||||
|
|
||||||
<VCol cols="12" md="8">
|
<div class="d-flex flex-column gap-2 mb-4">
|
||||||
<VCard class="pa-4">
|
<VBtn block color="black" variant="outlined" href="https://www.amazon.de" target="_blank">
|
||||||
<VCardTitle class="text-h5 font-weight-bold">
|
<VIcon start icon="tabler-brand-amazon" /> Amazon
|
||||||
{{ book.title }}<br>
|
</VBtn>
|
||||||
<span class="text-subtitle-1" v-if="book.subtitle">{{ book.subtitle }}</span>
|
<VBtn block color="blue" variant="outlined">
|
||||||
</VCardTitle>
|
<VIcon start icon="tabler-book" /> Hugendubel
|
||||||
|
</VBtn>
|
||||||
|
<VBtn block color="grey" variant="outlined">
|
||||||
|
<VIcon start icon="tabler-brand-apple" /> Apple
|
||||||
|
</VBtn>
|
||||||
|
<VBtn block color="green" variant="outlined">
|
||||||
|
<VIcon start icon="tabler-book-2" /> Thalia
|
||||||
|
</VBtn>
|
||||||
|
</div>
|
||||||
|
|
||||||
<VCardText>
|
<!-- Community-Statistik -->
|
||||||
<div v-if="book.authors?.length" class="mb-2">
|
<VCard class="pa-3" variant="outlined" style="min-height: 220px;">
|
||||||
<strong>Autor(en):</strong>
|
<VCardTitle>Community-Statistik</VCardTitle>
|
||||||
{{ book.authors.map(a => a.name).join(', ') }}
|
<VCardText>
|
||||||
</div>
|
<VList density="compact">
|
||||||
|
<VListItem prepend-icon="tabler-library">In 47 Bibliotheken</VListItem>
|
||||||
|
<VListItem prepend-icon="tabler-bookmark">Auf 20 Merkzettel</VListItem>
|
||||||
|
<VListItem prepend-icon="tabler-book">4 Leser*innen lesen es gerade</VListItem>
|
||||||
|
</VList>
|
||||||
|
</VCardText>
|
||||||
|
</VCard>
|
||||||
|
</VCol>
|
||||||
|
|
||||||
<!-- Genres mit Icons -->
|
<!-- Hauptbereich -->
|
||||||
<div class="d-flex flex-wrap align-center mb-3">
|
<VCol cols="12" md="9">
|
||||||
<VChip
|
<div class="mb-6">
|
||||||
v-for="genre in book.genres"
|
<h1 class="text-h4 font-weight-bold mb-1">{{ book.title }}</h1>
|
||||||
:key="genre"
|
<h2 class="text-subtitle-1">von {{ book.authors[0]?.name }}</h2>
|
||||||
color="primary"
|
<div class="mt-2 text-muted">{{ book.subtitle }}</div>
|
||||||
class="ma-1"
|
</div>
|
||||||
size="small"
|
|
||||||
>
|
|
||||||
<VIcon
|
|
||||||
v-if="genreIconMap[genre]"
|
|
||||||
:icon="genreIconMap[genre].icon"
|
|
||||||
:size="genreIconMap[genre].size"
|
|
||||||
class="me-1"
|
|
||||||
/>
|
|
||||||
{{ genre }}
|
|
||||||
</VChip>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Fieberkurve -->
|
<!-- Genres -->
|
||||||
<Fieberkurve :is-static="true" :default-values="book.fieberkurve" :hide-text="true" class="mb-4" />
|
<div class="d-flex align-center gap-2 flex-wrap mb-4">
|
||||||
|
<VChip
|
||||||
|
v-for="genre in book.genres"
|
||||||
|
:key="genre"
|
||||||
|
color="primary"
|
||||||
|
variant="flat"
|
||||||
|
class="me-1"
|
||||||
|
>
|
||||||
|
<VIcon start :icon="genreIcon(genre)" /> {{ genre }}
|
||||||
|
</VChip>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Beschreibung -->
|
<!-- Neue statische Fieberkurve -->
|
||||||
<div class="mb-4">
|
<Fieberkurve :isStatic="true" :defaultValues="[{ value: 5 }, { value: 2 }, { value: 7 }, { value: 3 }, { value: 5 }]" class="my-4" />
|
||||||
<strong>Beschreibung:</strong>
|
|
||||||
<p class="mt-1">{{ book.blurb }}</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Detailtabelle -->
|
<!-- Inhaltsangabe -->
|
||||||
<VTable dense>
|
<VCard class="mb-4" variant="outlined" style="min-height: 180px;">
|
||||||
<tbody>
|
<VCardTitle>Inhaltsangabe</VCardTitle>
|
||||||
<tr><td><strong>Seitenzahl</strong></td><td>{{ book.pageCount }}</td></tr>
|
<VCardText>{{ book.blurb }}</VCardText>
|
||||||
<tr><td><strong>Sprache</strong></td><td>{{ book.language }}</td></tr>
|
</VCard>
|
||||||
<tr v-if="book.publishers"><td><strong>Verlag</strong></td><td>{{ book.publishers }}</td></tr>
|
|
||||||
<tr><td><strong>Veröffentlicht</strong></td><td>{{ book.publishedDate }}</td></tr>
|
|
||||||
<tr v-if="book.isbn"><td><strong>ISBN</strong></td><td>{{ book.isbn }}</td></tr>
|
|
||||||
</tbody>
|
|
||||||
</VTable>
|
|
||||||
|
|
||||||
<!-- Shoplink (Platzhalter) -->
|
<!-- Buchdetails & Infos -->
|
||||||
<div class="mt-4">
|
<VRow>
|
||||||
<VBtn color="success" variant="flat">
|
<VCol cols="12" md="6">
|
||||||
<VIcon icon="tabler-shopping-cart" class="me-2" />
|
<VCard class="pa-3" variant="outlined" style="min-height: 220px;">
|
||||||
Bei Amazon suchen
|
<VCardTitle>Buchdetails</VCardTitle>
|
||||||
</VBtn>
|
<VCardText>
|
||||||
</div>
|
<strong>ISBN:</strong> {{ book.isbn || '–' }}<br />
|
||||||
|
<strong>Sprache:</strong> {{ book.language }}<br />
|
||||||
|
<strong>Seiten:</strong> {{ book.pageCount }}<br />
|
||||||
|
<strong>Verlag:</strong> {{ book.publishers || '–' }}<br />
|
||||||
|
<strong>Veröffentlicht:</strong> {{ book.publishedDate }}
|
||||||
|
</VCardText>
|
||||||
|
</VCard>
|
||||||
|
</VCol>
|
||||||
|
<VCol cols="12" md="6">
|
||||||
|
<VCard class="pa-3" variant="outlined" style="min-height: 220px;">
|
||||||
|
<VCardTitle>Weitere Informationen</VCardTitle>
|
||||||
|
<VCardText>
|
||||||
|
<ul class="pa-0" style="list-style: none">
|
||||||
|
<li><a href="#">Alle Ausgaben in der Übersicht</a></li>
|
||||||
|
<li><a href="#">Vergleichbare Bücher suchen</a></li>
|
||||||
|
<li><a href="#">Mehr über das Buch (z. B. Skoutz-Artikel)</a></li>
|
||||||
|
<li><a href="#">Über den Autor/die Autorin</a></li>
|
||||||
|
<li><a href="#">Über den Verlag</a></li>
|
||||||
|
<li><a href="#">Weitere Bücher aus der Reihe</a></li>
|
||||||
|
</ul>
|
||||||
|
</VCardText>
|
||||||
|
</VCard>
|
||||||
|
</VCol>
|
||||||
|
</VRow>
|
||||||
|
|
||||||
</VCardText>
|
<!-- Weitere Bücher vom Autor -->
|
||||||
</VCard>
|
<VCard class="mt-6 mb-6" elevation="0">
|
||||||
</VCol>
|
<VCardTitle>Bücher von {{ book.authors[0]?.name }}</VCardTitle>
|
||||||
</VRow>
|
<VCardText>
|
||||||
|
<VRow>
|
||||||
|
<VCol v-for="item in authorBooks" :key="item.id" cols="12" sm="6" md="3">
|
||||||
|
<RouterLink :to="`/buchdetailseite/${item.id}`">
|
||||||
|
<VCard class="hover:scale-105 transition-transform duration-200">
|
||||||
|
<VImg :src="item.image" height="180" cover />
|
||||||
|
<VCardText>
|
||||||
|
<div class="text-sm font-semibold">{{ item.title }}</div>
|
||||||
|
</VCardText>
|
||||||
|
</VCard>
|
||||||
|
</RouterLink>
|
||||||
|
</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>
|
||||||
|
</VCardText>
|
||||||
|
</VCard>
|
||||||
|
|
||||||
|
<!-- Rezensionen -->
|
||||||
|
<VCard elevation="0">
|
||||||
|
<VCardTitle>Rezensionen & Bewertungen</VCardTitle>
|
||||||
|
<VCardText>
|
||||||
|
<p class="mb-2">⭐⭐⭐⭐☆ 4,3 / 5 Sterne (15 Stimmen)</p>
|
||||||
|
<em>Hier könnten später echte Rezensionen von Nutzern folgen.</em>
|
||||||
|
</VCardText>
|
||||||
|
</VCard>
|
||||||
|
|
||||||
|
<!-- Ähnliche Bücher -->
|
||||||
|
<VCard class="mt-6" elevation="0">
|
||||||
|
<VCardTitle>Ähnliche Bücher</VCardTitle>
|
||||||
|
<VCardText>
|
||||||
|
<VRow>
|
||||||
|
<VCol
|
||||||
|
v-for="similar in similarBooks"
|
||||||
|
:key="similar.id"
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
md="3"
|
||||||
|
>
|
||||||
|
<RouterLink :to="`/buchdetailseite/${similar.id}`">
|
||||||
|
<VCard class="hover:scale-105 transition-transform duration-200">
|
||||||
|
<VImg :src="similar.image" height="180" cover />
|
||||||
|
<VCardText>
|
||||||
|
<div class="text-sm font-semibold">{{ similar.title }}</div>
|
||||||
|
</VCardText>
|
||||||
|
</VCard>
|
||||||
|
</RouterLink>
|
||||||
|
</VCol>
|
||||||
|
</VRow>
|
||||||
|
</VCardText>
|
||||||
|
</VCard>
|
||||||
|
</VCol>
|
||||||
|
</VRow>
|
||||||
|
</VCard>
|
||||||
</VContainer>
|
</VContainer>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from 'vue'
|
import { computed } from 'vue'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import { books } from '@/components/buecherdatenbank.js'
|
import { books } from '@/components/buecherdatenbank'
|
||||||
import { genres as genreIcons } from '@/components/genredatenbank.js'
|
|
||||||
import Fieberkurve from '@/components/Fieberkurve.vue'
|
import Fieberkurve from '@/components/Fieberkurve.vue'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const bookId = parseInt(route.params.id)
|
const id = parseInt(route.params.id)
|
||||||
const book = books.find(b => b.id === bookId) || {}
|
const book = books.find(b => b.id === id) || {}
|
||||||
|
|
||||||
const genreIconMap = genreIcons.reduce((acc, g) => {
|
const authorBooks = computed(() => {
|
||||||
acc[g.value] = g.icon
|
if (!book?.authors?.[0]?.name) return []
|
||||||
return acc
|
return books.filter(b => b.authors?.[0]?.name === book.authors[0].name && b.id !== book.id)
|
||||||
}, {})
|
})
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
const similarBooks = computed(() => {
|
||||||
p {
|
if (!book.genres || !book.genres.length) return []
|
||||||
line-height: 1.6;
|
return books.filter(b =>
|
||||||
|
b.id !== book.id &&
|
||||||
|
b.genres?.some(g => book.genres.includes(g))
|
||||||
|
).slice(0, 4)
|
||||||
|
})
|
||||||
|
|
||||||
|
const genreIcon = genre => {
|
||||||
|
const icons = {
|
||||||
|
Crime: 'tabler-fingerprint',
|
||||||
|
Erotik: 'tabler-bed',
|
||||||
|
Fantasy: 'tabler-paw',
|
||||||
|
History: 'tabler-swords',
|
||||||
|
Horror: 'tabler-ghost-2',
|
||||||
|
Humor: 'tabler-mood-xd',
|
||||||
|
Romance: 'tabler-hearts',
|
||||||
|
ScienceFiction: 'tabler-ufo',
|
||||||
|
Contemporary: 'tabler-building-skyscraper',
|
||||||
|
Abenteuer: 'tabler-compass',
|
||||||
|
}
|
||||||
|
return icons[genre] || 'tabler-book'
|
||||||
}
|
}
|
||||||
</style>
|
</script>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user