Englisch als zweite Sprache fuer die oeffentlichen Seiten
Hub und Bot-Produktseite lassen sich jetzt auf Englisch umstellen. Die Wahl haengt am Browser (Deutsch nur, wenn der Browser es will) und bleibt im localStorage stehen. - src/i18n.jsx: Context mit t(), tOr(), Datums- und Zahlenformat der Sprache. Keine Bibliothek, die Woerterbuecher werden mitgebaut — kein Nachlade-Blitzer. - Platzhalter im %s-Stil, dieselbe Schreibweise wie in den Bot-Texten. - Umschalter in der Navigation, zusaetzlich im Schubladen-Menue: .auth ist auf schmalen Schirmen ausgeblendet, sonst waere der Wechsel dort unerreichbar. - Datums- und Zahlenformat folgen mit (31.07.2026 / 31/07/2026, 45.231 / 45,231). - Die Funktionsliste kommt weiter deutsch vom Server; englische Modulnamen liegen unter feat.<id> im Woerterbuch. Fehlt einer, bleibt der Servertext stehen — ein neues Modul verschwindet nie von der Seite. Das Config-Panel und die Discord-Texte bleiben deutsch. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+24
-16
@@ -10,6 +10,7 @@ import Settings from './pages/Settings.jsx';
|
||||
import Impressum from './pages/Impressum.jsx';
|
||||
import Datenschutz from './pages/Datenschutz.jsx';
|
||||
import { IconMenu, IconX } from './icons.jsx';
|
||||
import { useT, LangSwitch } from './i18n.jsx';
|
||||
|
||||
export default function BotApp() {
|
||||
const [me, setMe] = useState({ user: null, admin: false, scopes: [], loading: true });
|
||||
@@ -17,6 +18,7 @@ export default function BotApp() {
|
||||
const [drawer, setDrawer] = useState(false);
|
||||
const [hub, setHub] = useState(null);
|
||||
const location = useLocation();
|
||||
const { t } = useT();
|
||||
|
||||
useEffect(() => { setDrawer(false); }, [location.pathname]);
|
||||
|
||||
@@ -43,40 +45,46 @@ export default function BotApp() {
|
||||
</NavLink>
|
||||
|
||||
<nav className="nav-links">
|
||||
<NavLink to="/features">Funktionen</NavLink>
|
||||
<NavLink to="/commands">Befehle</NavLink>
|
||||
{canDashboard && <NavLink to="/dashboard">Dashboard</NavLink>}
|
||||
{hub && <a href={hub}>Community</a>}
|
||||
<NavLink to="/features">{t('nav.features')}</NavLink>
|
||||
<NavLink to="/commands">{t('nav.commands')}</NavLink>
|
||||
{canDashboard && <NavLink to="/dashboard">{t('nav.dashboard')}</NavLink>}
|
||||
{hub && <a href={hub}>{t('nav.community')}</a>}
|
||||
</nav>
|
||||
|
||||
<div className="auth">
|
||||
<LangSwitch />
|
||||
{me.loading ? null : me.user ? (
|
||||
<span className="user-chip">
|
||||
{me.user.avatar && <img className="avatar" src={me.user.avatar} alt="" />}
|
||||
<span className="username">{me.user.username}</span>
|
||||
<a className="logout" href="/auth/logout" title="Abmelden">
|
||||
<a className="logout" href="/auth/logout" title={t('nav.signOut')}>
|
||||
<IconX size={13} />
|
||||
</a>
|
||||
</span>
|
||||
) : (
|
||||
<a className="btn-login" href="/auth/login">Anmelden</a>
|
||||
<a className="btn-login" href="/auth/login">{t('nav.signIn')}</a>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<button className="burger" onClick={() => setDrawer((d) => !d)} aria-label="Menü">
|
||||
<button className="burger" onClick={() => setDrawer((d) => !d)} aria-label={t('nav.menu')}>
|
||||
{drawer ? <IconX size={20} /> : <IconMenu size={20} />}
|
||||
</button>
|
||||
</header>
|
||||
|
||||
{drawer && (
|
||||
<nav className="drawer" onClick={() => setDrawer(false)}>
|
||||
<NavLink to="/features">Funktionen</NavLink>
|
||||
<NavLink to="/commands">Befehle</NavLink>
|
||||
{canDashboard && <NavLink to="/dashboard">Dashboard</NavLink>}
|
||||
{hub && <a href={hub}>Community</a>}
|
||||
<NavLink to="/features">{t('nav.features')}</NavLink>
|
||||
<NavLink to="/commands">{t('nav.commands')}</NavLink>
|
||||
{canDashboard && <NavLink to="/dashboard">{t('nav.dashboard')}</NavLink>}
|
||||
{hub && <a href={hub}>{t('nav.community')}</a>}
|
||||
{me.user
|
||||
? <a href="/auth/logout">Abmelden</a>
|
||||
: <a href="/auth/login">Anmelden</a>}
|
||||
? <a href="/auth/logout">{t('nav.signOut')}</a>
|
||||
: <a href="/auth/login">{t('nav.signIn')}</a>}
|
||||
{/* Auf schmalen Schirmen ist .auth ausgeblendet — der
|
||||
Sprachwechsel muss trotzdem erreichbar bleiben. */}
|
||||
<div className="drawer-lang" onClick={(e) => e.stopPropagation()}>
|
||||
<LangSwitch />
|
||||
</div>
|
||||
</nav>
|
||||
)}
|
||||
|
||||
@@ -96,11 +104,11 @@ export default function BotApp() {
|
||||
<span className="footer-logo">D4RKBOT<span>.</span></span>
|
||||
<span className="footer-sep">//</span>
|
||||
<a href="https://git.d4rkst3r.de/D4rkst3r/d4rkbot" target="_blank" rel="noreferrer">
|
||||
Quellcode
|
||||
{t('footer.source')}
|
||||
</a>
|
||||
<span className="footer-sep">//</span>
|
||||
<NavLink to="/impressum">Impressum</NavLink>
|
||||
<NavLink to="/datenschutz">Datenschutz</NavLink>
|
||||
<NavLink to="/impressum">{t('footer.imprint')}</NavLink>
|
||||
<NavLink to="/datenschutz">{t('footer.privacy')}</NavLink>
|
||||
</footer>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user