feat: modularize media display by creating MediaItem component, define Media interface, and simplify media list rendering

This commit is contained in:
ethan.chen
2025-05-26 17:05:24 +08:00
parent 96becb0363
commit dd0c6b8e2e
3 changed files with 86 additions and 35 deletions

69
src/lib/MediaItem.svelte Normal file
View File

@@ -0,0 +1,69 @@
<script lang="ts">
import type { Media } from './interfaces';
import { fade } from 'svelte/transition';
export let media: Media;
// 状态映射
const statusMap = {
'completed': '已完成',
'in_progress': '进行中',
'plan_to_watch': '计划中'
};
// 星星评分组件
function StarRating({ rating }: { rating: number }) {
const maxStars = 5;
const stars = [];
for (let i = 1; i <= maxStars; i++) {
const fill = i <= rating ? '#FFD700' : '#E5E7EB';
stars.push(`
<svg class="w-4 h-4" viewBox="0 0 24 24" fill="${fill}" stroke="currentColor">
<path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/>
</svg>
`);
}
return stars.join('');
}
</script>
<div class="border rounded-lg p-4 hover:bg-gray-50" transition:fade>
<div class="flex justify-between items-start">
<div class="space-y-2 flex-1">
<div class="flex items-center justify-between">
<h3 class="text-lg font-medium text-gray-900 truncate max-w-[70%]">{media.title}</h3>
<div class="text-sm text-gray-500">
{media.date ? new Date(media.date).toLocaleDateString() : '未设置日期'}
</div>
</div>
<div class="flex flex-wrap gap-2">
<span class="px-2 py-1 bg-gray-100 rounded text-sm text-gray-700">
状态:{statusMap[media.status] || media.status}
</span>
{#if media.rating}
<div class="px-2 py-1 bg-gray-100 rounded text-sm text-gray-700 flex items-center gap-1">
<span>评分:</span>
<div class="flex items-center">
{@html StarRating({ rating: media.rating / 2 })}
</div>
<span class="ml-1">({media.rating}/10)</span>
</div>
{/if}
{#if media.platform}
<span class="px-2 py-1 bg-gray-100 rounded text-sm text-gray-700">
平台:{media.platform}
</span>
{/if}
</div>
{#if media.notes}
<div class="mt-2 text-sm text-gray-600 bg-gray-50 p-3 rounded">
<div class="whitespace-pre-wrap text-left line-clamp-1">{media.notes}</div>
</div>
{/if}
</div>
</div>
</div>