feat: Initial implementation of GymFlow fitness tracking application with workout, plan, and exercise management, stats, and AI coach features.

This commit is contained in:
aodulov
2025-11-19 07:39:39 +02:00
commit 10819cc6f5
23 changed files with 6241 additions and 0 deletions

279
services/i18n.ts Normal file
View File

@@ -0,0 +1,279 @@
import { Language } from '../types';
export const getSystemLanguage = (): Language => {
if (typeof navigator === 'undefined') return 'en';
const lang = navigator.language.split('-')[0];
return lang === 'ru' ? 'ru' : 'en';
};
const translations = {
en: {
// Tabs
tab_tracker: 'Tracker',
tab_plans: 'Plans',
tab_history: 'History',
tab_stats: 'Stats',
tab_ai: 'AI Coach',
tab_profile: 'Profile',
// Auth
login_title: 'GymFlow AI',
login_email: 'Email',
login_password: 'Password',
login_btn: 'Login',
login_contact_admin: 'Contact administrator to get an account.',
login_error: 'Invalid email or password',
login_password_short: 'Password too short',
change_pass_title: 'Change Password',
change_pass_desc: 'This is your first login. Please set a new password.',
change_pass_new: 'New Password',
change_pass_save: 'Save & Login',
// Tracker
ready_title: 'Ready?',
ready_subtitle: 'Start your workout and break records.',
my_weight: 'My Weight (kg)',
change_in_profile: 'Change in profile',
free_workout: 'Free Workout',
or_choose_plan: 'Or choose a plan',
exercises_count: 'exercises',
prep_title: 'Preparation',
prep_no_instructions: 'No specific instructions.',
cancel: 'Cancel',
start: 'Start',
finish: 'Finish',
plan_completed: 'Plan Completed!',
step: 'Step',
of: 'of',
select_exercise: 'Select Exercise',
weight_kg: 'Weight (kg)',
reps: 'Reps',
time_sec: 'Time (sec)',
dist_m: 'Dist (m)',
height_cm: 'Height (cm)',
body_weight_percent: 'Body Weight',
log_set: 'Log Set',
prev: 'Prev',
history_section: 'History',
create_exercise: 'New Exercise',
ex_name: 'Name',
ex_type: 'Type',
create_btn: 'Create',
completed_session_sets: 'Completed in this session',
add_weight: 'Add. Weight',
// Types
type_strength: 'Strength',
type_bodyweight: 'Bodyweight',
type_cardio: 'Cardio',
type_static: 'Static',
type_height: 'Height',
type_dist: 'Length',
type_jump: 'Plyo',
// History
history_empty: 'History is empty. Finish your first workout!',
sets_count: 'Sets',
finished: 'Finished',
delete_workout: 'Delete workout?',
delete_confirm: 'This action cannot be undone.',
delete: 'Delete',
edit: 'Edit',
save: 'Save',
start_time: 'Start',
end_time: 'End',
max: 'Max',
upto: 'Up to',
// Plans
plans_empty: 'No plans created',
plan_editor: 'Plan Editor',
plan_name_ph: 'E.g. Leg Day',
plan_desc_ph: 'Describe preparation...',
exercises_list: 'Exercises',
weighted: 'Weighted',
add_exercise: 'Add Exercise',
my_plans: 'My Plans',
// Stats
progress: 'Progress',
volume_title: 'Work Volume',
volume_subtitle: 'Tonnage (kg * reps)',
sets_title: 'Number of Sets',
weight_title: 'Body Weight History',
not_enough_data: 'Not enough data for statistics. Complete a few workouts!',
// AI
ai_expert: 'AI Expert',
ai_intro: 'Hi! I am your AI coach. I analyzed your workouts. Ask me about progress, technique, or routine.',
ai_typing: 'Typing...',
ai_placeholder: 'Ask about workouts...',
ai_error: 'API Key not configured',
// Profile
profile_title: 'Profile',
logout: 'Logout',
personal_data: 'Personal Data',
height: 'Height (cm)',
birth_date: 'Birth Date',
gender: 'Gender',
male: 'Male',
female: 'Female',
other: 'Other',
save_profile: 'Save Profile',
change_pass_btn: 'Change Password',
admin_area: 'Manage Users',
create_user: 'Create User',
user_created: 'User created',
language: 'Language',
admin_users_list: 'Users List',
block: 'Block',
unblock: 'Unblock',
reset_pass: 'Reset Pass',
delete_account: 'Delete Account',
delete_account_confirm: 'Are you sure? All your data (sessions, plans) will be permanently deleted.',
user_deleted: 'User deleted',
pass_reset: 'Password reset',
manage_exercises: 'Manage Exercises',
archive: 'Archive',
unarchive: 'Unarchive',
show_archived: 'Show Archived',
},
ru: {
// Tabs
tab_tracker: 'Трекер',
tab_plans: 'Планы',
tab_history: 'История',
tab_stats: 'Статы',
tab_ai: 'AI Тренер',
tab_profile: 'Профиль',
// Auth
login_title: 'GymFlow AI',
login_email: 'Email',
login_password: 'Пароль',
login_btn: 'Войти',
login_contact_admin: 'Свяжитесь с администратором для получения учетной записи.',
login_error: 'Неверный email или пароль',
login_password_short: 'Пароль слишком короткий',
change_pass_title: 'Смена пароля',
change_pass_desc: 'Это ваш первый вход. Пожалуйста, установите новый пароль.',
change_pass_new: 'Новый пароль',
change_pass_save: 'Сохранить и войти',
// Tracker
ready_title: 'Готовы?',
ready_subtitle: 'Начните тренировку и побейте рекорды.',
my_weight: 'Мой вес (кг)',
change_in_profile: 'Можно изменить в профиле',
free_workout: 'Свободная тренировка',
or_choose_plan: 'Или выберите план',
exercises_count: 'упражнений',
prep_title: 'Подготовка',
prep_no_instructions: 'Нет особых указаний.',
cancel: 'Отмена',
start: 'Начать',
finish: 'Завершить',
plan_completed: 'План выполнен!',
step: 'Шаг',
of: 'из',
select_exercise: 'Выберите упражнение',
weight_kg: 'Вес (кг)',
reps: 'Повторения',
time_sec: 'Время (сек)',
dist_m: 'Дистанция (м)',
height_cm: 'Высота (см)',
body_weight_percent: 'Вес тела',
log_set: 'Записать подход',
prev: 'Предыдущий',
history_section: 'История',
create_exercise: 'Новое упражнение',
ex_name: 'Название',
ex_type: 'Тип упражнения',
create_btn: 'Создать',
completed_session_sets: 'Выполнено в этой тренировке',
add_weight: 'Доп. вес',
// Types
type_strength: 'Силовое',
type_bodyweight: 'Свой вес',
type_cardio: 'Кардио',
type_static: 'Статика',
type_height: 'Высота',
type_dist: 'Длина',
type_jump: 'Прыжки',
// History
history_empty: 'История пуста. Завершите свою первую тренировку!',
sets_count: 'Сетов',
finished: 'Завершено',
delete_workout: 'Удалить тренировку?',
delete_confirm: 'Это действие нельзя отменить.',
delete: 'Удалить',
edit: 'Редактировать',
save: 'Сохранить',
start_time: 'Начало',
end_time: 'Конец',
max: 'Макс',
upto: 'До',
// Plans
plans_empty: 'Нет созданных планов',
plan_editor: 'Редактор плана',
plan_name_ph: 'Например: День ног',
plan_desc_ph: 'Опишите подготовку...',
exercises_list: 'Упражнения',
weighted: 'С отягощением',
add_exercise: 'Добавить упражнение',
my_plans: 'Мои планы',
// Stats
progress: 'Прогресс',
volume_title: 'Объем работы',
volume_subtitle: 'Тоннаж (кг * повторения)',
sets_title: 'Количество сетов',
weight_title: 'История веса тела',
not_enough_data: 'Недостаточно данных для статистики. Проведите хотя бы пару тренировок!',
// AI
ai_expert: 'AI Эксперт',
ai_intro: 'Привет! Я твой AI-тренер. Я проанализировал твои тренировки. Спрашивай меня о прогрессе, технике или плане занятий.',
ai_typing: 'Печатает...',
ai_placeholder: 'Спроси о тренировках...',
ai_error: 'API ключ не настроен',
// Profile
profile_title: 'Профиль',
logout: 'Выйти',
personal_data: 'Личные данные',
height: 'Рост (см)',
birth_date: 'Дата рожд.',
gender: 'Пол',
male: 'Мужской',
female: 'Женский',
other: 'Другой',
save_profile: 'Сохранить профиль',
change_pass_btn: 'Сменить пароль',
admin_area: 'Управление пользователями',
create_user: 'Создать пользователя',
user_created: 'Пользователь создан',
language: 'Язык / Language',
admin_users_list: 'Список пользователей',
block: 'Блок',
unblock: 'Разблок',
reset_pass: 'Сброс пароля',
delete_account: 'Удалить аккаунт',
delete_account_confirm: 'Вы уверены? Все ваши данные (сессии, планы) будут безвозвратно удалены.',
user_deleted: 'Пользователь удален',
pass_reset: 'Пароль сброшен',
manage_exercises: 'Управление упражнениями',
archive: 'Архив',
unarchive: 'Вернуть',
show_archived: 'Показать архивные',
}
};
export const t = (key: keyof typeof translations['en'], lang: Language) => {
return translations[lang][key] || translations['en'][key] || key;
};