59 lines
1.7 KiB
Vue
59 lines
1.7 KiB
Vue
<script setup lang="ts">
|
|
import type { Chapter } from '~/types'
|
|
|
|
const props = defineProps<{
|
|
chapters: Chapter[]
|
|
currentChapterId?: string
|
|
novelId: string
|
|
}>()
|
|
|
|
const router = useRouter()
|
|
|
|
const formatNumber = (num: number): string => {
|
|
if (num >= 1000000) {
|
|
return `${(num / 1000000).toFixed(1)}M`
|
|
} else if (num >= 1000) {
|
|
return `${(num / 1000).toFixed(1)}k`
|
|
}
|
|
return num.toString()
|
|
}
|
|
|
|
const goToChapter = (chapterId: string) => {
|
|
router.push(`/novel/${props.novelId}/${chapterId}`)
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="space-y-2 max-h-96 overflow-y-auto w-full">
|
|
<div
|
|
v-for="chapter in chapters"
|
|
:key="chapter.id"
|
|
class="p-3 rounded-lg border cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-900 transition-colors w-full"
|
|
:class="{ 'bg-primary/10 border-primary': chapter.id === currentChapterId }"
|
|
@click="goToChapter(chapter.id)"
|
|
>
|
|
<div class="flex items-start justify-between">
|
|
<div>
|
|
<p class="font-semibold text-sm">
|
|
<!-- Chapter {{ chapter.number }}: -->
|
|
{{ chapter.title }}
|
|
</p>
|
|
<p class="text-xs text-gray-500 dark:text-gray-400">
|
|
{{ new Date(chapter.createdAt).toLocaleDateString() }}
|
|
</p>
|
|
</div>
|
|
<div class="flex items-center gap-2 text-xs text-gray-500">
|
|
<span class="flex items-center gap-1">
|
|
<UIcon name="i-lucide-eye" class="size-3" />
|
|
{{ formatNumber(chapter.views) }}
|
|
</span>
|
|
<span class="flex items-center gap-1">
|
|
<UIcon name="i-lucide-heart" class="size-3" />
|
|
{{ formatNumber(chapter.likes) }}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|