File size: 1,832 Bytes
b068b76
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
(function () {
  const stack = document.createElement('div');
  stack.className = 'toast-stack';
  const mountStack = () => document.body.appendChild(stack);
  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', mountStack, { once: true });
  } else {
    mountStack();
  }

  const createToast = (type, title, message) => {
    const toast = document.createElement('div');
    toast.className = `toast ${type}`;
    toast.innerHTML = `<div><strong>${title}</strong>${message ? `<small>${message}</small>` : ''}</div>`;
    stack.appendChild(toast);
    setTimeout(() => toast.remove(), 4500);
  };

  const setBadge = (element, text, tone = 'info') => {
    if (!element) return;
    element.textContent = text;
    element.className = `badge ${tone}`;
  };

  const showLoading = (container, message = 'Loading data...') => {
    if (!container) return;
    container.innerHTML = `<div class="loading-indicator">${message}</div>`;
  };

  const fadeReplace = (container, html) => {
    if (!container) return;
    container.innerHTML = html;
    container.classList.add('fade-in');
    setTimeout(() => container.classList.remove('fade-in'), 200);
  };

  const fetchJSON = async (url, options = {}, context = '') => {
    try {
      const response = await fetch(url, options);
      if (!response.ok) {
        const text = await response.text();
        createToast('error', context || 'Request failed', text || response.statusText);
        throw new Error(text || response.statusText);
      }
      return await response.json();
    } catch (err) {
      createToast('error', context || 'Network error', err.message || String(err));
      throw err;
    }
  };

  window.UIFeedback = {
    toast: createToast,
    setBadge,
    showLoading,
    fadeReplace,
    fetchJSON,
  };
})();