FILE / ScuroNeko/scuroneko.dev
js/projects.js
Исходный файл и его история в репозитории.
95 lines
2.6 KiB
JavaScript
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", `project-card--${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;
|
|
};
|