feat: add vue-i18n infrastructure and externalize all UI strings (A11Y-03)

Set up vue-i18n with English locale file containing 500+ keys organized
by view namespace. All 15 views converted to use t() calls instead of
hardcoded strings. Infrastructure ready for community translations.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-03-11 13:45:59 +00:00
co-authored by Claude Opus 4.6
parent b9cc0a924e
commit aba7aba25f
21 changed files with 2491 additions and 640 deletions
+6 -3
View File
@@ -1,7 +1,7 @@
<template>
<div class="min-h-screen flex relative dashboard-view" :class="{ 'glass-throw-active': showZoomIn }">
<!-- Skip to main content link for keyboard users -->
<a href="#main-content" class="skip-to-content">Skip to main content</a>
<a href="#main-content" class="skip-to-content">{{ t('common.skipToContent') }}</a>
<!-- Background container with 3D perspective - full width to avoid letterboxing -->
<div class="bg-perspective-container">
<!-- Background - primary layer (visible for all routes, transitions out only for detail pages) -->
@@ -76,7 +76,7 @@
</div>
</div>
<nav class="sidebar-nav flex-1 min-h-0 space-y-2 p-6 pt-4" aria-label="Main navigation">
<nav class="sidebar-nav flex-1 min-h-0 space-y-2 p-6 pt-4" :aria-label="t('dashboard.mainNav')">
<RouterLink
v-for="(item, idx) in desktopNavItems"
:key="item.path"
@@ -296,7 +296,7 @@
<nav
ref="mobileTabBar"
data-mobile-tab-bar
aria-label="Mobile navigation"
:aria-label="t('dashboard.mobileNav')"
class="md:hidden fixed bottom-0 left-0 right-0 border-t border-glass-border shadow-glass z-50 glass-piece"
:class="{ 'glass-throw-tabbar': showZoomIn }"
style="background: rgba(0, 0, 0, 0.25); backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px); padding-bottom: env(safe-area-inset-bottom, 0px);"
@@ -381,7 +381,10 @@
<script setup lang="ts">
import { computed, ref, watch, onMounted, onBeforeUnmount, nextTick } from 'vue'
import { RouterLink, RouterView, useRouter, useRoute, type RouteLocationNormalizedLoaded } from 'vue-router'
import { useI18n } from 'vue-i18n'
import { useAppStore } from '../stores/app'
const { t } = useI18n()
import { useLoginTransitionStore } from '../stores/loginTransition'
import AnimatedLogo from '@/components/AnimatedLogo.vue'
import OnlineStatusPill from '@/components/OnlineStatusPill.vue'