feat: profiles and /set profile, and id cards

* New functionality to set meta data on businesscards.
* Can develop a user profile.
* Business cards link to user profile.
This commit is contained in:
Evan Carroll 2026-01-25 10:50:10 -06:00
parent cd8dfb94a3
commit 710985638f
35 changed files with 4932 additions and 435 deletions

View file

@ -284,6 +284,12 @@
font-size: 0.75rem;
color: #aaa;
text-transform: capitalize;
text-decoration: none;
}
.prop-name:hover {
color: #4ECDC4;
text-decoration: underline;
}
/* Selected prop display */
@ -420,6 +426,11 @@
<div class="prop-items" id="tea-props" role="group" aria-label="Tea props"></div>
</div>
<div class="prop-category">
<h3>Identification</h3>
<div class="prop-items" id="id-props" role="group" aria-label="Identification props"></div>
</div>
<div class="prop-category">
<h3>Misc</h3>
<div class="prop-items" id="misc-props" role="group" aria-label="Miscellaneous props"></div>
@ -557,7 +568,8 @@
coffee: ['espresso', 'latte', 'iced', 'frenchpress', 'pourover', 'turkish', 'cup-empty'],
soda: ['cola', 'lemonlime', 'orange', 'grape', 'rootbeer'],
tea: ['iced', 'pot', 'cup', 'cup-empty', 'bag'],
misc: ['iou', 'signed-dollar', 'thankyou', 'yousuck', 'businesscard'],
misc: ['iou', 'signed-dollar', 'thankyou', 'yousuck'],
id: ['businesscard', 'businesscard-box', 'card', 'dogtags'],
goodpol: ['cccp', 'china', 'palestine'],
screen: ['projector-screen', 'projector-screen-with-stand', 'projector-remote-control'],
keyboard: ['standard']
@ -583,9 +595,12 @@
preview.className = 'prop-preview';
preview.innerHTML = svgText;
const label = document.createElement('span');
const label = document.createElement('a');
label.className = 'prop-name';
label.href = filename;
label.target = '_blank';
label.textContent = name.replace(/([A-Z])/g, ' $1').trim();
label.addEventListener('click', (e) => e.stopPropagation());
card.appendChild(preview);
card.appendChild(label);
@ -620,9 +635,12 @@
preview.className = 'prop-preview';
preview.innerHTML = svgText;
const label = document.createElement('span');
const label = document.createElement('a');
label.className = 'prop-name';
label.href = filename;
label.target = '_blank';
label.textContent = name.replace(/([A-Z])/g, ' $1').trim();
label.addEventListener('click', (e) => e.stopPropagation());
card.appendChild(preview);
card.appendChild(label);
@ -648,6 +666,7 @@
const coffeeContainer = document.getElementById('coffee-props');
const sodaContainer = document.getElementById('soda-props');
const teaContainer = document.getElementById('tea-props');
const idContainer = document.getElementById('id-props');
const miscContainer = document.getElementById('misc-props');
const goodpolContainer = document.getElementById('goodpol-props');
const screenContainer = document.getElementById('screen-props');
@ -665,6 +684,9 @@
for (const name of props.tea) {
await loadPropPreview('tea', name, teaContainer);
}
for (const name of props.id) {
await loadPropPreview('id', name, idContainer);
}
for (const name of props.misc) {
await loadPropPreview('misc', name, miscContainer);
}