Files

104 lines
5.2 KiB
JavaScript

/* NetDesk marketing site: shared header + footer, theme, mobile nav. */
(function () {
"use strict";
var YEAR = 2026;
var NAV = [
["Features", "/features"], ["Pricing", "/pricing"],
["Security", "/security"], ["Download", "/download"],
["Source", "/git/akronlogic/netdesk"]
];
var page = (document.body.getAttribute("data-page") || "").toLowerCase();
function svgLogo() {
return '<svg width="20" height="20" viewBox="0 0 32 32"><path d="M8 20l8-12 8 12-8-4z" fill="#fff"/>' +
'<rect x="12" y="18" width="8" height="7" rx="2" fill="#fff"/></svg>';
}
function header() {
var links = NAV.map(function (n) {
var active = page === n[0].toLowerCase() ? " class=\"active\"" : "";
return '<a href="' + n[1] + '"' + active + '>' + n[0] + "</a>";
}).join("");
return '<header class="nz"><div class="wrap nz-in">' +
'<a class="nz-brand" href="/"><span class="nz-logo">' + svgLogo() + "</span>NetDesk</a>" +
'<nav class="nz-links" id="nzLinks">' + links +
'<a href="/contact">Contact</a><a href="/portal">Self-Host Console</a></nav>' +
'<div class="nz-cta">' +
'<a class="btn btn-ghost" href="/app" id="btnSignin">Sign in</a>' +
'<a class="btn btn-primary" href="/download">Get NetDesk</a>' +
'<button class="nz-burger" id="nzBurger" aria-label="Menu">☰</button>' +
"</div></div></header>";
}
function footer() {
return '<footer class="ft"><div class="wrap">' +
'<div class="ft-top">' +
'<div class="ft-brand"><a class="nz-brand" href="/"><span class="nz-logo">' + svgLogo() + "</span>NetDesk</a>" +
"<p>The fast, secure, self-hosted remote desktop. Own your infrastructure, your keys, and your data — " +
"the alternative to TeamViewer, AnyDesk and RustDesk that you fully control.</p>" +
'<button class="theme-toggle" id="ftTheme">☀ Toggle theme</button></div>' +
'<div class="ft-col"><h4>Product</h4>' +
'<a href="/features">Features</a><a href="/pricing">Pricing</a><a href="/download">Download</a>' +
'<a href="/security">Security</a><a href="/app">Web Client</a><a href="/git/akronlogic/netdesk">Source Code</a></div>' +
'<div class="ft-col"><h4>Company</h4>' +
'<a href="/about">About</a><a href="/contact">Contact</a><a href="/portal">Self-Hosting Console</a>' +
'<a href="/git/akronlogic/netdesk">Open Source</a></div>' +
'<div class="ft-col"><h4>Legal</h4>' +
'<a href="/terms">Terms of Service</a><a href="/privacy">Privacy Policy</a>' +
'<a href="/security">Security &amp; Trust</a><a href="/refund">Refund Policy</a></div>' +
"</div>" +
'<div class="ft-bot"><span>© ' + YEAR + ' NetDesk. Self-hosted remote access, done right.</span>' +
'<span class="ft-social">' +
'<a href="/git/akronlogic/netdesk" aria-label="Source code">Source</a>' +
'<a href="/contact">Support</a><a href="/privacy">Privacy</a></span>' +
"</div></div></footer>";
}
function applyTheme(t) {
document.documentElement.setAttribute("data-theme", t);
try { localStorage.setItem("nd.theme", t); } catch (e) {}
}
document.addEventListener("DOMContentLoaded", function () {
var h = document.getElementById("siteHeader");
var f = document.getElementById("siteFooter");
if (h) h.innerHTML = header();
if (f) f.innerHTML = footer();
var burger = document.getElementById("nzBurger");
if (burger) burger.onclick = function () { document.getElementById("nzLinks").classList.toggle("open"); };
var ft = document.getElementById("ftTheme");
if (ft) ft.onclick = function () {
applyTheme(document.documentElement.getAttribute("data-theme") === "light" ? "dark" : "light");
};
// reflect signed-in state in the header
fetch("/api/auth/me").then(function (r) { return r.ok ? r.json() : null; }).then(function (d) {
var b = document.getElementById("btnSignin");
if (d && d.email && b) { b.textContent = "My Computers"; b.href = "/app"; }
}).catch(function () {});
// --- scroll reveal (every page that uses .reveal) ---
var revs = document.querySelectorAll(".reveal");
if (revs.length && "IntersectionObserver" in window) {
var io = new IntersectionObserver(function (es) {
es.forEach(function (e) { if (e.isIntersecting) { e.target.classList.add("in"); io.unobserve(e.target); } });
}, { threshold: 0.1, rootMargin: "0px 0px -8% 0px" });
revs.forEach(function (el) { io.observe(el); });
} else {
revs.forEach(function (el) { el.classList.add("in"); });
}
// --- cursor spotlight on cards (sets --mx/--my for the ::before glow) ---
function spot(e) {
var r = e.currentTarget.getBoundingClientRect();
e.currentTarget.style.setProperty("--mx", (e.clientX - r.left) + "px");
e.currentTarget.style.setProperty("--my", (e.clientY - r.top) + "px");
}
document.querySelectorAll(".feat, .plan").forEach(function (c) {
c.addEventListener("mousemove", spot, { passive: true });
});
});
try { applyTheme(localStorage.getItem("nd.theme") || "dark"); } catch (e) { applyTheme("dark"); }
})();