lastwebnovel-app/app/components/home/HomePopularNovels.vue
2026-04-11 22:55:16 +02:00

60 lines
2.0 KiB
Vue

<script setup lang="ts">
import type { WebNovel } from '~/types'
interface Props {
novels?: WebNovel[]
loading?: boolean
}
withDefaults(defineProps<Props>(), {
loading: false
})
</script>
<template>
<div>
<div class="flex items-center justify-between mb-6">
<h2 class="text-2xl font-bold text-gray-900 dark:text-white">
Popular Now
</h2>
<NuxtLink to="/novels" class="text-sm text-blue-600 dark:text-blue-400 hover:underline">
Browse All
</NuxtLink>
</div>
<div v-if="loading" class="space-y-3">
<USkeleton v-for="i in 3" :key="i" class="h-20 rounded-lg" />
</div>
<div v-else-if="novels && novels.length > 0" class="space-y-3">
<div
v-for="(novel, idx) in novels.slice(0, 5)"
:key="novel.id"
class="flex items-center gap-4 p-4 rounded-lg border border-gray-200 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-800 transition cursor-pointer"
>
<div class="flex-shrink-0">
<span class="inline-flex items-center justify-center h-8 w-8 rounded-full bg-blue-100 dark:bg-blue-900 text-sm font-semibold text-blue-600 dark:text-blue-300">
{{ idx + 1 }}
</span>
</div>
<NuxtLink :to="`/novels/${novel.slug}`" class="flex-1 min-w-0">
<p class="text-sm font-semibold text-gray-900 dark:text-white truncate">
{{ novel.title }}
</p>
<p class="text-xs text-gray-500 dark:text-gray-400">
{{ novel.author }} • {{ novel.views }}M views
</p>
</NuxtLink>
<div class="flex-shrink-0 flex items-center gap-1">
<UIcon name="i-lucide-star" class="w-4 h-4 text-yellow-400" />
<span class="text-sm font-semibold text-gray-900 dark:text-white">{{ novel.rating }}</span>
</div>
</div>
</div>
<div v-else class="py-8 text-center text-gray-500 dark:text-gray-400">
<p>No novels available</p>
</div>
</div>
</template>