|
|
@@ -78,5 +78,62 @@ function renderReportsChart() {
|
|
|
|
|
|
document.addEventListener('DOMContentLoaded', renderReportsChart);
|
|
|
|
|
|
+// Locale-aware <time> rendering. Templates emit `<time class="irdb-dt"
|
|
|
+// datetime="<iso>">…</iso></time>`; the text content holds the raw ISO
|
|
|
+// string as a no-JS fallback. This pass replaces it with the user's
|
|
|
+// browser locale formatting, with an optional configured fallback (set
|
|
|
+// via UI_LOCALE on the html data attribute) appended so browser locale
|
|
|
+// wins but a deployment can still ensure something sensible if the
|
|
|
+// browser's preference isn't supported. `data-irdb-dt-format="date"`
|
|
|
+// switches to date-only output.
|
|
|
+function getDateLocales() {
|
|
|
+ const fallback = document.documentElement.getAttribute('data-irdb-locale-fallback');
|
|
|
+ const locales = [];
|
|
|
+ if (typeof navigator !== 'undefined' && navigator.language) {
|
|
|
+ locales.push(navigator.language);
|
|
|
+ }
|
|
|
+ if (fallback && fallback.trim()) {
|
|
|
+ locales.push(fallback.trim());
|
|
|
+ }
|
|
|
+ return locales.length > 0 ? locales : undefined;
|
|
|
+}
|
|
|
+
|
|
|
+function buildDateFormatters() {
|
|
|
+ const locales = getDateLocales();
|
|
|
+ return {
|
|
|
+ datetime: new Intl.DateTimeFormat(locales, {
|
|
|
+ year: 'numeric', month: '2-digit', day: '2-digit',
|
|
|
+ hour: '2-digit', minute: '2-digit', second: '2-digit',
|
|
|
+ }),
|
|
|
+ date: new Intl.DateTimeFormat(locales, {
|
|
|
+ year: 'numeric', month: '2-digit', day: '2-digit',
|
|
|
+ }),
|
|
|
+ };
|
|
|
+}
|
|
|
+
|
|
|
+function formatTimes(root) {
|
|
|
+ const scope = root && root.querySelectorAll ? root : document;
|
|
|
+ const formatters = buildDateFormatters();
|
|
|
+ const elements = scope.querySelectorAll('time.irdb-dt[datetime]');
|
|
|
+ elements.forEach((el) => {
|
|
|
+ const iso = el.getAttribute('datetime');
|
|
|
+ if (!iso) return;
|
|
|
+ const d = new Date(iso);
|
|
|
+ if (isNaN(d.getTime())) return;
|
|
|
+ const fmt = el.dataset.irdbDtFormat === 'date' ? formatters.date : formatters.datetime;
|
|
|
+ try {
|
|
|
+ el.textContent = fmt.format(d);
|
|
|
+ if (!el.hasAttribute('title')) {
|
|
|
+ el.setAttribute('title', iso);
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ /* leave the ISO fallback in place */
|
|
|
+ }
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+document.addEventListener('DOMContentLoaded', () => formatTimes(document));
|
|
|
+document.body.addEventListener('htmx:afterSettle', (e) => formatTimes(e.target));
|
|
|
+
|
|
|
window.Alpine = Alpine;
|
|
|
Alpine.start();
|