Premium szczegóły zmiana sekcji

This commit is contained in:
dm
2025-12-19 09:01:24 +01:00
parent 005e9d3555
commit 3c5430069f

View File

@@ -6,7 +6,6 @@ import Markdown from "../../islands/Markdown.jsx";
import AddonChannelsGrid from "../../islands/jambox/AddonChannelsModal.jsx"; import AddonChannelsGrid from "../../islands/jambox/AddonChannelsModal.jsx";
import "../../styles/jambox-tematyczne.css"; import "../../styles/jambox-tematyczne.css";
/** Typy minimalne */
type AddonPriceRow = { type AddonPriceRow = {
pakiety?: string[] | any; pakiety?: string[] | any;
"12m"?: number | string; "12m"?: number | string;
@@ -25,7 +24,6 @@ type TvAddon = {
group_mode?: string; group_mode?: string;
}; };
// ✅ OPCJA A: metadane grupy + CTA
type GroupCta = { type GroupCta = {
label?: string; label?: string;
href?: string; href?: string;
@@ -41,7 +39,6 @@ type GroupMeta = {
type TvAddonsDoc = { type TvAddonsDoc = {
tytul?: string; tytul?: string;
opis?: string; opis?: string;
cena_opis?: string;
dodatki?: TvAddon[]; dodatki?: TvAddon[];
grupy?: Record<string, GroupMeta>; grupy?: Record<string, GroupMeta>;
}; };
@@ -50,113 +47,86 @@ const doc = yaml.load(
fs.readFileSync("./src/content/internet-telewizja/tv-addons.yaml", "utf8"), fs.readFileSync("./src/content/internet-telewizja/tv-addons.yaml", "utf8"),
) as TvAddonsDoc; ) as TvAddonsDoc;
const pageTitle = doc?.tytul ?? "Dodatkowe pakiety TV"; const addons = Array.isArray(doc?.dodatki) ? doc.dodatki : [];
const pageDesc = doc?.opis ?? ""; const groupMeta = doc?.grupy ?? {};
const addons: TvAddon[] = Array.isArray(doc?.dodatki) ? doc.dodatki : [];
// ✅ mapa meta grup const tid = Number(Astro.params.tid);
const groupMeta: Record<string, GroupMeta> = doc?.grupy ?? {}; const picked = addons.find((a) => Number(a?.tid) === tid);
// --- dynamic param ---
const tidParam = Astro.params.tid; // np. "49"
const tid = Number(tidParam);
const picked =
Number.isFinite(tid)
? addons.find((a) => Number(a?.tid) === tid)
: null;
if (!picked) { if (!picked) {
return new Response("Nie znaleziono pakietu dla podanego tid.", { status: 404 }); return new Response("Nie znaleziono pakietu.", { status: 404 });
} }
// --- jeśli jest group => bierzemy całą grupę ---
const pickedGroup = String(picked?.group ?? "").trim(); const pickedGroup = String(picked?.group ?? "").trim();
let viewAddons: TvAddon[] = []; const viewAddons = pickedGroup
if (pickedGroup) { ? addons.filter((a) => String(a?.group ?? "").trim() === pickedGroup)
viewAddons = addons.filter((a) => String(a?.group ?? "").trim() === pickedGroup); : [picked];
} else {
viewAddons = [picked];
}
// (jak miałeś) sortowanie w grupie — możesz zostawić albo wywalić const footerCta =
viewAddons = viewAddons
.slice()
.sort((a, b) => Number(a?.tid ?? 0) - Number(b?.tid ?? 0));
// tytuł/description strony
const singleTitle = pickedGroup
? (groupMeta[pickedGroup]?.tytul ?? pickedGroup.toUpperCase() ?? pageTitle)
: (String(picked?.nazwa ?? "").trim() || pageTitle);
const singleDesc = pageDesc;
// ✅ CTA dla tej grupy (jeśli istnieje)
const footerCta: GroupCta | undefined =
pickedGroup ? groupMeta[pickedGroup]?.rejestracja : undefined; pickedGroup ? groupMeta[pickedGroup]?.rejestracja : undefined;
--- ---
<DefaultLayout title={singleTitle} description={singleDesc}> <DefaultLayout
{/* Opcjonalnie: box jak na stronie ogólnej, tylko jeśli jesteśmy w grupie */} title={picked?.nazwa ?? doc?.tytul}
<div class={pickedGroup ? "f-addon-group" : ""}> description={doc?.opis}
{ >
viewAddons.map((addon: TvAddon, index: number) => { {
const isAboveFold = index === 0; viewAddons.map((addon, index) => {
const pkgName = String(addon?.nazwa ?? "").trim();
const hasYamlImage = !!String(addon?.image ?? "").trim();
const assumeHasMedia = pkgName || hasYamlImage;
const isAboveFold = index === 0;
const pkgName = String(addon?.nazwa ?? "").trim(); return (
const hasYamlImage = !!String(addon?.image ?? "").trim(); <section class="f-section" id={`tid-${addon.tid}`}>
const assumeHasMedia = pkgName ? true : hasYamlImage; <div
class={`f-section-grid f-addon-section ${
const anchorId = addon?.tid != null ? `tid-${addon.tid}` : undefined; assumeHasMedia ? "md:grid-cols-2" : "md:grid-cols-1"
}`}
return ( data-addon-section
<section class="f-section" id={anchorId}> data-has-media={assumeHasMedia ? "1" : "0"}
<div >
class={`f-section-grid f-addon-grid f-addon-section ${ {/* MEDIA — odpowiednik <Image /> */}
assumeHasMedia ? "md:grid-cols-2" : "md:grid-cols-1" <div class="f-addon-media md:order-2">
}`} {pkgName ? (
data-addon-section <AddonChannelsGrid
data-has-media={assumeHasMedia ? "1" : "0"} client:idle
> packageName={pkgName}
<div class="f-addon-text"> fallbackImage={String(addon?.image ?? "")}
{pkgName && <h2 class="f-section-title">{pkgName}</h2>} aboveFold={isAboveFold}
{addon?.opis && <Markdown text={addon.opis} />} title={pkgName}
</div> />
) : null}
<div class="f-addon-media">
{pkgName ? (
<AddonChannelsGrid
client:idle
packageName={pkgName}
fallbackImage={String(addon?.image ?? "")}
aboveFold={isAboveFold}
title={pkgName}
/>
) : null}
</div>
</div> </div>
</section>
);
})
}
{/* ✅ STOPKA GRUPY: tylko na stronach grupowych */} {/* TEKST */}
{pickedGroup && footerCta?.href && footerCta?.label ? ( <div class="md:order-1">
<div class="f-addon-group-footer fuz-markdown max-w-none"> {pkgName && <h2 class="f-section-title">{pkgName}</h2>}
{footerCta.opis ? <p>{footerCta.opis}</p> : null} {addon?.opis && <Markdown text={addon.opis} />}
</div>
</div>
</section>
);
})
}
<a {footerCta?.href && footerCta?.label ? (
class="btn btn-primary" <section class="f-section">
href={footerCta.href} <div class="f-section-grid md:grid-cols-1">
title={footerCta.title ?? footerCta.label} <div class="fuz-markdown max-w-none">
target="_blank" {footerCta.opis && <p>{footerCta.opis}</p>}
rel="noopener noreferrer" <div class="f-section-nav">
> <a
{footerCta.label} class="btn btn-primary"
</a> href={footerCta.href}
title={footerCta.title ?? footerCta.label}
>
{footerCta.label}
</a>
</div>
</div>
</div> </div>
) : null} </section>
</div> ) : null}
</DefaultLayout> </DefaultLayout>