ContactSection add, zmiany w MapGoogle

This commit is contained in:
dm
2025-11-21 12:09:45 +01:00
parent f42a242d9c
commit 0eaebc2faf
10 changed files with 448 additions and 5 deletions

View File

@@ -8,7 +8,7 @@ const links = [
{ name: "INTERNET RADIOWY", href: "/internet-radiowy" },
{ name: "TELEFON", href: "/telefon" },
{ name: "ZASIĘG SIECI", href: "/mapa-zasiegu" },
{ name: "KONTAKT", href: "/kontakt" }
{ name: "KONTAKT", href: "/#contact" }
];
---

View File

@@ -0,0 +1,79 @@
---
const {
apiKey,
lat,
lon,
zoom = 15,
title = "",
description = "",
} = Astro.props;
import "../../styles/map-google.css";
---
<div class="fuz-map-wrapper">
<div
id="fuz-map-google"
class="fuz-map-google"
data-lat={lat}
data-lon={lon}
data-title={title}
data-description={description}
>
</div>
</div>
<!-- TODO: Popracować nad wygladem markera -->
<script is:inline>
window.initFuzGoogleMap = function () {
const el = document.getElementById("fuz-map-google");
if (!el) return;
const lat = Number(el.dataset.lat);
const lon = Number(el.dataset.lon);
const title = el.dataset.title || "";
const desc = el.dataset.description || "";
const map = new google.maps.Map(el, {
zoom: Number(`{{zoom}}`) || 15,
center: { lat, lng: lon },
mapTypeControl: false,
scrollwheel: false,
zoomControl: true,
streetViewControl: false,
});
const infowindow = new google.maps.InfoWindow({
content: `<div class="fuz-map-infowindow"><b>${title}</b><br/>${desc}</div>`,
});
const marker = new google.maps.Marker({
position: { lat, lng: lon },
map,
title,
});
marker.addListener("click", () => {
infowindow.open({
map,
anchor: marker,
shouldFocus: false,
});
});
// auto-open popup on load
setTimeout(() => {
infowindow.open({
map,
anchor: marker,
shouldFocus: false,
});
}, 100);
// Light fade-in
el.classList.add("loaded");
};
</script>
<script
async
src={`https://maps.googleapis.com/maps/api/js?key=${apiKey}&callback=initFuzGoogleMap`}
></script>

View File

@@ -0,0 +1,173 @@
---
import yaml from "js-yaml";
import fs from "fs";
import MapGoogle from "../maps/MapGoogle.astro";
import "../../styles/contact.css";
const data = yaml.load(
fs.readFileSync("./src/content/contact/contact.yaml", "utf8"),
);
const apiKey = import.meta.env.PUBLIC_GOOGLE_MAPS_KEY;
---
<!-- TODO: Obrobić wysyłanie maila przez api -->
<section id="contact" class="fuz-section">
<!-- GRID 2 kolumny -->
<div class="fuz-contact-grid">
<!-- Lewa kolumna -->
<div class="space-y-6">
<h2 class="fuz-section-title">{data.title}</h2>
<div class="fuz-contact-description" set:html={data.description} />
</div>
<!-- Formularz -->
<div class="fuz-contact-box">
<h2 class="fuz-section-title">{data.contactFormTitle}</h2>
<form id="contactForm" class="fuz-contact-form">
<div class="grid grid-cols-2 gap-4">
<input
type="text"
name="firstName"
placeholder="Imię"
class="fuz-input"
required
/>
<input
type="text"
name="lastName"
placeholder="Nazwisko"
class="fuz-input"
required
/>
</div>
<div class="grid grid-cols-2 gap-4">
<input
type="email"
name="email"
placeholder="Email"
class="fuz-input"
required
/>
<input
type="tel"
name="phone"
placeholder="Telefon"
class="fuz-input"
required
/>
</div>
<input
type="text"
name="subject"
placeholder="Temat wiadomości"
class="fuz-input"
required
/>
<textarea
rows="5"
name="message"
placeholder="Treść wiadomości"
class="fuz-input"
required></textarea>
<label class="fuz-rodo">
<input
type="checkbox"
name="rodo"
class="mt-1 h-4 w-4"
required
/>
<span>
Wyrażam zgodę na przetwarzanie moich danych osobowych
zgodnie z
<a href="/polityka-prywatnosci">polityką prywatności</a
>.
</span>
</label>
<button class="btn btn-outline w-full py-3 text-lg">
Wyślij wiadomość →
</button>
</form>
</div>
</div>
<!-- GOOGLE MAPS -->
<MapGoogle
apiKey={apiKey}
lat={data.lat}
lon={data.lng}
zoom={16}
title={data.markerTitle}
description={data.markerAddress}
/>
<div id="toast" class="fuz-toast hidden"></div>
</section>
<!-- ReCaptcha init -->
<script
is:inline
define:vars={{ siteKey: import.meta.env.PUBLIC_RECAPTCHA_SITE_KEY }}
>
window.FUZ_RECAPTCHA_KEY = siteKey;
const recaptchaScript = document.createElement("script");
recaptchaScript.src =
"https://www.google.com/recaptcha/api.js?render=" + siteKey;
document.head.appendChild(recaptchaScript);
</script>
<!-- Formularz + toast -->
<script is:inline>
document.addEventListener("DOMContentLoaded", () => {
const form = document.getElementById("contactForm");
const toast = document.getElementById("toast");
if (!form) return; // Safety
form.addEventListener("submit", async (e) => {
if (!form.reportValidity()) return;
e.preventDefault();
const formData = new FormData(form);
const payload = Object.fromEntries(formData.entries());
payload.rodo = formData.get("rodo") === "on";
const token = await grecaptcha.execute(window.FUZ_RECAPTCHA_KEY, {
action: "submit",
});
payload.recaptcha = token;
const resp = await fetch("/api/contact", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(payload),
});
const json = await resp.json();
showToast(
json.ok ? "Wiadomość wysłana!" : "Błąd podczas wysyłania.",
json.ok ? "success" : "error",
);
if (json.ok) form.reset();
});
function showToast(message, type = "success") {
toast.innerHTML = `
<div class="fuz-toast-msg ${type}">
${message}
</div>
`;
toast.classList.remove("hidden");
setTimeout(() => toast.classList.add("hidden"), 3000);
}
});
</script>