Files
FamilyHUB/frontend/src/i18n.ts
T

342 lines
16 KiB
TypeScript

import { computed, reactive } from 'vue'
export type Locale = 'en' | 'ru'
type Messages = Record<string, string>
const STORAGE_KEY = 'familyhub-locale'
const messages: Record<Locale, Messages> = {
en: {
'language.english': 'English',
'language.russian': 'Russian',
'language.title': 'Language',
'language.description': 'Choose your app language',
'nav.calendar': 'Calendar',
'nav.finance': 'Finance',
'nav.home': 'Home',
'nav.votes': 'Votes',
'nav.intimacy': 'Intimacy',
'header.greeting.night': 'Good night',
'header.greeting.morning': 'Good morning',
'header.greeting.afternoon': 'Good afternoon',
'header.greeting.evening': 'Good evening',
'header.familyName': 'Anderson Family',
'home.balance.total': 'Total Balance',
'home.balance.income': 'Income',
'home.balance.expenses': 'Expenses',
'home.today.title': 'Today',
'home.today.events': 'events',
'home.today.event.familyDinner': 'Family Dinner',
'home.today.event.movieNight': 'Movie Night',
'home.today.location.home': 'Home',
'home.today.location.livingRoom': 'Living Room',
'home.activity.title': 'Activity',
'home.activity.viewAll': 'View all',
'home.activity.shopping': 'Grocery Shopping',
'home.activity.shoppingSubtitle': 'Sarah • $124.50',
'home.activity.movieVote': 'Movie Vote',
'home.activity.movieVoteSubtitle': '3 votes for "Dune 2"',
'home.activity.subscription': 'Subscription',
'home.activity.subscriptionSubtitle': 'Netflix • $15.99',
'home.activity.newEvent': 'New Event',
'home.activity.newEventSubtitle': 'Family BBQ Saturday',
'home.swipe.title': 'Vote Now',
'home.swipe.subtitle': 'Swipe to decide',
'home.swipe.type.food': 'Restaurant',
'home.swipe.type.movie': 'Movie',
'home.swipe.card.italian.title': 'Italian Restaurant',
'home.swipe.card.italian.subtitle': 'Authentic pasta & pizza',
'home.swipe.card.italian.location': '2.3 km away',
'home.swipe.card.dune.title': 'Dune: Part Two',
'home.swipe.card.dune.subtitle': 'Sci-Fi Epic',
'home.swipe.card.dune.duration': '2h 46m',
'home.swipe.card.sushi.title': 'Sushi House',
'home.swipe.card.sushi.subtitle': 'Fresh Japanese cuisine',
'home.swipe.card.sushi.location': '1.8 km away',
'finance.header.eyebrow': 'Family budget',
'finance.header.title': 'Finance',
'finance.tab.transactions': 'Transactions',
'finance.tab.analytics': 'Analytics',
'finance.tab.categories': 'Categories',
'finance.balance.total': 'Total Balance',
'finance.balance.vsLastMonth': 'vs last month',
'finance.balance.thisMonth': 'This Month',
'finance.balance.income': 'income',
'finance.balance.expenses': 'Expenses',
'finance.balance.saved': 'saved',
'finance.transactions.today': 'Today',
'finance.transactions.yesterday': 'Yesterday',
'finance.transactions.apr1': 'Apr 1',
'finance.transactions.loading': 'Loading transactions...',
'finance.transactions.empty': 'No transactions yet',
'finance.transactions.error': 'Failed to load transactions',
'finance.transactions.untitled': 'Transaction',
'finance.category.groceries': 'Groceries',
'finance.category.foodDining': 'Food & Dining',
'finance.category.coffee': 'Coffee',
'finance.category.income': 'Income',
'finance.category.transport': 'Transport',
'finance.category.entertainment': 'Entertainment',
'finance.category.donation': 'Donation',
'finance.category.housing': 'Housing',
'finance.analytics.avgIncome': 'Avg. Income',
'finance.analytics.growth': '+5.2% growth',
'finance.analytics.avgExpenses': 'Avg. Expenses',
'finance.analytics.decrease': '-12% decrease',
'finance.analytics.byCategory': 'Spending by Category',
'finance.analytics.lastMonths': 'Last 6 Months',
'finance.analytics.month.oct': 'Oct',
'finance.analytics.month.nov': 'Nov',
'finance.analytics.month.dec': 'Dec',
'finance.analytics.month.jan': 'Jan',
'finance.analytics.month.feb': 'Feb',
'finance.analytics.month.mar': 'Mar',
'finance.analytics.month.income': 'Income',
'finance.analytics.month.expenses': 'Expenses',
'finance.analytics.food': 'Food',
'finance.analytics.transport': 'Transport',
'finance.analytics.shopping': 'Shopping',
'finance.analytics.bills': 'Bills',
'finance.analytics.others': 'Others',
'finance.categories.foodDining': 'Food & Dining',
'finance.categories.shopping': 'Shopping',
'finance.categories.transport': 'Transport',
'finance.categories.housing': 'Housing',
'finance.categories.entertainment': 'Entertainment',
'finance.categories.coffee': 'Coffee',
'finance.categories.billsUtilities': 'Bills & Utilities',
'finance.categories.work': 'Work',
'finance.categories.giftsDonations': 'Gifts & Donations',
'finance.categories.others': 'Others',
'finance.categories.of': 'of',
'settings.header.eyebrow': 'Manage your family hub',
'settings.header.title': 'Settings',
'settings.profile.role': 'Family Admin',
'settings.section.family': 'Family',
'settings.section.customization': 'Customization',
'settings.section.activeModules': 'Active Modules',
'settings.section.privacy': 'Privacy & Security',
'settings.section.advanced': 'Advanced',
'settings.family.members.label': 'Family Members',
'settings.family.members.description': 'Manage family access',
'settings.family.roles.label': 'Roles & Permissions',
'settings.family.roles.description': 'Control what members can do',
'settings.customization.widgets.label': 'Dashboard Widgets',
'settings.customization.widgets.description': 'Customize your home screen',
'settings.customization.theme.label': 'Theme & Appearance',
'settings.customization.theme.description': 'Dark mode, colors, fonts',
'settings.privacy.label': 'Privacy Settings',
'settings.privacy.description': 'Control data sharing',
'settings.visibility.label': 'Visibility Controls',
'settings.visibility.description': 'Who can see what',
'settings.security.label': 'Security',
'settings.security.description': 'Password, 2FA, biometrics',
'settings.notifications.label': 'Notifications',
'settings.notifications.description': 'Push, email, SMS settings',
'settings.preferences.label': 'App Preferences',
'settings.preferences.description': 'Language, timezone, units',
'settings.module.finance': 'Finance Tracking',
'settings.module.calendar': 'Family Calendar',
'settings.module.food': 'Food Voting',
'settings.module.movies': 'Movie Voting',
'settings.module.activities': 'Activity Feed',
'settings.module.active': 'Active',
'settings.module.disabled': 'Disabled',
'settings.signOut': 'Sign Out',
},
ru: {
'language.english': 'Английский',
'language.russian': 'Русский',
'language.title': 'Язык',
'language.description': 'Выберите язык приложения',
'nav.calendar': 'Календарь',
'nav.finance': 'Финансы',
'nav.home': 'Главная',
'nav.votes': 'Голосования',
'nav.intimacy': 'Близость',
'header.greeting.night': 'Доброй ночи',
'header.greeting.morning': 'Доброе утро',
'header.greeting.afternoon': 'Добрый день',
'header.greeting.evening': 'Добрый вечер',
'header.familyName': 'Семья Андерсон',
'home.balance.total': 'Общий баланс',
'home.balance.income': 'Доходы',
'home.balance.expenses': 'Расходы',
'home.today.title': 'Сегодня',
'home.today.events': 'события',
'home.today.event.familyDinner': 'Семейный ужин',
'home.today.event.movieNight': 'Киновечер',
'home.today.location.home': 'Дом',
'home.today.location.livingRoom': 'Гостиная',
'home.activity.title': 'Активность',
'home.activity.viewAll': 'Смотреть все',
'home.activity.shopping': 'Покупка продуктов',
'home.activity.shoppingSubtitle': 'Сара • $124.50',
'home.activity.movieVote': 'Голосование за фильм',
'home.activity.movieVoteSubtitle': '3 голоса за "Дюна 2"',
'home.activity.subscription': 'Подписка',
'home.activity.subscriptionSubtitle': 'Netflix • $15.99',
'home.activity.newEvent': 'Новое событие',
'home.activity.newEventSubtitle': 'Семейное барбекю в субботу',
'home.swipe.title': 'Голосуйте',
'home.swipe.subtitle': 'Свайпните, чтобы выбрать',
'home.swipe.type.food': 'Ресторан',
'home.swipe.type.movie': 'Фильм',
'home.swipe.card.italian.title': 'Итальянский ресторан',
'home.swipe.card.italian.subtitle': 'Аутентичная паста и пицца',
'home.swipe.card.italian.location': '2.3 км отсюда',
'home.swipe.card.dune.title': 'Дюна: Часть вторая',
'home.swipe.card.dune.subtitle': 'Научно-фантастический эпик',
'home.swipe.card.dune.duration': '2 ч 46 мин',
'home.swipe.card.sushi.title': 'Суши Хаус',
'home.swipe.card.sushi.subtitle': 'Свежая японская кухня',
'home.swipe.card.sushi.location': '1.8 км отсюда',
'finance.header.eyebrow': 'Семейный бюджет',
'finance.header.title': 'Финансы',
'finance.tab.transactions': 'Транзакции',
'finance.tab.analytics': 'Аналитика',
'finance.tab.categories': 'Категории',
'finance.balance.total': 'Общий баланс',
'finance.balance.vsLastMonth': 'по сравнению с прошлым месяцем',
'finance.balance.thisMonth': 'Этот месяц',
'finance.balance.income': 'доход',
'finance.balance.expenses': 'Расходы',
'finance.balance.saved': 'сэкономлено',
'finance.transactions.today': 'Сегодня',
'finance.transactions.yesterday': 'Вчера',
'finance.transactions.apr1': '1 апр',
'finance.transactions.loading': 'Загрузка транзакций...',
'finance.transactions.empty': 'Транзакций пока нет',
'finance.transactions.error': 'Не удалось загрузить транзакции',
'finance.transactions.untitled': 'Транзакция',
'finance.category.groceries': 'Продукты',
'finance.category.foodDining': 'Еда и рестораны',
'finance.category.coffee': 'Кофе',
'finance.category.income': 'Доход',
'finance.category.transport': 'Транспорт',
'finance.category.entertainment': 'Развлечения',
'finance.category.donation': 'Пожертвование',
'finance.category.housing': 'Жильё',
'finance.analytics.avgIncome': 'Средний доход',
'finance.analytics.growth': '+5.2% рост',
'finance.analytics.avgExpenses': 'Средние расходы',
'finance.analytics.decrease': '-12% снижение',
'finance.analytics.byCategory': 'Расходы по категориям',
'finance.analytics.lastMonths': 'Последние 6 месяцев',
'finance.analytics.month.oct': 'Окт',
'finance.analytics.month.nov': 'Ноя',
'finance.analytics.month.dec': 'Дек',
'finance.analytics.month.jan': 'Янв',
'finance.analytics.month.feb': 'Фев',
'finance.analytics.month.mar': 'Мар',
'finance.analytics.month.income': 'Доход',
'finance.analytics.month.expenses': 'Расходы',
'finance.analytics.food': 'Еда',
'finance.analytics.transport': 'Транспорт',
'finance.analytics.shopping': 'Покупки',
'finance.analytics.bills': 'Счета',
'finance.analytics.others': 'Прочее',
'finance.categories.foodDining': 'Еда и рестораны',
'finance.categories.shopping': 'Покупки',
'finance.categories.transport': 'Транспорт',
'finance.categories.housing': 'Жильё',
'finance.categories.entertainment': 'Развлечения',
'finance.categories.coffee': 'Кофе',
'finance.categories.billsUtilities': 'Счета и коммунальные',
'finance.categories.work': 'Работа',
'finance.categories.giftsDonations': 'Подарки и пожертвования',
'finance.categories.others': 'Прочее',
'finance.categories.of': 'из',
'settings.header.eyebrow': 'Управляйте семейным хабом',
'settings.header.title': 'Настройки',
'settings.profile.role': 'Администратор семьи',
'settings.section.family': 'Семья',
'settings.section.customization': 'Кастомизация',
'settings.section.activeModules': 'Активные модули',
'settings.section.privacy': 'Конфиденциальность и защита',
'settings.section.advanced': 'Дополнительно',
'settings.family.members.label': 'Члены семьи',
'settings.family.members.description': 'Управление доступом семьи',
'settings.family.roles.label': 'Роли и разрешения',
'settings.family.roles.description': 'Контроль возможностей участников',
'settings.customization.widgets.label': 'Виджеты дашборда',
'settings.customization.widgets.description': 'Настройте главный экран',
'settings.customization.theme.label': 'Тема и внешний вид',
'settings.customization.theme.description': 'Тёмная тема, цвета, шрифты',
'settings.privacy.label': 'Настройки приватности',
'settings.privacy.description': 'Управление обменом данными',
'settings.visibility.label': 'Параметры видимости',
'settings.visibility.description': 'Кто что может видеть',
'settings.security.label': 'Безопасность',
'settings.security.description': 'Пароль, 2FA, биометрия',
'settings.notifications.label': 'Уведомления',
'settings.notifications.description': 'Push, email, SMS настройки',
'settings.preferences.label': 'Параметры приложения',
'settings.preferences.description': 'Язык, часовой пояс, единицы',
'settings.module.finance': 'Учёт финансов',
'settings.module.calendar': 'Семейный календарь',
'settings.module.food': 'Голосование за еду',
'settings.module.movies': 'Голосование за фильмы',
'settings.module.activities': 'Лента активности',
'settings.module.active': 'Активен',
'settings.module.disabled': 'Отключён',
'settings.signOut': 'Выйти',
},
}
function detectLocale(): Locale {
if (typeof window === 'undefined') {
return 'en'
}
const stored = window.localStorage.getItem(STORAGE_KEY)
if (stored === 'en' || stored === 'ru') {
return stored
}
const browserLocale = window.navigator.language.toLowerCase()
return browserLocale.startsWith('ru') ? 'ru' : 'en'
}
const state = reactive({
locale: detectLocale() as Locale,
})
export function setLocale(locale: Locale) {
state.locale = locale
if (typeof window !== 'undefined') {
window.localStorage.setItem(STORAGE_KEY, locale)
}
}
export function useI18n() {
const locale = computed(() => state.locale)
function t(key: string): string {
return messages[state.locale][key] ?? messages.en[key] ?? key
}
return {
locale,
setLocale,
t,
}
}