diff --git a/client/src/components/Layout/BottomNav.test.tsx b/client/src/components/Layout/BottomNav.test.tsx
index d603a6a9..9244efc9 100644
--- a/client/src/components/Layout/BottomNav.test.tsx
+++ b/client/src/components/Layout/BottomNav.test.tsx
@@ -19,8 +19,10 @@ vi.mock('react-router-dom', async () => {
import { render, screen, fireEvent } from '../../../tests/helpers/render';
import userEvent from '@testing-library/user-event';
import { useAuthStore } from '../../store/authStore';
+import { useSettingsStore } from '../../store/settingsStore';
+import { useAddonStore } from '../../store/addonStore';
import { resetAllStores, seedStore } from '../../../tests/helpers/store';
-import { buildUser } from '../../../tests/helpers/factories';
+import { buildUser, buildSettings } from '../../../tests/helpers/factories';
import BottomNav from './BottomNav';
const currentUser = buildUser({ id: 1, username: 'testuser', email: 'test@example.com' });
@@ -39,7 +41,7 @@ describe('BottomNav', () => {
it('FE-COMP-BOTTOMNAV-002: shows Trips nav link', () => {
render();
- expect(screen.getByText('Trips')).toBeInTheDocument();
+ expect(screen.getByText('My Trips')).toBeInTheDocument();
});
it('FE-COMP-BOTTOMNAV-003: shows Profile button', () => {
@@ -99,4 +101,39 @@ describe('BottomNav', () => {
// Sheet should be closed — username no longer visible (only the nav Profile text remains)
expect(screen.queryByText('testuser')).not.toBeInTheDocument();
});
+
+ it('FE-COMP-BOTTOMNAV-010: Trips label translates when language is fr', () => {
+ seedStore(useSettingsStore, { settings: buildSettings({ language: 'fr' }) });
+ render();
+ expect(screen.getByText('Mes voyages')).toBeInTheDocument();
+ });
+
+ it('FE-COMP-BOTTOMNAV-011: Profile label translates when language is fr', () => {
+ seedStore(useSettingsStore, { settings: buildSettings({ language: 'fr' }) });
+ render();
+ expect(screen.getByText('Profil')).toBeInTheDocument();
+ });
+
+ it('FE-COMP-BOTTOMNAV-012: addon labels translate when language is fr', () => {
+ seedStore(useSettingsStore, { settings: buildSettings({ language: 'fr' }) });
+ seedStore(useAddonStore, {
+ addons: [
+ { id: 'vacay', name: 'Vacay', type: 'global', icon: 'calendar', enabled: true },
+ { id: 'atlas', name: 'Atlas', type: 'global', icon: 'globe', enabled: true },
+ { id: 'journey', name: 'Journey', type: 'global', icon: 'compass', enabled: true },
+ ],
+ });
+ render();
+ expect(screen.getByText('Vacances')).toBeInTheDocument();
+ expect(screen.getByText('Atlas')).toBeInTheDocument();
+ expect(screen.getByText('Journal de voyage')).toBeInTheDocument();
+ });
+
+ it('FE-COMP-BOTTOMNAV-013: unknown addon id is not rendered', () => {
+ seedStore(useAddonStore, {
+ addons: [{ id: 'foo', name: 'Foo Addon', type: 'global', icon: 'star', enabled: true }],
+ });
+ render();
+ expect(screen.queryByText('Foo Addon')).not.toBeInTheDocument();
+ });
});
diff --git a/client/src/components/Layout/BottomNav.tsx b/client/src/components/Layout/BottomNav.tsx
index 16aa9ffd..59fd9854 100644
--- a/client/src/components/Layout/BottomNav.tsx
+++ b/client/src/components/Layout/BottomNav.tsx
@@ -7,14 +7,10 @@ import { useTranslation } from '../../i18n'
import { Plane, CalendarDays, Globe, Compass, User, Settings, Shield, LogOut, X } from 'lucide-react'
import type { LucideIcon } from 'lucide-react'
-const BASE_ITEMS: { to: string; label: string; icon: LucideIcon; addonId?: string }[] = [
- { to: '/trips', label: 'Trips', icon: Plane },
-]
-
-const ADDON_NAV: Record = {
- vacay: { to: '/vacay', label: 'Vacay', icon: CalendarDays },
- atlas: { to: '/atlas', label: 'Atlas', icon: Globe },
- journey: { to: '/journey', label: 'Journey', icon: Compass },
+const ADDON_NAV: Record = {
+ vacay: { icon: CalendarDays, labelKey: 'admin.addons.catalog.vacay.name' },
+ atlas: { icon: Globe, labelKey: 'admin.addons.catalog.atlas.name' },
+ journey: { icon: Compass, labelKey: 'admin.addons.catalog.journey.name' },
}
export default function BottomNav() {
@@ -25,11 +21,13 @@ export default function BottomNav() {
const globalAddons = addons.filter(a => a.type === 'global' && a.enabled)
const [showProfile, setShowProfile] = useState(false)
- const items = [...BASE_ITEMS]
- for (const addon of globalAddons) {
- const nav = ADDON_NAV[addon.id]
- if (nav) items.push(nav)
- }
+ const items: { to: string; label: string; icon: LucideIcon }[] = [
+ { to: '/trips', label: t('nav.myTrips'), icon: Plane },
+ ...globalAddons.flatMap(addon => {
+ const nav = ADDON_NAV[addon.id]
+ return nav ? [{ to: `/${addon.id}`, label: t(nav.labelKey), icon: nav.icon }] : []
+ }),
+ ]
return (
<>