Shrink UI controls and iconize language/edit/delete
This commit is contained in:
@@ -45,13 +45,10 @@ function setupHandlers() {
|
||||
loginUser.addEventListener("blur", () => { delete loginUser.dataset.userEditing; });
|
||||
}
|
||||
|
||||
const langSelects = Array.from(document.querySelectorAll(".lang-select"));
|
||||
const syncLanguageSelects = () => langSelects.forEach((sel) => (sel.value = getLanguage()));
|
||||
syncLanguageSelects();
|
||||
langSelects.forEach((sel) => sel.addEventListener("change", () => setLanguage(sel.value)));
|
||||
setupLanguageSwitchers();
|
||||
|
||||
onLanguageChange(() => {
|
||||
syncLanguageSelects();
|
||||
updateLanguageButtons();
|
||||
renderWelcome();
|
||||
renderPhasePill();
|
||||
renderCounts();
|
||||
@@ -212,3 +209,47 @@ async function main() {
|
||||
}
|
||||
|
||||
main();
|
||||
|
||||
function languageEmoji(lang) {
|
||||
const map = { en: "🇬🇧", de: "🇩🇪" };
|
||||
return map[lang] || "🌐";
|
||||
}
|
||||
|
||||
function updateLanguageButtons() {
|
||||
document.querySelectorAll(".lang-button").forEach((btn) => {
|
||||
btn.textContent = languageEmoji(getLanguage());
|
||||
btn.title = t("lang.label");
|
||||
btn.setAttribute("aria-label", t("lang.label"));
|
||||
});
|
||||
}
|
||||
|
||||
function setupLanguageSwitchers() {
|
||||
const switches = document.querySelectorAll(".lang-switch");
|
||||
const closeAll = () =>
|
||||
switches.forEach((wrap) => wrap.querySelector(".lang-menu")?.classList.add("hidden"));
|
||||
|
||||
switches.forEach((wrap) => {
|
||||
const btn = wrap.querySelector(".lang-button");
|
||||
const menu = wrap.querySelector(".lang-menu");
|
||||
if (!btn || !menu) return;
|
||||
btn.addEventListener("click", (e) => {
|
||||
e.preventDefault();
|
||||
const isHidden = menu.classList.contains("hidden");
|
||||
closeAll();
|
||||
if (isHidden) menu.classList.remove("hidden");
|
||||
});
|
||||
menu.querySelectorAll("[data-lang]").forEach((item) =>
|
||||
item.addEventListener("click", () => {
|
||||
const lang = item.dataset.lang;
|
||||
if (lang) setLanguage(lang);
|
||||
closeAll();
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
document.addEventListener("click", (e) => {
|
||||
if (!e.target.closest(".lang-switch")) closeAll();
|
||||
});
|
||||
|
||||
updateLanguageButtons();
|
||||
}
|
||||
|
||||
@@ -21,11 +21,13 @@
|
||||
<h2 id="auth-title" data-i18n="auth.loginHeading">Log in</h2>
|
||||
</div>
|
||||
<div class="stack lang-field">
|
||||
<span class="label" data-i18n="lang.label">Language</span>
|
||||
<select class="lang-select">
|
||||
<option value="en" data-i18n="lang.en">English</option>
|
||||
<option value="de" data-i18n="lang.de">Deutsch</option>
|
||||
</select>
|
||||
<div class="lang-switch" id="lang-switch-auth">
|
||||
<button class="lang-button" type="button" aria-label="Language" title="Language">🌐</button>
|
||||
<div class="lang-menu hidden">
|
||||
<button type="button" data-lang="en">🇬🇧 English</button>
|
||||
<button type="button" data-lang="de">🇩🇪 Deutsch</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<form id="login-form" class="stack auth-form" data-mode="login">
|
||||
<label class="stack">
|
||||
@@ -74,11 +76,13 @@
|
||||
<span class="counts" id="counts">—</span>
|
||||
</div>
|
||||
<div class="status-right">
|
||||
<span class="label" data-i18n="lang.label">Language</span>
|
||||
<select class="lang-select compact-select">
|
||||
<option value="en" data-i18n="lang.en">English</option>
|
||||
<option value="de" data-i18n="lang.de">Deutsch</option>
|
||||
</select>
|
||||
<div class="lang-switch" id="lang-switch-status">
|
||||
<button class="lang-button" type="button" aria-label="Language" title="Language">🌐</button>
|
||||
<div class="lang-menu hidden">
|
||||
<button type="button" data-lang="en">🇬🇧 English</button>
|
||||
<button type="button" data-lang="de">🇩🇪 Deutsch</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
@@ -317,8 +317,8 @@ export function buildCard(
|
||||
<h3 class="card-title" title="${s.name}">${s.name}</h3>
|
||||
<div class="title-meta">
|
||||
${showAuthor && s.author ? `<span class="chip">${s.author}</span>` : ""}
|
||||
${allowEdit ? `<button class="chip" data-edit="${s.id}" type="button">${t("card.edit")}</button>` : ""}
|
||||
${allowDelete ? `<button class="chip danger-chip" data-delete="${s.id}" type="button">${t("card.delete")}</button>` : ""}
|
||||
${allowEdit ? `<button class="chip" data-edit="${s.id}" type="button" title="${t("card.edit")}">✏️</button>` : ""}
|
||||
${allowDelete ? `<button class="chip danger-chip" data-delete="${s.id}" type="button" title="${t("card.delete")}">🗑️</button>` : ""}
|
||||
</div>
|
||||
</div>
|
||||
${hasExtraInfo ? `<p class="muted">` : ""}
|
||||
|
||||
@@ -48,11 +48,39 @@ html {
|
||||
.lang-field {
|
||||
margin-top: 8px;
|
||||
}
|
||||
.lang-field select {
|
||||
min-width: 160px;
|
||||
.lang-switch {
|
||||
position: relative;
|
||||
}
|
||||
.compact-select {
|
||||
min-width: 120px;
|
||||
.lang-button {
|
||||
border: 1px solid #d5c7b5;
|
||||
background: #fffaf3;
|
||||
border-radius: 10px;
|
||||
padding: 6px 10px;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
min-width: 44px;
|
||||
}
|
||||
.lang-menu {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: calc(100% + 6px);
|
||||
background: #fffaf3;
|
||||
border: 1px solid #e3d4bd;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
|
||||
padding: 6px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
z-index: 50;
|
||||
}
|
||||
.lang-menu button {
|
||||
border: 1px solid #d5c7b5;
|
||||
background: #ffffff;
|
||||
border-radius: 8px;
|
||||
padding: 6px 10px;
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.status-bar {
|
||||
|
||||
Reference in New Issue
Block a user