🤩 File Manager - Mr.X
PHP:
8.3.33
Server:
Apache
OS:
Linux 5.14.0-611.49.1.el9_7.x86_64
User:
websparkit
Navigate
Upload:
Upload
New File
New Folder
Editing:main.js
/** * ARCHI-TECH Premium JavaScript Features */ document.addEventListener("DOMContentLoaded", () => { // 1. Before/After Image Slider Controller const sliders = document.querySelectorAll('.ba-slider'); sliders.forEach(slider => { const resize = slider.querySelector('.ba-resize'); const handle = slider.querySelector('.ba-handle'); const moveSlider = (clientX) => { const rect = slider.getBoundingClientRect(); const position = clientX - rect.left; let percentage = (position / rect.width) * 100; // Boundary constraints if (percentage < 0) percentage = 0; if (percentage > 100) percentage = 100; resize.style.width = `${percentage}%`; handle.style.left = `${percentage}%`; }; let isSliding = false; slider.addEventListener('mousedown', (e) => { isSliding = true; moveSlider(e.clientX); }); window.addEventListener('mouseup', () => { isSliding = false; }); slider.addEventListener('mousemove', (e) => { if (!isSliding) return; moveSlider(e.clientX); }); // Touch support for mobiles slider.addEventListener('touchstart', (e) => { isSliding = true; moveSlider(e.touches[0].clientX); }); window.addEventListener('touchend', () => { isSliding = false; }); slider.addEventListener('touchmove', (e) => { if (!isSliding) return; moveSlider(e.touches[0].clientX); }); }); // 2. Dynamic Numbers Counter Animation const counters = document.querySelectorAll('.counter-number'); const animateCounters = () => { counters.forEach(counter => { const target = +counter.getAttribute('data-target'); let count = 0; const speed = target / 40; // division increments const updateCount = () => { if (count < target) { count += speed; counter.innerText = Math.ceil(count); setTimeout(updateCount, 30); } else { counter.innerText = target; } }; updateCount(); }); }; // Observer triggers counting once statistics enter viewport const statsSection = document.querySelector('.statistics-section'); if (statsSection && counters.length > 0) { const observer = new IntersectionObserver((entries, obs) => { entries.forEach(entry => { if (entry.isIntersecting) { animateCounters(); obs.unobserve(entry.target); } }); }, { threshold: 0.2 }); observer.observe(statsSection); } // 5. Interactive Sri Lanka Projects Map const initProjectMap = (containerId) => { const container = document.getElementById(containerId); if (!container || typeof L === 'undefined') return; // Sri Lanka Center coordinates const map = L.map(containerId, { scrollWheelZoom: false, zoomControl: true }).setView([7.8731, 80.7718], 7.5); L.tileLayer('https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png', { attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors © <a href="https://carto.com/attributions">CARTO</a>' }).addTo(map); // Custom div-based pin builder using SVGs const getCustomPin = (color) => { return L.divIcon({ className: 'custom-leaflet-pin', html: `<svg width="28" height="28" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z" fill="${color}"/> </svg>`, iconSize: [28, 28], iconAnchor: [14, 28], popupAnchor: [0, -25] }); }; // Static project location tags mapping Completed/In Progress/Future statuses const dataPoints = [ { name: 'Colombo Heights', category: 'Luxury Residential', location: 'Colombo 03', status: 'Completed', color: '#1B263B', lat: 6.9150, lng: 79.8500 }, { name: 'Zen Oasis Gardens', category: 'Landscape Design', location: 'Kandy', status: 'In Progress', color: '#B2BEB5', lat: 7.2906, lng: 80.6337 }, { name: 'The Grand Horizon Villa', category: 'Architecture & Planning', location: 'Galle', status: 'Completed', color: '#1B263B', lat: 6.0535, lng: 80.2210 }, { name: 'Trinco Heights Resort', category: 'Architecture & Design', location: 'Trincomalee', status: 'Future', color: '#555555', lat: 8.5873, lng: 81.2152 }, { name: 'Heritage Conservation Center', category: 'Architecture & Planning', location: 'Anuradhapura', status: 'Completed', color: '#1B263B', lat: 8.3114, lng: 80.4037 }, { name: 'Jaffna Library Annex', category: 'Construction Services', location: 'Jaffna', status: 'Completed', color: '#1B263B', lat: 9.6615, lng: 80.0255 }, { name: 'Badulla Eco-Lodge', category: 'Urban Green Solutions', location: 'Badulla', status: 'Completed', color: '#1B263B', lat: 6.9934, lng: 81.0550 }, { name: 'Tea Estate Luxury Villa', category: 'Interior Design', location: 'Nuwara Eliya', status: 'Completed', color: '#1B263B', lat: 6.9497, lng: 80.7891 }, { name: 'Gemological Trade Center', category: 'Architecture & Planning', location: 'Ratnapura', status: 'Future', color: '#555555', lat: 6.6828, lng: 80.3992 }, { name: 'Maritime Logistics Office', category: 'Construction Services', location: 'Hambantota', status: 'Completed', color: '#1B263B', lat: 6.1248, lng: 81.1185 } ]; // Also add the Studio itself as a distinct glowing pin! dataPoints.push({ name: 'ARCHI-TECH Head Studio', category: 'Main Design Office', location: 'No 35B Wijerama Rd, Nugegoda', status: 'Design Studio', color: '#B2BEB5', // Ash Gray lat: 6.8861, lng: 79.8942, isStudio: true }); dataPoints.forEach(p => { let statusBadge = `<span style="font-size: 0.7rem; font-weight: bold; color: ${p.color === '#B2BEB5' ? '#B2BEB5' : '#FFF'};">Status: ${p.status}</span>`; if (p.isStudio) { statusBadge = `<span class="badge" style="background-color: rgba(178, 190, 181, 0.2); color: var(--accent-color); font-size: 0.7rem; border: 1px solid rgba(178, 190, 181, 0.4);">Headquarters</span>`; } const popupHtml = ` <div style="font-family: 'Syne', sans-serif; min-width: 140px;"> <h6 style="color: var(--accent-color); font-weight: 700; text-transform: uppercase; margin-bottom: 5px; font-size: 0.8rem; letter-spacing: 0.02em;">${p.name}</h6> <p style="margin: 0 0 3px 0; font-size: 0.72rem; color: #B0B0B0;">${p.category}</p> <p style="margin: 0 0 5px 0; font-size: 0.72rem; color: #B0B0B0;"><i class="bi bi-geo-alt-fill text-accent-color me-1" style="font-size: 0.65rem;"></i> ${p.location}</p> ${statusBadge} </div> `; const marker = L.marker([p.lat, p.lng], { icon: getCustomPin(p.color) }) .bindPopup(popupHtml) .addTo(map); if (p.isStudio) { marker.openPopup(); } }); }; initProjectMap('projectMapIndex'); initProjectMap('projectMapContact'); }); /** * 3. Premium Responsive Lightbox Module */ window.openLightbox = function(imageSrc, titleText = '') { let lightboxModal = document.getElementById('customLightboxModal'); if (!lightboxModal) { const modalHtml = ` <div class="modal fade lightbox-modal" id="customLightboxModal" tabindex="-1" aria-hidden="true" style="z-index: 1060;"> <div class="modal-dialog modal-dialog-centered modal-xl"> <div class="modal-content"> <div class="modal-body text-center position-relative"> <button type="button" class="lightbox-close" data-bs-dismiss="modal" aria-label="Close" style="position: absolute; right: 20px; top: -45px; background: none; border: none; font-size: 2.5rem; color: #FFF;">×</button> <img id="lightboxImage" src="" alt="ARCHI-TECH Project Image" style="max-height: 80vh; max-width: 100%; object-fit: contain; border-radius: 4px;"> <h5 id="lightboxTitle" class="mt-3 text-uppercase text-center" style="color: var(--accent-color); font-family: 'Syne', sans-serif;"></h5> </div> </div> </div> </div> `; document.body.insertAdjacentHTML('beforeend', modalHtml); lightboxModal = document.getElementById('customLightboxModal'); } document.getElementById('lightboxImage').src = imageSrc; document.getElementById('lightboxTitle').innerText = titleText; const bsModal = new bootstrap.Modal(lightboxModal); bsModal.show(); }; /** * 4. Animated Grid Category Filtering */ window.filterGrid = function(category) { const items = document.querySelectorAll('.filter-item'); const buttons = document.querySelectorAll('.filter-btn'); buttons.forEach(btn => { if (btn.getAttribute('data-filter') === category) { btn.classList.add('active'); btn.classList.remove('btn-outline-light'); btn.classList.add('btn-gold-filled'); } else { btn.classList.remove('active'); btn.classList.add('btn-outline-light'); btn.classList.remove('btn-gold-filled'); } }); items.forEach(item => { const itemCat = item.getAttribute('data-category'); if (category === 'all' || (itemCat && itemCat.toLowerCase().trim() === category.toLowerCase().trim())) { item.style.display = 'block'; setTimeout(() => { item.style.opacity = '1'; item.style.transform = 'scale(1)'; }, 50); } else { item.style.opacity = '0'; item.style.transform = 'scale(0.8)'; setTimeout(() => { item.style.display = 'none'; }, 300); } }); }; /** * 5. Header Search Suggestions (Live AJAX Autocomplete) */ (function () { const input = document.getElementById('header-search-input'); const dropdown = document.getElementById('header-search-suggestions'); const form = document.getElementById('header-search-form'); if (!input || !dropdown || !form) return; let debounceTimer = null; let activeIndex = -1; let currentResults = []; function escapeHtml(s) { return s.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'); } function escapeRegex(s) { return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); } function highlight(text, query) { if (!query) return escapeHtml(text); const re = new RegExp('(' + escapeRegex(query) + ')', 'gi'); return escapeHtml(text).replace(re, '<mark style="background:rgba(178,190,181,0.25);color:#fff;border-radius:2px;padding:0 1px;">$1</mark>'); } function showSuggestions() { dropdown.classList.add('active'); } function hideSuggestions() { dropdown.classList.remove('active'); dropdown.innerHTML = ''; activeIndex = -1; currentResults = []; } function setActiveItem(index) { const items = dropdown.querySelectorAll('.search-suggestion-item'); items.forEach(el => el.classList.remove('keyboard-active')); if (index >= 0 && index < items.length) { items[index].classList.add('keyboard-active'); items[index].scrollIntoView({ block: 'nearest' }); } activeIndex = index; } function renderSuggestions(results, query) { dropdown.innerHTML = ''; activeIndex = -1; currentResults = results; if (!results.length) { hideSuggestions(); return; } results.forEach(item => { const li = document.createElement('li'); li.setAttribute('role', 'option'); const a = document.createElement('a'); a.className = 'search-suggestion-item'; // Build URL relative to current host const base = window.location.pathname.replace(/\/[^/]+\.php.*$/, '/'); a.href = base + 'projects.php?search=' + encodeURIComponent(item.name); const nameEl = document.createElement('span'); nameEl.className = 'suggest-name'; nameEl.innerHTML = highlight(item.name, query); const metaEl = document.createElement('span'); metaEl.className = 'suggest-meta'; const catEl = document.createElement('span'); catEl.className = 'suggest-category'; catEl.textContent = item.category; metaEl.appendChild(catEl); if (item.location) { const locEl = document.createElement('span'); locEl.className = 'suggest-location'; locEl.textContent = item.location; metaEl.appendChild(locEl); } a.appendChild(nameEl); a.appendChild(metaEl); li.appendChild(a); dropdown.appendChild(li); }); const footer = document.createElement('div'); footer.className = 'search-suggestions-footer'; footer.textContent = 'Press Enter to see all results'; footer.addEventListener('click', () => form.submit()); dropdown.appendChild(footer); showSuggestions(); } function fetchSuggestions(query) { const base = window.location.pathname.replace(/\/[^/]+\.php.*$/, '/'); fetch(base + 'search-suggestions.php?q=' + encodeURIComponent(query)) .then(res => res.json()) .then(data => { if (input.value.trim() === query) renderSuggestions(data, query); }) .catch(() => hideSuggestions()); } input.addEventListener('input', () => { clearTimeout(debounceTimer); const q = input.value.trim(); if (q.length < 2) { hideSuggestions(); return; } debounceTimer = setTimeout(() => fetchSuggestions(q), 220); }); input.addEventListener('keydown', e => { if (!dropdown.classList.contains('active')) return; const items = dropdown.querySelectorAll('.search-suggestion-item'); if (e.key === 'ArrowDown') { e.preventDefault(); setActiveItem(Math.min(activeIndex + 1, items.length - 1)); } else if (e.key === 'ArrowUp') { e.preventDefault(); setActiveItem(Math.max(activeIndex - 1, -1)); } else if (e.key === 'Enter' && activeIndex >= 0 && items[activeIndex]) { e.preventDefault(); items[activeIndex].click(); } else if (e.key === 'Escape') { hideSuggestions(); input.blur(); } }); input.addEventListener('focus', () => { const q = input.value.trim(); if (q.length >= 2 && currentResults.length > 0) renderSuggestions(currentResults, q); }); document.addEventListener('click', e => { if (!form.contains(e.target)) hideSuggestions(); }); })();
Save Changes
Cancel
Create New File
Create New Folder