Refine landing layout: calendar actions and editorial gift section
This commit is contained in:
138
script.js
138
script.js
@ -5,6 +5,33 @@ const attendanceInputs = Array.from(document.querySelectorAll('input[name="atten
|
||||
const successModal = document.getElementById('success-modal');
|
||||
const successOkButton = document.getElementById('success-ok');
|
||||
const closeModalNodes = Array.from(document.querySelectorAll('[data-close-modal]'));
|
||||
const googleCalendarLink = document.getElementById('google-calendar-link');
|
||||
const iCalDownloadButton = document.getElementById('ical-download');
|
||||
const copyIbanButton = document.getElementById('copy-iban');
|
||||
const ibanFeedback = document.getElementById('iban-feedback');
|
||||
const giftHolder = document.getElementById('gift-holder');
|
||||
const giftIban = document.getElementById('gift-iban');
|
||||
const giftCausal = document.getElementById('gift-causal');
|
||||
const giftNote = document.getElementById('gift-note');
|
||||
|
||||
// Modifica qui i dati del calendario evento.
|
||||
const EVENT_CALENDAR = {
|
||||
title: 'I 40 anni del Gianca',
|
||||
location: 'Lost Paradise Beach Club, Bacoli',
|
||||
description: 'Conferma la tua presenza per i 40 anni del Gianca.',
|
||||
date: '2026-04-25',
|
||||
startTime: '12:00',
|
||||
durationHours: 6,
|
||||
timezone: 'Europe/Rome'
|
||||
};
|
||||
|
||||
// Modifica qui i dati regalo / quota viaggio.
|
||||
const GIFT_DETAILS = {
|
||||
holder: 'Giancarlo ...',
|
||||
iban: 'IT00X0000000000000000000000',
|
||||
causal: 'Regalo 40 anni Gianca',
|
||||
note: 'Nota facoltativa: un pensiero semplice e sempre gradito.'
|
||||
};
|
||||
|
||||
function updateAttendanceFields() {
|
||||
const selected = document.querySelector('input[name="attendance"]:checked');
|
||||
@ -34,15 +61,126 @@ function closeSuccessModal() {
|
||||
document.body.classList.remove('modal-open');
|
||||
}
|
||||
|
||||
function pad(value) {
|
||||
return String(value).padStart(2, '0');
|
||||
}
|
||||
|
||||
function createFloatingDateTime(date, time, plusHours = 0) {
|
||||
const [year, month, day] = date.split('-').map(Number);
|
||||
const [hours, minutes] = time.split(':').map(Number);
|
||||
const normalizedDate = new Date(Date.UTC(year, month - 1, day, hours, minutes, 0));
|
||||
normalizedDate.setUTCHours(normalizedDate.getUTCHours() + plusHours);
|
||||
|
||||
return `${normalizedDate.getUTCFullYear()}${pad(normalizedDate.getUTCMonth() + 1)}${pad(normalizedDate.getUTCDate())}T${pad(normalizedDate.getUTCHours())}${pad(normalizedDate.getUTCMinutes())}00`;
|
||||
}
|
||||
|
||||
function buildGoogleCalendarUrl(eventData) {
|
||||
const start = createFloatingDateTime(eventData.date, eventData.startTime, 0);
|
||||
const end = createFloatingDateTime(eventData.date, eventData.startTime, eventData.durationHours);
|
||||
const params = new URLSearchParams({
|
||||
action: 'TEMPLATE',
|
||||
text: eventData.title,
|
||||
details: eventData.description,
|
||||
location: eventData.location,
|
||||
ctz: eventData.timezone,
|
||||
dates: `${start}/${end}`
|
||||
});
|
||||
return `https://calendar.google.com/calendar/render?${params.toString()}`;
|
||||
}
|
||||
|
||||
function escapeIcsText(value) {
|
||||
return value
|
||||
.replace(/\\/g, '\\\\')
|
||||
.replace(/\n/g, '\\n')
|
||||
.replace(/,/g, '\\,')
|
||||
.replace(/;/g, '\\;');
|
||||
}
|
||||
|
||||
function buildIcsContent(eventData) {
|
||||
const start = createFloatingDateTime(eventData.date, eventData.startTime, 0);
|
||||
const end = createFloatingDateTime(eventData.date, eventData.startTime, eventData.durationHours);
|
||||
const stamp = `${createFloatingDateTime(eventData.date, eventData.startTime, 0)}Z`;
|
||||
const uid = `gianca-40-${start}@gianca-event`;
|
||||
|
||||
return [
|
||||
'BEGIN:VCALENDAR',
|
||||
'VERSION:2.0',
|
||||
'PRODID:-//Gianca40//Event Landing//IT',
|
||||
'CALSCALE:GREGORIAN',
|
||||
'BEGIN:VEVENT',
|
||||
`UID:${uid}`,
|
||||
`DTSTAMP:${stamp}`,
|
||||
`DTSTART;TZID=${eventData.timezone}:${start}`,
|
||||
`DTEND;TZID=${eventData.timezone}:${end}`,
|
||||
`SUMMARY:${escapeIcsText(eventData.title)}`,
|
||||
`LOCATION:${escapeIcsText(eventData.location)}`,
|
||||
`DESCRIPTION:${escapeIcsText(eventData.description)}`,
|
||||
'END:VEVENT',
|
||||
'END:VCALENDAR'
|
||||
].join('\r\n');
|
||||
}
|
||||
|
||||
function triggerIcsDownload() {
|
||||
const content = buildIcsContent(EVENT_CALENDAR);
|
||||
const blob = new Blob([content], { type: 'text/calendar;charset=utf-8' });
|
||||
const downloadUrl = URL.createObjectURL(blob);
|
||||
const link = document.createElement('a');
|
||||
link.href = downloadUrl;
|
||||
link.download = 'i-40-anni-del-gianca.ics';
|
||||
document.body.append(link);
|
||||
link.click();
|
||||
link.remove();
|
||||
URL.revokeObjectURL(downloadUrl);
|
||||
}
|
||||
|
||||
function setIbanFeedback(message) {
|
||||
if (!ibanFeedback) return;
|
||||
ibanFeedback.textContent = message;
|
||||
}
|
||||
|
||||
async function copyIbanToClipboard() {
|
||||
if (!copyIbanButton) return;
|
||||
const ibanNodeId = copyIbanButton.dataset.copyTarget;
|
||||
const ibanText = document.getElementById(ibanNodeId || '')?.textContent?.trim();
|
||||
if (!ibanText) return;
|
||||
|
||||
try {
|
||||
await navigator.clipboard.writeText(ibanText);
|
||||
setIbanFeedback('IBAN copiato negli appunti.');
|
||||
} catch (error) {
|
||||
const fallbackField = document.createElement('input');
|
||||
fallbackField.value = ibanText;
|
||||
document.body.append(fallbackField);
|
||||
fallbackField.select();
|
||||
const copied = document.execCommand('copy');
|
||||
fallbackField.remove();
|
||||
setIbanFeedback(copied ? 'IBAN copiato negli appunti.' : 'Copia non riuscita. Riprova.');
|
||||
}
|
||||
}
|
||||
|
||||
attendanceInputs.forEach((input) => input.addEventListener('change', updateAttendanceFields));
|
||||
closeModalNodes.forEach((node) => node.addEventListener('click', closeSuccessModal));
|
||||
successOkButton?.addEventListener('click', closeSuccessModal);
|
||||
iCalDownloadButton?.addEventListener('click', triggerIcsDownload);
|
||||
copyIbanButton?.addEventListener('click', async () => {
|
||||
await copyIbanToClipboard();
|
||||
window.clearTimeout(copyIbanButton.dataset.feedbackTimeoutId);
|
||||
const timeoutId = window.setTimeout(() => setIbanFeedback(''), 2500);
|
||||
copyIbanButton.dataset.feedbackTimeoutId = String(timeoutId);
|
||||
});
|
||||
document.addEventListener('keydown', (event) => {
|
||||
if (event.key === 'Escape' && successModal?.classList.contains('success-modal--open')) {
|
||||
closeSuccessModal();
|
||||
}
|
||||
});
|
||||
updateAttendanceFields();
|
||||
if (googleCalendarLink) {
|
||||
googleCalendarLink.href = buildGoogleCalendarUrl(EVENT_CALENDAR);
|
||||
}
|
||||
if (giftHolder) giftHolder.textContent = GIFT_DETAILS.holder;
|
||||
if (giftIban) giftIban.textContent = GIFT_DETAILS.iban;
|
||||
if (giftCausal) giftCausal.textContent = GIFT_DETAILS.causal;
|
||||
if (giftNote) giftNote.textContent = GIFT_DETAILS.note;
|
||||
|
||||
function encode(data) {
|
||||
return new URLSearchParams(data).toString();
|
||||
|
||||
Reference in New Issue
Block a user