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; });
|
loginUser.addEventListener("blur", () => { delete loginUser.dataset.userEditing; });
|
||||||
}
|
}
|
||||||
|
|
||||||
const langSelects = Array.from(document.querySelectorAll(".lang-select"));
|
setupLanguageSwitchers();
|
||||||
const syncLanguageSelects = () => langSelects.forEach((sel) => (sel.value = getLanguage()));
|
|
||||||
syncLanguageSelects();
|
|
||||||
langSelects.forEach((sel) => sel.addEventListener("change", () => setLanguage(sel.value)));
|
|
||||||
|
|
||||||
onLanguageChange(() => {
|
onLanguageChange(() => {
|
||||||
syncLanguageSelects();
|
updateLanguageButtons();
|
||||||
renderWelcome();
|
renderWelcome();
|
||||||
renderPhasePill();
|
renderPhasePill();
|
||||||
renderCounts();
|
renderCounts();
|
||||||
@@ -212,3 +209,47 @@ async function main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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>
|
<h2 id="auth-title" data-i18n="auth.loginHeading">Log in</h2>
|
||||||
</div>
|
</div>
|
||||||
<div class="stack lang-field">
|
<div class="stack lang-field">
|
||||||
<span class="label" data-i18n="lang.label">Language</span>
|
<div class="lang-switch" id="lang-switch-auth">
|
||||||
<select class="lang-select">
|
<button class="lang-button" type="button" aria-label="Language" title="Language">🌐</button>
|
||||||
<option value="en" data-i18n="lang.en">English</option>
|
<div class="lang-menu hidden">
|
||||||
<option value="de" data-i18n="lang.de">Deutsch</option>
|
<button type="button" data-lang="en">🇬🇧 English</button>
|
||||||
</select>
|
<button type="button" data-lang="de">🇩🇪 Deutsch</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<form id="login-form" class="stack auth-form" data-mode="login">
|
<form id="login-form" class="stack auth-form" data-mode="login">
|
||||||
<label class="stack">
|
<label class="stack">
|
||||||
@@ -74,11 +76,13 @@
|
|||||||
<span class="counts" id="counts">—</span>
|
<span class="counts" id="counts">—</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="status-right">
|
<div class="status-right">
|
||||||
<span class="label" data-i18n="lang.label">Language</span>
|
<div class="lang-switch" id="lang-switch-status">
|
||||||
<select class="lang-select compact-select">
|
<button class="lang-button" type="button" aria-label="Language" title="Language">🌐</button>
|
||||||
<option value="en" data-i18n="lang.en">English</option>
|
<div class="lang-menu hidden">
|
||||||
<option value="de" data-i18n="lang.de">Deutsch</option>
|
<button type="button" data-lang="en">🇬🇧 English</button>
|
||||||
</select>
|
<button type="button" data-lang="de">🇩🇪 Deutsch</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|||||||
@@ -317,8 +317,8 @@ export function buildCard(
|
|||||||
<h3 class="card-title" title="${s.name}">${s.name}</h3>
|
<h3 class="card-title" title="${s.name}">${s.name}</h3>
|
||||||
<div class="title-meta">
|
<div class="title-meta">
|
||||||
${showAuthor && s.author ? `<span class="chip">${s.author}</span>` : ""}
|
${showAuthor && s.author ? `<span class="chip">${s.author}</span>` : ""}
|
||||||
${allowEdit ? `<button class="chip" data-edit="${s.id}" type="button">${t("card.edit")}</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">${t("card.delete")}</button>` : ""}
|
${allowDelete ? `<button class="chip danger-chip" data-delete="${s.id}" type="button" title="${t("card.delete")}">🗑️</button>` : ""}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
${hasExtraInfo ? `<p class="muted">` : ""}
|
${hasExtraInfo ? `<p class="muted">` : ""}
|
||||||
|
|||||||
@@ -48,11 +48,39 @@ html {
|
|||||||
.lang-field {
|
.lang-field {
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
}
|
}
|
||||||
.lang-field select {
|
.lang-switch {
|
||||||
min-width: 160px;
|
position: relative;
|
||||||
}
|
}
|
||||||
.compact-select {
|
.lang-button {
|
||||||
min-width: 120px;
|
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 {
|
.status-bar {
|
||||||
|
|||||||
Reference in New Issue
Block a user