63 lines
1.8 KiB
Vue
63 lines
1.8 KiB
Vue
<script setup lang="ts">
|
|
import type { WebNovel, Chapter } from '~/types'
|
|
|
|
interface ContinueReading {
|
|
novel: WebNovel
|
|
lastChapter: Chapter
|
|
readingTime?: string
|
|
}
|
|
|
|
interface Props {
|
|
items?: ContinueReading[]
|
|
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">
|
|
Continue Reading
|
|
</h2>
|
|
</div>
|
|
|
|
<div v-if="loading" class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
<USkeleton v-for="i in 2" :key="i" class="h-32 rounded-lg" />
|
|
</div>
|
|
|
|
<div v-else-if="items && items.length > 0" class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
<NuxtLink
|
|
v-for="item in items"
|
|
:key="item.novel.id"
|
|
:to="`/novel/${item.novel.slug}/${item.lastChapter.slug}`"
|
|
class="p-4 rounded-lg border border-gray-200 dark:border-gray-700 hover:shadow-lg dark:hover:shadow-xl transition"
|
|
>
|
|
<div class="flex gap-4">
|
|
<div class="flex-1">
|
|
<h3 class="font-semibold text-gray-900 dark:text-white line-clamp-2">
|
|
{{ item.novel.title }}
|
|
</h3>
|
|
<p class="text-sm text-gray-600 dark:text-gray-400 mt-1">
|
|
{{ item.lastChapter.title }}
|
|
</p>
|
|
<p v-if="item.readingTime" class="text-xs text-gray-500 dark:text-gray-500 mt-2">
|
|
Reading time: {{ item.readingTime }}
|
|
</p>
|
|
</div>
|
|
<div class="flex-shrink-0">
|
|
<UIcon name="i-lucide-arrow-right" class="w-5 h-5 text-gray-400 dark:text-gray-600" />
|
|
</div>
|
|
</div>
|
|
</NuxtLink>
|
|
</div>
|
|
|
|
<div v-else class="py-8 text-center text-gray-500 dark:text-gray-400">
|
|
<p>No reading history yet. Start reading a novel!</p>
|
|
</div>
|
|
</div>
|
|
</template>
|