Adding dynamic generation of the gear list

The gear list is generated based on `/gear/gear.json`, which contains
a list of objects following the schema defined in `/gear/gear.mjs`.
This commit is contained in:
April Eaton 2025-12-15 18:29:12 +01:00
parent 0abf209616
commit f352b04b64
7 changed files with 130 additions and 17 deletions

View file

@ -1 +0,0 @@
// Gear list JS

13
gear/gear.json Normal file
View file

@ -0,0 +1,13 @@
{
"bondage": {
"name": "Bondage",
"id": "bondage",
"values": [
{
"name": "Rope",
"id": "rope",
"desc": "10m pink, black, or purple"
}
]
}
}

115
gear/gear.mjs Normal file
View file

@ -0,0 +1,115 @@
// Gear list JS
// @ts-check
/**
* @typedef {{name: string, id: string, desc: string}} GearListItem
*
* @typedef {{name: string, id: string, values: GearListItem[]}} GearListSection
*
* @typedef {{bondage: GearListSection}} GearList
*/
/**
* Fetches the gear.json to be parsed seperately
* @returns {Promise<GearList>}
*/
async function getGearList() {
try {
const response = await fetch("/gear/gear.json");
const data = await response.json();
return data;
} catch (error) {
console.error("Error fetching JSON:", error);
throw "Could not load gear.json";
}
}
/**
* @param {GearListItem} gear
* @param {string} group
* @returns {HTMLLIElement}
*/
function gearToElement(gear, group) {
let li = document.createElement("li");
li.setAttribute("id", `gl-${group}-${gear.id}`);
let heading = document.createElement("h3");
heading.setAttribute("class", "gl-item-name");
heading.textContent = gear.name;
li.appendChild(heading);
let description = document.createElement("p");
description.setAttribute("class", "gl-item-desc");
li.appendChild(description);
return li;
}
/**
* @param {GearListSection} gear
* @returns {HTMLLIElement[]}
*/
function gearListToList(gear) {
let lis = [];
for (const item of gear.values) {
lis.push(gearToElement(item, gear.id));
}
return lis;
}
/**
* @param {GearListSection} items
* @returns {HTMLUListElement}
*/
function bondageItemsToUl(items) {
let ul = document.createElement("ul");
ul.setAttribute("id", `gl-${items.id}-list`);
for (const i of gearListToList(items)) {
ul.appendChild(i);
}
return ul;
}
/**
* @returns {Promise<HTMLElement>}
*/
async function generateGearListArticle() {
let list = await getGearList();
let bondageItems = document.createElement("article");
bondageItems.setAttribute("id", "gl-body");
let heading = document.createElement("h2");
heading.textContent = "Gear List";
bondageItems.appendChild(heading);
for (const section of Object.values(list)) {
let listSection = buildSection(section);
bondageItems.appendChild(listSection);
}
return bondageItems;
}
/**
* @param {GearListSection} items
* @returns {HTMLElement}
*/
function buildSection(items) {
let section = document.createElement("article");
section.setAttribute("id", `gl-${items.id}-body`);
let heading = document.createElement("h3");
heading.textContent = items.name;
section.appendChild(heading);
let ul = bondageItemsToUl(items);
section.appendChild(ul);
return section;
}
/**
* @param {string} position
* @returns void
*/
export async function attachGearList(position) {
document
.getElementById(position)
.replaceWith(await generateGearListArticle());
}

View file

@ -1,8 +0,0 @@
function loadHTML(elementId, url) {
fetch(url)
.then((response) => response.text())
.then((data) => {
document.getElementById(elementId).innerHTML = data;
})
.catch((error) => console.error("Error loading HTML:", error));
}

View file

@ -8,9 +8,9 @@
<div id="hd-left">nekoapril.blog</div> <div id="hd-left">nekoapril.blog</div>
<div id="hd-mid"></div> <div id="hd-mid"></div>
<div id="hd-right"> <div id="hd-right">
<span>Home</span> <a href="/">Home</a>
<span class="spacer"></span> <span class="spacer"></span>
<span>Kinks</span> <span>Kinks</span>
<span class="spacer"></span> <span class="spacer"></span>
<span>Gear</span> <a href="/gear">Gear</a>
</div> </div>

View file

@ -1,5 +0,0 @@
// Landing page JS
function loadDependencies() {
loadHTML("hd-box", "/header/header.html");
loadHTML("footer", "/footer/footer.html");
}

View file

@ -1 +0,0 @@
// Kinks page JS