diff --git a/README.md b/README.md index ef3a719..f02f264 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ RF4DB/RF4-STAT/RF4MAP/RF4 Posts сначала принимаются в изо На сайте у каждой записи отображается источник, а у агрегированной активности — все вошедшие в расчёт источники. Неполные community-наблюдения публикуются сразу в отдельной ленте «Полевые сигналы» с предупреждением и перечнем отсутствующих полей; до подтверждения полноты они не влияют на индекс клёва. -Базовый SEO-контур готов для `rf4spotter.ru`: страницы имеют уникальные метаданные, canonical, Open Graph/Twitter Card, фирменное изображение 1200×630 и JSON-LD; доступны динамические `/robots.txt` и `/sitemap.xml`, административные и ошибочные страницы закрыты от индексации, добавлена собственная страница 404. Индексируемые каталоги рыб и водоёмов, detail-страницы и сочетания водоём + рыба строятся из актуального разрешённого справочника и включаются в sitemap. Подключены фирменные favicon/app icons, web manifest и production-кэширование статических ресурсов. Карточки активности показывают единый паспорт данных: источники, свежесть, полноту и уровень доверия. +Базовый SEO-контур готов для `rf4spotter.ru`: страницы имеют уникальные метаданные, canonical, Open Graph/Twitter Card, фирменное изображение 1200×630 и JSON-LD; доступны динамические `/robots.txt` и `/sitemap.xml`, административные и ошибочные страницы закрыты от индексации, добавлена собственная страница 404. Индексируемые каталоги рыб и водоёмов, detail-страницы и сочетания водоём + рыба строятся из актуального разрешённого справочника и включаются в sitemap. Подключены фирменные favicon/app icons, web manifest и production-кэширование статических ресурсов. Карточки активности показывают единый паспорт данных: источники, свежесть, полноту и уровень доверия. На `/status` опубликована легенда цветов всех источников и статусов качества. Публичные точки используют постоянные читаемые адреса вида `/spots/kuori-85x92`; старые UUID-адреса остаются совместимыми и перенаправляются на канонический URL. diff --git a/apps/web/src/components/DataLegend.astro b/apps/web/src/components/DataLegend.astro new file mode 100644 index 0000000..ae50940 --- /dev/null +++ b/apps/web/src/components/DataLegend.astro @@ -0,0 +1,23 @@ +--- +import SourceBadge from "./SourceBadge.astro"; +const sourceGroups = [ + { source: "rf4-official", text: "официальные таблицы игры" }, + { source: "players", text: "сообщения игроков" }, + { source: "rf4db", text: "разрешённый community-источник" }, + { source: "rf4stat-fishing", text: "разрешённая статистика уловов" }, + { source: "rf4stat-post", text: "разрешённые публикации" }, + { source: "rf4map", text: "разрешённые точки карты" }, + { source: "rf4posts-spot", text: "разрешённые полевые сигналы" }, +]; +--- +
+
Как читать плашки

Легенда данных

Цвет означает происхождение, а статус — пригодность записи. Плашка источника ведёт на исходную публикацию, когда ссылка доступна.

+
+
{sourceGroups.map(item =>
{item.text}
)}
+
+

УчтеноПроверено и участвует в расчёте активности.

+
?

Ждёт проверкиПоказывается, но пока не влияет на индекс.

+
!

Неполные данныеЧасть полей отсутствует и явно перечислена.

+
+
+
diff --git a/apps/web/src/layouts/Layout.astro b/apps/web/src/layouts/Layout.astro index 9b07bee..ddbde87 100644 --- a/apps/web/src/layouts/Layout.astro +++ b/apps/web/src/layouts/Layout.astro @@ -3,6 +3,7 @@ import "../styles/global.css"; import "../styles/catalog.css"; import "../styles/source-status.css"; import "../styles/data-passport.css"; +import "../styles/data-legend.css"; import FishingIcon from "../components/FishingIcon.astro"; const { title = "RF4 Spotter — свежие точки клёва Russian Fishing 4", diff --git a/apps/web/src/pages/status.astro b/apps/web/src/pages/status.astro index c1881bd..4162a04 100644 --- a/apps/web/src/pages/status.astro +++ b/apps/web/src/pages/status.astro @@ -1,6 +1,7 @@ --- import Layout from "../layouts/Layout.astro"; import SourceBadge from "../components/SourceBadge.astro"; +import DataLegend from "../components/DataLegend.astro"; import { ago, api, plural, type SourceStatus } from "../lib/api"; let sources: SourceStatus[] = [], unavailable = false; try { sources = await api("/api/v1/source-status"); } catch { unavailable = true; } @@ -9,4 +10,5 @@ const labels = { healthy:"Актуален", stale:"Данные устарел
Прозрачность данных

Статус источников

Пауза или изменение страницы не удаляют уже опубликованные данные.

{unavailable ?

Статус временно недоступен

:
{sources.map(source =>
{labels[source.status]}

{source.name}

{source.observations} {plural(source.observations,["наблюдение","наблюдения","наблюдений"])}

{source.last_success_at ? `Последнее успешное обновление ${ago(source.last_success_at)}` : "Успешных запусков пока нет"}

)}
} +
diff --git a/apps/web/src/styles/data-legend.css b/apps/web/src/styles/data-legend.css new file mode 100644 index 0000000..8be62c8 --- /dev/null +++ b/apps/web/src/styles/data-legend.css @@ -0,0 +1 @@ +.data-legend{display:grid;grid-template-columns:.7fr 1.3fr;gap:60px;margin-bottom:100px;padding-top:42px;border-top:1px solid #cbd6ce}.data-legend h2{font:400 42px/.95 Georgia,serif;margin:10px 0 14px}.data-legend__intro p{max-width:440px;color:#526662;line-height:1.55}.data-legend__body{display:grid;grid-template-columns:1fr 1fr;gap:30px}.legend-sources{display:grid;gap:8px}.legend-sources>div{display:flex;align-items:center;justify-content:space-between;gap:15px;padding-bottom:8px;border-bottom:1px solid #d8e0da}.legend-sources>div>span{color:#687976;font-size:10px;text-align:right}.legend-quality{display:grid;align-content:start;gap:9px}.legend-quality>div{display:grid;grid-template-columns:30px 1fr;gap:10px;padding:10px;border-radius:10px;background:#fff}.legend-quality i{width:28px;height:28px;display:grid;place-items:center;border-radius:50%;background:#e2efcf;color:#49651f;font-style:normal;font-weight:800}.legend-quality i[data-quality="unverified"]{background:#e8e2f4;color:#59438d}.legend-quality i[data-quality="incomplete"]{background:#f5e6b8;color:#755609}.legend-quality p{display:flex;flex-direction:column;margin:0}.legend-quality strong{font-size:12px}.legend-quality span{margin-top:3px;color:#687976;font-size:10px;line-height:1.35}@media(max-width:900px){.data-legend{grid-template-columns:1fr;gap:25px}.data-legend__body{grid-template-columns:1fr 1fr}}@media(max-width:620px){.data-legend__body{grid-template-columns:1fr}} diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index 0b6508a..82bb764 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -128,7 +128,7 @@ - [ ] Добавить временную шкалу активности 24/72 часа в рыболовной стилистике. - [ ] Добавить лёгкие силуэты видов рыб, не перегружая карточки результатов. - [x] Собрать единый визуальный «паспорт данных»: источник, свежесть, полнота и доверие; применить к карточкам активности (7 сентября 2026). -- [ ] Добавить публичную легенду цветов источников и статусов качества. +- [x] Добавить публичную легенду цветов источников и статусов качества на странице `/status` (7 сентября 2026). - [ ] Добавить skeleton-состояния для динамических публичных блоков. - [ ] Добавить ненавязчивый баннер открытой альфы и канал обратной связи. - [ ] Дополнить пустые состояния собственными рыболовными иллюстрациями с поддержкой `prefers-reduced-motion`.