Przebudowa stron na indywidualne karty , pobierane z bazy danych
This commit is contained in:
193
src/islands/Offers/JamboxBasePackages.jsx
Normal file
193
src/islands/Offers/JamboxBasePackages.jsx
Normal file
@@ -0,0 +1,193 @@
|
||||
import { useEffect, useMemo, useState } from "preact/hooks";
|
||||
import "../../styles/offers/offers-table.css"; //
|
||||
|
||||
const BUILDING_MAP = {
|
||||
jednorodzinny: 1,
|
||||
wielorodzinny: 2,
|
||||
};
|
||||
|
||||
const CONTRACT_MAP = {
|
||||
"24m": 1,
|
||||
bezterminowa: 2,
|
||||
};
|
||||
|
||||
export default function JamboxBasePackages({
|
||||
source = "PLUS",
|
||||
title,
|
||||
selected = {},
|
||||
}) {
|
||||
const [packages, setPackages] = useState([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState("");
|
||||
|
||||
// wyliczamy kody na podstawie tego samego selected, którego używasz w OffersCards
|
||||
const buildingCode = useMemo(() => {
|
||||
const val = selected?.budynek;
|
||||
return BUILDING_MAP[val] ?? 1; // domyślnie jednorodzinny
|
||||
}, [selected?.budynek]);
|
||||
|
||||
const contractCode = useMemo(() => {
|
||||
const val = selected?.umowa;
|
||||
return CONTRACT_MAP[val] ?? 1; // domyślnie 24m
|
||||
}, [selected?.umowa]);
|
||||
|
||||
useEffect(() => {
|
||||
let cancelled = false;
|
||||
|
||||
async function load() {
|
||||
setLoading(true);
|
||||
setError("");
|
||||
|
||||
try {
|
||||
const params = new URLSearchParams();
|
||||
|
||||
if (source && source !== "ALL") {
|
||||
params.set("source", source);
|
||||
}
|
||||
if (buildingCode) {
|
||||
params.set("building", String(buildingCode));
|
||||
}
|
||||
if (contractCode) {
|
||||
params.set("contract", String(contractCode));
|
||||
}
|
||||
|
||||
const query = params.toString();
|
||||
const url = `/api/jambox/base-packages${query ? `?${query}` : ""}`;
|
||||
|
||||
const res = await fetch(url);
|
||||
|
||||
if (!res.ok) {
|
||||
throw new Error(`HTTP ${res.status}`);
|
||||
}
|
||||
|
||||
const json = await res.json();
|
||||
|
||||
if (!cancelled) {
|
||||
setPackages(Array.isArray(json.data) ? json.data : []);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("Błąd pobierania pakietów JAMBOX:", err);
|
||||
if (!cancelled) {
|
||||
setError("Nie udało się załadować pakietów JAMBOX.");
|
||||
}
|
||||
} finally {
|
||||
if (!cancelled) {
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
load();
|
||||
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, [source, buildingCode, contractCode]);
|
||||
|
||||
const effectiveTitle =
|
||||
title ||
|
||||
(source === "PLUS"
|
||||
? "Pakiety podstawowe JAMBOX PLUS"
|
||||
: source === "EVIO"
|
||||
? "Pakiety podstawowe JAMBOX EVIO"
|
||||
: "Pakiety podstawowe JAMBOX");
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<section class="f-offers">
|
||||
<h2 class="f-offers-title">{effectiveTitle}</h2>
|
||||
<p>Ładowanie pakietów...</p>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return (
|
||||
<section class="f-offers">
|
||||
<h2 class="f-offers-title">{effectiveTitle}</h2>
|
||||
<p class="text-red-600">{error}</p>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
if (!packages.length) {
|
||||
return (
|
||||
<section class="f-offers">
|
||||
<h2 class="f-offers-title">{effectiveTitle}</h2>
|
||||
<p>Brak pakietów do wyświetlenia.</p>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<section class="f-offers">
|
||||
{effectiveTitle && <h2 class="f-offers-title">{effectiveTitle}</h2>}
|
||||
|
||||
<div class={`f-offers-grid f-count-${packages.length}`}>
|
||||
{packages.map((pkg) => (
|
||||
<JamboxPackageCard key={`${pkg.source}-${pkg.tid}`} pkg={pkg} />
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
function JamboxPackageCard({ pkg }) {
|
||||
const updatedDate = pkg.updated_at
|
||||
? new Date(pkg.updated_at).toLocaleDateString("pl-PL")
|
||||
: "-";
|
||||
|
||||
const hasPrice = pkg.price_monthly != null;
|
||||
const hasInstall = pkg.price_installation != null;
|
||||
|
||||
return (
|
||||
<div class="f-card">
|
||||
<div class="f-card-header">
|
||||
<div class="f-card-name">{pkg.name}</div>
|
||||
|
||||
{/* TU zamiast JAMBOX PLUS/EVIO pokazujemy cenę */}
|
||||
<div class="f-card-price">
|
||||
{hasPrice
|
||||
? `${pkg.price_monthly} zł/mies.`
|
||||
: pkg.source === "PLUS"
|
||||
? "JAMBOX PLUS"
|
||||
: "JAMBOX EVIO"}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul class="f-card-features">
|
||||
{/* ID / slug jako techniczne info */}
|
||||
<li class="f-card-row">
|
||||
<span class="f-card-label">ID pakietu</span>
|
||||
<span class="f-card-value">{pkg.tid}</span>
|
||||
</li>
|
||||
|
||||
<li class="f-card-row">
|
||||
<span class="f-card-label">Slug</span>
|
||||
<span class="f-card-value">{pkg.slug || "—"}</span>
|
||||
</li>
|
||||
|
||||
{/* nowa linia: cena instalacji z bazy */}
|
||||
<li class="f-card-row">
|
||||
<span class="f-card-label">Aktywacja</span>
|
||||
<span class="f-card-value">
|
||||
{hasInstall ? `${pkg.price_installation} zł` : "—"}
|
||||
</span>
|
||||
</li>
|
||||
|
||||
{/* opcjonalnie informacja o źródle pakietu */}
|
||||
<li class="f-card-row">
|
||||
<span class="f-card-label">Platforma</span>
|
||||
<span class="f-card-value">
|
||||
{pkg.source === "PLUS" ? "JAMBOX PLUS" : "JAMBOX EVIO"}
|
||||
</span>
|
||||
</li>
|
||||
|
||||
<li class="f-card-row">
|
||||
<span class="f-card-label">Ostatnia aktualizacja</span>
|
||||
<span class="f-card-value">{updatedDate}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user