Translate nav bars

This commit is contained in:
MartinBraquet
2025-12-26 19:56:23 +02:00
parent 8c14212e10
commit ce447db6b5
5 changed files with 78 additions and 31 deletions

View File

@@ -14,6 +14,7 @@ import {User} from 'common/user'
import {Col} from 'web/components/layout/col'
import {useProfile} from 'web/hooks/use-profile'
import {useIsMobile} from "web/hooks/use-is-mobile"
import {useT} from "web/lib/locale";
const itemClass =
'sm:hover:bg-ink-200 block w-full py-1 px-3 text-center sm:hover:text-primary-700 transition-colors'
@@ -32,6 +33,7 @@ export function BottomNavBar(props: {
const currentPage = router.pathname
const user = useUser()
const t = useT()
const isIframe = useIsIframe()
if (isIframe) {
@@ -62,7 +64,7 @@ export function BottomNavBar(props: {
onClick={() => setSidebarOpen(true)}
>
<MenuAlt3Icon className="mx-auto my-1 h-6 w-6" aria-hidden="true"/>
More
{t('nav.more', 'More')}
</div>
<MobileSidebar
sidebarOpen={sidebarOpen}

View File

@@ -14,6 +14,7 @@ import {useProfile} from 'web/hooks/use-profile'
import Image from 'next/image'
import {ANDROID_APP_URL} from "common/constants";
import {isAndroidApp} from "web/lib/util/webview";
import {useT} from 'web/lib/locale'
export default function Sidebar(props: {
className?: string
@@ -29,7 +30,8 @@ export default function Sidebar(props: {
const navOptions = props.navigationOptions
const bottomNavOptions = bottomNav(!!user)
const t = useT()
const bottomNavOptions = bottomNav(!!user, t)
const isAndroid = isAndroidApp()
@@ -52,15 +54,15 @@ export default function Sidebar(props: {
<SidebarItem key={item.name} item={item} currentPage={currentPage}/>
))}
{!isAndroid && <Image
src="https://firebasestorage.googleapis.com/v0/b/compass-130ba.firebasestorage.app/o/misc%2FGoogle_Play_Store_badge_EN.svg.png?alt=media&token=3e0e8605-800a-422b-84d1-8ecec8af3e80"
alt="divider"
width={160}
height={80}
className="mx-auto pt-4 hover:opacity-70 cursor-pointer invert dark:invert-0"
onClick={() => router.push(ANDROID_APP_URL)}
src="https://firebasestorage.googleapis.com/v0/b/compass-130ba.firebasestorage.app/o/misc%2FGoogle_Play_Store_badge_EN.svg.png?alt=media&token=3e0e8605-800a-422b-84d1-8ecec8af3e80"
alt="divider"
width={160}
height={80}
className="mx-auto pt-4 hover:opacity-70 cursor-pointer invert dark:invert-0"
onClick={() => router.push(ANDROID_APP_URL)}
/>}
{user === null && <SignUpButton className="mt-4" text="Sign up"/>}
{user === null && <SignUpButton className="mt-4" text={t('nav.sign_up', 'Sign up')}/>}
{/*{user === null && <SignUpAsMatchmaker className="mt-2" />}*/}
{user && profile === null && (
@@ -87,10 +89,11 @@ const logout = async () => {
const bottomNav = (
loggedIn: boolean,
t: (k: string, fallback: string) => string,
) =>
buildArray<Item>(
!loggedIn && {name: 'Sign in', icon: LoginIcon, href: '/signin'},
loggedIn && {name: 'Sign out', icon: LogoutIcon, onClick: logout}
!loggedIn && {name: t('nav.sign_in', 'Sign in'), icon: LoginIcon, href: '/signin'},
loggedIn && {name: t('nav.sign_out', 'Sign out'), icon: LogoutIcon, onClick: logout}
)
export const SignUpButton = (props: {
@@ -100,6 +103,7 @@ export const SignUpButton = (props: {
size?: SizeType
}) => {
const {className, text, color, size} = props
const t = useT()
return (
<Button
@@ -108,7 +112,7 @@ export const SignUpButton = (props: {
onClick={signupRedirect}
className={clsx('w-full', className)}
>
{text ?? 'Sign up now'}
{text ?? t('nav.sign_up_now', 'Sign up now')}
</Button>
)
}

View File

@@ -12,7 +12,7 @@ import clsx from 'clsx'
import {User} from 'common/user'
import {buildArray} from 'common/util/array'
import {useOnline} from 'web/hooks/use-online'
import {ReactNode, useState} from 'react'
import {ReactNode, useEffect, useState} from 'react'
import {Toaster} from 'react-hot-toast'
import {Col} from 'web/components/layout/col'
import {PrivateMessagesIcon} from 'web/components/messaging/messages-icon'
@@ -28,6 +28,7 @@ import {NotificationsIcon, SolidNotificationsIcon} from './notifications-icon'
import {IS_MAINTENANCE} from "common/constants"
import {MdThumbUp} from "react-icons/md"
import {FaEnvelope} from "react-icons/fa"
import {useLocale, useT} from 'web/lib/locale'
export function PageBase(props: {
trackPageView: string | false
@@ -48,6 +49,10 @@ export function PageBase(props: {
const user = useUser()
const isMobile = useIsMobile()
const profile = useProfile()
const t = useT()
const {locale} = useLocale()
const bottomNavOptions = user
? getBottomNavigation(user, profile)
: getBottomSignedOutNavigation()
@@ -56,6 +61,22 @@ export function PageBase(props: {
const mobileSidebarOptions = getMobileSidebar(user, () => setIsAddFundsModalOpen(true))
useEffect(() => {
// Add this helper function to translate navigation options
const translateNavOptions = (options: any[]) => {
options.forEach(option => {
const key = `nav.${option.key}`;
option.name = t(key, option.name)
console.log(key)
})
}
translateNavOptions(bottomNavOptions)
translateNavOptions(desktopSidebarOptions)
translateNavOptions(mobileSidebarOptions)
}, [locale, bottomNavOptions, desktopSidebarOptions, mobileSidebarOptions, t]);
// eslint-disable-next-line react-hooks/rules-of-hooks
trackPageView && useTracking(`view ${trackPageView}`, trackPageProps)
useOnline()
@@ -107,20 +128,20 @@ export function PageBase(props: {
)
}
const Profiles = {name: 'People', href: '/', icon: UsersIcon}
const Home = {name: 'Home', href: '/', icon: HomeIcon}
const faq = {name: 'FAQ', href: '/faq', icon: SolidQuestionIcon}
const About = {name: 'About', href: '/about', icon: QuestionMarkCircleIcon}
const Signin = {name: 'Sign in', href: '/signin', icon: UserCircleIcon}
const Notifs = {name: 'Notifs', href: `/notifications`, icon: NotificationsIcon}
const NotifsSolid = {name: 'Notifs', href: `/notifications`, icon: SolidNotificationsIcon}
const Messages = {name: 'Messages', href: '/messages', icon: PrivateMessagesIcon}
const Social = {name: 'Social', href: '/social', icon: LinkIcon}
const Organization = {name: 'Organization', href: '/organization', icon: GlobeAltIcon}
const Vote = {name: 'Vote', href: '/vote', icon: MdThumbUp}
const Contact = {name: 'Contact', href: '/contact', icon: FaEnvelope}
const News = {name: "What's new", href: '/news', icon: NewspaperIcon}
const Settings = {name: "Settings", href: '/settings', icon: CogIcon}
const Profiles = {key: 'people', name: 'People', href: '/', icon: UsersIcon}
const Home = {key: 'home', name: 'Home', href: '/', icon: HomeIcon}
const faq = {key: 'faq', name: 'FAQ', href: '/faq', icon: SolidQuestionIcon}
const About = {key: 'about', name: 'About', href: '/about', icon: QuestionMarkCircleIcon}
const Signin = {key: 'signin', name: 'Sign in', href: '/signin', icon: UserCircleIcon}
const Notifs = {key: 'notifs', name: 'Notifs', href: `/notifications`, icon: NotificationsIcon}
const NotifsSolid = {key: 'notifs', name: 'Notifs', href: `/notifications`, icon: SolidNotificationsIcon}
const Messages = {key: 'messages', name: 'Messages', href: '/messages', icon: PrivateMessagesIcon}
const Social = {key: 'social', name: 'Social', href: '/social', icon: LinkIcon}
const Organization = {key: 'organization', name: 'Organization', href: '/organization', icon: GlobeAltIcon}
const Vote = {key: 'vote', name: 'Vote', href: '/vote', icon: MdThumbUp}
const Contact = {key: 'contact', name: 'Contact', href: '/contact', icon: FaEnvelope}
const News = {key: 'news', name: "What's new", href: '/news', icon: NewspaperIcon}
const Settings = {key: 'settings', name: "Settings", href: '/settings', icon: CogIcon}
const base = [
About,
@@ -137,11 +158,13 @@ function getBottomNavigation(user: User, profile: Profile | null | undefined) {
Profiles,
NotifsSolid,
{
key: 'profile',
name: 'Profile',
href: profile === null ? '/signup' : `/${user.username}`,
icon: SolidHomeIcon,
},
{
key: 'messages',
name: 'Messages',
href: '/messages',
icon: (props) => (

View File

@@ -37,8 +37,8 @@ export function useT() {
.catch(() => setMessages({}))
}, [locale])
return (key: string, english: string) => {
if (locale === defaultLocale) return english
return messages[key] ?? english
return (key: string, fallback: string) => {
if (locale === defaultLocale) return fallback
return messages[key] ?? fallback
}
}

View File

@@ -41,5 +41,23 @@
"home.feature2.text": "Recherchez et filtrez par valeurs, centres dintérêt, objectifs et mots-clés — de « stoïcisme » à « vie durable ». Faites émerger les connexions qui comptent vraiment.",
"home.feature3.title": "Communautaire & Open Source",
"home.feature3.text": "Gratuit pour toujours. Pas de pubs, pas dabonnements. Construit par et pour la communauté.",
"home.bottom": "Compass est aux relations humaines ce que Linux est au logiciel, Wikipédia est au savoir, et Firefox est à la navigation — un bien numérique public conçu pour servir les gens, pas le profit."
"home.bottom": "Compass est aux relations humaines ce que Linux est au logiciel, Wikipédia est au savoir, et Firefox est à la navigation — un bien numérique public conçu pour servir les gens, pas le profit.",
"nav.sign_in": "Se connecter",
"nav.sign_out": "Se déconnecter",
"nav.sign_up": "S'inscrire",
"nav.sign_up_now": "S'inscrire maintenant",
"nav.people": "Personnes",
"nav.home": "Accueil",
"nav.faq": "FAQ",
"nav.about": "À propos",
"nav.notifs": "Notifications",
"nav.messages": "Messages",
"nav.social": "Social",
"nav.organization": "Organisation",
"nav.vote": "Vote",
"nav.contact": "Contact",
"nav.news": "Quoi de neuf",
"nav.settings": "Paramètres",
"nav.more": "Plus",
"nav.profile": "Profil"
}