Files
rf4-spotter/apps/web/src/pages/waterbodies/[slug]/[fish].astro
T

28 lines
3.2 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 ActivityCard from "../../../components/ActivityCard.astro";
import PageHero from "../../../components/PageHero.astro";
import StatePanel from "../../../components/StatePanel.astro";
import Layout from "../../../layouts/Layout.astro";
import { api, plural, type Activity, type DictionaryItem, type PaginatedActivity } from "../../../lib/api";
const { slug, fish: fishSlug } = Astro.params;
let water: DictionaryItem | undefined, fish: DictionaryItem | undefined, items: Activity[] = [], unavailable = false;
try {
const [waters, fishes] = await Promise.all([api<DictionaryItem[]>("/api/v1/waterbodies?limit=500"), api<DictionaryItem[]>("/api/v1/fishes?limit=500")]);
water = waters.find(item => item.slug === slug); fish = fishes.find(item => item.slug === fishSlug);
if (water && fish) { const paginated = await api<PaginatedActivity>(`/api/v1/activity?hours=72&waterbody=${encodeURIComponent(water.slug)}&fish=${encodeURIComponent(fish.slug)}&limit=100`); items = paginated.items; }
} catch { unavailable = true; }
if (unavailable) {
Astro.response.status = 503;
Astro.response.headers.set("Retry-After", "60");
Astro.response.headers.set("Cache-Control", "no-store");
}
if ((!water || !fish) && !unavailable) Astro.response.status = 404;
const valid = Boolean(water && fish);
const schema = valid ? { "@type":"CollectionPage", name:`${fish!.name_ru} на ${water!.name_ru} в RF4`, url:`https://rf4spotter.ru/waterbodies/${water!.slug}/${fish!.slug}` } : null;
---
<Layout title={valid ? `${fish!.name_ru} на ${water!.name_ru} в RF4 — точки и приманки` : "Страница не найдена — RF4 Spotter"} description={valid ? `Где ловить ${fish!.name_ru} на ${water!.name_ru} в Russian Fishing 4: свежие координаты, приманки, активность и источники.` : "Такого сочетания рыбы и водоёма нет в каталоге."} noindex={!valid || unavailable} structuredData={schema} errorPage={!valid || unavailable}>
<a class="back" href={water ? `/waterbodies/${water.slug}` : "/waterbodies"}>← К водоёму</a>
<PageHero eyebrow={water?.name_ru ?? "Каталог RF4"} title={fish?.name_ru ?? "Данные не найдены"} description={valid ? `${items.length} ${plural(items.length,["свежая точка","свежие точки","свежих точек"])} за последние 72 часа.` : undefined} />
{unavailable ? <StatePanel tone="unavailable" title="Данные временно недоступны" description="Свежие наблюдения сейчас не получены. Попробуйте позднее." /> : !valid ? <StatePanel tone="error" title="Такого сочетания нет в справочнике" actionHref="/" actionLabel="Вернуться на главную" /> : <section class="catalog-results catalog-results--single content-grid"><div>{items.length ? items.map(item => <ActivityCard item={item}/>) : <StatePanel contained={false} title="Свежих точек пока нет" description="Данные появятся после новых подтверждённых наблюдений." />}</div></section>}
</Layout>