PageSourceSearch

https://eggacademy.co.nz/landing-lab-open-day.js

js eggacademy.co.nz collected 2026-09-26 13:05:33 UTC 10,507 bytes, 311 lines download raw bytes

1(function () {
2  "use strict";
3
4  var NZ_TZ = "Pacific/Auckland";
5  var LOBBY_OPEN_MINUTES_BEFORE_START = 5;
6
7  function apiBase() {
8    var w = window;
9    if (w.__EGG_ACADEMY_API_BASE__ && typeof w.__EGG_ACADEMY_API_BASE__ === "string") {
10      return String(w.__EGG_ACADEMY_API_BASE__).replace(/\/$/, "");
11    }
12    if (w.EggSite && typeof w.EggSite.getEggAcademyApiBase === "function") {
13      return w.EggSite.getEggAcademyApiBase();
14    }
15    var host = w.location.hostname;
16    if (host === "localhost" || host === "127.0.0.1") return "http://localhost:3000";
17    return "https://egg.ac";
18  }
19
20  function formatNzDateTime(iso) {
21    try {
22      return new Date(iso).toLocaleString("en-NZ", {
23        timeZone: NZ_TZ,
24        weekday: "long",
25        day: "numeric",
26        month: "long",
27        hour: "numeric",
28        minute: "2-digit",
29        hour12: true,
30      });
31    } catch (e) {
32      return iso;
33    }
34  }
35
36  function formatNzTime(iso) {
37    try {
38      return new Date(iso).toLocaleString("en-NZ", {
39        timeZone: NZ_TZ,
40        hour: "numeric",
41        minute: "2-digit",
42        hour12: true,
43      });
44    } catch (e2) {
45      return iso;
46    }
47  }
48
49  function lobbyOpensAtFromStart(startAtIso) {
50    var startMs = new Date(startAtIso).getTime();
51    if (!Number.isFinite(startMs)) {
52      return null;
53    }
54    return new Date(
55      startMs - LOBBY_OPEN_MINUTES_BEFORE_START * 60 * 1000,
56    );
57  }
58
59  function resolveSessionLobbyState(session) {
60    var lobbyOpensAt = lobbyOpensAtFromStart(session.startAt);
61    var joinOpen =
62      typeof session.joinOpen === "boolean"
63        ? session.joinOpen
64        : (function () {
65            var lobbyOpensMs = lobbyOpensAt ? lobbyOpensAt.getTime() : NaN;
66            var now = Date.now();
67            return Number.isFinite(lobbyOpensMs) && now >= lobbyOpensMs;
68          })();
69    return {
70      lobbyLabel: lobbyOpensAt ? formatNzTime(lobbyOpensAt.toISOString()) : "",
71      joinOpen: joinOpen,
72    };
73  }
74
75  function formatComeBackAt(iso) {
76    try {
77      var d = new Date(iso);
78      var time = d.toLocaleString("en-NZ", {
79        timeZone: NZ_TZ,
80        hour: "numeric",
81        minute: "2-digit",
82        hour12: true,
83      });
84      var date = d.toLocaleString("en-NZ", {
85        timeZone: NZ_TZ,
86        weekday: "long",
87        day: "numeric",
88        month: "long",
89      });
90      return time + ", " + date;
91    } catch (e) {
92      return iso;
93    }
94  }
95
96  function escapeHtml(value) {
97    return String(value || "")
98      .replace(/&/g, "&")
99      .replace(/</g, "&lt;")
100      .replace(/>/g, "&gt;")
101      .replace(/"/g, "&quot;");
102  }
103
104  function bindDisabledJoinHint(card) {
105    var wrap = card.querySelector(".hs-info-session__join-wrap");
106    var trigger = card.querySelector("[data-open-day-join-hint-trigger]");
107    var popover = card.querySelector("[data-open-day-join-hint]");
108    if (!wrap || !trigger || !popover) return;
109
110    var hoverUi = window.matchMedia("(hover: hover) and (pointer: fine)").matches;
111
112    function hideHint() {
113      popover.hidden = true;
114      trigger.setAttribute("aria-expanded", "false");
115    }
116
117    function showHint() {
118      if (!popover.textContent.trim()) return;
119      popover.hidden = false;
120      trigger.setAttribute("aria-expanded", "true");
121    }
122
123    trigger.addEventListener("click", function (ev) {
124      ev.preventDefault();
125      ev.stopPropagation();
126      if (hoverUi) return;
127      if (popover.hidden) showHint();
128      else hideHint();
129    });
130
131    if (hoverUi) {
132      wrap.addEventListener("mouseenter", showHint);
133      wrap.addEventListener("mouseleave", hideHint);
134      wrap.addEventListener("focusin", showHint);
135      wrap.addEventListener("focusout", function (ev) {
136        if (!wrap.contains(ev.relatedTarget)) hideHint();
137      });
138    }
139
140    document.addEventListener("click", function (ev) {
141      if (!wrap.contains(ev.target)) hideHint();
142    });
143
144    document.addEventListener("keydown", function (ev) {
145      if (ev.key === "Escape") hideHint();
146    });
147  }
148
149  function bindReminderForm(card, session) {
150    var form = card.querySelector("[data-open-day-reminder-form]");
151    if (!form || !window.fetch) return;
152    var phoneInp = form.querySelector("[data-open-day-reminder-phone]");
153    var submitBtn = form.querySelector("[data-open-day-reminder-submit]");
154    var statusEl = form.querySelector("[data-open-day-reminder-status]");
155
156    form.addEventListener("submit", function (ev) {
157      ev.preventDefault();
158      if (!phoneInp || !submitBtn) return;
159      var phone = String(phoneInp.value || "").trim();
160      if (!phone || phone.replace(/\D/g, "").length < 7) {
161        if (statusEl) {
162          statusEl.textContent = "Enter a valid phone number.";
163          statusEl.hidden = false;
164        }
165        return;
166      }
167      submitBtn.disabled = true;
168      fetch(apiBase() + "/api/public/eggsite/open-day-session-reminder", {
169        method: "POST",
170        headers: { "Content-Type": "application/json" },
171        body: JSON.stringify({ slotId: session.id, phone: phone }),
172      })
173        .then(function (res) {
174          return res.json().then(function (body) {
175            return { ok: res.ok, body: body };
176          });
177        })
178        .then(function (result) {
179          if (!result.ok) {
180            throw new Error((result.body && result.body.error) || "Could not save reminder");
181          }
182          if (statusEl) {
183            statusEl.textContent =
184              "Reminder saved -- we will text you about an hour before start. No marketing list.";
185            statusEl.hidden = false;
186          }
187          submitBtn.disabled = false;
188        })
189        .catch(function (err) {
190          submitBtn.disabled = false;
191          if (statusEl) {
192            statusEl.textContent = err.message || "Could not save reminder";
193            statusEl.hidden = false;
194          }
195        });
196    });
197  }
198
199  function renderSessionCard(session) {
200    var card = document.createElement("article");
201    card.className =
202      "hs-info-session hs-info-session--ticket-stub odl-session-panel odl-session-panel--layout-05";
203    card.setAttribute("data-session-id", session.id);
204
205    var whenLabel = formatNzDateTime(session.startAt);
206    var lobbyState = resolveSessionLobbyState(session);
207    var lobbyOpensAt = lobbyOpensAtFromStart(session.startAt);
208    var joinOpen = lobbyState.joinOpen;
209    var ended = Boolean(session.ended) && !joinOpen;
210    var joinUrl = session.joinUrl || "#";
211    var comeBackTitle =
212      lobbyOpensAt && !joinOpen && !ended
213        ? "Come back at " + formatComeBackAt(lobbyOpensAt.toISOString())
214        : "Join opens shortly before the session starts.";
215
216    var joinHtml = ended
217      ? '<p class="hs-info-session__ended">This Open Day has ended.</p>'
218      : joinOpen
219        ? '<a class="btn btn-primary hs-info-session__join" href="' +
220          escapeHtml(joinUrl) +
221          '" rel="noopener noreferrer" title="Join the Open Day tour">' +
222          "Join the tour</a>"
223        : '<div class="hs-info-session__join-wrap">' +
224          '<button type="button" class="btn btn-primary hs-info-session__join hs-info-session__join--disabled" aria-disabled="true" aria-expanded="false" aria-controls="open-day-join-hint-' +
225          escapeHtml(session.id) +
226          '" data-open-day-join-hint-trigger>Join the tour</button>' +
227          '<p class="hs-info-session__join-popover" id="open-day-join-hint-' +
228          escapeHtml(session.id) +
229          '" data-open-day-join-hint hidden role="status">' +
230          escapeHtml(comeBackTitle) +
231          "</p></div>";
232
233    card.innerHTML =
234      '<div class="hs-info-session__when-block">' +
235      '<div class="hs-info-session__head">' +
236      '<h3 class="eg-slim-h4 hs-info-session__when">' +
237      escapeHtml(whenLabel) +
238      " NZ</h3>" +
239      "</div>" +
240      "</div>" +
241      '<div class="hs-info-session__join-block">' +
242      '<div class="hs-info-session__actions">' +
243      joinHtml +
244      "</div>" +
245      "</div>" +
246      '<form class="hs-info-session__reminder hs-info-session__reminder-block" data-open-day-reminder-form>' +
247      '<p class="hs-info-session__reminder-label">Want a text reminder 1 hour before?</p>' +
248      '<div class="hs-info-session__reminder-row">' +
249      '<input type="tel" class="hs-info-session__reminder-phone" placeholder="021 123 4567" autocomplete="tel" inputmode="tel" maxlength="40" data-open-day-reminder-phone required />' +
250      '<button type="submit" class="btn btn-secondary hs-info-session__reminder-btn" data-open-day-reminder-submit>Remind Me</button>' +
251      "</div>" +
252      '<p class="hs-info-session__reminder-status" data-open-day-reminder-status hidden></p>' +
253      "</form>";
254
255    bindReminderForm(card, session);
256    bindDisabledJoinHint(card);
257    return card;
258  }
259
260  function initOpenDaySessions() {
261    var roots = document.querySelectorAll("[data-open-day-root]");
262    if (!roots.length || !window.fetch) return;
263
264    roots.forEach(function (root) {
265      if (root.hidden) return;
266      if (root.getAttribute("data-open-day-static") === "true") return;
267      var listEl = root.querySelector("[data-open-day-sessions-list]");
268      var emptyEl = root.querySelector("[data-open-day-sessions-empty]");
269      var loadingEl = root.querySelector("[data-open-day-sessions-loading]");
270      if (!listEl) return;
271
272      fetch(apiBase() + "/api/public/eggsite/open-day-sessions")
273        .then(function (res) {
274          return res.json();
275        })
276        .then(function (payload) {
277          if (loadingEl) loadingEl.hidden = true;
278          var sessions = (payload && payload.sessions) || [];
279          if (!sessions.length) {
280            root.hidden = true;
281            root.setAttribute("hidden", "");
282            return;
283          }
284          root.hidden = false;
285          root.removeAttribute("hidden");
286          if (emptyEl) emptyEl.hidden = true;
287          for (var i = 0; i < sessions.length; i++) {
288            listEl.appendChild(renderSessionCard(sessions[i]));
289          }
290        })
291        .catch(function () {
292          if (loadingEl) loadingEl.hidden = true;
293          if (emptyEl) {
294            emptyEl.textContent =
295              "Could not load Open Day times right now. Refresh the page or contact us.";
296            emptyEl.hidden = false;
297          }
298        });
299    });
300  }
301
302  function init() {
303    initOpenDaySessions();
304  }
305
306  if (document.readyState === "loading") {
307    document.addEventListener("DOMContentLoaded", init);
308  } else {
309    init();
310  }
311})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.