92 lines
3.3 KiB
Text
92 lines
3.3 KiB
Text
|
|
---
|
|||
|
|
import type { Post } from '@globalInterfaces';
|
|||
|
|
|
|||
|
|
interface Props {
|
|||
|
|
posts: Post[];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const { posts } = Astro.props;
|
|||
|
|
|
|||
|
|
function formatDate(date: string): string {
|
|||
|
|
if (!date) return '';
|
|||
|
|
return new Date(date).toLocaleString('ru-RU', {
|
|||
|
|
year: 'numeric',
|
|||
|
|
month: 'long',
|
|||
|
|
day: 'numeric',
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
{
|
|||
|
|
posts.map((post) => {
|
|||
|
|
const postLink = `/blog/${post.slug}`;
|
|||
|
|
const formattedDate = formatDate(post.publishDate);
|
|||
|
|
const displayTitle = post.title.replace('{year}', new Date().getFullYear().toString());
|
|||
|
|
|
|||
|
|
return (
|
|||
|
|
<div class="relative p-6 md:p-7 rounded-2xl border border-neutral-200 dark:border-neutral-800 bg-white dark:bg-neutral-950 hover:border-neutral-300 dark:hover:border-neutral-700 transition-colors duration-300 group">
|
|||
|
|
|
|||
|
|
{/*
|
|||
|
|
ГЛАВНАЯ ССЫЛКА
|
|||
|
|
z-0 - самый нижний слой
|
|||
|
|
*/}
|
|||
|
|
<a href={postLink} class="absolute inset-0 z-0" aria-label={`Читать: ${displayTitle}`}></a>
|
|||
|
|
|
|||
|
|
{/*
|
|||
|
|
КОНТЕНТ
|
|||
|
|
z-10 - слой выше
|
|||
|
|
*/}
|
|||
|
|
<div class="relative z-10 pointer-events-none">
|
|||
|
|
|
|||
|
|
{/*
|
|||
|
|
ВЕРХНЯЯ СТРОКА:
|
|||
|
|
Слева - декоративная линия
|
|||
|
|
Справа - Дата
|
|||
|
|
*/}
|
|||
|
|
<div class="flex items-center justify-between mb-4">
|
|||
|
|
|
|||
|
|
{/* Слева: Декоративная линия ("строка") */}
|
|||
|
|
<div class="w-12 h-0.5 bg-neutral-200 dark:bg-neutral-800 rounded-full group-hover:bg-neutral-300 dark:group-hover:bg-neutral-700 transition-colors"></div>
|
|||
|
|
|
|||
|
|
{/* Справа: Дата */}
|
|||
|
|
<div class="flex items-center gap-2 text-xs text-neutral-500">
|
|||
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-4 h-4 text-neutral-400">
|
|||
|
|
<path fill-rule="evenodd" d="M6.75 2.25A.75.75 0 017.5 3v1.5h9V3A.75.75 0 0118 3v1.5h.75a3 3 0 013 3v11.25a3 3 0 01-3 3H5.25a3 3 0 01-3-3V7.5a3 3 0 013-3H6V3a.75.75 0 01.75-.75zm13.5 9a1.5 1.5 0 00-1.5-1.5H5.25a1.5 1.5 0 00-1.5 1.5v7.5a1.5 1.5 0 001.5 1.5h13.5a1.5 1.5 0 001.5-1.5v-7.5z" clip-rule="evenodd" />
|
|||
|
|
</svg>
|
|||
|
|
<span class="font-medium">{formattedDate}</span>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
{/* Заголовок */}
|
|||
|
|
<h2 class="text-xl font-bold text-neutral-900 dark:text-neutral-100 mb-2 group-hover:text-indigo-600 dark:group-hover:text-indigo-400 transition-colors">
|
|||
|
|
{displayTitle}
|
|||
|
|
</h2>
|
|||
|
|
|
|||
|
|
{/* Описание */}
|
|||
|
|
<p class="text-sm text-neutral-600 dark:text-neutral-400 leading-relaxed line-clamp-2 mb-4">
|
|||
|
|
{post.description}
|
|||
|
|
</p>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
{/*
|
|||
|
|
НИЗ: Теги
|
|||
|
|
z-20 - верхний слой, клики включены
|
|||
|
|
*/}
|
|||
|
|
{post.tags && post.tags.length > 0 && (
|
|||
|
|
<div class="relative z-20 mt-auto pt-4 border-t border-neutral-100 dark:border-neutral-900 flex flex-wrap gap-2 pointer-events-auto">
|
|||
|
|
{post.tags.map((tag) => (
|
|||
|
|
<a
|
|||
|
|
href={`/blog/tags/${tag.toLowerCase()}`}
|
|||
|
|
class="text-xs text-neutral-500 hover:text-indigo-600 dark:hover:text-indigo-400 transition-colors bg-neutral-50 dark:bg-neutral-900/50 px-2 py-1 rounded"
|
|||
|
|
>
|
|||
|
|
#{tag}
|
|||
|
|
</a>
|
|||
|
|
))}
|
|||
|
|
</div>
|
|||
|
|
)}
|
|||
|
|
|
|||
|
|
</div>
|
|||
|
|
);
|
|||
|
|
})
|
|||
|
|
}
|