Formatowanie cen
This commit is contained in:
@@ -4,21 +4,10 @@ import OffersSwitches from "../Switches.jsx";
|
||||
import InternetAddonsModal from "./InternetAddonsModal.jsx";
|
||||
import "../../styles/cards.css";
|
||||
|
||||
function formatMoney(amount, currency = "PLN") {
|
||||
if (typeof amount !== "number" || Number.isNaN(amount)) return "";
|
||||
try {
|
||||
return new Intl.NumberFormat("pl-PL", {
|
||||
style: "",
|
||||
currency,
|
||||
maximumFractionDigits: 0,
|
||||
}).format(amount);
|
||||
} catch {
|
||||
return String(amount);
|
||||
}
|
||||
}
|
||||
import { moneyWithLabel, money } from "../../lib/money.js";
|
||||
|
||||
// ✅ mapper: InternetCard(YAML) + match + labels -> plan (dla modala)
|
||||
function mapCardToPlan(card, match, labels, waluta) {
|
||||
function mapCardToPlan(card, match, labels, cenaOpis) {
|
||||
const baseParams = Array.isArray(card?.parametry) ? card.parametry : [];
|
||||
|
||||
const features = baseParams.map((p) => ({
|
||||
@@ -30,8 +19,7 @@ function mapCardToPlan(card, match, labels, waluta) {
|
||||
features.push({ label: "Umowa", value: labels?.umowa || "—" });
|
||||
features.push({
|
||||
label: "Aktywacja",
|
||||
value:
|
||||
typeof match?.aktywacja === "number" ? formatMoney(match.aktywacja, waluta) : "—",
|
||||
value: typeof match?.aktywacja === "number" ? `${money(match.aktywacja)} zł` : "—",
|
||||
});
|
||||
|
||||
return {
|
||||
@@ -39,6 +27,7 @@ function mapCardToPlan(card, match, labels, waluta) {
|
||||
price_monthly: typeof match?.miesiecznie === "number" ? match.miesiecznie : 0,
|
||||
price_installation: typeof match?.aktywacja === "number" ? match.aktywacja : 0,
|
||||
features,
|
||||
cenaOpis,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -52,23 +41,23 @@ function mapCardToPlan(card, match, labels, waluta) {
|
||||
* phoneCards?: any[],
|
||||
* addons?: any[],
|
||||
* addonsCenaOpis?: string,
|
||||
* switches?: any[] // ✅ NOWE: przełączniki z YAML
|
||||
* switches?: any[]
|
||||
* }} props
|
||||
*/
|
||||
export default function InternetCards({
|
||||
title = "",
|
||||
description = "",
|
||||
cards = [],
|
||||
waluta = "PLN",
|
||||
waluta = "PLN", // zostawiamy, bo może się przydać dalej (np. w modalu), ale tu nie jest używana
|
||||
cenaOpis = "zł/mies.",
|
||||
phoneCards = [],
|
||||
addons = [],
|
||||
addonsCenaOpis = "zł/mies.",
|
||||
switches = [], // ✅ NOWE
|
||||
switches = [],
|
||||
}) {
|
||||
const visibleCards = Array.isArray(cards) ? cards : [];
|
||||
|
||||
// switch state (teraz idzie z OffersSwitches na podstawie YAML)
|
||||
// switch state (idzie z OffersSwitches na podstawie YAML)
|
||||
const [selected, setSelected] = useState({});
|
||||
const [labels, setLabels] = useState({});
|
||||
|
||||
@@ -103,7 +92,6 @@ export default function InternetCards({
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* ✅ TERAZ switcher dostaje dane z YAML */}
|
||||
<OffersSwitches switches={switches} />
|
||||
|
||||
{visibleCards.length === 0 ? (
|
||||
@@ -116,7 +104,6 @@ export default function InternetCards({
|
||||
card={card}
|
||||
selected={selected}
|
||||
labels={labels}
|
||||
waluta={waluta}
|
||||
cenaOpis={cenaOpis}
|
||||
onConfigureAddons={(plan) => {
|
||||
setActivePlan(plan);
|
||||
@@ -139,7 +126,7 @@ export default function InternetCards({
|
||||
);
|
||||
}
|
||||
|
||||
function OfferCard({ card, selected, labels, waluta, cenaOpis, onConfigureAddons }) {
|
||||
function OfferCard({ card, selected, labels, cenaOpis, onConfigureAddons }) {
|
||||
const baseParams = Array.isArray(card?.parametry) ? card.parametry : [];
|
||||
const ceny = Array.isArray(card?.ceny) ? card.ceny : [];
|
||||
|
||||
@@ -160,7 +147,7 @@ function OfferCard({ card, selected, labels, waluta, cenaOpis, onConfigureAddons
|
||||
{
|
||||
klucz: "aktywacja",
|
||||
label: "Aktywacja",
|
||||
value: typeof akt === "number" ? formatMoney(akt, waluta) : "—",
|
||||
value: typeof akt === "number" ? `${money(akt)} zł` : "—",
|
||||
},
|
||||
];
|
||||
|
||||
@@ -175,9 +162,7 @@ function OfferCard({ card, selected, labels, waluta, cenaOpis, onConfigureAddons
|
||||
|
||||
<div class="f-card-price">
|
||||
{typeof mies === "number" ? (
|
||||
<>
|
||||
{formatMoney(mies, waluta)} <span class="opacity-80">{cenaOpis}</span>
|
||||
</>
|
||||
<>{moneyWithLabel(mies, cenaOpis, false)}</>
|
||||
) : (
|
||||
<span class="opacity-70">Wybierz opcje</span>
|
||||
)}
|
||||
@@ -198,7 +183,7 @@ function OfferCard({ card, selected, labels, waluta, cenaOpis, onConfigureAddons
|
||||
class="btn btn-primary mt-4"
|
||||
disabled={!canConfigureAddons}
|
||||
onClick={() => {
|
||||
const plan = mapCardToPlan(card, match, labels, waluta);
|
||||
const plan = mapCardToPlan(card, match, labels, cenaOpis);
|
||||
onConfigureAddons(plan);
|
||||
}}
|
||||
title={!canConfigureAddons ? "Wybierz typ budynku i umowę" : ""}
|
||||
|
||||
@@ -6,18 +6,7 @@ import JamboxChannelsModal from "./JamboxChannelsModal.jsx";
|
||||
import JamboxAddonsModal from "./JamboxAddonsModal.jsx";
|
||||
import Markdown from "../Markdown.jsx";
|
||||
|
||||
function formatMoney(amount, currency = "PLN") {
|
||||
if (typeof amount !== "number" || Number.isNaN(amount)) return "";
|
||||
try {
|
||||
return new Intl.NumberFormat("pl-PL", {
|
||||
style: "currency",
|
||||
currency,
|
||||
maximumFractionDigits: 0,
|
||||
}).format(amount);
|
||||
} catch {
|
||||
return String(amount);
|
||||
}
|
||||
}
|
||||
import { moneyWithLabel, money } from "../../lib/money.js";
|
||||
|
||||
function toFeatureRows(params) {
|
||||
const list = Array.isArray(params) ? params : [];
|
||||
@@ -52,7 +41,6 @@ function toFeatureRows(params) {
|
||||
* decoders?: Decoder[],
|
||||
* addonsCenaOpis?: string,
|
||||
* channels?: ChannelYaml[],
|
||||
* channels?: ChannelYaml[]
|
||||
* }} props
|
||||
*/
|
||||
export default function JamboxCards({
|
||||
@@ -60,7 +48,7 @@ export default function JamboxCards({
|
||||
description = "",
|
||||
cards = [],
|
||||
internetWspolne = [],
|
||||
waluta = "PLN",
|
||||
waluta = "PLN", // zostawiamy (może być potrzebne w modalach), ale tu nie jest używane do formatowania
|
||||
cenaOpis = "zł/mies.",
|
||||
|
||||
phoneCards = [],
|
||||
@@ -122,7 +110,6 @@ export default function JamboxCards({
|
||||
wsp={wsp}
|
||||
selected={selected}
|
||||
labels={labels}
|
||||
waluta={waluta}
|
||||
cenaOpis={cenaOpis}
|
||||
onShowChannels={(pkg) => {
|
||||
setActivePkg(pkg);
|
||||
@@ -163,7 +150,6 @@ function JamboxPackageCard({
|
||||
wsp,
|
||||
selected,
|
||||
labels,
|
||||
waluta,
|
||||
cenaOpis,
|
||||
onShowChannels,
|
||||
onConfigureAddons,
|
||||
@@ -186,7 +172,7 @@ function JamboxPackageCard({
|
||||
{
|
||||
klucz: "aktywacja",
|
||||
label: "Aktywacja",
|
||||
value: typeof installPrice === "number" ? formatMoney(installPrice, waluta) : "—",
|
||||
value: typeof installPrice === "number" ? `${money(installPrice)} zł` : "—",
|
||||
},
|
||||
];
|
||||
|
||||
@@ -206,15 +192,13 @@ function JamboxPackageCard({
|
||||
const hasPrice = typeof basePrice === "number";
|
||||
|
||||
return (
|
||||
<div class="f-card" id={`pkg-${card?.nazwa}`} data-pkg={card?.nazwa} >
|
||||
<div class="f-card" id={`pkg-${card?.nazwa}`} data-pkg={card?.nazwa}>
|
||||
<div class="f-card-header">
|
||||
<div class="f-card-name">{card.nazwa}</div>
|
||||
|
||||
<div class="f-card-price">
|
||||
{hasPrice ? (
|
||||
<>
|
||||
{formatMoney(basePrice, waluta)} <span class="opacity-80">{cenaOpis}</span>
|
||||
</>
|
||||
<>{moneyWithLabel(basePrice, cenaOpis, false)}</>
|
||||
) : (
|
||||
<span class="opacity-70">Wybierz opcje</span>
|
||||
)}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import Markdown from "../../islands/Markdown.jsx";
|
||||
import { moneyWithLabel } from "../../lib/money.js";
|
||||
import "../../styles/cards.css";
|
||||
|
||||
/**
|
||||
@@ -25,9 +26,13 @@ export default function PhoneDbOffersCards({
|
||||
return (
|
||||
<section class="f-offers">
|
||||
{title && <h2 class="f-section-header">{title}</h2>}
|
||||
<div>
|
||||
<Markdown text={description} />
|
||||
</div>
|
||||
|
||||
{description && (
|
||||
<div class="mb-4">
|
||||
<Markdown text={description} />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{visibleCards.length === 0 ? (
|
||||
<p class="opacity-80">Brak dostępnych pakietów.</p>
|
||||
) : (
|
||||
@@ -42,8 +47,8 @@ export default function PhoneDbOffersCards({
|
||||
}
|
||||
|
||||
function PhoneOfferCard({ card }) {
|
||||
const price = card?.cena?.wartosc ?? "";
|
||||
const priceDesc = card?.cena?.opis ?? "zł/mies.";
|
||||
const priceValue = card?.cena?.wartosc;
|
||||
const priceLabel = card?.cena?.opis || "zł/mies.";
|
||||
|
||||
const params = Array.isArray(card?.parametry) ? card.parametry : [];
|
||||
|
||||
@@ -53,8 +58,11 @@ function PhoneOfferCard({ card }) {
|
||||
|
||||
<div class="f-card-header">
|
||||
<div class="f-card-name">{card.nazwa}</div>
|
||||
|
||||
<div class="f-card-price">
|
||||
{price} {priceDesc}
|
||||
{typeof priceValue === "number"
|
||||
? moneyWithLabel(priceValue, priceLabel, false)
|
||||
: "—"}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user