i18n: style the settings select + add a topbar lang toggle
Two issues addressed: 1. The /settings language <select> was unstyled — .settings-select and .settings-status classes didn't exist, so the dropdown rendered with full native browser chrome and clashed visually with the rest of the panel. Added a terminal-aesthetic select: transparent background, 1px var(--border), custom chevron via crossed linear-gradients, accent border on focus/hover. Disabled options (ES/FR/DE 'coming soon') render in --dim. 2. Added a compact EN | IT pill in the topbar next to the theme toggle, mirroring the .tone-toggle visual rhythm. Shown only when a user is signed in (admins skipped). Optimistic UI: clicking flips the pill immediately, PATCHes /api/settings/language, and reverts on failure. On /log specifically the page reloads so the user sees the localized version of the strategic log right away. The /settings dropdown still surfaces all five languages (with ES/FR/DE disabled) for visibility; the topbar pill keeps to the two active languages to stay compact. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
50ac6b9366
commit
fb71854238
2 changed files with 107 additions and 0 deletions
|
|
@ -134,6 +134,34 @@
|
|||
if (el && window.htmx) window.htmx.trigger(el, 'tone-changed');
|
||||
});
|
||||
};
|
||||
|
||||
window.cassandraSetLang = async function (newLang) {
|
||||
var pill = document.getElementById('lang-toggle');
|
||||
if (!pill) return;
|
||||
var prev = pill.dataset.lang;
|
||||
if (prev === newLang) return;
|
||||
// Optimistic update — flip the pill immediately so the click feels
|
||||
// responsive. Revert on PATCH failure.
|
||||
pill.dataset.lang = newLang;
|
||||
try {
|
||||
var r = await fetch('/api/settings/language', {
|
||||
method: 'PATCH',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
credentials: 'same-origin',
|
||||
body: JSON.stringify({lang: newLang}),
|
||||
});
|
||||
if (!r.ok) throw new Error('HTTP ' + r.status);
|
||||
// Reload localized panels so the user immediately sees content
|
||||
// in the new language (strategic log, dashboard header, etc.).
|
||||
if (window.location.pathname === '/log' ||
|
||||
window.location.pathname.startsWith('/log/')) {
|
||||
window.location.reload();
|
||||
}
|
||||
} catch (e) {
|
||||
pill.dataset.lang = prev;
|
||||
console.warn('language switch failed:', e);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<script>
|
||||
// Render any <time datetime="..."> in the browser's local timezone.
|
||||
|
|
@ -180,6 +208,16 @@
|
|||
<span class="theme-toggle__label"></span>
|
||||
</button>
|
||||
{% set cu = request.state.current_user if request.state and request.state.current_user is defined else None %}
|
||||
{% if cu and cu.user %}
|
||||
<div id="lang-toggle" class="lang-toggle" data-lang="{{ cu.user.lang or 'en' }}"
|
||||
role="group" aria-label="AI output language"
|
||||
title="Language the AI uses for the log, digest and portfolio commentary">
|
||||
<button type="button" data-value="en"
|
||||
onclick="cassandraSetLang('en')">EN</button>
|
||||
<button type="button" data-value="it"
|
||||
onclick="cassandraSetLang('it')">IT</button>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if cu and (cu.user or cu.is_admin) %}
|
||||
<div class="user-menu">
|
||||
<button type="button" id="user-menu-toggle" class="user-chip"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue