Uname:Linux server17213-10344.hostycare.online 5.14.0-687.38.1.el9_8.x86_64 #1 SMP PREEMPT_DYNAMIC Wed Aug 12 17:19:12 EDT 2026 x86_64

403WebShell
403Webshell
Server IP : 103.243.232.44  /  Your IP : 216.73.216.237
Web Server : LiteSpeed
System : Linux server17213-10344.hostycare.online 5.14.0-687.38.1.el9_8.x86_64 #1 SMP PREEMPT_DYNAMIC Wed Aug 12 17:19:12 EDT 2026 x86_64
User : iamakash ( 1400)
PHP Version : 8.1.34
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : OFF  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /home/iamakash/public_html/ftnconsortium.com/js/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /home/iamakash/public_html/ftnconsortium.com/js/main.js
// ============================================================
// FTN Consortium — main.js
// ============================================================

// ---- Mobile menu ----
const hamburger  = document.getElementById('hamburger');
const mobileMenu = document.getElementById('mobileMenu');
if (hamburger && mobileMenu) {
  hamburger.addEventListener('click', () => mobileMenu.classList.toggle('open'));
  document.addEventListener('click', e => {
    if (!hamburger.contains(e.target) && !mobileMenu.contains(e.target))
      mobileMenu.classList.remove('open');
  });
}

// ---- Navbar shadow on scroll ----
const navbar = document.getElementById('navbar');
window.addEventListener('scroll', () => {
  if (navbar) navbar.style.boxShadow = window.scrollY > 20 ? '0 2px 20px rgba(0,0,0,0.3)' : 'none';
}, { passive: true });

// ---- Scroll-to-top button ----
const scrollTopBtn = document.getElementById('scrollTop');
if (scrollTopBtn) {
  window.addEventListener('scroll', () => scrollTopBtn.classList.toggle('visible', window.scrollY > 400), { passive: true });
  scrollTopBtn.addEventListener('click', () => window.scrollTo({ top: 0, behavior: 'smooth' }));
}

// ---- Fade-in on scroll ----
const fadeEls = document.querySelectorAll('.fade-in');
if (fadeEls.length) {
  const observer = new IntersectionObserver((entries) => {
    entries.forEach((entry, i) => {
      if (entry.isIntersecting) {
        setTimeout(() => entry.target.classList.add('visible'), i * 90);
        observer.unobserve(entry.target);
      }
    });
  }, { threshold: 0.1 });
  fadeEls.forEach(el => observer.observe(el));
}

// ---- Portfolio filter ----
const filterBtns    = document.querySelectorAll('.filter-btn');
const portfolioCards = document.querySelectorAll('.portfolio-card[data-category]');
filterBtns.forEach(btn => {
  btn.addEventListener('click', () => {
    filterBtns.forEach(b => b.classList.remove('active'));
    btn.classList.add('active');
    const f = btn.dataset.filter;
    portfolioCards.forEach(card => {
      card.style.display = (f === 'all' || card.dataset.category === f) ? 'block' : 'none';
    });
  });
});

// ---- Smooth scroll for anchor links ----
document.querySelectorAll('a[href^="#"]').forEach(link => {
  link.addEventListener('click', e => {
    const target = document.querySelector(link.getAttribute('href'));
    if (target) {
      e.preventDefault();
      window.scrollTo({ top: target.offsetTop - 80, behavior: 'smooth' });
    }
  });
});

// ---- Animate stat numbers ----
function animateCount(el, target, duration) {
  const isSpecial = isNaN(parseInt(target));
  if (isSpecial) return;
  const suffix = target.replace(/[0-9]/g, '');
  const num    = parseInt(target);
  let startTime = null;
  const step = (ts) => {
    if (!startTime) startTime = ts;
    const progress = Math.min((ts - startTime) / duration, 1);
    const ease = 1 - Math.pow(1 - progress, 3);
    el.textContent = Math.floor(ease * num) + suffix;
    if (progress < 1) requestAnimationFrame(step);
    else el.textContent = target;
  };
  requestAnimationFrame(step);
}
const statNums = document.querySelectorAll('.stat-box .number, .hero-stat .number');
const statObs  = new IntersectionObserver(entries => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      animateCount(entry.target, entry.target.textContent.trim(), 1400);
      statObs.unobserve(entry.target);
    }
  });
}, { threshold: 0.6 });
statNums.forEach(el => statObs.observe(el));

// ---- Hero Slider ----
const heroSection    = document.getElementById('heroSection');
const slides         = document.querySelectorAll('.hslide');
const dots           = document.querySelectorAll('.sdot');
const prevBtn        = document.getElementById('sliderPrev');
const nextBtn        = document.getElementById('sliderNext');
const progressFill   = document.getElementById('sliderProgress');
const SLIDE_DURATION = 5500;

if (slides.length > 1) {
  let current = 0;
  let autoTimer = null;
  let paused = false;

  function startProgress() {
    if (!progressFill) return;
    progressFill.style.transition = 'none';
    progressFill.style.width = '0%';
    requestAnimationFrame(() => requestAnimationFrame(() => {
      progressFill.style.transition = `width ${SLIDE_DURATION}ms linear`;
      progressFill.style.width = '100%';
    }));
  }

  function goTo(n) {
    const prev = current;
    current = ((n % slides.length) + slides.length) % slides.length;
    if (prev === current) return;

    slides[prev].classList.add('leaving');
    slides[prev].classList.remove('active');
    dots[prev].classList.remove('active');

    setTimeout(() => slides[prev].classList.remove('leaving'), 900);

    slides[current].classList.add('active');
    dots[current].classList.add('active');

    startProgress();
  }

  function startAuto() {
    clearInterval(autoTimer);
    autoTimer = setInterval(() => { if (!paused) goTo(current + 1); }, SLIDE_DURATION);
  }

  // Controls
  if (prevBtn) prevBtn.addEventListener('click', () => { goTo(current - 1); startAuto(); });
  if (nextBtn) nextBtn.addEventListener('click', () => { goTo(current + 1); startAuto(); });
  dots.forEach((dot, i) => dot.addEventListener('click', () => { goTo(i); startAuto(); }));

  // Pause on hover
  if (heroSection) {
    heroSection.addEventListener('mouseenter', () => { paused = true; });
    heroSection.addEventListener('mouseleave', () => { paused = false; });
  }

  // Touch / swipe support
  let touchStartX = 0;
  if (heroSection) {
    heroSection.addEventListener('touchstart', e => { touchStartX = e.touches[0].clientX; }, { passive: true });
    heroSection.addEventListener('touchend', e => {
      const diff = touchStartX - e.changedTouches[0].clientX;
      if (Math.abs(diff) > 50) { goTo(diff > 0 ? current + 1 : current - 1); startAuto(); }
    }, { passive: true });
  }

  startProgress();
  startAuto();
}

// ---- Contact Form — AJAX + CAPTCHA ----
const contactForm = document.getElementById('contactForm');
if (contactForm) {
  const submitBtn    = document.getElementById('submitBtn');
  const formAlert    = document.getElementById('formAlert');
  const captchaQ     = document.getElementById('captchaQuestion');
  const captchaInput = document.getElementById('captcha');

  // Resolve absolute URL to contact.php regardless of current path
  const contactUrl = (function () {
    const a = document.createElement('a');
    a.href = 'contact.php';
    return a.href;
  })();

  function showAlert(msg, type) {
    if (!formAlert) return;
    formAlert.innerHTML = `<div class="alert alert-${type}" role="alert">${type === 'success' ? '✅' : '❌'} ${msg}</div>`;
    formAlert.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
  }

  function clearAlert() {
    if (formAlert) formAlert.innerHTML = '';
  }

  function refreshCaptcha(question) {
    if (captchaQ && question) captchaQ.textContent = question;
    if (captchaInput) captchaInput.value = '';
  }

  contactForm.addEventListener('submit', async (e) => {
    e.preventDefault();
    clearAlert();

    // Client-side required field check
    const fields = [
      { name: 'name',    label: 'Full Name' },
      { name: 'email',   label: 'Email Address' },
      { name: 'service', label: 'Service' },
      { name: 'message', label: 'Project Details' },
      { name: 'captcha', label: 'Security Answer' },
    ];
    for (const f of fields) {
      const el = contactForm.elements[f.name];
      if (!el || !el.value.trim()) {
        showAlert(`Please fill in: ${f.label}.`, 'error');
        el?.focus();
        return;
      }
    }

    // Disable button while sending
    submitBtn.disabled    = true;
    submitBtn.textContent = 'Sending…';

    try {
      const res = await fetch(contactUrl, {
        method:  'POST',
        headers: { 'X-Requested-With': 'XMLHttpRequest' },
        body:    new FormData(contactForm),
      });

      // Try to parse JSON; fall back gracefully if server returned HTML (PHP error)
      let data;
      const raw = await res.text();
      try {
        data = JSON.parse(raw);
      } catch (_) {
        throw new Error('Unexpected server response.');
      }

      showAlert(data.message, data.success ? 'success' : 'error');

      if (data.success) {
        contactForm.reset();
      }

      // Always refresh captcha after any submission attempt
      if (data.new_captcha) {
        refreshCaptcha(data.new_captcha);
      } else {
        fetch(contactUrl + '?refresh_captcha=1')
          .then(r => r.json())
          .then(d => { if (d.question) refreshCaptcha(d.question); })
          .catch(() => {});
      }

    } catch (err) {
      showAlert('Something went wrong. Please try again or email us at <a href="mailto:ftn-support@ftnconsortium.com">ftn-support@ftnconsortium.com</a>.', 'error');
    } finally {
      submitBtn.disabled    = false;
      submitBtn.textContent = 'Send Message →';
    }
  });
}

Youez - 2016 - github.com/yon3zu
LinuXploit