diff --git a/src/data/ServicesRange.db b/src/data/ServicesRange.db index d187eb1..ec5e921 100644 Binary files a/src/data/ServicesRange.db and b/src/data/ServicesRange.db differ diff --git a/src/islands/Internet/OffersInternetCards.jsx b/src/islands/Internet/OffersInternetCards.jsx index 13bd8ea..18b5213 100644 --- a/src/islands/Internet/OffersInternetCards.jsx +++ b/src/islands/Internet/OffersInternetCards.jsx @@ -1,9 +1,8 @@ import { useEffect, useState } from "preact/hooks"; +import InternetAddonsModal from "./InternetAddonsModal.jsx"; import "../../styles/offers/offers-table.css"; -import InternetAddonsModal from "./InternetAddonsModal.jsx"; // 🔹 dostosuj ścieżkę, jeśli inna export default function InternetDbOffersCards({ - title = "Oferty Internetu FUZ", }) { const [selected, setSelected] = useState({}); const [labels, setLabels] = useState({}); @@ -11,12 +10,16 @@ export default function InternetDbOffersCards({ const [loading, setLoading] = useState(false); const [error, setError] = useState(""); - // 🔹 stan modala z dodatkami const [addonsModalOpen, setAddonsModalOpen] = useState(false); const [activePlan, setActivePlan] = useState(null); - // nasłuchuj globalnego eventu z OffersSwitches useEffect(() => { + if (typeof window !== "undefined" && window.fuzSwitchState) { + const { selected: sel, labels: labs } = window.fuzSwitchState; + if (sel) setSelected(sel); + if (labs) setLabels(labs); + } + function handler(e) { const detail = e.detail || {}; if (detail.selected) { @@ -31,6 +34,7 @@ export default function InternetDbOffersCards({ return () => window.removeEventListener("fuz:switch-change", handler); }, []); + const buildingCode = Number(selected.budynek) || 1; const contractCode = Number(selected.umowa) || 1; @@ -74,7 +78,7 @@ export default function InternetDbOffersCards({ return (
- + {loading &&

Ładowanie ofert...

} {error &&

{error}

} @@ -94,7 +98,6 @@ export default function InternetDbOffersCards({ )} - {/* 🔹 Modal z usługami dodatkowymi (internet + telefon + addon’y) */} setAddonsModalOpen(false)} @@ -108,32 +111,24 @@ function OfferCard({ plan, contractLabel, onConfigureAddons }) { const basePrice = plan.price_monthly; const installPrice = plan.price_installation; - const allFeatures = plan.features || []; + const featureRows = plan.features || []; - // 🔹 to są inne cechy (bez umowy i instalacji) - const featureRows = allFeatures.filter( - (f) => f.id !== "umowa_info" && f.id !== "instalacja" - ); - - // 🔹 cecha opisująca umowę (z backendu) - const contractFeature = allFeatures.find((f) => f.id === "umowa_info"); - - // 🔹 tekst, który faktycznie pokażemy w wierszu "Umowa" - const effectiveContract = - contractLabel || contractFeature?.value || contractFeature?.label || "—"; + const effectiveContract = contractLabel || "—"; return (
{plan.name}
-
{basePrice} zł/mies.
+
+ {basePrice != null ? `${basePrice} zł/mies.` : "—"} +
    {featureRows.map((f) => { let val = f.value; - let display; + if (val === true || val === "true") display = "✓"; else if (val === false || val === "false" || val == null) display = "✕"; else display = val; @@ -146,11 +141,13 @@ function OfferCard({ plan, contractLabel, onConfigureAddons }) { ); })} + {/* Umowa – już tylko z przełącznika */}
  • Umowa {effectiveContract}
  • + {/* Aktywacja – z pola plan.price_installation */}
  • Aktywacja diff --git a/src/islands/Offers/OffersSwitches.jsx b/src/islands/Offers/OffersSwitches.jsx index 7af1d57..b599354 100644 --- a/src/islands/Offers/OffersSwitches.jsx +++ b/src/islands/Offers/OffersSwitches.jsx @@ -1,5 +1,4 @@ import { useEffect, useState } from "preact/hooks"; -// import "../../styles/offers/offers-switches.css"; function buildLabels(switches, selected) { const out = {}; @@ -24,7 +23,7 @@ export default function OffersSwitches(props) { const [loading, setLoading] = useState(false); const [error, setError] = useState(""); - // AUTO: pobieramy konfigurację z API + // 🔹 AUTO mode – sam pobieram /api/switches + wysyłam event useEffect(() => { if (isControlled) return; @@ -35,7 +34,7 @@ export default function OffersSwitches(props) { setError(""); try { - const res = await fetch("/api/internet"); + const res = await fetch("/api/switches"); if (!res.ok) throw new Error(`HTTP ${res.status}`); const json = await res.json(); @@ -53,18 +52,24 @@ export default function OffersSwitches(props) { setAutoSwitches(sws); setAutoSelected(initial); + // 🔥 zapisz globalny stan + window.fuzSwitchState = { + selected: initial, + labels, + }; + window.dispatchEvent( new CustomEvent("fuz:switch-change", { detail: { id: null, value: null, selected: initial, - labels, // tu lecą etykiety z DB + labels, }, }), ); } catch (err) { - console.error("❌ Błąd pobierania switchy:", err); + console.error("Błąd pobierania switchy:", err); if (!cancelled) setError("Nie udało się załadować przełączników."); } finally { if (!cancelled) setLoading(false); @@ -88,13 +93,19 @@ export default function OffersSwitches(props) { const next = { ...prev, [id]: value }; const labels = buildLabels(autoSwitches, next); + // 🔥 aktualizuj globalny stan + window.fuzSwitchState = { + selected: next, + labels, + }; + window.dispatchEvent( new CustomEvent("fuz:switch-change", { detail: { id, value, selected: next, - labels, // etykiety po kliknięciu + labels, }, }), ); @@ -104,6 +115,32 @@ export default function OffersSwitches(props) { } }; + // 🔥 CONTROLLED: zsynchronizuj globalny stan + event + useEffect(() => { + if (!isControlled) return; + if (!Array.isArray(switches) || !switches.length) return; + + const safeSelected = selected || {}; + const labels = buildLabels(switches, safeSelected); + + // 🔥 globalny stan + window.fuzSwitchState = { + selected: safeSelected, + labels, + }; + + window.dispatchEvent( + new CustomEvent("fuz:switch-change", { + detail: { + id: null, + value: null, + selected: safeSelected, + labels, + }, + }), + ); + }, [isControlled, switches, selected]); + if (!isControlled && loading) { return (
    diff --git a/src/pages/api/internet.js b/src/pages/api/switches.js similarity index 84% rename from src/pages/api/internet.js rename to src/pages/api/switches.js index 08d3922..6d0d502 100644 --- a/src/pages/api/internet.js +++ b/src/pages/api/switches.js @@ -1,4 +1,4 @@ -// src/pages/api/switches/internet.js +// src/pages/api/switches.js import Database from "better-sqlite3"; const DB_PATH = @@ -13,13 +13,11 @@ export function GET() { try { const buildingTypes = db - .prepare("SELECT code, label FROM jambox_building_types ORDER BY code") + .prepare("SELECT code, label FROM jambox_building_types ORDER BY is_default DESC, code") .all(); const contractTypes = db - .prepare( - "SELECT code, label FROM jambox_contract_types ORDER BY code" - ) + .prepare("SELECT code, label FROM jambox_contract_types ORDER BY is_default DESC, code") .all(); const switches = [ @@ -29,7 +27,7 @@ export function GET() { domyslny: buildingTypes[0]?.code ?? 1, title: "Zmień rodzaj budynku by zobaczyć odpowiednie ceny", opcje: buildingTypes.map((b) => ({ - id: b.code, // 1,2,... + id: b.code, nazwa: b.label, })), }, @@ -39,7 +37,7 @@ export function GET() { domyslny: contractTypes[0]?.code ?? 1, title: "Wybierz okres umowy by zobaczyć odpowiednie ceny", opcje: contractTypes.map((c) => ({ - id: c.code, // 1,2,... + id: c.code, nazwa: c.label, })), }, @@ -56,7 +54,7 @@ export function GET() { } ); } catch (err) { - console.error("❌ Błąd w /api/switches/internet:", err); + console.error("Błąd w /api/switches:", err); return new Response( JSON.stringify({ ok: false, error: err.message || "DB_ERROR" }), {