570 lines
17 KiB
JavaScript

document.addEventListener("DOMContentLoaded", function () {
const sections = document.querySelectorAll(".section");
const navLinks = document.querySelectorAll(".fbs__net-navbar .scroll-link");
function removeActiveClasses() {
if (navLinks) {
navLinks.forEach((link) => link.classList.remove("active"));
}
}
function addActiveClass(currentSectionId) {
const activeLink = document.querySelector(
`.fbs__net-navbar .scroll-link[href="#${currentSectionId}"]`
);
if (activeLink) {
activeLink.classList.add("active");
}
}
function openNewPatient(){
document.getElementById('modal-new').showModal();
}
function exportCSV(){
const rows = [['Paciente','CPF','Idade','Status']];
document.querySelectorAll('#patients tbody tr').forEach(tr=>{
const tds = [...tr.querySelectorAll('td')].map(td=>td.innerText.replace(/\n.*/,'').trim());
rows.push([tds[0],tds[1],tds[2],tds[3]]);
});
const csv = rows.map(r=>r.map(s=>`"${s.replaceAll('"','""')}"`).join(',')).join('\n');
const blob = new Blob([csv], {type:'text/csv;charset=utf-8;'});
const url = URL.createObjectURL(blob);
const a = Object.assign(document.createElement('a'), {href:url, download:'pacientes.csv'});
document.body.appendChild(a); a.click(); a.remove();
setTimeout(()=>URL.revokeObjectURL(url), 1000);
}
function filterTable(q){
q = (q||'').toLowerCase();
document.querySelectorAll('#patients tbody tr').forEach(tr => {
const text = tr.innerText.toLowerCase();
tr.style.display = text.includes(q) ? '' : 'none';
});
}
function getCurrentSection() {
let currentSection = null;
let minDistance = Infinity;
if (sections) {
sections.forEach((section) => {
const rect = section.getBoundingClientRect();
const distance = Math.abs(rect.top - window.innerHeight / 4);
if (distance < minDistance && rect.top < window.innerHeight) {
minDistance = distance;
currentSection = section.getAttribute("id");
}
});
}
return currentSection;
}
function updateActiveLink() {
const currentSectionId = getCurrentSection();
if (currentSectionId) {
removeActiveClasses();
addActiveClass(currentSectionId);
}
}
window.addEventListener("scroll", updateActiveLink);
const portfolioGrid = document.querySelector('#portfolio-grid');
if (portfolioGrid) {
var iso = new Isotope("#portfolio-grid", {
itemSelector: ".portfolio-item",
layoutMode: "masonry",
});
if (iso) {
iso.on("layoutComplete", updateActiveLink);
imagesLoaded("#portfolio-grid", function () {
iso.layout();
updateActiveLink();
});
}
var filterButtons = document.querySelectorAll(".filter-button");
if (filterButtons) {
filterButtons.forEach(function (button) {
button.addEventListener("click", function (e) {
e.preventDefault();
var filterValue = button.getAttribute("data-filter");
iso.arrange({ filter: filterValue });
filterButtons.forEach(function (btn) {
btn.classList.remove("active");
});
button.classList.add("active");
updateActiveLink();
});
});
}
updateActiveLink();
}
});
const navbarScrollInit = () => {
var navbar = document.querySelector(".fbs__net-navbar");
var scrollTop = window.pageYOffset || document.documentElement.scrollTop;
if (navbar) {
if (scrollTop > 0) {
navbar.classList.add("active");
} else {
navbar.classList.remove("active");
}
}
};
const navbarInit = () => {
document.querySelectorAll('.dropdown-toggle[href="#"]').forEach(function (el, index) {
el.addEventListener("click", function (event) {
event.stopPropagation();
});
});
};
// ======= Marquee =======
const logoMarqueeInit = () => {
const wrapper = document.querySelector(".logo-wrapper");
const boxes = gsap.utils.toArray(".logo-item");
if (boxes.length > 0) {
const loop = horizontalLoop(boxes, {
paused: false,
repeat: -1,
speed: 0.25,
reversed: false,
});
function horizontalLoop(items, config) {
items = gsap.utils.toArray(items);
config = config || {};
let tl = gsap.timeline({
repeat: config.repeat,
paused: config.paused,
defaults: { ease: "none" },
onReverseComplete: () =>
tl.totalTime(tl.rawTime() + tl.duration() * 100),
}),
length = items.length,
startX = items[0].offsetLeft,
times = [],
widths = [],
xPercents = [],
curIndex = 0,
pixelsPerSecond = (config.speed || 1) * 100,
snap =
config.snap === false ? (v) => v : gsap.utils.snap(config.snap || 1), // some browsers shift by a pixel to accommodate flex layouts, so for example if width is 20% the first element's width might be 242px, and the next 243px, alternating back and forth. So we snap to 5 percentage points to make things look more natural
totalWidth,
curX,
distanceToStart,
distanceToLoop,
item,
i;
gsap.set(items, {
// convert "x" to "xPercent" to make things responsive, and populate the widths/xPercents Arrays to make lookups faster.
xPercent: (i, el) => {
let w = (widths[i] = parseFloat(gsap.getProperty(el, "width", "px")));
xPercents[i] = snap(
(parseFloat(gsap.getProperty(el, "x", "px")) / w) * 100 +
gsap.getProperty(el, "xPercent")
);
return xPercents[i];
},
});
gsap.set(items, { x: 0 });
totalWidth =
items[length - 1].offsetLeft +
(xPercents[length - 1] / 100) * widths[length - 1] -
startX +
items[length - 1].offsetWidth *
gsap.getProperty(items[length - 1], "scaleX") +
(parseFloat(config.paddingRight) || 0);
for (i = 0; i < length; i++) {
item = items[i];
curX = (xPercents[i] / 100) * widths[i];
distanceToStart = item.offsetLeft + curX - startX;
distanceToLoop =
distanceToStart + widths[i] * gsap.getProperty(item, "scaleX");
tl.to(
item,
{
xPercent: snap(((curX - distanceToLoop) / widths[i]) * 100),
duration: distanceToLoop / pixelsPerSecond,
},
0
)
.fromTo(
item,
{
xPercent: snap(
((curX - distanceToLoop + totalWidth) / widths[i]) * 100
),
},
{
xPercent: xPercents[i],
duration:
(curX - distanceToLoop + totalWidth - curX) / pixelsPerSecond,
immediateRender: false,
},
distanceToLoop / pixelsPerSecond
)
.add("label" + i, distanceToStart / pixelsPerSecond);
times[i] = distanceToStart / pixelsPerSecond;
}
function toIndex(index, vars) {
vars = vars || {};
Math.abs(index - curIndex) > length / 2 &&
(index += index > curIndex ? -length : length); // always go in the shortest direction
let newIndex = gsap.utils.wrap(0, length, index),
time = times[newIndex];
if (time > tl.time() !== index > curIndex) {
// if we're wrapping the timeline's playhead, make the proper adjustments
vars.modifiers = { time: gsap.utils.wrap(0, tl.duration()) };
time += tl.duration() * (index > curIndex ? 1 : -1);
}
curIndex = newIndex;
vars.overwrite = true;
return tl.tweenTo(time, vars);
}
tl.next = (vars) => toIndex(curIndex + 1, vars);
tl.previous = (vars) => toIndex(curIndex - 1, vars);
tl.current = () => curIndex;
tl.toIndex = (index, vars) => toIndex(index, vars);
tl.times = times;
tl.progress(1, true).progress(0, true); // pre-render for performance
if (config.reversed) {
tl.vars.onReverseComplete();
tl.reverse();
}
return tl;
}
}
};
document.addEventListener("DOMContentLoaded", logoMarqueeInit);
// ======= Navbar Scroll =======
document.addEventListener("DOMContentLoaded", function () {
logoMarqueeInit();
navbarInit();
window.addEventListener("scroll", navbarScrollInit);
});
// ======= Swiper =======
const swiperInit = () => {
var swiper = new Swiper(".testimonialSwiper", {
slidesPerView: 1,
speed: 700,
spaceBetween: 30,
loop: true,
pagination: {
el: ".swiper-pagination",
clickable: true,
},
breakpoints: {
640: {
slidesPerView: 1.5,
spaceBetween: 20,
},
768: {
slidesPerView: 2.5,
spaceBetween: 30,
},
1024: {
slidesPerView: 2.5,
spaceBetween: 30,
},
},
navigation: {
nextEl: ".custom-button-next",
prevEl: ".custom-button-prev",
},
});
const progressCircle = document.querySelector(".autoplay-progress svg");
const progressContent = document.querySelector(".autoplay-progress span");
if (progressCircle && progressContent ) {
var swiper2 = new Swiper(".sliderSwiper", {
slidesPerView: 1,
speed: 700,
spaceBetween: 0,
loop: true,
centeredSlides: true,
autoplay: {
delay: 7000,
disableOnInteraction: false
},
pagination: {
el: ".swiper-pagination",
clickable: true,
},
navigation: {
nextEl: ".custom-button-next",
prevEl: ".custom-button-prev",
},
on: {
autoplayTimeLeft(s, time, progress) {
progressCircle.style.setProperty("--progress", 1 - progress);
progressContent.textContent = `${Math.ceil(time / 1000)}s`;
}
}
});
}
};
document.addEventListener("DOMContentLoaded", swiperInit);
// ======= Glightbox =======
const glightBoxInit = () => {
const lightbox = GLightbox({
touchNavigation: true,
loop: true,
autoplayVideos: true,
});
};
document.addEventListener("DOMContentLoaded", glightBoxInit);
// ======= BS OffCanvass =======
const bsOffCanvasInit = () => {
var offcanvasElement = document.getElementById("fbs__net-navbars");
if (offcanvasElement) {
offcanvasElement.addEventListener("show.bs.offcanvas", function () {
document.body.classList.add("offcanvas-active");
});
offcanvasElement.addEventListener("hidden.bs.offcanvas", function () {
document.body.classList.remove("offcanvas-active");
});
}
};
document.addEventListener("DOMContentLoaded", bsOffCanvasInit);
// ======= Back To Top =======
const backToTopInit = () => {
const backToTopButton = document.getElementById("back-to-top");
if (backToTopButton) {
window.addEventListener("scroll", () => {
if (window.scrollY > 170) {
backToTopButton.classList.add("show");
} else {
backToTopButton.classList.remove("show");
}
});
backToTopButton.addEventListener("click", () => {
window.scrollTo({
top: 0,
behavior: "smooth",
});
});
}
};
document.addEventListener("DOMContentLoaded", backToTopInit);
// ======= Inline SVG =======
const inlineSvgInit = () => {
const imgElements = document.querySelectorAll(".js-img-to-inline-svg");
if (imgElements) {
imgElements.forEach((imgElement) => {
const imgURL = imgElement.getAttribute("src");
fetch(imgURL)
.then((response) => response.text())
.then((svgText) => {
const parser = new DOMParser();
const svgDocument = parser.parseFromString(svgText, "image/svg+xml");
const svgElement = svgDocument.documentElement;
Array.from(imgElement.attributes).forEach((attr) => {
if (attr.name !== "class") {
svgElement.setAttribute(attr.name, attr.value);
} else {
const classes = attr.value
.split(" ")
.filter((className) => className !== "js-img-to-inline-svg");
if (classes.length > 0) {
svgElement.setAttribute("class", classes.join(" "));
}
}
});
imgElement.replaceWith(svgElement);
})
.catch((error) => console.error("Error fetching SVG:", error));
});
}
};
document.addEventListener("DOMContentLoaded", inlineSvgInit);
// ======= AOS =======
const aosInit = () => {
AOS.init({
duration: 800,
easing: 'slide',
once: true
});
}
document.addEventListener("DOMContentLoaded", aosInit);
// ======= PureCounter =======
const pureCounterInit = () => {
new PureCounter({
selector: ".purecounter",
});
}
document.addEventListener("DOMContentLoaded", pureCounterInit);
// ======= Disable Click Navbar Dropdown =======
const addHoverEvents = (dropdown) => {
const dropdownToggle = dropdown.querySelector('.dropdown-toggle');
const preventClick = (event) => event.preventDefault();
const showDropdown = () => {
dropdown.classList.add('show');
dropdownToggle.setAttribute('aria-expanded', 'true');
const dropdownMenu = dropdown.querySelector('.dropdown-menu');
dropdownMenu.classList.add('show');
};
const hideDropdown = () => {
dropdown.classList.remove('show');
dropdownToggle.setAttribute('aria-expanded', 'false');
const dropdownMenu = dropdown.querySelector('.dropdown-menu');
dropdownMenu.classList.remove('show');
};
// Disable the click event for toggling the dropdown
dropdownToggle.addEventListener('click', preventClick);
// Open dropdown on hover
dropdown.addEventListener('mouseover', showDropdown);
// Close dropdown when mouse leaves
dropdown.addEventListener('mouseleave', hideDropdown);
// Store references to the event listeners for later removal
dropdown.__events = { preventClick, showDropdown, hideDropdown };
};
const removeHoverEvents = (dropdown) => {
const dropdownToggle = dropdown.querySelector('.dropdown-toggle');
const { preventClick, showDropdown, hideDropdown } = dropdown.__events || {};
if (preventClick) {
// Remove the event listeners
dropdownToggle.removeEventListener('click', preventClick);
dropdown.removeEventListener('mouseover', showDropdown);
dropdown.removeEventListener('mouseleave', hideDropdown);
// Remove the reference to the stored events
delete dropdown.__events;
}
};
const handleNavbarEvents = () => {
const dropdowns = document.querySelectorAll('.navbar .dropdown');
const dropstarts = document.querySelectorAll('.navbar .dropstart');
const dropends = document.querySelectorAll('.navbar .dropend');
if (window.innerWidth >= 992) {
// Add hover events to dropdowns
dropdowns.forEach(addHoverEvents);
dropstarts.forEach(addHoverEvents);
dropends.forEach(addHoverEvents);
} else {
// Remove hover events from dropdowns
dropdowns.forEach(removeHoverEvents);
dropstarts.forEach(removeHoverEvents);
dropends.forEach(removeHoverEvents);
}
};
// Function to handle resizing
const handleResize = () => {
const dropdowns = document.querySelectorAll('.navbar .dropdown');
const dropstarts = document.querySelectorAll('.navbar .dropstart');
const dropends = document.querySelectorAll('.navbar .dropend');
// Remove hover events before rechecking window size
dropdowns.forEach(removeHoverEvents);
dropstarts.forEach(removeHoverEvents);
dropends.forEach(removeHoverEvents);
// Re-apply hover events based on window size
handleNavbarEvents();
};
// Call the function on resize event and initially
window.addEventListener('resize', handleResize);
handleNavbarEvents();
// ======= Coming Soon Countdown =======
const countdownInit = () => {
// Get the current year
const currentYear = new Date().getFullYear();
const nextYear = currentYear + 1;
const launchDate = new Date(`December 31, ${nextYear} 23:59:59`).getTime();
// Change this "December 31, 2024 23:59:59" to your your website launch date
// const launchDate = new Date("December 31, 2024 23:59:59").getTime();
const x = setInterval(function () {
const now = new Date().getTime();
const distance = launchDate - now;
const days = Math.floor(distance / (1000 * 60 * 60 * 24));
const hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
const seconds = Math.floor((distance % (1000 * 60)) / 1000);
// Output the result in an element with id
const daysEl = document.getElementById("days");
const hoursEl = document.getElementById("hours");
const minutesEl = document.getElementById("minutes");
const secondsEl = document.getElementById("seconds");
if (daysEl) {
daysEl.innerText = days;
}
if (hoursEl) {
hoursEl.innerText = hours;
}
if (minutesEl) {
minutesEl.innerText = minutes;
}
if (secondsEl) {
secondsEl.innerText = seconds;
}
// If the count down is finished, write some text
if (distance < 0) {
clearInterval(x);
document.querySelector(".countdown").innerText = "Launched!";
}
}, 1000);
};
document.addEventListener('DOMContentLoaded', countdownInit);
window.openNewPatient = openNewPatient;
window.exportCSV = exportCSV;
window.filterTable = filterTable;