mail ready
This commit is contained in:
+71
-46
@@ -1,50 +1,75 @@
|
||||
(() => {
|
||||
const menuButton = document.querySelector('[data-menu-toggle]');
|
||||
const mobileNav = document.querySelector('[data-mobile-nav]');
|
||||
if (menuButton && mobileNav) {
|
||||
menuButton.addEventListener('click', () => {
|
||||
const open = mobileNav.classList.toggle('open');
|
||||
menuButton.classList.toggle('open', open);
|
||||
menuButton.setAttribute('aria-expanded', String(open));
|
||||
const menuButton = document.querySelector('[data-menu-toggle]');
|
||||
const mobileNav = document.querySelector('[data-mobile-nav]');
|
||||
if (menuButton && mobileNav) {
|
||||
menuButton.addEventListener('click', () => {
|
||||
const open = mobileNav.classList.toggle('open');
|
||||
menuButton.classList.toggle('open', open);
|
||||
menuButton.setAttribute('aria-expanded', String(open));
|
||||
});
|
||||
mobileNav.querySelectorAll('a').forEach(a => a.addEventListener('click', () => {
|
||||
mobileNav.classList.remove('open');
|
||||
menuButton.classList.remove('open');
|
||||
menuButton.setAttribute('aria-expanded', 'false');
|
||||
}));
|
||||
}
|
||||
|
||||
const observer = 'IntersectionObserver' in window ? new IntersectionObserver(entries => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
entry.target.classList.add('visible');
|
||||
observer.unobserve(entry.target);
|
||||
}
|
||||
});
|
||||
}, {threshold: .12}) : null;
|
||||
document.querySelectorAll('.reveal-on-scroll').forEach(el => observer ? observer.observe(el) : el.classList.add('visible'));
|
||||
|
||||
document.querySelectorAll('[data-contact-form]').forEach(form => {
|
||||
let challengePromise = fetch('/api/contact', {credentials: 'same-origin', cache: 'no-store'}).then(r => {
|
||||
if (!r.ok) throw new Error('challenge');
|
||||
return r.json();
|
||||
}).catch(() => null);
|
||||
form.addEventListener('submit', async event => {
|
||||
event.preventDefault();
|
||||
if (!form.reportValidity()) return;
|
||||
const fd = new FormData(form);
|
||||
const lang = document.documentElement.lang || 'de';
|
||||
const status = form.querySelector('.form-status');
|
||||
const button = form.querySelector('button[type="submit"]');
|
||||
button.disabled = true;
|
||||
status.style.display = 'block';
|
||||
status.textContent = lang === 'de' ? 'Nachricht wird gesendet …' : 'Sending message …';
|
||||
try {
|
||||
const challenge = await challengePromise;
|
||||
if (!challenge?.token) throw new Error('challenge');
|
||||
const {token} = challenge;
|
||||
const payload = Object.fromEntries(fd.entries());
|
||||
payload.token = token;
|
||||
payload.lang = lang;
|
||||
const response = await fetch('/api/contact', {
|
||||
method: 'POST', credentials: 'same-origin',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify(payload)
|
||||
});
|
||||
if (!response.ok) throw new Error('send');
|
||||
status.textContent = lang === 'de' ? 'Vielen Dank. Ihre Nachricht wurde übermittelt.' : 'Thank you. Your message has been submitted.';
|
||||
form.reset();
|
||||
challengePromise = fetch('/api/contact', {credentials: 'same-origin', cache: 'no-store'}).then(r => r.json()).catch(() => null);
|
||||
} catch (_) {
|
||||
status.textContent = lang === 'de' ? 'Die Nachricht konnte nicht gesendet werden. Bitte versuchen Sie es später erneut oder schreiben Sie an info@dilibworld.com.' : 'Your message could not be sent. Please try again later or email info@dilibworld.com.';
|
||||
} finally {
|
||||
button.disabled = false;
|
||||
}
|
||||
});
|
||||
});
|
||||
mobileNav.querySelectorAll('a').forEach(a => a.addEventListener('click', () => {
|
||||
mobileNav.classList.remove('open'); menuButton.classList.remove('open');
|
||||
menuButton.setAttribute('aria-expanded', 'false');
|
||||
|
||||
const notice = document.querySelector('[data-cookie-notice]');
|
||||
const choice = localStorage.getItem('dilibworld-cookie-choice');
|
||||
if (notice && !choice) notice.classList.add('show');
|
||||
document.querySelectorAll('[data-cookie-choice]').forEach(btn => btn.addEventListener('click', () => {
|
||||
localStorage.setItem('dilibworld-cookie-choice', btn.dataset.cookieChoice);
|
||||
notice?.classList.remove('show');
|
||||
}));
|
||||
}
|
||||
|
||||
const observer = 'IntersectionObserver' in window ? new IntersectionObserver(entries => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) { entry.target.classList.add('visible'); observer.unobserve(entry.target); }
|
||||
});
|
||||
}, {threshold: .12}) : null;
|
||||
document.querySelectorAll('.reveal-on-scroll').forEach(el => observer ? observer.observe(el) : el.classList.add('visible'));
|
||||
|
||||
document.querySelectorAll('[data-mailto-form]').forEach(form => {
|
||||
form.addEventListener('submit', event => {
|
||||
event.preventDefault();
|
||||
if (!form.reportValidity()) return;
|
||||
const fd = new FormData(form);
|
||||
const lang = document.documentElement.lang || 'de';
|
||||
const lines = [];
|
||||
for (const [key, value] of fd.entries()) {
|
||||
if (key !== 'privacy' && key !== 'website') lines.push(`${key}: ${value}`);
|
||||
}
|
||||
const subject = lang === 'de' ? 'Anfrage über dilibworld.com' : 'Enquiry via dilibworld.com';
|
||||
const email = form.dataset.recipient || 'info@dilibworld.com';
|
||||
window.location.href = `mailto:${email}?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(lines.join('\n'))}`;
|
||||
const status = form.querySelector('.form-status');
|
||||
if (status) { status.style.display = 'block'; }
|
||||
});
|
||||
});
|
||||
|
||||
const notice = document.querySelector('[data-cookie-notice]');
|
||||
const choice = localStorage.getItem('dilibworld-cookie-choice');
|
||||
if (notice && !choice) notice.classList.add('show');
|
||||
document.querySelectorAll('[data-cookie-choice]').forEach(btn => btn.addEventListener('click', () => {
|
||||
localStorage.setItem('dilibworld-cookie-choice', btn.dataset.cookieChoice);
|
||||
notice?.classList.remove('show');
|
||||
}));
|
||||
|
||||
document.querySelectorAll('[data-current-year]').forEach(el => el.textContent = new Date().getFullYear());
|
||||
})();
|
||||
document.querySelectorAll('[data-current-year]').forEach(el => el.textContent = new Date().getFullYear());
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user