synch
All checks were successful
Deploy / deploy (push) Successful in 1m43s

This commit is contained in:
2026-07-27 00:24:12 +02:00
parent 56d29f09e5
commit e274e07f45
142 changed files with 235 additions and 295 deletions

View File

@@ -739,10 +739,10 @@ document.addEventListener('DOMContentLoaded', () => {
const image = preview.querySelector('.pkt-avatar__img');
if (!image) return;
const preset = readValue('avatar_preset');
if (!preset) return;
image.src = `/assets/avatars/presets/${preset}.png`;
const checked = form.querySelector('[data-avatar-field="avatar_preset"]:checked');
const url = checked?.getAttribute('data-avatar-url') || '';
if (!url) return;
image.src = url;
};
document.querySelectorAll('[data-avatar-builder]').forEach((form) => {
@@ -752,35 +752,49 @@ document.addEventListener('DOMContentLoaded', () => {
field.addEventListener('input', () => updateAvatarPreview(form));
});
const setActivePresetGroup = (groupKey) => {
form.querySelectorAll('[data-avatar-preset-filter]').forEach((button) => {
const active = button.getAttribute('data-avatar-preset-filter') === groupKey;
button.classList.toggle('is-active', active);
button.setAttribute('aria-selected', active ? 'true' : 'false');
});
form.querySelectorAll('[data-avatar-preset-group]').forEach((group) => {
group.classList.toggle('is-active', group.getAttribute('data-avatar-preset-group') === groupKey);
});
const avatarPrefixes = [
'abend', 'ahorn', 'anker', 'atlas', 'berg', 'blick', 'brise', 'echo',
'eiche', 'fjord', 'fluss', 'fokus', 'hafen', 'herz', 'horizont', 'insel',
'kiesel', 'kompass', 'kraft', 'linie', 'licht', 'lotse', 'mond', 'morgen',
'nord', 'pfad', 'quelle', 'rauch', 'runde', 'sand', 'sommer', 'stein',
'sturm', 'tal', 'ufer', 'wald', 'welle', 'wind', 'winkel', 'zeit',
];
const avatarSuffixes = [
'alpha', 'atlas', 'balu', 'bravo', 'caspar', 'dario', 'emil', 'felix',
'fiete', 'finn', 'gerrit', 'hanno', 'ilan', 'joris', 'kian', 'leon',
'linus', 'maik', 'malo', 'marlon', 'mats', 'mika', 'milan', 'noel',
'ole', 'oskar', 'pepe', 'quinn', 'remo', 'sam', 'taro', 'timo',
'veit', 'vito', 'yaro', 'yuri', 'zeno', 'zuri',
];
const slugifySeed = (value) => value.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '').slice(0, 64) || 'papa-kind-treff';
const dicebearUrl = (seed) => `/api/avatar?seed=${encodeURIComponent(seed)}`;
const buildSeed = () => {
const prefix = avatarPrefixes[Math.floor(Math.random() * avatarPrefixes.length)];
const suffix = avatarSuffixes[Math.floor(Math.random() * avatarSuffixes.length)];
const tail = Math.floor(Math.random() * 997);
return slugifySeed(`${prefix}-${suffix}-${tail}`);
};
const checkedPreset = form.querySelector('[data-avatar-field="avatar_preset"]:checked');
if (checkedPreset) {
const activeGroup = checkedPreset.closest('[data-avatar-preset-group]')?.getAttribute('data-avatar-preset-group');
if (activeGroup) setActivePresetGroup(activeGroup);
}
form.querySelectorAll('[data-avatar-preset-filter]').forEach((button) => {
button.addEventListener('click', () => {
const groupKey = button.getAttribute('data-avatar-preset-filter');
if (groupKey) setActivePresetGroup(groupKey);
});
});
form.querySelectorAll('[data-avatar-field="avatar_preset"]').forEach((field) => {
field.addEventListener('change', () => {
const activeGroup = field.closest('[data-avatar-preset-group]')?.getAttribute('data-avatar-preset-group');
if (activeGroup) setActivePresetGroup(activeGroup);
form.querySelector('[data-avatar-reroll]')?.addEventListener('click', () => {
const radios = Array.from(form.querySelectorAll('[data-avatar-field="avatar_preset"]'));
const used = new Set();
radios.forEach((radio, index) => {
let seed = buildSeed();
while (used.has(seed)) {
seed = buildSeed();
}
used.add(seed);
const url = dicebearUrl(seed);
radio.value = seed;
radio.setAttribute('data-avatar-url', url);
radio.checked = index === 0;
const card = radio.closest('.avatar-preset-card');
card?.querySelector('img')?.setAttribute('src', url);
card?.querySelector('img')?.setAttribute('alt', `Variante ${index + 1}`);
const label = card?.querySelector('.avatar-preset-card__label');
if (label) label.textContent = index === 0 ? 'Neue Auswahl' : `Variante ${index + 1}`;
});
updateAvatarPreview(form);
});
});