FILE / ScuroNeko/scuroneko.dev
js/stack.js
Исходный файл и его история в репозитории.
91 lines
2.4 KiB
JavaScript
91 lines
2.4 KiB
JavaScript
let isStackExpanded = false;
|
|
|
|
const getExperienceLevel = (years) => {
|
|
if (years >= 7) return "Core";
|
|
if (years >= 4) return "Strong";
|
|
return "Growing";
|
|
};
|
|
|
|
const loadStackForProject = (keys) => {
|
|
const stacks = stackList.filter((stack) => keys.includes(stack.key));
|
|
const output = {};
|
|
|
|
stacks.forEach((stack) => {
|
|
output[stack.key] = stack;
|
|
});
|
|
|
|
return output;
|
|
};
|
|
|
|
const loadStack = async () => {
|
|
const stackContainer = document.getElementById("stack");
|
|
const stackToggle = document.getElementById("stack-toggle");
|
|
|
|
if (!stackContainer) {
|
|
return;
|
|
}
|
|
|
|
stackList = await fetchJson("./data/stack.json");
|
|
renderStack(stackContainer);
|
|
|
|
if (stackToggle && stackList.some((stack) => stack.hide === true)) {
|
|
stackToggle.hidden = false;
|
|
stackToggle.addEventListener("click", () => {
|
|
isStackExpanded = !isStackExpanded;
|
|
stackToggle.textContent = isStackExpanded ? "Show less" : "View all";
|
|
stackToggle.setAttribute("aria-expanded", String(isStackExpanded));
|
|
renderStack(stackContainer);
|
|
});
|
|
}
|
|
};
|
|
|
|
const renderStack = (stackContainer) => {
|
|
const stackCards = stackList
|
|
.filter((stack) => isStackExpanded || stack.hide !== true)
|
|
.map(buildStackCard);
|
|
stackContainer.replaceChildren(...stackCards);
|
|
};
|
|
|
|
const buildStackCard = (stack) => {
|
|
const card = document.createElement("div");
|
|
card.classList.add("stack-card", `tone-${stack.tone ?? "mint"}`);
|
|
|
|
const badge = document.createElement("div");
|
|
badge.classList.add("stack-card__badge");
|
|
badge.textContent = stack.key;
|
|
loadIcon(stack.key).then((svg) => (badge.innerHTML = svg));
|
|
|
|
const body = document.createElement("div");
|
|
body.classList.add("stack-card__body");
|
|
|
|
const eyebrow = document.createElement("p");
|
|
eyebrow.classList.add("stack-card__eyebrow");
|
|
eyebrow.textContent = getExperienceLevel(stack.years);
|
|
|
|
const name = document.createElement("h3");
|
|
name.classList.add("stack-card__title");
|
|
name.textContent = stack.name;
|
|
|
|
const footer = document.createElement("div");
|
|
footer.classList.add("stack-card__footer");
|
|
|
|
const years = document.createElement("span");
|
|
years.textContent = `${stack.years}+ years`;
|
|
footer.append(years);
|
|
|
|
if (stack.tags) {
|
|
footer.append(
|
|
...stack.tags.map((tag) => {
|
|
const badge = document.createElement("span");
|
|
badge.textContent = tag;
|
|
return badge;
|
|
}),
|
|
);
|
|
}
|
|
|
|
body.append(eyebrow, name, footer);
|
|
card.append(badge, body);
|
|
|
|
return card;
|
|
};
|