From 6c91584fe1a7751d12ea5f8d1ba835bdf47eea2e Mon Sep 17 00:00:00 2001 From: dm Date: Tue, 16 Dec 2025 05:00:33 +0100 Subject: [PATCH] Podmiana image w hero, Kontakt pole readonly dla danych z ofert dodanie do tresci maila --- package.json | 3 +- src/content/home/hero.yaml | 2 +- .../Internet/InternetAddonsModalCompact.jsx | 3 +- src/pages/api/contact/contact.js | 12 ++ src/pages/kontakt/index.astro | 148 +++++++++--------- src/styles/buttons.css | 2 +- 6 files changed, 91 insertions(+), 79 deletions(-) diff --git a/package.json b/package.json index 35a2831..f32f2a3 100644 --- a/package.json +++ b/package.json @@ -5,8 +5,7 @@ "scripts": { "dev": "astro dev", "build": "astro build", - "preview": "astro preview", - "update:jambox:base": "node src/scripts/update-jambox-base.js" + "preview": "astro preview" }, "dependencies": { "@astrojs/node": "^9.5.1", diff --git a/src/content/home/hero.yaml b/src/content/home/hero.yaml index f7bf72e..8205f08 100644 --- a/src/content/home/hero.yaml +++ b/src/content/home/hero.yaml @@ -8,7 +8,7 @@ subtitle: description: | -imageUrl: "fiber.webp" +imageUrl: "section-tv.webp" ctas: - label: "Zobacz ofertę Internetu" href: "/internet-swiatlowodowy" diff --git a/src/islands/Internet/InternetAddonsModalCompact.jsx b/src/islands/Internet/InternetAddonsModalCompact.jsx index 02c4ce3..62ad598 100644 --- a/src/islands/Internet/InternetAddonsModalCompact.jsx +++ b/src/islands/Internet/InternetAddonsModalCompact.jsx @@ -512,7 +512,7 @@ export default function InternetAddonsModal({ saveOfferToLocalStorage()} > @@ -523,7 +523,6 @@ export default function InternetAddonsModal({ - {/* ✅ pływająca suma (ten sam styl co w Jambox, jeśli już masz CSS) */}
e.stopPropagation()}>
Razem diff --git a/src/pages/api/contact/contact.js b/src/pages/api/contact/contact.js index aa61fc4..356601e 100644 --- a/src/pages/api/contact/contact.js +++ b/src/pages/api/contact/contact.js @@ -10,6 +10,7 @@ function esc(str = "") { function buildHtmlMail(form) { const when = new Date().toLocaleString("pl-PL"); + const offerText = (form.offerSummary || "").trim() return ` @@ -79,6 +80,17 @@ function buildHtmlMail(form) { ${esc(form.message)}
+ ${offerText ? ` +
+ Wybrana oferta: +
+ +
+ ${esc(offerText)} +
+ ` : ``} +
Wysłano: ${when}
diff --git a/src/pages/kontakt/index.astro b/src/pages/kontakt/index.astro index 212cb47..4a8c36f 100644 --- a/src/pages/kontakt/index.astro +++ b/src/pages/kontakt/index.astro @@ -1,16 +1,17 @@ --- +import path from "node:path"; import DefaultLayout from "../../layouts/DefaultLayout.astro"; import MapGoogle from "../../components/maps/MapGoogle.astro"; +import { loadYamlFile } from "../../lib/loadYaml"; -import yaml from "js-yaml"; -import fs from "fs"; - -const data = yaml.load( - fs.readFileSync("./src/content/contact/contact.yaml", "utf8"), +type SeoYaml = any; +const seo = loadYamlFile( + path.join(process.cwd(), "src", "content", "contact", "seo.yaml"), ); -const seo = yaml.load( - fs.readFileSync("./src/content/internet-swiatlowodowy/seo.yaml", "utf8"), +type ContactData = any; +const data = loadYamlFile( + path.join(process.cwd(), "src", "content", "contact", "contact.yaml"), ); const apiKey = import.meta.env.PUBLIC_GOOGLE_MAPS_KEY; @@ -25,8 +26,9 @@ const form = data.form;
-
+

{data.contactFormTitle}

+
+ required + > + + +
- - @@ -142,59 +155,32 @@ const form = data.form; }} > document.addEventListener("DOMContentLoaded", () => { - const form = document.getElementById("contactForm"); + const formEl = document.getElementById("contactForm"); const toast = document.getElementById("toast"); + if (!formEl) return; - if (!form) return; - - form.addEventListener("submit", async (e) => { - if (!form.reportValidity()) return; - e.preventDefault(); - - const data = Object.fromEntries(new FormData(form).entries()); - data.rodo = form.rodo.checked; - - const token = await grecaptcha.execute(window.FUZ_RECAPTCHA_KEY, { - action: "submit", - }); - data.recaptcha = token; - - const resp = await fetch("/api/contact/contact", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify(data), - }); - - const json = await resp.json(); - - showToast( - json.ok ? successMsg : errorMsg, - json.ok ? "success" : "error", - ); - - if (json.ok) form.reset(); - }); + const LS_KEY = "fuz_offer_config_v1"; + const SS_INJECTED_KEY = "fuz_offer_injected_v1"; function showToast(msg, type) { + if (!toast) return; toast.innerHTML = `
${msg}
`; toast.classList.remove("visible"); void toast.offsetWidth; toast.classList.add("visible"); - setTimeout(() => toast.classList.remove("visible"), 3000); } - // ---------- - const LS_KEY = "fuz_offer_config_v1"; - const SS_INJECTED_KEY = "fuz_offer_injected_v1"; - function clearOfferDraft() { try { localStorage.removeItem(LS_KEY); sessionStorage.removeItem(SS_INJECTED_KEY); - const hidden = document.getElementById("offerConfig"); - if (hidden) hidden.value = ""; + const wrap = document.getElementById("offerSummaryWrap"); + if (wrap) wrap.classList.add("hidden"); + + const offerSummary = document.getElementById("offerSummary"); + if (offerSummary) offerSummary.value = ""; } catch {} } @@ -207,9 +193,9 @@ const form = data.form; const payload = JSON.parse(raw); - const msg = document.querySelector('textarea[name="message"]'); - const subject = document.querySelector('input[name="subject"]'); - const hidden = document.getElementById("offerConfig"); + const subject = formEl.querySelector('input[name="subject"]'); + const wrap = document.getElementById("offerSummaryWrap"); + const offerSummary = document.getElementById("offerSummary"); const offerText = typeof payload?.message === "string" && payload.message.trim() @@ -218,19 +204,13 @@ const form = data.form; if (!offerText) return; + if (wrap) wrap.classList.remove("hidden"); + if (subject && !subject.value) { subject.value = `Zapytanie: ${payload?.pkg?.name || "Oferta"}`; } - if (msg) { - const marker = "Wybrana oferta:"; - const alreadyHas = msg.value && msg.value.includes(marker); - if (!alreadyHas) { - msg.value = (msg.value ? msg.value + "\n\n" : "") + offerText; - } - } - - if (hidden) hidden.value = offerText; + if (offerSummary) offerSummary.value = offerText; sessionStorage.setItem(SS_INJECTED_KEY, "1"); } catch {} @@ -238,21 +218,43 @@ const form = data.form; hydrateOfferIntoForm(); - function onSubmitSuccessCleanup() { - clearOfferDraft(); - } + window.addEventListener("pagehide", clearOfferDraft); + window.addEventListener("beforeunload", clearOfferDraft); - function onLeaveCleanup() { - clearOfferDraft(); - } + formEl.addEventListener("submit", async (e) => { + if (!formEl.reportValidity()) return; + e.preventDefault(); - window.addEventListener("pagehide", onLeaveCleanup); - window.addEventListener("beforeunload", onLeaveCleanup); - if (json.ok) { - form.reset(); - onSubmitSuccessCleanup(); - } - // ---------- + try { + const data = Object.fromEntries(new FormData(formEl).entries()); + data.rodo = formEl.rodo?.checked === true; + + const token = await grecaptcha.execute(window.FUZ_RECAPTCHA_KEY, { + action: "submit", + }); + data.recaptcha = token; + + const resp = await fetch("/api/contact/contact", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(data), + }); + + const json = await resp.json().catch(() => ({})); + + showToast( + json?.ok ? successMsg : errorMsg, + json?.ok ? "success" : "error", + ); + + if (json?.ok) { + formEl.reset(); + clearOfferDraft(); + } + } catch { + showToast(errorMsg, "error"); + } + }); }); diff --git a/src/styles/buttons.css b/src/styles/buttons.css index 1cce19b..0766387 100644 --- a/src/styles/buttons.css +++ b/src/styles/buttons.css @@ -1,5 +1,5 @@ .btn { - @apply inline-flex items-center justify-center gap-2 font-semibold rounded-lg px-6 py-3 text-base transition-all duration-200 cursor-pointer select-none focus:outline-none focus-visible:ring-2 focus-visible:ring-[--f-header] focus-visible:ring-offset-2 focus-visible:ring-offset-[--f-background]; + @apply inline-flex items-center justify-center gap-2 font-semibold rounded-lg px-6 py-3 mt-3 text-base transition-all duration-200 cursor-pointer select-none focus:outline-none focus-visible:ring-2 focus-visible:ring-[--f-header] focus-visible:ring-offset-2 focus-visible:ring-offset-[--f-background]; } .btn-primary {