72 lines
2.3 KiB
Vue
72 lines
2.3 KiB
Vue
<script setup lang="ts">
|
|
import type { WebNovel } from '~/types'
|
|
|
|
defineProps<{
|
|
novel: WebNovel
|
|
featured?: boolean
|
|
}>()
|
|
|
|
const router = useRouter()
|
|
</script>
|
|
|
|
<template>
|
|
<UCard class="overflow-hidden cursor-pointer hover:shadow-xl transition-shadow duration-300">
|
|
<div class="flex flex-col md:flex-row gap-4">
|
|
<img
|
|
:src="novel.cover"
|
|
:alt="novel.title"
|
|
class="w-full md:w-32 h-48 object-cover rounded"
|
|
>
|
|
<div class="flex-1 flex flex-col justify-between">
|
|
<div>
|
|
<div class="flex items-start justify-between mb-2">
|
|
<div>
|
|
<h3 class="text-lg font-bold">
|
|
{{ novel.title }}
|
|
</h3>
|
|
<p class="text-sm text-gray-600 dark:text-gray-400">
|
|
by {{ typeof novel.author === 'string' ? novel.author : novel.author?.name }}
|
|
</p>
|
|
</div>
|
|
<UBadge
|
|
:color="novel.status === 'completed' ? 'green' : novel.status === 'hiatus' ? 'amber' : 'blue'"
|
|
>
|
|
{{ novel.status }}
|
|
</UBadge>
|
|
</div>
|
|
<p class="text-sm text-gray-700 dark:text-gray-300 line-clamp-2 mb-3">
|
|
{{ novel.description }}
|
|
</p>
|
|
<div class="flex flex-wrap gap-1 mb-3">
|
|
<UBadge v-for="genre in novel.genres" :key="genre" size="xs">
|
|
{{ genre }}
|
|
</UBadge>
|
|
</div>
|
|
</div>
|
|
<div class="flex items-center justify-between">
|
|
<div class="flex items-center gap-4 text-sm">
|
|
<div class="flex items-center gap-1">
|
|
<UIcon name="i-lucide-star" class="size-4 text-yellow-500" />
|
|
<span>{{ (novel.rating || 0).toFixed(1) }}</span>
|
|
</div>
|
|
<div class="flex items-center gap-1">
|
|
<UIcon name="i-lucide-eye" class="size-4" />
|
|
<span>{{ ((novel.views || 0) / 1000).toFixed(0) }}k</span>
|
|
</div>
|
|
<div class="flex items-center gap-1">
|
|
<UIcon name="i-lucide-book" class="size-4" />
|
|
<span>{{ novel.chapters || 0 }}</span>
|
|
</div>
|
|
</div>
|
|
<UButton
|
|
icon="i-lucide-arrow-right"
|
|
@click.stop="router.push(`/novels/${novel.id}`)"
|
|
>
|
|
Read
|
|
</UButton>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</UCard>
|
|
</template>
|