Copy Create a maintenance-window opt-in CTA with Tailwind CSS for a database upgrade. Include the version change, expected downtime, recommended window, timezone, alternative slots, and a status badge. Add JavaScript that lets the user pick a window, converts the displayed time between local and UTC, confirms the schedule, and changes the banner into a booked state with an Add to calendar action. <div class="mx-auto max-w-4xl p-6"><aside class="overflow-hidden rounded-2xl border border-sky-200 bg-white shadow-sm"><div class="grid md:grid-cols-[1fr_auto]"><div class="p-6"><div class="flex items-center gap-2"><span class="rounded-full bg-sky-50 px-2.5 py-1 text-xs font-medium text-sky-700">Action recommended</span><span class="text-xs text-neutral-400">Postgres 16 → 17</span></div><h2 class="mt-4 text-xl font-semibold text-neutral-900">Choose your maintenance window</h2><p class="mt-2 max-w-xl text-sm leading-6 text-neutral-500">The upgrade includes automatic rollback and is expected to pause writes for less than four minutes.</p><div id="windowOptions" class="mt-5 grid gap-2 sm:grid-cols-3"><button data-window="2026-09-06T01:00:00Z" class="rounded-xl border border-neutral-900 bg-neutral-900 p-3 text-left text-white"><b class="block text-sm">Recommended</b><span class="mt-1 block text-xs text-white/60" data-time></span></button><button data-window="2026-09-07T22:00:00Z" class="rounded-xl border border-neutral-200 p-3 text-left"><b class="block text-sm">Monday evening</b><span class="mt-1 block text-xs text-neutral-400" data-time></span></button><button data-window="2026-09-10T01:00:00Z" class="rounded-xl border border-neutral-200 p-3 text-left"><b class="block text-sm">Thursday morning</b><span class="mt-1 block text-xs text-neutral-400" data-time></span></button></div></div><div class="flex min-w-52 flex-col justify-between border-t border-sky-100 bg-sky-50 p-6 md:border-l md:border-t-0"><button id="timezoneToggle" class="self-start text-xs font-medium text-sky-700">Showing local time</button><div id="windowSummary" class="mt-8"><p class="text-xs text-neutral-500">Selected window</p><p id="selectedWindow" class="mt-1 text-sm font-semibold text-neutral-900"></p></div><button id="windowConfirm" class="mt-5 rounded-xl bg-sky-600 px-4 py-2.5 text-sm font-medium text-white">Schedule upgrade</button></div></div></aside></div> var options = [].slice.call(document.querySelectorAll("[data-window]")); var selectedWindow = options[0]; var useUtc = false;
function formatWindow(value) { return new Intl.DateTimeFormat("en", { weekday: "short", month: "short", day: "numeric", hour: "numeric", minute: "2-digit", timeZoneName: "short", timeZone: useUtc ? "UTC" : undefined }).format(new Date(value)); }
function renderWindows() { options.forEach(function (option) { option.querySelector("[data-time]").textContent = formatWindow(option.getAttribute("data-window")); var on = option === selectedWindow; option.className = on ? "rounded-xl border border-neutral-900 bg-neutral-900 p-3 text-left text-white" : "rounded-xl border border-neutral-200 p-3 text-left"; }); document.getElementById("selectedWindow").textContent = formatWindow(selectedWindow.getAttribute("data-window")); document.getElementById("timezoneToggle").textContent = useUtc ? "Showing UTC · switch to local" : "Showing local time · switch to UTC"; }
options.forEach(function (option) { option.addEventListener("click", function () { selectedWindow = option; renderWindows(); }); }); document.getElementById("timezoneToggle").addEventListener("click", function () { useUtc = !useUtc; renderWindows(); }); document.getElementById("windowConfirm").addEventListener("click", function () { var button = document.getElementById("windowConfirm"); button.textContent = "Scheduled ✓"; button.className = "mt-5 rounded-xl bg-green-600 px-4 py-2.5 text-sm font-medium text-white"; button.disabled = true; }); renderWindows();