import i18n from 'i18next' import { initReactI18next } from 'react-i18next' const resources = { ru: { translation: { appName: 'TeleWave', nav: { home: 'Главная', dashboard: 'Эфир', admin: 'Админка', settings: 'Настройки', login: 'Войти', register: 'Регистрация', logout: 'Выйти', }, theme: { light: 'Светлая', dark: 'Тёмная', system: 'Системная' }, lang: { ru: 'RU', en: 'EN' }, common: { save: 'Сохранить', cancel: 'Отмена', delete: 'Удалить', create: 'Создать', loading: 'Загрузка…', error: 'Что-то пошло не так', confirm: 'Подтвердить', search: 'Поиск', actions: 'Действия', yes: 'Да', no: 'Нет', }, home: { title: 'TELEWAVE', subtitle: 'ЭФИРНАЯ СЕТКА КАНАЛОВ', tagline: 'Твои каналы. Твой эфир. В любое время.', cta: 'Войти в эфир', ctaRegister: 'Создать аккаунт', }, auth: { userName: 'Имя пользователя', password: 'Пароль', loginTitle: 'Вход в эфир', loginSubtitle: 'Введите учётные данные для доступа к сетке каналов', registerTitle: 'Новый зритель', registerSubtitle: 'Создайте аккаунт, чтобы настроить свою сетку каналов', submitLogin: 'Войти', submitRegister: 'Зарегистрироваться', noAccount: 'Нет аккаунта?', haveAccount: 'Уже есть аккаунт?', invalidCredentials: 'Неверное имя пользователя или пароль', userNameTaken: 'Это имя пользователя уже занято', blocked: 'Аккаунт заблокирован администратором', genericError: 'Не удалось выполнить вход. Попробуйте ещё раз', }, dashboard: { welcome: 'На связи, {{userName}}', placeholder: 'Список каналов появится здесь позже — пока в эфире только тестовая заставка.', role: 'Роль', }, air: { now: 'Сейчас', next: 'Далее', ad: 'Реклама', episode: 'Серия', live: 'В эфире', noChannels: 'Пока нет доступных каналов. Загляните позже.', offline: 'Канал сейчас не в эфире', offlineHint: 'Нет расписания или контента. Загляните позже.', retry: 'Повторить', }, settings: { title: 'Настройки аккаунта', changeUserName: 'Смена имени пользователя', newUserName: 'Новое имя пользователя', changePassword: 'Смена пароля', currentPassword: 'Текущий пароль', newPassword: 'Новый пароль', dangerZone: 'Опасная зона', deleteAccount: 'Удалить аккаунт', deleteAccountConfirm: 'Аккаунт и все данные будут удалены безвозвратно. Продолжить?', saved: 'Сохранено', }, admin: { roles: { title: 'Роли', name: 'Название', system: 'Системная', create: 'Новая роль', rename: 'Переименовать', cannotModifySystem: 'Системную роль нельзя изменить или удалить', roleInUse: 'Роль назначена пользователям', }, users: { title: 'Пользователи', userName: 'Имя пользователя', role: 'Роль', status: 'Статус', createdAt: 'Регистрация', blocked: 'Заблокирован', active: 'Активен', block: 'Заблокировать', unblock: 'Разблокировать', filterAll: 'Все роли', }, media: { title: 'Медиа', upload: 'Загрузить', uploaded: 'Файл загружен, идёт обработка', uploadedCount: 'Загружено файлов: {{count}}', skippedDuplicates: 'Пропущено дубликатов: {{count}}', filterActive: 'Активные', filterAll: 'Все', name: 'Файл', status: 'Статус', duration: 'Длительность', resolution: 'Разрешение', empty: 'Пока нет загруженных файлов', statuses: { Pending: 'В очереди', Processing: 'Обработка', Ready: 'Готов', Failed: 'Ошибка', }, }, shows: { title: 'Шоу', name: 'Название', kind: 'Тип', kinds: { Series: 'Сериал', Single: 'Полнометражка' }, seasons: 'Сезоны', episodes: 'Серии', episode: 'Серия', addEpisode: 'Добавить серию', pickAsset: 'Выберите файл', noEpisodes: 'Серий пока нет', filterAssets: 'Фильтр по имени, напр. Family.Guy.S16', selectAll: 'Выбрать все', deselectAll: 'Снять все', addSelected: 'Добавить выбранные', noMatches: 'Нет подходящих файлов', addedCount: 'Добавлено серий: {{count}}', }, channels: { title: 'Каналы', name: 'Название', slug: 'Slug', state: 'Состояние', enabled: 'В эфире', disabled: 'Выключен', enabledLabel: 'Канал в эфире', regenerate: 'Пересобрать', regenerated: 'Расписание пересобрано', settings: 'Настройки', adPolicy: 'Реклама', betweenBlocks: 'Между блоками', betweenEpisodes: 'Между сериями', adsPerBreak: 'Роликов подряд', filler: 'Заглушка', noFiller: 'Без заглушки', shows: 'Шоу канала', show: 'Шоу', weight: 'Вес', block: 'Блок', on: 'Вкл', noShows: 'Шоу не добавлены', pickShow: 'Выберите шоу', blockCount: 'По сериям', blockDuration: 'По времени', episodes: 'серий', minutes: 'минут', ads: 'Реклама', pickAd: 'Выберите ролик', noAds: 'Пул рекламы пуст', overrides: 'Марафоны / override', modes: { Exclusive: 'Эксклюзив', Boost: 'Буст' }, from: 'С', to: 'По', noOverrides: 'Override не заданы', schedule: 'Расписание (12 ч)', noSchedule: 'Расписание ещё не построено — нажмите «Пересобрать»', }, maintenance: { title: 'Обслуживание', warning: 'Операции необратимы — удаляют данные и файлы навсегда.', clearMedia: 'Очистить все медиа', clearMediaHint: 'Удалит все загруженные файлы и их нарезку, а также расписание каналов.', confirmClearMedia: 'Удалить ВСЕ медиа-файлы безвозвратно?', clearShowMedia: 'Удалить медиа шоу', clearShowMediaHint: 'Удалит файлы всех серий выбранного шоу и очистит его серии.', confirmClearShowMedia: 'Удалить все медиа выбранного шоу безвозвратно?', pickShow: 'Выберите шоу', deleteShows: 'Удалить все шоу', deleteShowsHint: 'Удалит все шоу и их серии. Медиа-файлы останутся в библиотеке.', confirmDeleteShows: 'Удалить ВСЕ шоу безвозвратно?', doneCount: 'Удалено: {{count}}', }, }, }, }, en: { translation: { appName: 'TeleWave', nav: { home: 'Home', dashboard: 'On Air', admin: 'Admin', settings: 'Settings', login: 'Log in', register: 'Sign up', logout: 'Log out', }, theme: { light: 'Light', dark: 'Dark', system: 'System' }, lang: { ru: 'RU', en: 'EN' }, common: { save: 'Save', cancel: 'Cancel', delete: 'Delete', create: 'Create', loading: 'Loading…', error: 'Something went wrong', confirm: 'Confirm', search: 'Search', actions: 'Actions', yes: 'Yes', no: 'No', }, home: { title: 'TELEWAVE', subtitle: 'BROADCAST CHANNEL GRID', tagline: 'Your channels. Your broadcast. Anytime.', cta: 'Go on air', ctaRegister: 'Create account', }, auth: { userName: 'Username', password: 'Password', loginTitle: 'Sign in', loginSubtitle: 'Enter your credentials to access the channel grid', registerTitle: 'New viewer', registerSubtitle: 'Create an account to set up your channel grid', submitLogin: 'Log in', submitRegister: 'Sign up', noAccount: "Don't have an account?", haveAccount: 'Already have an account?', invalidCredentials: 'Invalid username or password', userNameTaken: 'This username is already taken', blocked: 'Account blocked by an administrator', genericError: 'Could not sign in. Please try again', }, dashboard: { welcome: 'On air, {{userName}}', placeholder: 'The channel list will show up here later — for now, enjoy the test card.', role: 'Role', }, air: { now: 'Now', next: 'Up next', ad: 'Ad', episode: 'Episode', live: 'Live', noChannels: 'No channels available yet. Check back later.', offline: 'This channel is off the air', offlineHint: 'No schedule or content yet. Check back later.', retry: 'Retry', }, settings: { title: 'Account settings', changeUserName: 'Change username', newUserName: 'New username', changePassword: 'Change password', currentPassword: 'Current password', newPassword: 'New password', dangerZone: 'Danger zone', deleteAccount: 'Delete account', deleteAccountConfirm: 'The account and all its data will be permanently deleted. Continue?', saved: 'Saved', }, admin: { roles: { title: 'Roles', name: 'Name', system: 'System', create: 'New role', rename: 'Rename', cannotModifySystem: 'A system role cannot be modified or deleted', roleInUse: 'Role is assigned to users', }, users: { title: 'Users', userName: 'Username', role: 'Role', status: 'Status', createdAt: 'Joined', blocked: 'Blocked', active: 'Active', block: 'Block', unblock: 'Unblock', filterAll: 'All roles', }, media: { title: 'Media', upload: 'Upload', uploaded: 'File uploaded, processing started', uploadedCount: 'Uploaded files: {{count}}', skippedDuplicates: 'Skipped duplicates: {{count}}', filterActive: 'Active', filterAll: 'All', name: 'File', status: 'Status', duration: 'Duration', resolution: 'Resolution', empty: 'No uploaded files yet', statuses: { Pending: 'Queued', Processing: 'Processing', Ready: 'Ready', Failed: 'Failed', }, }, shows: { title: 'Shows', name: 'Name', kind: 'Kind', kinds: { Series: 'Series', Single: 'Movie' }, seasons: 'Seasons', episodes: 'Episodes', episode: 'Episode', addEpisode: 'Add episode', pickAsset: 'Pick a file', noEpisodes: 'No episodes yet', filterAssets: 'Filter by name, e.g. Family.Guy.S16', selectAll: 'Select all', deselectAll: 'Clear', addSelected: 'Add selected', noMatches: 'No matching files', addedCount: 'Episodes added: {{count}}', }, channels: { title: 'Channels', name: 'Name', slug: 'Slug', state: 'State', enabled: 'On air', disabled: 'Off', enabledLabel: 'Channel on air', regenerate: 'Rebuild', regenerated: 'Schedule rebuilt', settings: 'Settings', adPolicy: 'Ads', betweenBlocks: 'Between blocks', betweenEpisodes: 'Between episodes', adsPerBreak: 'Ads per break', filler: 'Filler', noFiller: 'No filler', shows: 'Channel shows', show: 'Show', weight: 'Weight', block: 'Block', on: 'On', noShows: 'No shows added', pickShow: 'Pick a show', blockCount: 'By episodes', blockDuration: 'By time', episodes: 'episodes', minutes: 'minutes', ads: 'Ads', pickAd: 'Pick an ad', noAds: 'Ad pool is empty', overrides: 'Marathons / overrides', modes: { Exclusive: 'Exclusive', Boost: 'Boost' }, from: 'From', to: 'To', noOverrides: 'No overrides set', schedule: 'Schedule (12h)', noSchedule: 'Schedule not built yet — click “Rebuild”', }, maintenance: { title: 'Maintenance', warning: 'These actions are irreversible — data and files are deleted permanently.', clearMedia: 'Clear all media', clearMediaHint: 'Deletes all uploaded files and their segments, plus channel schedules.', confirmClearMedia: 'Permanently delete ALL media files?', clearShowMedia: 'Delete show media', clearShowMediaHint: "Deletes files of the selected show's episodes and clears its episodes.", confirmClearShowMedia: 'Permanently delete all media of the selected show?', pickShow: 'Pick a show', deleteShows: 'Delete all shows', deleteShowsHint: 'Deletes all shows and their episodes. Media files stay in the library.', confirmDeleteShows: 'Permanently delete ALL shows?', doneCount: 'Deleted: {{count}}', }, }, }, }, } const STORAGE_KEY = 'tw-lang' const stored = typeof localStorage !== 'undefined' ? localStorage.getItem(STORAGE_KEY) : null void i18n.use(initReactI18next).init({ resources, lng: stored ?? 'ru', fallbackLng: 'ru', interpolation: { escapeValue: false }, }) export function setLanguage(lng: string) { localStorage.setItem(STORAGE_KEY, lng) void i18n.changeLanguage(lng) } export default i18n