Files
portfolioIndex/assets/js/main.js

89 lines
2.4 KiB
JavaScript

(() => {
const tbody = document.getElementById("sitesBody");
const lastUpdatedEl = document.getElementById("lastUpdated");
const formatTimestamp = () => {
const formatter = new Intl.DateTimeFormat("en", {
dateStyle: "medium",
timeStyle: "short",
});
lastUpdatedEl.textContent = formatter.format(new Date());
};
const renderRows = () => {
if (!Array.isArray(window.sitesDirectory) || !window.sitesDirectory.length) {
tbody.innerHTML = `
<tr>
<td colspan="3">No entries yet. Update assets/js/data.js to get started.</td>
</tr>`;
return;
}
const rows = window.sitesDirectory
.map((site) => {
const {
label = "Site",
url = "#",
ipv4 = [],
ipv6 = [],
remarks = "",
} = site;
const ipv4Badges = ipv4
.map((ip) => `<span class="pill pill--ipv4">${ip}</span>`)
.join("");
const ipv6Badges = ipv6
.map((ip) => `<span class="pill pill--ipv6">${ip}</span>`)
.join("");
const ipMarkup =
ipv4.length || ipv6.length
? `<div class="ip-list">${ipv4Badges}${ipv6Badges}</div>`
: `<span class="remarks">—</span>`;
return `
<tr>
<td>
<a href="${url}" target="_blank" rel="noopener noreferrer">
${label}
</a>
<div class="remarks">${url.replace(/^https?:\/\//, "")}</div>
</td>
<td>${ipMarkup}</td>
<td class="remarks">${remarks}</td>
</tr>`;
})
.join("");
tbody.innerHTML = rows;
};
const initPhotoSizeControls = () => {
const card = document.querySelector(".visual-card");
if (!card) return;
const buttons = card.querySelectorAll("[data-photo-size-option]");
if (!buttons.length) return;
const setSize = (size) => {
card.setAttribute("data-photo-size", size);
buttons.forEach((btn) => {
btn.classList.toggle("is-active", btn.dataset.photoSizeOption === size);
});
};
const initial = card.getAttribute("data-photo-size") || "standard";
setSize(initial);
buttons.forEach((button) => {
button.addEventListener("click", () => {
const size = button.dataset.photoSizeOption;
setSize(size);
});
});
};
formatTimestamp();
renderRows();
initPhotoSizeControls();
})();