Jake Vanderwerf
2026-01-04 552d48a1424417da160c4952650ea6f4a3d7bafa
assets/js/concise/UtilityFunctions.js
@@ -25,7 +25,7 @@
 * @param {string|Date} dateStr Date to format
 * @returns {string} Formatted time string
 */
window.formatTimeAgo = function(dateStr) {
window.formatTimeAgo = function(dateStr, dateFormat = 'default') {
   const date = dateStr instanceof Date ? dateStr : new Date(dateStr);
   const now = new Date();
   const diffMs = date - now;
@@ -57,14 +57,43 @@
         timeStr = `${minutes} ${minutes === 1 ? 'minute' : 'minutes'}`;
      } else {
         // Hours
         timeStr = `${hours} ${hours === 1 ? 'hour' : 'hours'}`;
         timeStr = `about ${hours} ${hours === 1 ? 'hour' : 'hours'}`;
      }
   } else if (days < 7) {
      if (days === 1) {
         return isPast ? 'yesterday' : 'tomorrow';
      }
      timeStr = `about ${days} days`;
      // Days
      timeStr = `${days} ${days === 1 ? 'day' : 'days'}`;
   } else {
      // More than a week - just show the date
      return date.toLocaleDateString();
      // More than a week - show the date based on format
      if (dateFormat === 'default') {
         return date.toLocaleDateString();
      }
      // Parse PHP-style format string
      const formatMap = {
         'Y': date.getFullYear(),
         'y': String(date.getFullYear()).slice(-2),
         'F': date.toLocaleDateString('en-CA', { month: 'long' }),
         'M': date.toLocaleDateString('en-CA', { month: 'short' }),
         'm': String(date.getMonth() + 1).padStart(2, '0'),
         'n': date.getMonth() + 1,
         'd': String(date.getDate()).padStart(2, '0'),
         'j': date.getDate(),
         'D': date.toLocaleDateString('en-CA', { weekday: 'short' }),
         'l': date.toLocaleDateString('en-CA', { weekday: 'long' }),
         'H': String(date.getHours()).padStart(2, '0'),
         'i': String(date.getMinutes()).padStart(2, '0'),
         's': String(date.getSeconds()).padStart(2, '0'),
         'h': String(date.getHours() % 12 || 12).padStart(2, '0'),
         'g': date.getHours() % 12 || 12,
         'A': date.getHours() >= 12 ? 'PM' : 'AM',
         'a': date.getHours() >= 12 ? 'pm' : 'am',
      };
      return dateFormat.replace(/[YyFMmnjDlHishgAa]/g, match => formatMap[match]);
   }
   // Add appropriate prefix/suffix based on past or future
@@ -274,6 +303,26 @@
   return div.innerHTML;
}
window.generateID = function(prefix = 'jvb') {
   return `${prefix}_${Date.now()}_${Math.random().toString(36).slice(2,9)}`;
}
window.showProgress = function(elements, current, total, message = '', icon = '') {
   const show = current < total;
   if (elements.progress && show) {
      window.fade(elements.progress, true);
   }
   const percent = total > 0 ? (current / total) * 100 : 0;
   if (elements.fill) elements.fill.style.width = `${percent}%`;
   if (elements.details) elements.details.textContent = message;
   if (elements.count) elements.count.textContent = `${current}/${total}`;
   if (elements.icon) elements.icon.className = (icon === '') ? 'icon' : 'icon icon-'+icon;
   if (elements.progress && current === total) {
      window.fade(elements.progress, false);
   }
}
/**
 * Format a date string for display
 * @param {string} dateString - ISO date string