440 lines
18 KiB
JavaScript
440 lines
18 KiB
JavaScript
var si = 0,
|
|
slides = document.querySelectorAll(".hero-slide"),
|
|
dots = document.querySelectorAll(".carousel-dot"),
|
|
t,
|
|
dir = 1,
|
|
autoStop = false,
|
|
autoInterval = 7000;
|
|
|
|
function show(i, direction) {
|
|
if (direction === undefined) return;
|
|
var current = slides[si];
|
|
var next = slides[i];
|
|
if (direction === 1) {
|
|
current.style.transform = "translateY(100%)";
|
|
current.style.opacity = "0";
|
|
current.style.zIndex = "1";
|
|
next.style.transform = "translateY(-100%)";
|
|
next.style.opacity = "0";
|
|
next.style.zIndex = "1";
|
|
requestAnimationFrame(function () {
|
|
next.style.transition =
|
|
"transform 0.5s ease, opacity 0.5s ease";
|
|
next.style.transform = "translateY(0)";
|
|
next.style.opacity = "1";
|
|
next.style.zIndex = "2";
|
|
});
|
|
} else {
|
|
current.style.transform = "translateY(-100%)";
|
|
current.style.opacity = "0";
|
|
current.style.zIndex = "1";
|
|
next.style.transform = "translateY(100%)";
|
|
next.style.opacity = "0";
|
|
next.style.zIndex = "1";
|
|
requestAnimationFrame(function () {
|
|
next.style.transition =
|
|
"transform 0.5s ease, opacity 0.5s ease";
|
|
next.style.transform = "translateY(0)";
|
|
next.style.opacity = "1";
|
|
next.style.zIndex = "2";
|
|
});
|
|
}
|
|
for (var j = 0; j < dots.length; j++) {
|
|
if (j === i) {
|
|
dots[j].classList.add("active");
|
|
} else {
|
|
dots[j].classList.remove("active");
|
|
}
|
|
}
|
|
si = i;
|
|
}
|
|
function nextSlide() {
|
|
show((si + 1) % slides.length, 1);
|
|
resetTimer();
|
|
}
|
|
function prevSlide() {
|
|
show((si - 1 + slides.length) % slides.length, -1);
|
|
resetTimer();
|
|
}
|
|
function goSlide(i) {
|
|
autoStop = true;
|
|
show(i, i > si ? 1 : -1);
|
|
clearInterval(t);
|
|
t = null;
|
|
}
|
|
function resetTimer() {
|
|
clearInterval(t);
|
|
t = setInterval(nextSlide, autoInterval);
|
|
}
|
|
|
|
window.addEventListener("load", function () {
|
|
var o = document.getElementById("spinner");
|
|
o.classList.add("hidden");
|
|
setTimeout(function () {
|
|
o.style.display = "none";
|
|
}, 500);
|
|
});
|
|
setTimeout(function () {
|
|
var o = document.getElementById("spinner");
|
|
o.classList.add("hidden");
|
|
setTimeout(function () {
|
|
o.style.display = "none";
|
|
}, 500);
|
|
}, 3000);
|
|
t = setInterval(nextSlide, autoInterval);
|
|
|
|
for (var s = 0; s < slides.length; s++) {
|
|
slides[s].addEventListener("click", function () {
|
|
autoStop = true;
|
|
clearInterval(t);
|
|
t = null;
|
|
});
|
|
}
|
|
|
|
document.querySelectorAll(".tab-btn").forEach(function (b) {
|
|
b.addEventListener("click", function () {
|
|
document.querySelectorAll(".tab-btn").forEach(function (x) {
|
|
x.classList.remove("active");
|
|
});
|
|
document
|
|
.querySelectorAll(".tab-pane")
|
|
.forEach(function (p) {
|
|
p.classList.remove("active");
|
|
});
|
|
this.classList.add("active");
|
|
document
|
|
.getElementById(this.getAttribute("data-t"))
|
|
.classList.add("active");
|
|
});
|
|
});
|
|
|
|
/* ---- Order Widget ---- */
|
|
var orderPopupShown = false;
|
|
function openOrderWidget(
|
|
plan,
|
|
monthlyPrice,
|
|
yearlyPrice,
|
|
isEmpire,
|
|
) {
|
|
document.getElementById("orderPanelBuy").style.display =
|
|
"block";
|
|
var widget = document.getElementById("orderWidgetOverlay");
|
|
document.getElementById("orderPlanTitle").textContent = plan;
|
|
var yearly = yearlyMode;
|
|
var price = yearly ? yearlyPrice : monthlyPrice;
|
|
var amountEl = document.getElementById("orderPlanPrice");
|
|
var prefix = isEmpire ? ">$" : "$";
|
|
amountEl.textContent = prefix + " " + price.toFixed(2);
|
|
document.getElementById("orderPlanPeriod").textContent = yearly
|
|
? "/ year"
|
|
: "/ month";
|
|
var couponMsg = document.getElementById("orderCouponMsg");
|
|
var yearlySave = document.getElementById("orderYearlySave");
|
|
if (!yearly) {
|
|
couponMsg.style.display = "block";
|
|
yearlySave.style.display = "none";
|
|
} else {
|
|
couponMsg.style.display = "none";
|
|
yearlySave.style.display = "block";
|
|
var saved = Math.round(
|
|
(1 - yearlyPrice / (monthlyPrice * 12)) * 100,
|
|
);
|
|
document.getElementById("orderSavePercent").textContent =
|
|
saved;
|
|
}
|
|
var buyBtn = document.getElementById("orderBuyBtn");
|
|
var loc = document.getElementById("orderServerLocation").value;
|
|
buyBtn.href =
|
|
"/3/" +
|
|
price.toFixed(2) +
|
|
"/4/" +
|
|
encodeURIComponent(plan) +
|
|
"?location=" +
|
|
encodeURIComponent(loc);
|
|
widget.style.display = "flex";
|
|
orderPopupShown = true;
|
|
}
|
|
function closeOrderWidget() {
|
|
document.getElementById("orderWidgetOverlay").style.display =
|
|
"none";
|
|
}
|
|
document
|
|
.getElementById("orderServerLocation")
|
|
.addEventListener("change", function () {
|
|
var plan =
|
|
document.getElementById("orderPlanTitle").textContent;
|
|
var priceText = document
|
|
.getElementById("orderPlanPrice")
|
|
.textContent.replace(">$", "")
|
|
.replace("$", "")
|
|
.trim();
|
|
var price = parseFloat(priceText);
|
|
var loc = this.value;
|
|
document.getElementById("orderBuyBtn").href =
|
|
"/3/" +
|
|
price.toFixed(2) +
|
|
"/4/" +
|
|
encodeURIComponent(plan) +
|
|
"?location=" +
|
|
encodeURIComponent(loc);
|
|
});
|
|
function applyCoupon() {
|
|
var input = document.getElementById("orderCouponInput");
|
|
var status = document.getElementById("orderCouponStatus");
|
|
var code = input.value.trim();
|
|
if (code.toLowerCase() === "free trial") {
|
|
status.textContent =
|
|
"\u2713 Coupon FREE TRIAL applied - 1 month free";
|
|
status.style.color = "#28a745";
|
|
} else {
|
|
status.textContent = "Invalid coupon code";
|
|
status.style.color = "#dc3545";
|
|
}
|
|
status.style.display = "block";
|
|
}
|
|
/* ---- Billing Toggle ---- */
|
|
var yearlyMode = false;
|
|
var biSwitch = document.getElementById("billingSwitch");
|
|
var labels = document.querySelectorAll(".toggle-label");
|
|
var monthlyLabel = document.querySelector(".toggle-label-monthly");
|
|
var yearlyLabel = document.querySelector(".toggle-label-yearly");
|
|
|
|
function updatePrices(yearly) {
|
|
var amounts = document.querySelectorAll(".price-amount");
|
|
for (var k = 0; k < amounts.length; k++) {
|
|
var el = amounts[k];
|
|
var val = yearly
|
|
? el.getAttribute("data-yearly")
|
|
: el.getAttribute("data-monthly");
|
|
var prefix =
|
|
el.textContent.trim().charAt(0) === ">" ? ">" : "";
|
|
el.textContent = prefix + "$ " + parseFloat(val).toFixed(2);
|
|
}
|
|
var periods = document.querySelectorAll(".price-period");
|
|
for (var k = 0; k < periods.length; k++) {
|
|
periods[k].textContent = yearly ? "/ year" : "/ month";
|
|
}
|
|
var saves = document.querySelectorAll(".price-save");
|
|
for (var k = 0; k < saves.length; k++) {
|
|
var s = saves[k];
|
|
if (yearly) {
|
|
s.style.display = "block";
|
|
s.textContent = s.getAttribute("data-yearly-text");
|
|
} else {
|
|
s.style.display = "block";
|
|
s.textContent = s.getAttribute("data-monthly-text");
|
|
}
|
|
}
|
|
var ctaNote = document.getElementById("pricingCtaNote");
|
|
if (ctaNote) {
|
|
ctaNote.innerHTML = yearly
|
|
? "Save money, less administration"
|
|
: "Perfect for trial, termination any time";
|
|
}
|
|
}
|
|
|
|
function setBilling(yearly) {
|
|
yearlyMode = yearly;
|
|
if (yearly) {
|
|
biSwitch.classList.add("yearly");
|
|
monthlyLabel.classList.remove("active");
|
|
yearlyLabel.classList.add("active");
|
|
} else {
|
|
biSwitch.classList.remove("yearly");
|
|
monthlyLabel.classList.add("active");
|
|
yearlyLabel.classList.remove("active");
|
|
}
|
|
updatePrices(yearly);
|
|
}
|
|
|
|
biSwitch.addEventListener("click", function () {
|
|
setBilling(!yearlyMode);
|
|
});
|
|
monthlyLabel.addEventListener("click", function () {
|
|
setBilling(false);
|
|
});
|
|
yearlyLabel.addEventListener("click", function () {
|
|
setBilling(true);
|
|
});
|
|
|
|
/* init billing display to monthly */
|
|
updatePrices(false);
|
|
|
|
/* ---- Blog Module ---- */
|
|
var blogState = {
|
|
allPosts: [],
|
|
filteredPosts: [],
|
|
currentPage: 1,
|
|
perPage: 6,
|
|
searchTerm: "",
|
|
};
|
|
|
|
function formatDate(dateStr) {
|
|
var d = new Date(dateStr + "T00:00:00Z");
|
|
var months = [
|
|
"Jan",
|
|
"Feb",
|
|
"Mar",
|
|
"Apr",
|
|
"May",
|
|
"Jun",
|
|
"Jul",
|
|
"Aug",
|
|
"Sep",
|
|
"Oct",
|
|
"Nov",
|
|
"Dec",
|
|
];
|
|
return (
|
|
months[d.getUTCMonth()] +
|
|
" " +
|
|
d.getUTCDate() +
|
|
", " +
|
|
d.getUTCFullYear()
|
|
);
|
|
}
|
|
|
|
function badgeClass(area) {
|
|
var m = {
|
|
"speed-run": "speed-run",
|
|
guide: "guide",
|
|
howto: "howto",
|
|
news: "news",
|
|
};
|
|
return m[area] || "default";
|
|
}
|
|
|
|
function renderBlog() {
|
|
var grid = document.getElementById("blogGrid");
|
|
var search = (blogState.searchTerm || "").toLowerCase();
|
|
blogState.filteredPosts = blogState.allPosts.filter(
|
|
function (p) {
|
|
if (!search) return true;
|
|
return (
|
|
(p.headline + " " + p.teaser)
|
|
.toLowerCase()
|
|
.indexOf(search) !== -1
|
|
);
|
|
},
|
|
);
|
|
var total = blogState.filteredPosts.length;
|
|
var totalPages = Math.max(
|
|
1,
|
|
Math.ceil(total / blogState.perPage),
|
|
);
|
|
if (blogState.currentPage > totalPages)
|
|
blogState.currentPage = totalPages;
|
|
var start = (blogState.currentPage - 1) * blogState.perPage;
|
|
var pagePosts = blogState.filteredPosts.slice(
|
|
start,
|
|
start + blogState.perPage,
|
|
);
|
|
|
|
var html = "";
|
|
if (pagePosts.length === 0) {
|
|
html =
|
|
'<div class="blog-empty">No posts match your search.</div>';
|
|
} else {
|
|
for (var i = 0; i < pagePosts.length; i++) {
|
|
var p = pagePosts[i];
|
|
var bc = badgeClass(p.area);
|
|
var agentHtml = "";
|
|
if (p.agent)
|
|
agentHtml =
|
|
'<span class="blog-agent">' +
|
|
p.agent +
|
|
"</span>";
|
|
html +=
|
|
'<div class="blog-card">' +
|
|
'<div class="blog-card-top">' +
|
|
'<span class="blog-badge blog-badge-' +
|
|
bc +
|
|
'">' +
|
|
p.area +
|
|
"</span>" +
|
|
agentHtml +
|
|
"</div>" +
|
|
'<div class="blog-date">' +
|
|
formatDate(p.date) +
|
|
"</div>" +
|
|
'<h3><a href="' +
|
|
p.link +
|
|
'">' +
|
|
p.headline +
|
|
"</a></h3>" +
|
|
'<p class="blog-teaser">' +
|
|
p.teaser +
|
|
"</p>" +
|
|
'<a href="' +
|
|
p.link +
|
|
'" class="blog-readmore">Read more →</a>' +
|
|
"</div>";
|
|
}
|
|
}
|
|
grid.innerHTML = html;
|
|
|
|
var pag = document.getElementById("blogPagination");
|
|
var pagHtml = "";
|
|
if (totalPages > 1) {
|
|
pagHtml +=
|
|
'<button class="blog-page-btn" onclick="blogGo(1)"' +
|
|
(blogState.currentPage <= 1 ? ' disabled"' : '"') +
|
|
">«</button>";
|
|
pagHtml +=
|
|
'<button class="blog-page-btn" onclick="blogGo(' +
|
|
(blogState.currentPage - 1) +
|
|
')"' +
|
|
(blogState.currentPage <= 1 ? ' disabled"' : '"') +
|
|
">‹ Prev</button>";
|
|
pagHtml +=
|
|
'<span class="blog-page-info">Page ' +
|
|
blogState.currentPage +
|
|
" of " +
|
|
totalPages +
|
|
"</span>";
|
|
pagHtml +=
|
|
'<button class="blog-page-btn" onclick="blogGo(' +
|
|
(blogState.currentPage + 1) +
|
|
')"' +
|
|
(blogState.currentPage >= totalPages
|
|
? ' disabled"'
|
|
: '"') +
|
|
">Next ›</button>";
|
|
pagHtml +=
|
|
'<button class="blog-page-btn" onclick="blogGo(' +
|
|
totalPages +
|
|
')"' +
|
|
(blogState.currentPage >= totalPages
|
|
? ' disabled"'
|
|
: '"') +
|
|
">»</button>";
|
|
}
|
|
pag.innerHTML = pagHtml;
|
|
}
|
|
|
|
function blogGo(page) {
|
|
blogState.currentPage = page;
|
|
renderBlog();
|
|
}
|
|
|
|
fetch("blog/index.json?_=" + Date.now())
|
|
.then(function (r) {
|
|
return r.json();
|
|
})
|
|
.then(function (data) {
|
|
blogState.allPosts = data.posts;
|
|
renderBlog();
|
|
})
|
|
.catch(function () {
|
|
document.getElementById("blogGrid").innerHTML =
|
|
'<div class="blog-empty">Could not load blog posts.</div>';
|
|
});
|
|
|
|
document
|
|
.getElementById("blogSearch")
|
|
.addEventListener("input", function () {
|
|
blogState.searchTerm = this.value;
|
|
blogState.currentPage = 1;
|
|
renderBlog();
|
|
});
|