1+ ---
2+ import FormattedDate from ' ./FormattedDate.astro' ;
3+ import { Image } from " astro:assets" ;
4+ import type { CollectionEntry } from ' astro:content' ;
5+
6+ export interface Props {
7+ relatedPosts: CollectionEntry <' blog' >[];
8+ }
9+
10+ const { relatedPosts } = Astro .props ;
11+
12+ // 只顯示前兩篇相關文章
13+ const displayPosts = relatedPosts .slice (0 , 2 );
14+ ---
15+
16+ { displayPosts .length > 0 && (
17+ <div class = " mt-6 md:mt-8" >
18+ <div class = " grid grid-cols-1 md:grid-cols-2 gap-5 md:gap-6" >
19+ { displayPosts .map ((post ) => {
20+ const { title, pubDate, description, category, tags } = post .data ;
21+
22+ return (
23+ <div class = " group bg-white dark:bg-zinc-900 rounded-xl border border-gray-100/50 dark:border-zinc-700/50 overflow-hidden transition duration-300 ease-out relative" >
24+ <div class = " absolute top-5 left-5 w-1 h-6 rounded-md bg-blue-600" ></div >
25+ <div class = " p-4 pl-8 md:pl-9 relative" >
26+ <a href = { ` /post/${post .slug }/ ` }
27+ class = " group/title block font-bold text-lg md:text-xl text-gray-900 dark:text-zinc-100
28+ hover:text-blue-600 dark:hover:text-blue-400
29+ transition-colors duration-200 mb-3 line-clamp-2 leading-tight relative" >
30+ { title }
31+ <svg class = " text-blue-600 dark:text-blue-400 text-lg hidden md:inline absolute translate-y-0.5 opacity-0 group-hover/title:opacity-100 -translate-x-1 group-hover/title:translate-x-0 transition-all duration-200 ease-out" width = " 20" height = " 20" viewBox = " 0 0 24 24" fill = " currentColor" >
32+ <path d = " M8.59 16.58L13.17 12L8.59 7.41L10 6L16 12L10 18L8.59 16.58Z" />
33+ </svg >
34+ </a >
35+ <div class = " flex flex-wrap items-center gap-2 md:gap-3 text-xs text-gray-500 dark:text-gray-400 mb-3" >
36+ <div class = " flex items-center" >
37+ <div class = " flex items-center justify-center w-4 h-4 md:w-5 md:h-5 bg-gray-100 dark:bg-gray-500/20 rounded-md mr-1" >
38+ <svg width = " 10" height = " 10" viewBox = " 0 0 24 24" fill = " none" stroke = " currentColor" stroke-width = " 2" stroke-linecap = " round" stroke-linejoin = " round" class = " text-gray-600 dark:text-gray-400 md:w-[12px] md:h-[12px]" >
39+ <rect x = " 3" y = " 4" width = " 18" height = " 18" rx = " 2" ry = " 2" ></rect >
40+ <line x1 = " 16" y1 = " 2" x2 = " 16" y2 = " 6" ></line >
41+ <line x1 = " 8" y1 = " 2" x2 = " 8" y2 = " 6" ></line >
42+ <line x1 = " 3" y1 = " 10" x2 = " 21" y2 = " 10" ></line >
43+ </svg >
44+ </div >
45+ <span class = " text-xs font-medium" ><FormattedDate date = { pubDate } /></span >
46+ </div >
47+ <div class = " flex items-center" >
48+ <div class = " flex items-center justify-center w-4 h-4 md:w-5 md:h-5 bg-sky-100 dark:bg-sky-900/20 rounded-md mr-1" >
49+ <svg width = " 10" height = " 10" viewBox = " 0 0 24 24" fill = " none" stroke = " currentColor" stroke-width = " 2" stroke-linecap = " round" stroke-linejoin = " round" class = " text-sky-600 dark:text-sky-400 md:w-[12px] md:h-[12px]" >
50+ <path d = " M22 19a2 2 0 01-2 2H4a2 2 0 01-2-2V5a2 2 0 012-2h5l2 3h9a2 2 0 012 2z" ></path >
51+ </svg >
52+ </div >
53+ <a href = { ` /archive/category/${category .replace (/ \s + / g , ' -' )}/ ` }
54+ class = " text-xs font-medium hover:text-sky-600 dark:hover:text-sky-400 transition-colors" >
55+ { category }
56+ </a >
57+ </div >
58+ </div >
59+ <p class = " text-gray-600 dark:text-gray-300 text-sm line-clamp-2 leading-relaxed mb-3" >
60+ { description }
61+ </p >
62+ { tags && tags .length > 0 && (
63+ <div class = " flex items-center" >
64+ <div class = " flex items-center justify-center w-4 h-4 md:w-5 md:h-5 bg-green-100 dark:bg-green-900/20 rounded-md mr-1" >
65+ <svg width = " 10" height = " 10" viewBox = " 0 0 24 24" fill = " none" stroke = " currentColor" stroke-width = " 2" stroke-linecap = " round" stroke-linejoin = " round" class = " text-green-600 dark:text-green-400 md:w-[12px] md:h-[12px]" style = " transform: translateY(-0.5px);" >
66+ <path d = " M20.59 13.41l-7.17 7.17a2 2 0 01-2.83 0L2 12V2h10l8.59 8.59a2 2 0 010 2.82z" ></path >
67+ <line x1 = " 7" y1 = " 7" x2 = " 7.01" y2 = " 7" ></line >
68+ </svg >
69+ </div >
70+ <div class = " flex flex-wrap gap-1" >
71+ { tags .slice (0 , 2 ).map ((tag , i ) => (
72+ <>
73+ { i > 0 && <div class = " mx-1 text-neutral-400 text-xs" >/</div >}
74+ <a href = { ` /archive/tag/${tag .replace (/ \s + / g , ' -' )}/ ` }
75+ class = " text-xs font-medium hover:text-green-600 dark:hover:text-green-400 transition-colors whitespace-nowrap" >
76+ { tag .trim ()}
77+ </a >
78+ </>
79+ ))}
80+ { tags .length > 2 && (
81+ <span class = " ml-1 text-xs text-neutral-400" >+{ tags .length - 2 } </span >
82+ )}
83+ </div >
84+ </div >
85+ )}
86+ </div >
87+ </div >
88+ );
89+ })}
90+ </div >
91+ </div >
92+ )}
0 commit comments