Files
anotherreflections-website-v2/src/pages/index.astro
striker 6f2cfdd63d feat: счётчики с consent, политика, фиксы дизайна
Дизайн-фиксы:
- Перенесены картинки из старого WP в public/wp-content/uploads/
  (header_bg.gif + 3 размера NY-baner.png 2014/12). migrate-wp.mjs
  обновлён: корректно обрабатывает <a><img></a>, переписывает абсолютные
  URL anotherreflections.ru/wp-content/... в относительные
- Description в frontmatter теперь чистый plain text — без markdown-разметки
- Слаги 11/95/152 → kto-my, s-23-fevralya-2011, s-nastupayushhim-novym-2012-godom
- Hero-метрика: «N лет онлайн» → «с 2006 года» (последний пост 2015,
  активной жизни «20 лет» нет)
- Drop cap (буквица) — только для постов длиннее 240 символов
  (короткие посты раньше выглядели обрезанными)

Аналитика и конфиденциальность:
- Яндекс.Метрика (counter 13938862, webvisor) и Google gtag (GT-PH39R3X)
  перенесены со старого WP
- Cookie consent banner — самописный, без зависимостей: счётчики грузятся
  только после явного «Принять». Выбор хранится в localStorage + cookie
  ar-consent на 12 месяцев. Уведомление в духе 152-ФЗ
- /privacy/ — полная политика конфиденциальности: что собираем (через
  Метрику и GA), для чего, как cookies устроены, права пользователя,
  контакт для запросов на удаление
- В футере добавлены ссылки «Политика конфиденциальности» и «Контакты»
- sitemap.txt + llms.txt включают /privacy/
2026-05-21 02:07:08 +03:00

61 lines
2.4 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
import { getCollection } from 'astro:content';
import BaseLayout from '../layouts/BaseLayout.astro';
import { WORLDS, CATEGORY_COLORS, HERO_TAGLINE, SITE_FOUNDED, plural } from '../consts';
const posts = (await getCollection('posts'))
.sort((a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf());
const totalPosts = posts.length;
const totalWorlds = WORLDS.length; // используется в hero-meta
const oldestYear = posts.length ? posts[posts.length - 1].data.pubDate.getFullYear() : SITE_FOUNDED;
const fmtDate = (d: Date) =>
d.toLocaleDateString('ru-RU', { year: 'numeric', month: 'long', day: 'numeric' });
---
<BaseLayout>
<section class="hero">
<span class="hero-eyebrow">Ролевой проект · с {SITE_FOUNDED} года</span>
<h1>Иные<br/>Отражения</h1>
<p class="hero-tagline">{HERO_TAGLINE}</p>
<div class="hero-meta">
<span><strong>{totalWorlds}</strong> {plural(totalWorlds, ['мир', 'мира', 'миров'])}</span>
<span><strong>{totalPosts}</strong> {plural(totalPosts, ['публикация', 'публикации', 'публикаций'])}</span>
<span><strong>с {SITE_FOUNDED}</strong> года</span>
</div>
</section>
<section id="news">
<div class="section-head">
<h2>Хроника проекта</h2>
<span class="section-meta"><a href="/feed.xml">RSS-фид</a></span>
</div>
<ul class="post-list">
{posts.map((post) => {
const catColor = post.data.categorySlugs[0]
? CATEGORY_COLORS[post.data.categorySlugs[0]] ?? 'var(--accent)'
: 'var(--accent)';
return (
<li class="post-card" style={`--cat-color: ${catColor}`}>
<div class="post-meta">
<time datetime={post.data.pubDate.toISOString()}>{fmtDate(post.data.pubDate)}</time>
{post.data.categories.length > 0 && (
<a
href={`/category/${post.data.categorySlugs[0]}/`}
class="cat-tag"
style={`--cat-color: ${catColor}`}
>
{post.data.categories[0]}
</a>
)}
</div>
<h3><a href={`/${post.data.slug}/`}>{post.data.title}</a></h3>
{post.data.description && <p class="post-excerpt">{post.data.description}…</p>}
</li>
);
})}
</ul>
</section>
</BaseLayout>