FILE / ScuroNeko/scuroneko.dev

js/projects.js

Исходный файл и его история в репозитории.
FILE ae67b91d1c2aaa214ca545875ef1af9acffddec7
Files
scuroneko.dev/js/projects.js
T

95 lines
2.6 KiB
JavaScript

const loadProjects = async () => {
const projectContainer = document.getElementById("projects");
if (!projectContainer) {
return;
}
projectsList = await fetchJson("./data/projects.json");
if (projectsList.length === 0) {
const empty = document.createElement("p");
empty.classList.add("project-empty");
empty.textContent = "Projects are taking shape.";
projectContainer.replaceChildren(empty);
return;
}
const projectCards = projectsList.map(buildProjectCard);
projectContainer.replaceChildren(...projectCards);
};
const buildProjectCard = (project, index) => {
const card = document.createElement("article");
card.classList.add("project-card", `tone-${project.tone ?? "mint"}`);
const header = document.createElement("div");
header.classList.add("project-card__header");
const indexBadge = document.createElement("span");
indexBadge.classList.add("project-card__index");
indexBadge.textContent = formatIndex(index);
const key = document.createElement("span");
key.classList.add("project-card__key");
key.textContent = project.key;
const status = document.createElement("span");
status.classList.add("project-card__status");
status.textContent = project.status ?? "project";
const title = document.createElement("h3");
title.classList.add("project-card__title");
title.textContent = project.name;
const description = document.createElement("p");
description.classList.add("project-card__description");
description.textContent = project.description;
const stack = document.createElement("div");
stack.classList.add("project-card__stack");
if (project.stack) {
const badgeToStack = loadStackForProject(project.stack);
stack.append(
...project.stack.map((item) => {
const chip = document.createElement("span");
const stackItem = badgeToStack[item] ?? {
name: item,
tone: "blue",
};
chip.textContent = stackItem.name;
chip.classList.add(
"project-card__stack-chip",
`tone-${stackItem?.tone ?? "mint"}`,
);
return chip;
}),
);
}
header.append(indexBadge, key, status);
card.append(header, title, description, stack);
if (project.links) {
const links = document.createElement("div");
links.classList.add("project-card__links");
links.append(
...Object.entries(project.links).map(([label, url]) => {
const link = document.createElement("a");
link.href = url;
link.textContent = label;
link.target = "_blank";
link.rel = "noreferrer";
return link;
}),
);
card.append(links);
}
return card;
};