PHP WebShell

Текущая директория: /var/www/bitcardoApp/user/common

Просмотр файла: footer.php

<style>
  /* Make the FAB truly top-most and clickable everywhere */
.chat-fab{
  position: fixed;
  right: 16px;
  bottom: 86px; /* above your fixed-bottom footer */
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: #076289;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
  box-shadow: 0 6px 18px rgba(0,0,0,.2);
  z-index: 2147483647;          /* HUGE: above any widget/iframe/tooltips */
  pointer-events: auto;         /* ensure the anchor receives clicks */
}
.chat-fab:hover{ filter: brightness(0.95); }
.chat-fab i{ font-size: 1.4rem; line-height: 1; }

.chat-fab-badge{
  position: absolute;
  top: -6px;
  right: -6px;
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  border-radius: 10px;
  background: #dc3545;
  color: #fff;
  font-size: 12px;
  line-height: 20px;
  text-align: center;
  box-shadow: 0 2px 8px rgba(0,0,0,.15);
}

@media (min-width: 768px){
  .chat-fab{ display: none; }
}

/* If you show an "Opening chat…" overlay, keep it high too */
.chat-fab-overlay{
  position: fixed; inset: 0;
  display: none;
  align-items: center; justify-content: center;
  background: rgba(255,255,255,.8);
  backdrop-filter: blur(2px);
  z-index: 2147483600;
  font-weight: 600;
  color: #000;
}
.chat-fab.loading + .chat-fab-overlay{ display: flex; }


  small {
    font: arial;
    --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
               "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans",
               "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol",
               sans-serif;

  --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,
               "Liberation Mono", "Courier New", monospace;
  }

    /* Make offline overlay see-through but still block clicks */
    #offlineOverlay{
    background: rgba(255,255,255,0.1) !important; /* was 0.96 */
    /* optional: soften the blur a bit too */
    backdrop-filter: blur(1.5px) !important;
  }

  /* Keep the card readable even with lower overlay opacity */
  #offlineOverlay .offline-overlay__card{
    background: rgba(255,255,255,0.9);
  }
</style>

<div class="mt-5"></div>

<footer class="mt-5 d-md-none fixed-bottom bg-white border-top shadow-sm">
  <div class="d-flex justify-content-around text-center py-2 mb-2">

    <a href="../../user/dashboard/index.php" class="text-decoration-none text-dark">
      <div class="d-flex flex-column align-items-center">
        <i class="bi bi-house-door-fill"></i>
        <small>Home</small>
      </div>
    </a>

    <a href="../../user/wallets/wallets.php" class="text-decoration-none text-dark">
      <div class="d-flex flex-column align-items-center">
        <i class="bi bi-wallet2"></i>
        <small>Wallets</small>
      </div>
    </a>

    <a href="../../user/dashboard/index.php#convert" class="text-decoration-none text-dark">
      <div class="d-flex flex-column align-items-center">
        <i class="bi bi-shuffle"></i>
        <small>Convert</small>
      </div>
    </a>

    <a href="../../user/data/rates.php" class="text-decoration-none text-dark">
      <div class="d-flex flex-column align-items-center">
        <i class="bi bi-graph-up"></i>
        <small>Rates</small>
      </div>
    </a>

    <a href="../../user/account/account.php" class="text-decoration-none text-dark">
      <div class="d-flex flex-column align-items-center">
        <i class="bi bi-person-circle"></i>
        <small>Account</small>
      </div>
    </a>

  </div>
</footer>

<!-- Back to top -->
<button id="backToTop" class="btn btn-dark">Back to top</button>

<!-- Floating Chat FAB (wallet → Grupo SSO) -->
<div style="position:fixed; right:16px; bottom:86px; width:56px; height:56px; z-index:2147483646; pointer-events:none;">
  <!-- 🔴 Only change here: added id="chatFab" -->
  <a href="/chat/sso/" id="chatFab" class="chat-fab" style="pointer-events:auto;">
    <i class="bi bi-chat-dots-fill"></i>
    <span class="chat-fab-badge d-none" id="chatUnreadCount">0</span>
  </a>
</div>

<div id="chatFabOverlay" class="chat-fab-overlay" aria-hidden="true">Opening chat…</div>

<script>
  // Optional: Later you can fetch unread count and show it here
  // fetch('/chat/unread-count').then(r => r.json()).then(d => {
  //   if (d.count > 0) {
  //     const b = document.getElementById('chatUnreadCount');
  //     b.textContent = d.count > 99 ? '99+' : d.count;
  //     b.classList.remove('d-none');
  //   }
  // });
</script>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<!-- jQuery -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<!-- Owl Carousel JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/OwlCarousel2/2.3.4/owl.carousel.min.js"></script>

<script>
  // Back to top logic
  const backToTopBtn = document.getElementById('backToTop');
  window.addEventListener('scroll', () => {
    backToTopBtn.style.display = window.scrollY > 100 ? 'block' : 'none';
  });
  backToTopBtn.addEventListener('click', () => {
    window.scrollTo({ top: 0, behavior: 'smooth' });
  });

  // Currency swap demo
  function swapCurrencies() {
    const currencyFrom = document.getElementById("currencyFrom");
    const currencyTo = document.getElementById("currencyTo");
    const amountFrom = document.getElementById("amountFrom");
    const amountTo = document.getElementById("amountTo");

    const tempCurrency = currencyFrom.value;
    currencyFrom.value = currencyTo.value;
    currencyTo.value = tempCurrency;

    const tempAmount = amountFrom.value;
    amountFrom.value = amountTo.value;
    amountTo.value = tempAmount;
  }

  // SSO: show a quick overlay and prevent double-clicks while redirecting
  (function(){
    const fab = document.getElementById('chatFab');
    if (!fab) return;
    fab.addEventListener('click', function(){
      this.classList.add('loading');
      this.style.pointerEvents = 'none';
      // Note: we do NOT preventDefault, so browser still follows /chat/sso/
    });
  })();

  // Owl carousel init
  $(document).ready(function(){
    $(".owl-carousel").owlCarousel({
      loop: false,
      margin: 10,
      nav: true,
      dots: false,
      autoplay: false,
      responsive: {
        0:   { items: 2 },
        600: { items: 2 },
        1000:{ items: 4 }
      }
    });
  });
</script>


<!-- CHECK INTERNET -->
<script>
(function(){
  // ---------- CONFIG ----------
  const PING_URL   = '/health/ping.php'; // <-- change if your ping lives elsewhere
  const FAST_MS    = 3000;               // probe interval when online
  const FASTER_MS  = 2000;               // probe interval when offline
  const TIMEOUT_MS = 3000;               // per-probe timeout

  // ---------- ENSURE UI ELEMENTS EXIST ----------
  function ensureEl(id, html){
    let el = document.getElementById(id);
    if (!el){
      const wrapper = document.createElement('div');
      wrapper.innerHTML = html.trim();
      el = wrapper.firstElementChild;
      document.body.appendChild(el);
    }
    return el;
  }

  const overlay = ensureEl('offlineOverlay', `
    <div id="offlineOverlay" class="offline-overlay" aria-live="polite" aria-hidden="true"
         style="position:fixed;inset:0;display:none;align-items:center;justify-content:center;text-align:center;padding:24px;background:rgba(255,255,255,.96);backdrop-filter:blur(2px);z-index:2147483647;">
      <div class="offline-overlay__card" role="alert"
           style="max-width:340px;width:100%;border:1px solid #eee;border-radius:12px;background:#fff;box-shadow:0 10px 30px rgba(0,0,0,.08);padding:20px;">
        <div class="offline-spinner" aria-hidden="true"
             style="width:28px;height:28px;margin:0 auto 10px;border:3px solid #ddd;border-top-color:#076289;border-radius:50%;animation:spin 1s linear infinite;"></div>
        <div class="offline-overlay__title" style="font-weight:700;margin-bottom:6px;color:#111;">You’re offline</div>
        <p class="offline-overlay__text" style="color:#333;margin:0;">We’ll reconnect automatically. <br/> Actions are disabled for now.</p>
      </div>
    </div>
  `);

  const toast = ensureEl('onlineToast', `
    <div id="onlineToast" class="online-toast"
         style="position:fixed;left:50%;transform:translateX(-50%);bottom:100px;background:#16a34a;color:#fff;font-weight:600;padding:10px 14px;border-radius:999px;box-shadow:0 8px 22px rgba(0,0,0,.15);display:none;z-index:2147483600;">
      Back online
    </div>
  `);

  // Spinner keyframes (once)
  (function addSpin(){
    if (document.getElementById('offlineSpinKeyframes')) return;
    const style = document.createElement('style');
    style.id = 'offlineSpinKeyframes';
    style.textContent = '@keyframes spin{to{transform:rotate(360deg)}}';
    document.head.appendChild(style);
  })();

  // ---------- HELPERS ----------
  function showOverlay(){ overlay.style.display='flex'; overlay.setAttribute('aria-hidden','false'); document.documentElement.classList.add('app-offline'); }
  function hideOverlay(){ overlay.style.display='none'; overlay.setAttribute('aria-hidden','true'); document.documentElement.classList.remove('app-offline'); }
  function showToast(ms=1500){
    toast.style.display='block';
    clearTimeout(showToast._t);
    showToast._t = setTimeout(()=> toast.style.display='none', ms);
  }

  async function probe(url, timeoutMs){
    const ctrl = new AbortController();
    const t = setTimeout(()=> ctrl.abort(), timeoutMs);
    try{
      const res = await fetch(url + (url.includes('?') ? '&' : '?') + '_=' + Date.now(), {
        method: 'GET',           // HEAD can be blocked on some hosts
        cache: 'no-store',
        credentials: 'same-origin',
        signal: ctrl.signal
      });
      return res.ok;            // 200/204 is fine
    }catch(_){ return false; }
    finally{ clearTimeout(t); }
  }

  let lastOnline = null;
  let checking = false;
  let pollId = null;

  function setPoll(ms){
    if (pollId) clearInterval(pollId);
    pollId = setInterval(()=> { if (!document.hidden) evaluate(true); }, ms);
  }

  async function evaluate(immediate=false){
    if (checking) return; checking = true;

    // Trust immediate offline signal if browser provides it
    if (typeof navigator.onLine === 'boolean' && !navigator.onLine){
      goOffline('nav-offline');
      checking = false;
      return;
    }

    // Confirm with network probe
    const ok = await probe(PING_URL, TIMEOUT_MS);

    if (ok){
      goOnline();
    } else {
      goOffline('probe-fail');
    }

    checking = false;
  }

  function goOnline(){
    if (lastOnline === false) showToast();
    hideOverlay();
    lastOnline = true;
    setPoll(FAST_MS);
  }

  function goOffline(_reason){
    showOverlay();
    lastOnline = false;
    setPoll(FASTER_MS);
  }

  // ---------- EVENTS ----------
  window.addEventListener('online',  () => evaluate(true));
  window.addEventListener('offline', () => goOffline('event'));
  document.addEventListener('visibilitychange', () => { if (!document.hidden) evaluate(true); });

  const conn = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
  if (conn && typeof conn.addEventListener === 'function'){
    conn.addEventListener('change', () => evaluate(true));
  }

  // Block chat click while offline
  const chatFab = document.getElementById('chatFab');
  if (chatFab){
    chatFab.addEventListener('click', function(e){
      if (overlay.style.display === 'flex'){
        e.preventDefault();
        this.animate(
          [{ transform:'translateX(0)' }, { transform:'translateX(-4px)' }, { transform:'translateX(4px)' }, { transform:'translateX(0)' }],
          { duration: 250, iterations: 1 }
        );
      }
    });
  }

  // ---------- START ----------
  setPoll(FAST_MS);
  evaluate(true);
})();
</script>

<style>
/* Optional: disable pointer interactions on page when offline via a class */
html.app-offline { pointer-events: none; }
html.app-offline #offlineOverlay { pointer-events: all; } /* allow overlay buttons if you add any */
</style>


</body>
</html>

Выполнить команду


Для локальной разработки. Не используйте в интернете!