├── .dockerignore ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── beta_release_issue.md │ ├── bug_report.md │ ├── config.yml │ └── feature_request.md ├── PULL_REQUEST_TEMPLATE │ ├── bug_fix.md │ ├── documentation_update.md │ ├── feature_addition.md │ ├── general.md │ └── refactor.md └── workflows │ ├── docker-image_latest_manual.yml │ └── docker-image_manualORnewrelease.yml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── SECURITY.md ├── aux_scripts └── aux_gc_getbcstats.py ├── backend ├── app │ ├── __init__.py │ ├── activities │ │ ├── __init__.py │ │ ├── activity │ │ │ ├── __init__.py │ │ │ ├── crud.py │ │ │ ├── dependencies.py │ │ │ ├── models.py │ │ │ ├── public_router.py │ │ │ ├── router.py │ │ │ ├── schema.py │ │ │ └── utils.py │ │ ├── activity_exercise_titles │ │ │ ├── __init__.py │ │ │ ├── crud.py │ │ │ ├── models.py │ │ │ ├── public_router.py │ │ │ ├── router.py │ │ │ └── schema.py │ │ ├── activity_laps │ │ │ ├── __init__.py │ │ │ ├── crud.py │ │ │ ├── models.py │ │ │ ├── public_router.py │ │ │ ├── router.py │ │ │ ├── schema.py │ │ │ └── utils.py │ │ ├── activity_sets │ │ │ ├── __init__.py │ │ │ ├── crud.py │ │ │ ├── models.py │ │ │ ├── public_router.py │ │ │ ├── router.py │ │ │ ├── schema.py │ │ │ └── utils.py │ │ ├── activity_streams │ │ │ ├── __init__.py │ │ │ ├── crud.py │ │ │ ├── dependencies.py │ │ │ ├── models.py │ │ │ ├── public_router.py │ │ │ ├── router.py │ │ │ └── schema.py │ │ └── activity_workout_steps │ │ │ ├── __init__.py │ │ │ ├── crud.py │ │ │ ├── models.py │ │ │ ├── public_router.py │ │ │ ├── router.py │ │ │ └── schema.py │ ├── alembic.ini │ ├── alembic │ │ ├── README │ │ ├── env.py │ │ ├── script.py.mako │ │ └── versions │ │ │ ├── 0158771b9f18_v0_8_0_migration.py │ │ │ ├── 093d3fd32846_v0_11_0_migration.py │ │ │ ├── 0ab200a7f196_v0_2_0_migration.py │ │ │ ├── 1287b0e32297_v0_5_0_migration.py │ │ │ ├── 1bce2bd27873_v0_1_4_migration.py │ │ │ ├── 241bdc784fef_v0_6_0_migration.py │ │ │ ├── 446a199ddd37_v0_7_0_migration.py │ │ │ ├── 4ac2cc4f4e41_v0_10_0_migration.py │ │ │ ├── 542605083c0c_v0_6_5_migration.py │ │ │ ├── 65a0f1d72997_v0_6_2_migration.py │ │ │ ├── 7217cc0eee8c_v0_9_0_migration.py │ │ │ ├── 85f474ec5db2_v0_7_2_migration.py │ │ │ ├── ab815ee3beae_v0_3_0_migration.py │ │ │ └── cde44b1247dc_v0_10_4_migration.py │ ├── core │ │ ├── __init__.py │ │ ├── config.py │ │ ├── cryptography.py │ │ ├── database.py │ │ ├── dependencies.py │ │ ├── logger.py │ │ ├── migrations.py │ │ ├── router.py │ │ ├── routes.py │ │ ├── scheduler.py │ │ ├── tracing.py │ │ └── utils.py │ ├── files │ │ ├── __init__.py │ │ ├── bulk_import │ │ │ └── __init__.py │ │ └── processed │ │ │ └── __init__.py │ ├── fit │ │ ├── __init__.py │ │ └── utils.py │ ├── followers │ │ ├── __init__.py │ │ ├── crud.py │ │ ├── models.py │ │ ├── router.py │ │ └── schema.py │ ├── garmin │ │ ├── __init__.py │ │ ├── activity_utils.py │ │ ├── gear_utils.py │ │ ├── health_utils.py │ │ ├── router.py │ │ ├── schema.py │ │ └── utils.py │ ├── gears │ │ ├── __init__.py │ │ ├── crud.py │ │ ├── dependencies.py │ │ ├── models.py │ │ ├── router.py │ │ ├── schema.py │ │ └── utils.py │ ├── gpx │ │ ├── __init__.py │ │ └── utils.py │ ├── health_data │ │ ├── __init__.py │ │ ├── crud.py │ │ ├── models.py │ │ ├── router.py │ │ ├── schema.py │ │ └── utils.py │ ├── health_targets │ │ ├── __init__.py │ │ ├── crud.py │ │ ├── models.py │ │ ├── router.py │ │ └── schema.py │ ├── logs │ │ └── __init__.py │ ├── main.py │ ├── migrations │ │ ├── __init__.py │ │ ├── crud.py │ │ ├── migration_1.py │ │ ├── migration_2.py │ │ ├── migration_3.py │ │ ├── models.py │ │ ├── schema.py │ │ └── utils.py │ ├── profile │ │ ├── __init__.py │ │ └── router.py │ ├── server_images │ │ └── __init__.py │ ├── server_settings │ │ ├── __init__.py │ │ ├── crud.py │ │ ├── models.py │ │ ├── public_router.py │ │ ├── router.py │ │ └── schema.py │ ├── session │ │ ├── __init__.py │ │ ├── constants.py │ │ ├── crud.py │ │ ├── models.py │ │ ├── router.py │ │ ├── schema.py │ │ ├── security.py │ │ └── utils.py │ ├── strava │ │ ├── __init__.py │ │ ├── activity_utils.py │ │ ├── athlete_utils.py │ │ ├── gear_utils.py │ │ ├── router.py │ │ ├── schema.py │ │ └── utils.py │ ├── user_images │ │ └── __init__.py │ ├── users │ │ ├── __init__.py │ │ ├── user │ │ │ ├── __init__.py │ │ │ ├── crud.py │ │ │ ├── dependencies.py │ │ │ ├── models.py │ │ │ ├── public_router.py │ │ │ ├── router.py │ │ │ ├── schema.py │ │ │ └── utils.py │ │ ├── user_default_gear │ │ │ ├── __init__.py │ │ │ ├── crud.py │ │ │ ├── models.py │ │ │ ├── router.py │ │ │ ├── schema.py │ │ │ └── utils.py │ │ └── user_integrations │ │ │ ├── __init__.py │ │ │ ├── crud.py │ │ │ ├── models.py │ │ │ └── schema.py │ └── websocket │ │ ├── __init__.py │ │ ├── router.py │ │ └── schema.py ├── poetry.lock └── pyproject.toml ├── crowdin.yml ├── docker-compose.yml.example ├── docker ├── Dockerfile └── start.sh ├── docs ├── CNAME ├── assets │ ├── developer-guide │ │ └── npm_run_dev.png │ ├── gallery │ │ ├── screenshot_activity_page_1.png │ │ ├── screenshot_activity_page_2.png │ │ ├── screenshot_gear_page.png │ │ ├── screenshot_gears_page.png │ │ ├── screenshot_health_home.png │ │ ├── screenshot_health_weight.png │ │ ├── screenshot_home.png │ │ ├── screenshot_profile.png │ │ ├── screenshot_settings_general.png │ │ ├── screenshot_settings_integrations.png │ │ ├── screenshot_settings_profile.png │ │ ├── screenshot_settings_security.png │ │ ├── screenshot_settings_server_settings.png │ │ └── screenshot_settings_user.png │ └── logo.svg ├── developer-guide.md ├── gallery.md ├── getting-started.md ├── index.md └── integrations │ ├── 3rd-party-apps.md │ └── 3rd-party-services.md ├── frontend └── app │ ├── .env │ ├── .eslintrc.cjs │ ├── .prettierrc.json │ ├── .vscode │ └── extensions.json │ ├── index.html │ ├── jsconfig.json │ ├── package-lock.json │ ├── package.json │ ├── public │ └── logo │ │ ├── apple-touch-icon.png │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── favicon.ico │ │ ├── logo.png │ │ ├── logo.svg │ │ ├── pwa-192x192.png │ │ ├── pwa-512x512.png │ │ ├── pwa-maskable-192x192.png │ │ └── pwa-maskable-512x512.png │ ├── src │ ├── App.vue │ ├── assets │ │ ├── avatar │ │ │ ├── bicycle1.png │ │ │ ├── female1.png │ │ │ ├── male1.png │ │ │ ├── racquet1.png │ │ │ ├── running_shoe1.png │ │ │ ├── unspecified1.png │ │ │ └── wetsuit1.png │ │ ├── garminconnect │ │ │ ├── Garmin_Connect_app_1024x1024-02.png │ │ │ └── Garmin_connect_badge_print_RESOURCE_FILE-01.png │ │ ├── login.png │ │ └── strava │ │ │ ├── api_logo_cptblWith_strava_horiz_light.png │ │ │ └── api_logo_cptblWith_strava_stack_light.png │ ├── components │ │ ├── Activities │ │ │ ├── ActivitiesTableComponent.vue │ │ │ ├── ActivitiesTableRowComponent.vue │ │ │ ├── ActivityBellowMPillsComponent.vue │ │ │ ├── ActivityLapsComponent.vue │ │ │ ├── ActivityMandAbovePillsComponent.vue │ │ │ ├── ActivityMapComponent.vue │ │ │ ├── ActivityStreamsLineChartComponent.vue │ │ │ ├── ActivitySummaryComponent.vue │ │ │ ├── ActivityWorkoutStepsComponent.vue │ │ │ ├── Modals │ │ │ │ ├── AddGearToActivityModalComponent.vue │ │ │ │ └── EditActivityModalComponent.vue │ │ │ └── UserDistanceStatsComponent.vue │ │ ├── Followers │ │ │ └── FollowersListComponent.vue │ │ ├── FooterComponent.vue │ │ ├── Gears │ │ │ ├── GearsAddEditGearModalComponent.vue │ │ │ └── GearsListComponent.vue │ │ ├── GeneralComponents │ │ │ ├── BackButtonComponent.vue │ │ │ ├── LoadingComponent.vue │ │ │ ├── NoItemsFoundComponents.vue │ │ │ ├── PaginationComponent.vue │ │ │ └── PaginationMobileComponent.vue │ │ ├── Health │ │ │ ├── HealthDashboardZoneComponent.vue │ │ │ ├── HealthSideBarComponent.vue │ │ │ ├── HealthWeightZone.vue │ │ │ └── HealthWeightZone │ │ │ │ ├── HealthWeightAddEditModalComponent.vue │ │ │ │ ├── HealthWeightLineChartComponent.vue │ │ │ │ └── HealthWeightListComponent.vue │ │ ├── Modals │ │ │ ├── ModalComponent.vue │ │ │ ├── ModalComponentDateRangeInput.vue │ │ │ ├── ModalComponentNumberAndStringInput.vue │ │ │ ├── ModalComponentNumberInput.vue │ │ │ └── ModalComponentSelectInput.vue │ │ ├── Navbar │ │ │ ├── NavbarBottomMobileComponent.vue │ │ │ ├── NavbarComponent.vue │ │ │ ├── NavbarLanguageSwitcherComponent.vue │ │ │ ├── NavbarPipeComponent.vue │ │ │ └── NavbarThemeSwitcherComponent.vue │ │ ├── Settings │ │ │ ├── SettingsGeneralZone.vue │ │ │ ├── SettingsGeneralZone │ │ │ │ ├── SettingsLanguageSwitcherComponent.vue │ │ │ │ └── SettingsThemeSwitcherComponent.vue │ │ │ ├── SettingsIntegrations │ │ │ │ └── GarminConnectLoginModalComponent.vue │ │ │ ├── SettingsIntegrationsZone.vue │ │ │ ├── SettingsSecurityZone.vue │ │ │ ├── SettingsServerSettingsZone.vue │ │ │ ├── SettingsSideBarComponent.vue │ │ │ ├── SettingsUserProfileZone.vue │ │ │ ├── SettingsUserSessionsZone │ │ │ │ └── UserSessionsListComponent.vue │ │ │ ├── SettingsUsersZone.vue │ │ │ └── SettingsUsersZone │ │ │ │ ├── UsersAddEditUserModalComponent.vue │ │ │ │ ├── UsersChangeUserPasswordModalComponent.vue │ │ │ │ ├── UsersListComponent.vue │ │ │ │ └── UsersPasswordRequirementsComponent.vue │ │ └── Users │ │ │ └── UserAvatarComponent.vue │ ├── i18n │ │ ├── ca │ │ │ ├── activitiesView.json │ │ │ ├── activityView.json │ │ │ ├── components │ │ │ │ ├── activities │ │ │ │ │ ├── activitiesTableComponent.json │ │ │ │ │ ├── activityBellowMPillsComponent.json │ │ │ │ │ ├── activityLapsComponent.json │ │ │ │ │ ├── activityMandAbovePillsComponent.json │ │ │ │ │ ├── activitySummaryComponent.json │ │ │ │ │ ├── activityWorkoutStepsComponent.json │ │ │ │ │ ├── modals │ │ │ │ │ │ ├── addGearToActivityModalComponent.json │ │ │ │ │ │ └── editActivityModalComponent.json │ │ │ │ │ └── userDistanceStatsComponent.json │ │ │ │ ├── followers │ │ │ │ │ └── followersListComponent.json │ │ │ │ ├── gears │ │ │ │ │ ├── gearsAddEditGearModalComponent.json │ │ │ │ │ └── gearsListComponent.json │ │ │ │ ├── health │ │ │ │ │ ├── healthDashboardZoneComponent.json │ │ │ │ │ ├── healthSideBarComponent.json │ │ │ │ │ ├── healthWeightZone │ │ │ │ │ │ ├── healthWeightAddEditModalComponent.json │ │ │ │ │ │ └── healthWeightListComponent.json │ │ │ │ │ └── healthWeightZoneComponent.json │ │ │ │ ├── navbar │ │ │ │ │ ├── navbarBottomMobileComponent.json │ │ │ │ │ └── navbarComponent.json │ │ │ │ ├── noItemsFoundComponent.json │ │ │ │ └── settings │ │ │ │ │ ├── settingsGeneralZone │ │ │ │ │ ├── settingsLanguageSwitcherComponent.json │ │ │ │ │ └── settingsThemeSwitcherComponent.json │ │ │ │ │ ├── settingsIntegrationsZone │ │ │ │ │ └── garminConnectLoginModalComponent.json │ │ │ │ │ ├── settingsIntegrationsZoneComponent.json │ │ │ │ │ ├── settingsSecurityZoneComponent.json │ │ │ │ │ ├── settingsServerSettingsZoneComponent.json │ │ │ │ │ ├── settingsSideBarComponent.json │ │ │ │ │ ├── settingsUserProfileZoneComponent.json │ │ │ │ │ ├── settingsUserSessionsZone │ │ │ │ │ └── userSessionsListComponent.json │ │ │ │ │ ├── settingsUsersZone │ │ │ │ │ ├── usersAddEditUserModalComponent.json │ │ │ │ │ ├── usersChangeUserPasswordModalComponent.json │ │ │ │ │ ├── usersListComponent.json │ │ │ │ │ └── usersPasswordRequirementsComponent.json │ │ │ │ │ └── settingsUsersZoneComponent.json │ │ │ ├── gears │ │ │ │ ├── gearView.json │ │ │ │ └── gearsView.json │ │ │ ├── generalItems.json │ │ │ ├── healthView.json │ │ │ ├── homeView.json │ │ │ ├── loginView.json │ │ │ ├── notFoundView.json │ │ │ ├── searchView.json │ │ │ ├── settingsView.json │ │ │ ├── strava │ │ │ │ └── stravaCallbackView.json │ │ │ └── userView.json │ │ ├── de │ │ │ ├── activitiesView.json │ │ │ ├── activityView.json │ │ │ ├── components │ │ │ │ ├── activities │ │ │ │ │ ├── activitiesTableComponent.json │ │ │ │ │ ├── activityBellowMPillsComponent.json │ │ │ │ │ ├── activityLapsComponent.json │ │ │ │ │ ├── activityMandAbovePillsComponent.json │ │ │ │ │ ├── activitySummaryComponent.json │ │ │ │ │ ├── activityWorkoutStepsComponent.json │ │ │ │ │ ├── modals │ │ │ │ │ │ ├── addGearToActivityModalComponent.json │ │ │ │ │ │ └── editActivityModalComponent.json │ │ │ │ │ └── userDistanceStatsComponent.json │ │ │ │ ├── followers │ │ │ │ │ └── followersListComponent.json │ │ │ │ ├── gears │ │ │ │ │ ├── gearsAddEditGearModalComponent.json │ │ │ │ │ └── gearsListComponent.json │ │ │ │ ├── health │ │ │ │ │ ├── healthDashboardZoneComponent.json │ │ │ │ │ ├── healthSideBarComponent.json │ │ │ │ │ ├── healthWeightZone │ │ │ │ │ │ ├── healthWeightAddEditModalComponent.json │ │ │ │ │ │ └── healthWeightListComponent.json │ │ │ │ │ └── healthWeightZoneComponent.json │ │ │ │ ├── navbar │ │ │ │ │ ├── navbarBottomMobileComponent.json │ │ │ │ │ └── navbarComponent.json │ │ │ │ ├── noItemsFoundComponent.json │ │ │ │ └── settings │ │ │ │ │ ├── settingsGeneralZone │ │ │ │ │ ├── settingsLanguageSwitcherComponent.json │ │ │ │ │ └── settingsThemeSwitcherComponent.json │ │ │ │ │ ├── settingsIntegrationsZone │ │ │ │ │ └── garminConnectLoginModalComponent.json │ │ │ │ │ ├── settingsIntegrationsZoneComponent.json │ │ │ │ │ ├── settingsSecurityZoneComponent.json │ │ │ │ │ ├── settingsServerSettingsZoneComponent.json │ │ │ │ │ ├── settingsSideBarComponent.json │ │ │ │ │ ├── settingsUserProfileZoneComponent.json │ │ │ │ │ ├── settingsUserSessionsZone │ │ │ │ │ └── userSessionsListComponent.json │ │ │ │ │ ├── settingsUsersZone │ │ │ │ │ ├── usersAddEditUserModalComponent.json │ │ │ │ │ ├── usersChangeUserPasswordModalComponent.json │ │ │ │ │ ├── usersListComponent.json │ │ │ │ │ └── usersPasswordRequirementsComponent.json │ │ │ │ │ └── settingsUsersZoneComponent.json │ │ │ ├── gears │ │ │ │ ├── gearView.json │ │ │ │ └── gearsView.json │ │ │ ├── generalItems.json │ │ │ ├── healthView.json │ │ │ ├── homeView.json │ │ │ ├── loginView.json │ │ │ ├── notFoundView.json │ │ │ ├── searchView.json │ │ │ ├── settingsView.json │ │ │ ├── strava │ │ │ │ └── stravaCallbackView.json │ │ │ └── userView.json │ │ ├── es │ │ │ ├── activitiesView.json │ │ │ ├── activityView.json │ │ │ ├── components │ │ │ │ ├── activities │ │ │ │ │ ├── activitiesTableComponent.json │ │ │ │ │ ├── activityBellowMPillsComponent.json │ │ │ │ │ ├── activityLapsComponent.json │ │ │ │ │ ├── activityMandAbovePillsComponent.json │ │ │ │ │ ├── activitySummaryComponent.json │ │ │ │ │ ├── activityWorkoutStepsComponent.json │ │ │ │ │ ├── modals │ │ │ │ │ │ ├── addGearToActivityModalComponent.json │ │ │ │ │ │ └── editActivityModalComponent.json │ │ │ │ │ └── userDistanceStatsComponent.json │ │ │ │ ├── followers │ │ │ │ │ └── followersListComponent.json │ │ │ │ ├── gears │ │ │ │ │ ├── gearsAddEditGearModalComponent.json │ │ │ │ │ └── gearsListComponent.json │ │ │ │ ├── health │ │ │ │ │ ├── healthDashboardZoneComponent.json │ │ │ │ │ ├── healthSideBarComponent.json │ │ │ │ │ ├── healthWeightZone │ │ │ │ │ │ ├── healthWeightAddEditModalComponent.json │ │ │ │ │ │ └── healthWeightListComponent.json │ │ │ │ │ └── healthWeightZoneComponent.json │ │ │ │ ├── navbar │ │ │ │ │ ├── navbarBottomMobileComponent.json │ │ │ │ │ └── navbarComponent.json │ │ │ │ ├── noItemsFoundComponent.json │ │ │ │ └── settings │ │ │ │ │ ├── settingsGeneralZone │ │ │ │ │ ├── settingsLanguageSwitcherComponent.json │ │ │ │ │ └── settingsThemeSwitcherComponent.json │ │ │ │ │ ├── settingsIntegrationsZone │ │ │ │ │ └── garminConnectLoginModalComponent.json │ │ │ │ │ ├── settingsIntegrationsZoneComponent.json │ │ │ │ │ ├── settingsSecurityZoneComponent.json │ │ │ │ │ ├── settingsServerSettingsZoneComponent.json │ │ │ │ │ ├── settingsSideBarComponent.json │ │ │ │ │ ├── settingsUserProfileZoneComponent.json │ │ │ │ │ ├── settingsUserSessionsZone │ │ │ │ │ └── userSessionsListComponent.json │ │ │ │ │ ├── settingsUsersZone │ │ │ │ │ ├── usersAddEditUserModalComponent.json │ │ │ │ │ ├── usersChangeUserPasswordModalComponent.json │ │ │ │ │ ├── usersListComponent.json │ │ │ │ │ └── usersPasswordRequirementsComponent.json │ │ │ │ │ └── settingsUsersZoneComponent.json │ │ │ ├── gears │ │ │ │ ├── gearView.json │ │ │ │ └── gearsView.json │ │ │ ├── generalItems.json │ │ │ ├── healthView.json │ │ │ ├── homeView.json │ │ │ ├── loginView.json │ │ │ ├── notFoundView.json │ │ │ ├── searchView.json │ │ │ ├── settingsView.json │ │ │ ├── strava │ │ │ │ └── stravaCallbackView.json │ │ │ └── userView.json │ │ ├── fr │ │ │ ├── activitiesView.json │ │ │ ├── activityView.json │ │ │ ├── components │ │ │ │ ├── activities │ │ │ │ │ ├── activitiesTableComponent.json │ │ │ │ │ ├── activityBellowMPillsComponent.json │ │ │ │ │ ├── activityLapsComponent.json │ │ │ │ │ ├── activityMandAbovePillsComponent.json │ │ │ │ │ ├── activitySummaryComponent.json │ │ │ │ │ ├── activityWorkoutStepsComponent.json │ │ │ │ │ ├── modals │ │ │ │ │ │ ├── addGearToActivityModalComponent.json │ │ │ │ │ │ └── editActivityModalComponent.json │ │ │ │ │ └── userDistanceStatsComponent.json │ │ │ │ ├── followers │ │ │ │ │ └── followersListComponent.json │ │ │ │ ├── gears │ │ │ │ │ ├── gearsAddEditGearModalComponent.json │ │ │ │ │ └── gearsListComponent.json │ │ │ │ ├── health │ │ │ │ │ ├── healthDashboardZoneComponent.json │ │ │ │ │ ├── healthSideBarComponent.json │ │ │ │ │ ├── healthWeightZone │ │ │ │ │ │ ├── healthWeightAddEditModalComponent.json │ │ │ │ │ │ └── healthWeightListComponent.json │ │ │ │ │ └── healthWeightZoneComponent.json │ │ │ │ ├── navbar │ │ │ │ │ ├── navbarBottomMobileComponent.json │ │ │ │ │ └── navbarComponent.json │ │ │ │ ├── noItemsFoundComponent.json │ │ │ │ └── settings │ │ │ │ │ ├── settingsGeneralZone │ │ │ │ │ ├── settingsLanguageSwitcherComponent.json │ │ │ │ │ └── settingsThemeSwitcherComponent.json │ │ │ │ │ ├── settingsIntegrationsZone │ │ │ │ │ └── garminConnectLoginModalComponent.json │ │ │ │ │ ├── settingsIntegrationsZoneComponent.json │ │ │ │ │ ├── settingsSecurityZoneComponent.json │ │ │ │ │ ├── settingsServerSettingsZoneComponent.json │ │ │ │ │ ├── settingsSideBarComponent.json │ │ │ │ │ ├── settingsUserProfileZoneComponent.json │ │ │ │ │ ├── settingsUserSessionsZone │ │ │ │ │ └── userSessionsListComponent.json │ │ │ │ │ ├── settingsUsersZone │ │ │ │ │ ├── usersAddEditUserModalComponent.json │ │ │ │ │ ├── usersChangeUserPasswordModalComponent.json │ │ │ │ │ ├── usersListComponent.json │ │ │ │ │ └── usersPasswordRequirementsComponent.json │ │ │ │ │ └── settingsUsersZoneComponent.json │ │ │ ├── gears │ │ │ │ ├── gearView.json │ │ │ │ └── gearsView.json │ │ │ ├── generalItems.json │ │ │ ├── healthView.json │ │ │ ├── homeView.json │ │ │ ├── loginView.json │ │ │ ├── notFoundView.json │ │ │ ├── searchView.json │ │ │ ├── settingsView.json │ │ │ ├── strava │ │ │ │ └── stravaCallbackView.json │ │ │ └── userView.json │ │ ├── index.js │ │ ├── nl │ │ │ ├── activitiesView.json │ │ │ ├── activityView.json │ │ │ ├── components │ │ │ │ ├── activities │ │ │ │ │ ├── activitiesTableComponent.json │ │ │ │ │ ├── activityBellowMPillsComponent.json │ │ │ │ │ ├── activityLapsComponent.json │ │ │ │ │ ├── activityMandAbovePillsComponent.json │ │ │ │ │ ├── activitySummaryComponent.json │ │ │ │ │ ├── activityWorkoutStepsComponent.json │ │ │ │ │ ├── modals │ │ │ │ │ │ ├── addGearToActivityModalComponent.json │ │ │ │ │ │ └── editActivityModalComponent.json │ │ │ │ │ └── userDistanceStatsComponent.json │ │ │ │ ├── followers │ │ │ │ │ └── followersListComponent.json │ │ │ │ ├── gears │ │ │ │ │ ├── gearsAddEditGearModalComponent.json │ │ │ │ │ └── gearsListComponent.json │ │ │ │ ├── health │ │ │ │ │ ├── healthDashboardZoneComponent.json │ │ │ │ │ ├── healthSideBarComponent.json │ │ │ │ │ ├── healthWeightZone │ │ │ │ │ │ ├── healthWeightAddEditModalComponent.json │ │ │ │ │ │ └── healthWeightListComponent.json │ │ │ │ │ └── healthWeightZoneComponent.json │ │ │ │ ├── navbar │ │ │ │ │ ├── navbarBottomMobileComponent.json │ │ │ │ │ └── navbarComponent.json │ │ │ │ ├── noItemsFoundComponent.json │ │ │ │ └── settings │ │ │ │ │ ├── settingsGeneralZone │ │ │ │ │ ├── settingsLanguageSwitcherComponent.json │ │ │ │ │ └── settingsThemeSwitcherComponent.json │ │ │ │ │ ├── settingsIntegrationsZone │ │ │ │ │ └── garminConnectLoginModalComponent.json │ │ │ │ │ ├── settingsIntegrationsZoneComponent.json │ │ │ │ │ ├── settingsSecurityZoneComponent.json │ │ │ │ │ ├── settingsServerSettingsZoneComponent.json │ │ │ │ │ ├── settingsSideBarComponent.json │ │ │ │ │ ├── settingsUserProfileZoneComponent.json │ │ │ │ │ ├── settingsUserSessionsZone │ │ │ │ │ └── userSessionsListComponent.json │ │ │ │ │ ├── settingsUsersZone │ │ │ │ │ ├── usersAddEditUserModalComponent.json │ │ │ │ │ ├── usersChangeUserPasswordModalComponent.json │ │ │ │ │ ├── usersListComponent.json │ │ │ │ │ └── usersPasswordRequirementsComponent.json │ │ │ │ │ └── settingsUsersZoneComponent.json │ │ │ ├── gears │ │ │ │ ├── gearView.json │ │ │ │ └── gearsView.json │ │ │ ├── generalItems.json │ │ │ ├── healthView.json │ │ │ ├── homeView.json │ │ │ ├── loginView.json │ │ │ ├── notFoundView.json │ │ │ ├── searchView.json │ │ │ ├── settingsView.json │ │ │ ├── strava │ │ │ │ └── stravaCallbackView.json │ │ │ └── userView.json │ │ ├── pt │ │ │ ├── activitiesView.json │ │ │ ├── activityView.json │ │ │ ├── components │ │ │ │ ├── activities │ │ │ │ │ ├── activitiesTableComponent.json │ │ │ │ │ ├── activityBellowMPillsComponent.json │ │ │ │ │ ├── activityLapsComponent.json │ │ │ │ │ ├── activityMandAbovePillsComponent.json │ │ │ │ │ ├── activitySummaryComponent.json │ │ │ │ │ ├── activityWorkoutStepsComponent.json │ │ │ │ │ ├── modals │ │ │ │ │ │ ├── addGearToActivityModalComponent.json │ │ │ │ │ │ └── editActivityModalComponent.json │ │ │ │ │ └── userDistanceStatsComponent.json │ │ │ │ ├── followers │ │ │ │ │ └── followersListComponent.json │ │ │ │ ├── gears │ │ │ │ │ ├── gearsAddEditGearModalComponent.json │ │ │ │ │ └── gearsListComponent.json │ │ │ │ ├── health │ │ │ │ │ ├── healthDashboardZoneComponent.json │ │ │ │ │ ├── healthSideBarComponent.json │ │ │ │ │ ├── healthWeightZone │ │ │ │ │ │ ├── healthWeightAddEditModalComponent.json │ │ │ │ │ │ └── healthWeightListComponent.json │ │ │ │ │ └── healthWeightZoneComponent.json │ │ │ │ ├── navbar │ │ │ │ │ ├── navbarBottomMobileComponent.json │ │ │ │ │ └── navbarComponent.json │ │ │ │ ├── noItemsFoundComponent.json │ │ │ │ └── settings │ │ │ │ │ ├── settingsGeneralZone │ │ │ │ │ ├── settingsLanguageSwitcherComponent.json │ │ │ │ │ └── settingsThemeSwitcherComponent.json │ │ │ │ │ ├── settingsIntegrationsZone │ │ │ │ │ └── garminConnectLoginModalComponent.json │ │ │ │ │ ├── settingsIntegrationsZoneComponent.json │ │ │ │ │ ├── settingsSecurityZoneComponent.json │ │ │ │ │ ├── settingsServerSettingsZoneComponent.json │ │ │ │ │ ├── settingsSideBarComponent.json │ │ │ │ │ ├── settingsUserProfileZoneComponent.json │ │ │ │ │ ├── settingsUserSessionsZone │ │ │ │ │ └── userSessionsListComponent.json │ │ │ │ │ ├── settingsUsersZone │ │ │ │ │ ├── usersAddEditUserModalComponent.json │ │ │ │ │ ├── usersChangeUserPasswordModalComponent.json │ │ │ │ │ ├── usersListComponent.json │ │ │ │ │ └── usersPasswordRequirementsComponent.json │ │ │ │ │ └── settingsUsersZoneComponent.json │ │ │ ├── gears │ │ │ │ ├── gearView.json │ │ │ │ └── gearsView.json │ │ │ ├── generalItems.json │ │ │ ├── healthView.json │ │ │ ├── homeView.json │ │ │ ├── loginView.json │ │ │ ├── notFoundView.json │ │ │ ├── searchView.json │ │ │ ├── settingsView.json │ │ │ ├── strava │ │ │ │ └── stravaCallbackView.json │ │ │ └── userView.json │ │ └── us │ │ │ ├── activitiesView.json │ │ │ ├── activityView.json │ │ │ ├── components │ │ │ ├── activities │ │ │ │ ├── activitiesTableComponent.json │ │ │ │ ├── activityBellowMPillsComponent.json │ │ │ │ ├── activityLapsComponent.json │ │ │ │ ├── activityMandAbovePillsComponent.json │ │ │ │ ├── activitySummaryComponent.json │ │ │ │ ├── activityWorkoutStepsComponent.json │ │ │ │ ├── modals │ │ │ │ │ ├── addGearToActivityModalComponent.json │ │ │ │ │ └── editActivityModalComponent.json │ │ │ │ └── userDistanceStatsComponent.json │ │ │ ├── followers │ │ │ │ └── followersListComponent.json │ │ │ ├── gears │ │ │ │ ├── gearsAddEditGearModalComponent.json │ │ │ │ └── gearsListComponent.json │ │ │ ├── health │ │ │ │ ├── healthDashboardZoneComponent.json │ │ │ │ ├── healthSideBarComponent.json │ │ │ │ ├── healthWeightZone │ │ │ │ │ ├── healthWeightAddEditModalComponent.json │ │ │ │ │ └── healthWeightListComponent.json │ │ │ │ └── healthWeightZoneComponent.json │ │ │ ├── navbar │ │ │ │ ├── navbarBottomMobileComponent.json │ │ │ │ └── navbarComponent.json │ │ │ ├── noItemsFoundComponent.json │ │ │ └── settings │ │ │ │ ├── settingsGeneralZone │ │ │ │ ├── settingsLanguageSwitcherComponent.json │ │ │ │ └── settingsThemeSwitcherComponent.json │ │ │ │ ├── settingsIntegrationsZone │ │ │ │ └── garminConnectLoginModalComponent.json │ │ │ │ ├── settingsIntegrationsZoneComponent.json │ │ │ │ ├── settingsSecurityZoneComponent.json │ │ │ │ ├── settingsServerSettingsZoneComponent.json │ │ │ │ ├── settingsSideBarComponent.json │ │ │ │ ├── settingsUserProfileZoneComponent.json │ │ │ │ ├── settingsUserSessionsZone │ │ │ │ └── userSessionsListComponent.json │ │ │ │ ├── settingsUsersZone │ │ │ │ ├── usersAddEditUserModalComponent.json │ │ │ │ ├── usersChangeUserPasswordModalComponent.json │ │ │ │ ├── usersListComponent.json │ │ │ │ └── usersPasswordRequirementsComponent.json │ │ │ │ └── settingsUsersZoneComponent.json │ │ │ ├── gears │ │ │ ├── gearView.json │ │ │ └── gearsView.json │ │ │ ├── generalItems.json │ │ │ ├── healthView.json │ │ │ ├── homeView.json │ │ │ ├── loginView.json │ │ │ ├── notFoundView.json │ │ │ ├── searchView.json │ │ │ ├── settingsView.json │ │ │ ├── strava │ │ │ └── stravaCallbackView.json │ │ │ └── userView.json │ ├── main.js │ ├── router │ │ └── index.js │ ├── services │ │ ├── activitiesService.js │ │ ├── activityExerciseTitlesService.js │ │ ├── activityLapsService.js │ │ ├── activitySetsService.js │ │ ├── activityStreams.js │ │ ├── activityWorkoutStepsService.js │ │ ├── followersService.js │ │ ├── garminConnectService.js │ │ ├── gearsService.js │ │ ├── health_dataService.js │ │ ├── health_targetsService.js │ │ ├── profileService.js │ │ ├── serverSettingsService.js │ │ ├── sessionService.js │ │ ├── stravaService.js │ │ ├── userDefaultGear.js │ │ └── usersService.js │ ├── stores │ │ ├── authStore.js │ │ ├── serverSettingsStore.js │ │ └── themeStore.js │ ├── utils │ │ ├── activityUtils.js │ │ ├── dateTimeUtils.js │ │ ├── modalUtils.js │ │ ├── servicePublicUtils.js │ │ ├── serviceUtils.js │ │ └── unitsUtils.js │ └── views │ │ ├── ActivitiesView.vue │ │ ├── ActivityView.vue │ │ ├── Gears │ │ ├── GearView.vue │ │ └── GearsView.vue │ │ ├── HealthView.vue │ │ ├── HomeView.vue │ │ ├── LoginView.vue │ │ ├── MenuMobileView.vue │ │ ├── NotFoundView.vue │ │ ├── SearchView.vue │ │ ├── SettingsView.vue │ │ ├── Strava │ │ └── StravaCallbackView.vue │ │ └── UserView.vue │ ├── vite.config.js │ └── vitest.config.js ├── mkdocs.yml └── screenshot_01.png /.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .git 3 | __pycache__ 4 | *.pyc 5 | .env 6 | *.log 7 | postgres/ 8 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: joaovitoriasilva # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | #patreon: # Replace with a single Patreon username 5 | #open_collective: # Replace with a single Open Collective username 6 | #ko_fi: # Replace with a single Ko-fi username 7 | #tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | #community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | #liberapay: # Replace with a single Liberapay username 10 | #issuehunt: # Replace with a single IssueHunt username 11 | #otechie: # Replace with a single Otechie username 12 | #lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 13 | #custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 14 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/beta_release_issue.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🧪 Beta Release Feedback 3 | about: Report bugs or feedback specific to the beta version 4 | title: "[BETA]: " 5 | labels: beta-feedback 6 | assignees: '' 7 | --- 8 | 9 | ## Beta Version 10 | 11 | Which beta version are you testing? (e.g., dev_09042025) 12 | 13 | ## Issue Summary 14 | 15 | Briefly describe your issue or feedback. 16 | 17 | ## Steps to Reproduce 18 | 19 | 1. Version 20 | 2. Go to '...' 21 | 3. Click on '...' 22 | 4. See error 23 | 24 | ## Screenshots, logs or files 25 | 26 | If applicable, add screenshots, logs or files to help explain your problem. If you do not wish to upload sensitive information to the issue you can send that info to [joao@endurain.com](joao@endurain.com). 27 | 28 | ## Additional Context 29 | 30 | Add any other context about the problem here. 31 | 32 | ## Suggestions or Thoughts 33 | 34 | Let me know how I can improve the beta experience! -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🐞 Bug report 3 | about: Report a bug 4 | title: "[BUG]: " 5 | labels: bug 6 | assignees: '' 7 | --- 8 | 9 | ## Checklist 10 | 11 | - [ ] I have searched **existing issues** to make sure this bug hasn't already been reported. 12 | - [ ] I have checked the **documentation** at [https://docs.endurain.com](https://docs.endurain.com) and didn't find a solution. 13 | 14 | ## Description 15 | 16 | Describe the bug you encountered. 17 | 18 | ## Steps to Reproduce 19 | 20 | 1. Version 21 | 2. Go to '...' 22 | 3. Click on '...' 23 | 4. See error 24 | 25 | ## Expected Behavior 26 | 27 | What did you expect to happen? 28 | 29 | ## Screenshots, logs or files 30 | 31 | If applicable, add screenshots, logs or files to help explain your problem. If you do not wish to upload sensitive information to the issue you can send that info to [joao@endurain.com](joao@endurain.com). 32 | 33 | ## Additional Context 34 | 35 | Add any other context about the problem here. -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: 📚 Documentation 4 | url: https://docs.endurain.com 5 | about: Please check our documentation before creating an issue. -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 💡 Feature request 3 | about: Suggest an idea or enhancement for this project 4 | title: "[FEATURE]: " 5 | labels: enhancement 6 | assignees: '' 7 | --- 8 | 9 | ## Summary 10 | 11 | Briefly describe the feature you'd like to see. 12 | 13 | ## Motivation 14 | 15 | Why is this feature important? What problem does it solve? 16 | 17 | ## Proposed Solution 18 | 19 | How would this feature work? Describe any ideas you have. 20 | 21 | ## Alternatives 22 | 23 | Have you considered any alternatives? 24 | 25 | ## Additional Context 26 | 27 | Add screenshots, mockups, or examples if relevant. -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE/bug_fix.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🐛 Bug Fix 3 | about: Fixes a bug in Endurain 4 | title: "[Bugfix]: " 5 | labels: bug, fix 6 | --- 7 | 8 | ## Description 9 | 10 | Please provide a concise description of the bug and the fix implemented. 11 | 12 | ## Related Issue 13 | 14 | Closes #[issue_number] 15 | 16 | ## Steps Taken 17 | 18 | - [ ] Reproduced the issue 19 | - [ ] Identified the root cause 20 | - [ ] Implemented the fix 21 | - [ ] Added/Updated tests 22 | - [ ] Verified the fix in the development environment 23 | 24 | ## Screenshots (if applicable) 25 | 26 | Provide screenshots or logs that demonstrate the fix. 27 | 28 | ## Checklist 29 | 30 | - [ ] Followed the repo [contributions guidelines](https://github.com/joaovitoriasilva/endurain/blob/master/CONTRIBUTING.md) 31 | - [ ] The code follows the project's coding standards 32 | - [ ] Tests have been added/updated 33 | - [ ] Documentation has been updated (if necessary) 34 | - [ ] The PR has been self-reviewed 35 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE/documentation_update.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 📝 Documentation Update 3 | about: Updates or adds documentation 4 | title: "[Docs]: " 5 | labels: documentation 6 | --- 7 | 8 | ## Description 9 | 10 | Summarize the documentation changes made. 11 | 12 | ## Motivation and Context 13 | 14 | Explain why these changes are necessary. 15 | 16 | ## Checklist 17 | 18 | - [ ] Followed the repo [contributions guidelines](https://github.com/joaovitoriasilva/endurain/blob/master/CONTRIBUTING.md) 19 | - [ ] Documentation is clear and concise 20 | - [ ] The changes align with the project's documentation standards 21 | - [ ] The PR has been self-reviewed 22 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE/feature_addition.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: ✨ Feature Addition 3 | about: Adds a new feature to Endurain 4 | title: "[Feature]: " 5 | labels: enhancement, feature 6 | --- 7 | 8 | ## Description 9 | 10 | Describe the new feature and its purpose. 11 | 12 | ## Motivation and Context 13 | 14 | Explain why this feature is needed and how it benefits users. 15 | 16 | ## Implementation Details 17 | 18 | Provide an overview of the implementation, including any new dependencies or configurations. 19 | 20 | ## Screenshots (if applicable) 21 | 22 | Include visual representations of the new feature. 23 | 24 | ## Checklist 25 | 26 | - [ ] Followed the repo [contributions guidelines](https://github.com/joaovitoriasilva/endurain/blob/master/CONTRIBUTING.md) 27 | - [ ] The feature aligns with the project's roadmap 28 | - [ ] Unit tests have been added 29 | - [ ] Documentation has been updated 30 | - [ ] The code follows the project's coding standards 31 | - [ ] The PR has been self-reviewed 32 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE/general.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🔄 General Update 3 | about: General updates or miscellaneous changes 4 | title: "[Update]: " 5 | labels: update 6 | --- 7 | 8 | ## Description 9 | 10 | Provide an overview of the changes made. 11 | 12 | ## Checklist 13 | 14 | - [ ] Followed the repo [contributions guidelines](https://github.com/joaovitoriasilva/endurain/blob/master/CONTRIBUTING.md) 15 | - [ ] The changes have been tested 16 | - [ ] The code follows the project's coding standards 17 | - [ ] Documentation has been updated (if necessary) 18 | - [ ] The PR has been self-reviewed 19 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE/refactor.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🧹 Code Refactor 3 | about: Refactors code without changing functionality 4 | title: "[Refactor]: " 5 | labels: refactor, code-cleanup 6 | --- 7 | 8 | ## Description 9 | 10 | Detail the parts of the codebase that were refactored and the reasons for the changes. 11 | 12 | ## Benefits 13 | 14 | Explain how the refactoring improves the codebase (e.g., readability, performance). 15 | 16 | ## Checklist 17 | 18 | - [ ] Followed the repo [contributions guidelines](https://github.com/joaovitoriasilva/endurain/blob/master/CONTRIBUTING.md) 19 | - [ ] No functional changes have been introduced 20 | - [ ] Existing tests pass 21 | - [ ] The code follows the project's coding standards 22 | - [ ] The PR has been self-reviewed 23 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | | Version | Supported | 6 | | ------- | ------------------ | 7 | | 0.10.X | :white_check_mark: | 8 | | 0.9.X and earlier | :x: | 9 | 10 | ## Reporting a Vulnerability 11 | 12 | If you discover a security vulnerability, please follow these steps: 13 | 14 | 1. **Do not** open a public issue; 15 | 2. Send an email to joao@endurain.com with the details of the vulnerability; 16 | 3. Include the following in your report: 17 | - Steps to reproduce the vulnerability; 18 | - Potential impact; 19 | - Any suggested fixes, if available. 20 | 4. I will provide an acknowledgment when possible. 21 | 22 | Please include as much information as possible to help me resolve the issue promptly. 23 | 24 | Thank you for helping keep this project secure! 25 | -------------------------------------------------------------------------------- /backend/app/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/backend/app/__init__.py -------------------------------------------------------------------------------- /backend/app/activities/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/backend/app/activities/__init__.py -------------------------------------------------------------------------------- /backend/app/activities/activity/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/backend/app/activities/activity/__init__.py -------------------------------------------------------------------------------- /backend/app/activities/activity_exercise_titles/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/backend/app/activities/activity_exercise_titles/__init__.py -------------------------------------------------------------------------------- /backend/app/activities/activity_exercise_titles/models.py: -------------------------------------------------------------------------------- 1 | from sqlalchemy import ( 2 | Column, 3 | Integer, 4 | String, 5 | ) 6 | from core.database import Base 7 | 8 | 9 | class ActivityExerciseTitles(Base): 10 | __tablename__ = "activity_exercise_titles" 11 | 12 | id = Column(Integer, primary_key=True, autoincrement=True) 13 | exercise_category = Column( 14 | Integer, 15 | nullable=False, 16 | comment="Exercise category", 17 | ) 18 | exercise_name = Column( 19 | Integer, 20 | nullable=False, 21 | comment="Exercise name ID", 22 | ) 23 | wkt_step_name = Column( 24 | String(length=250), nullable=False, comment="WKT step name (May include spaces)" 25 | ) 26 | -------------------------------------------------------------------------------- /backend/app/activities/activity_exercise_titles/public_router.py: -------------------------------------------------------------------------------- 1 | from typing import Annotated 2 | 3 | from fastapi import APIRouter, Depends 4 | from sqlalchemy.orm import Session 5 | 6 | import activities.activity_exercise_titles.schema as activity_exercise_titles_schema 7 | import activities.activity_exercise_titles.crud as activity_exercise_titles_crud 8 | 9 | import core.database as core_database 10 | 11 | # Define the API router 12 | router = APIRouter() 13 | 14 | 15 | @router.get( 16 | "/all", 17 | response_model=list[activity_exercise_titles_schema.ActivityExerciseTitles] | None, 18 | ) 19 | async def read_public_activities_laps_for_activity_all( 20 | db: Annotated[ 21 | Session, 22 | Depends(core_database.get_db), 23 | ], 24 | ): 25 | # Get the exercise titles from the database and return them 26 | return activity_exercise_titles_crud.get_public_activity_exercise_titles(db) -------------------------------------------------------------------------------- /backend/app/activities/activity_exercise_titles/schema.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel 2 | 3 | 4 | class ActivityExerciseTitles(BaseModel): 5 | id: int | None = None 6 | exercise_category: int 7 | exercise_name: int 8 | wkt_step_name: str 9 | 10 | class Config: 11 | orm_mode = True 12 | -------------------------------------------------------------------------------- /backend/app/activities/activity_laps/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/backend/app/activities/activity_laps/__init__.py -------------------------------------------------------------------------------- /backend/app/activities/activity_laps/utils.py: -------------------------------------------------------------------------------- 1 | import os 2 | from zoneinfo import ZoneInfo 3 | 4 | from datetime import datetime 5 | 6 | import activities.activity_laps.schema as activity_laps_schema 7 | 8 | import activities.activity.schema as activities_schema 9 | 10 | def serialize_activity_lap(activity: activities_schema.Activity, activity_lap: activity_laps_schema.ActivityLaps): 11 | def make_aware_and_format(dt, timezone): 12 | if isinstance(dt, str): 13 | dt = datetime.fromisoformat(dt) 14 | if dt.tzinfo is None: 15 | dt = dt.replace(tzinfo=ZoneInfo("UTC")) 16 | return dt.astimezone(timezone).strftime("%Y-%m-%dT%H:%M:%S") 17 | 18 | timezone = ( 19 | ZoneInfo(activity.timezone) 20 | if activity.timezone 21 | else ZoneInfo(os.environ.get("TZ")) 22 | ) 23 | 24 | activity_lap.start_time = make_aware_and_format(activity_lap.start_time, timezone) 25 | 26 | return activity_lap -------------------------------------------------------------------------------- /backend/app/activities/activity_sets/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/backend/app/activities/activity_sets/__init__.py -------------------------------------------------------------------------------- /backend/app/activities/activity_sets/schema.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel 2 | 3 | 4 | class ActivitySets(BaseModel): 5 | id: int | None = None 6 | activity_id: int 7 | duration: float 8 | repetitions: int | None 9 | weight: float | None 10 | set_type: str 11 | start_time: str 12 | category: int | None 13 | category_subtype: int | None 14 | 15 | class Config: 16 | orm_mode = True 17 | -------------------------------------------------------------------------------- /backend/app/activities/activity_sets/utils.py: -------------------------------------------------------------------------------- 1 | import os 2 | from zoneinfo import ZoneInfo 3 | 4 | from datetime import datetime 5 | 6 | import activities.activity_sets.schema as activity_sets_schema 7 | 8 | import activities.activity.schema as activities_schema 9 | 10 | def serialize_activity_set(activity: activities_schema.Activity, activity_set: activity_sets_schema.ActivitySets): 11 | def make_aware_and_format(dt, timezone): 12 | if isinstance(dt, str): 13 | dt = datetime.fromisoformat(dt) 14 | if dt.tzinfo is None: 15 | dt = dt.replace(tzinfo=ZoneInfo("UTC")) 16 | return dt.astimezone(timezone).strftime("%Y-%m-%dT%H:%M:%S") 17 | 18 | timezone = ( 19 | ZoneInfo(activity.timezone) 20 | if activity.timezone 21 | else ZoneInfo(os.environ.get("TZ")) 22 | ) 23 | 24 | activity_set.start_time = make_aware_and_format(activity_set.start_time, timezone) 25 | 26 | return activity_set -------------------------------------------------------------------------------- /backend/app/activities/activity_streams/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/backend/app/activities/activity_streams/__init__.py -------------------------------------------------------------------------------- /backend/app/activities/activity_streams/dependencies.py: -------------------------------------------------------------------------------- 1 | import core.dependencies as core_dependencies 2 | 3 | def validate_activity_stream_type(stream_type: int): 4 | # Check if gear type is between 1 and 3 5 | core_dependencies.validate_type(type=stream_type, min=1, max=7, message="Invalid activity stream type") -------------------------------------------------------------------------------- /backend/app/activities/activity_streams/schema.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel 2 | from typing import List 3 | 4 | 5 | class ActivityStreams(BaseModel): 6 | id: int | None = None 7 | activity_id: int 8 | stream_type: int 9 | stream_waypoints: List[dict] 10 | strava_activity_stream_id: int | None = None 11 | 12 | class Config: 13 | orm_mode = True -------------------------------------------------------------------------------- /backend/app/activities/activity_workout_steps/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/backend/app/activities/activity_workout_steps/__init__.py -------------------------------------------------------------------------------- /backend/app/activities/activity_workout_steps/schema.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel 2 | 3 | 4 | class ActivityWorkoutSteps(BaseModel): 5 | id: int | None = None 6 | activity_id: int | None = None 7 | message_index: int 8 | duration_type: str 9 | duration_value: float | None = None 10 | target_type: str | None = None 11 | target_value: int | None = None 12 | intensity: str | None = None 13 | notes: str | None = None 14 | exercise_category: int | None = None 15 | exercise_name: int | None = None 16 | exercise_weight: float | None = None 17 | weight_display_unit: str | None = None 18 | secondary_target_value: str | None = None 19 | 20 | class Config: 21 | orm_mode = True -------------------------------------------------------------------------------- /backend/app/alembic/README: -------------------------------------------------------------------------------- 1 | Generic single-database configuration. -------------------------------------------------------------------------------- /backend/app/alembic/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from typing import Sequence, Union 9 | 10 | from alembic import op 11 | import sqlalchemy as sa 12 | ${imports if imports else ""} 13 | 14 | # revision identifiers, used by Alembic. 15 | revision: str = ${repr(up_revision)} 16 | down_revision: Union[str, None] = ${repr(down_revision)} 17 | branch_labels: Union[str, Sequence[str], None] = ${repr(branch_labels)} 18 | depends_on: Union[str, Sequence[str], None] = ${repr(depends_on)} 19 | 20 | 21 | def upgrade() -> None: 22 | ${upgrades if upgrades else "pass"} 23 | 24 | 25 | def downgrade() -> None: 26 | ${downgrades if downgrades else "pass"} 27 | -------------------------------------------------------------------------------- /backend/app/core/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/backend/app/core/__init__.py -------------------------------------------------------------------------------- /backend/app/core/migrations.py: -------------------------------------------------------------------------------- 1 | import migrations.utils as migrations_utils 2 | 3 | import core.logger as core_logger 4 | 5 | from core.database import SessionLocal 6 | 7 | 8 | def check_migrations(): 9 | core_logger.print_to_log_and_console("Checking for migrations not executed") 10 | 11 | # Create a new database session 12 | db = SessionLocal() 13 | try: 14 | # Check migrations not executed 15 | migrations_utils.check_migrations_not_executed(db) 16 | finally: 17 | # Ensure the session is closed after use 18 | db.close() 19 | 20 | core_logger.print_to_log_and_console("Migration check completed") 21 | -------------------------------------------------------------------------------- /backend/app/core/utils.py: -------------------------------------------------------------------------------- 1 | from fastapi.responses import FileResponse 2 | import os 3 | 4 | 5 | def return_frontend_index(path: str): 6 | return FileResponse("/app/frontend/dist/" + path) 7 | 8 | 9 | def return_user_img_path(user_img: str): 10 | file_path = "/app/backend/user_images/" + user_img 11 | if not os.path.isfile(file_path): 12 | return None 13 | return FileResponse(file_path) 14 | 15 | 16 | def return_server_img_path(server_img: str): 17 | file_path = "/app/backend/server_images/" + server_img 18 | if not os.path.isfile(file_path): 19 | return None 20 | return FileResponse(file_path) 21 | -------------------------------------------------------------------------------- /backend/app/files/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/backend/app/files/__init__.py -------------------------------------------------------------------------------- /backend/app/files/bulk_import/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/backend/app/files/bulk_import/__init__.py -------------------------------------------------------------------------------- /backend/app/files/processed/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/backend/app/files/processed/__init__.py -------------------------------------------------------------------------------- /backend/app/fit/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/backend/app/fit/__init__.py -------------------------------------------------------------------------------- /backend/app/followers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/backend/app/followers/__init__.py -------------------------------------------------------------------------------- /backend/app/followers/schema.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel 2 | 3 | 4 | class Follower(BaseModel): 5 | follower_id: int 6 | following_id: int 7 | is_accepted: bool 8 | 9 | class Config: 10 | orm_mode = True -------------------------------------------------------------------------------- /backend/app/garmin/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/backend/app/garmin/__init__.py -------------------------------------------------------------------------------- /backend/app/garmin/schema.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel 2 | 3 | 4 | class GarminLogin(BaseModel): 5 | username: str 6 | password: str 7 | 8 | 9 | class MFARequest(BaseModel): 10 | mfa_code: str 11 | 12 | 13 | class MFACodeStore: 14 | def __init__(self): 15 | self._store = {} 16 | 17 | def add_code(self, user_id, code): 18 | self._store[user_id] = code 19 | 20 | def get_code(self, user_id): 21 | return self._store.get(user_id) 22 | 23 | def delete_code(self, user_id): 24 | if user_id in self._store: 25 | del self._store[user_id] 26 | 27 | def has_code(self, user_id): 28 | return user_id in self._store 29 | 30 | def clear_all(self): 31 | self._store.clear() 32 | 33 | def __repr__(self): 34 | return f"{self._store}" 35 | 36 | 37 | def get_mfa_store(): 38 | return mfa_store 39 | 40 | 41 | mfa_store = MFACodeStore() 42 | -------------------------------------------------------------------------------- /backend/app/gears/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/backend/app/gears/__init__.py -------------------------------------------------------------------------------- /backend/app/gears/dependencies.py: -------------------------------------------------------------------------------- 1 | import core.dependencies as core_dependencies 2 | 3 | def validate_gear_id(gear_id: int): 4 | # Check if id higher than 0 5 | core_dependencies.validate_id(id=gear_id, min=0, message="Invalid gear ID") 6 | 7 | def validate_gear_type(gear_type: int): 8 | # Check if gear type is between 1 and 3 9 | core_dependencies.validate_type(type=gear_type, min=1, max=4, message="Invalid gear type") -------------------------------------------------------------------------------- /backend/app/gears/schema.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel 2 | 3 | class Gear(BaseModel): 4 | id: int | None = None 5 | brand: str | None = None 6 | model: str | None = None 7 | nickname: str 8 | gear_type: int 9 | user_id: int | None = None 10 | created_at: str | None = None 11 | is_active: int | None = None 12 | initial_kms: float | None = None 13 | strava_gear_id: str | None = None 14 | garminconnect_gear_id: str | None = None 15 | 16 | class Config: 17 | orm_mode = True -------------------------------------------------------------------------------- /backend/app/gpx/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/backend/app/gpx/__init__.py -------------------------------------------------------------------------------- /backend/app/health_data/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/backend/app/health_data/__init__.py -------------------------------------------------------------------------------- /backend/app/health_data/schema.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel 2 | from datetime import date as datetime_date 3 | 4 | class HealthData(BaseModel): 5 | id: int | None = None 6 | user_id: int | None = None 7 | date: datetime_date | None = None 8 | weight: float | None = None 9 | bmi: float | None = None 10 | #body_fat: float | None = None 11 | #body_water: float | None = None 12 | #bone_mass: float | None = None 13 | #muscle_mass: float | None = None 14 | #physique_rating: float | None = None 15 | #visceral_fat: float | None = None 16 | #metabolic_age: float | None = None 17 | garminconnect_body_composition_id: str | None = None 18 | 19 | class Config: 20 | orm_mode = True -------------------------------------------------------------------------------- /backend/app/health_targets/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/backend/app/health_targets/__init__.py -------------------------------------------------------------------------------- /backend/app/health_targets/models.py: -------------------------------------------------------------------------------- 1 | from sqlalchemy import ( 2 | Column, 3 | Integer, 4 | ForeignKey, 5 | DECIMAL, 6 | ) 7 | from sqlalchemy.orm import relationship 8 | from core.database import Base 9 | 10 | 11 | class HealthTargets(Base): 12 | __tablename__ = "health_targets" 13 | 14 | id = Column(Integer, primary_key=True, autoincrement=True) 15 | user_id = Column( 16 | Integer, 17 | ForeignKey("users.id", ondelete="CASCADE"), 18 | nullable=False, 19 | unique=True, 20 | index=True, 21 | comment="User ID that the health_target belongs", 22 | ) 23 | weight = Column( 24 | DECIMAL(precision=10, scale=2), 25 | nullable=True, 26 | comment="Weight in kg", 27 | ) 28 | 29 | # Define a relationship to the User model 30 | user = relationship("User", back_populates="health_targets") 31 | -------------------------------------------------------------------------------- /backend/app/health_targets/schema.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel 2 | 3 | 4 | class HealthTargets(BaseModel): 5 | id: int | None = None 6 | user_id: int | None = None 7 | weight: float | None = None 8 | 9 | class Config: 10 | orm_mode = True -------------------------------------------------------------------------------- /backend/app/logs/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/backend/app/logs/__init__.py -------------------------------------------------------------------------------- /backend/app/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/backend/app/migrations/__init__.py -------------------------------------------------------------------------------- /backend/app/migrations/models.py: -------------------------------------------------------------------------------- 1 | from sqlalchemy import ( 2 | Column, 3 | Integer, 4 | String, 5 | Boolean, 6 | ) 7 | from core.database import Base 8 | 9 | 10 | class Migration(Base): 11 | __tablename__ = "migrations" 12 | 13 | id = Column(Integer, primary_key=True) 14 | name = Column(String(length=250), nullable=False, comment="Migration name") 15 | description = Column( 16 | String(length=2500), nullable=False, comment="Migration description" 17 | ) 18 | executed = Column( 19 | Boolean, 20 | nullable=False, 21 | default=False, 22 | comment="Whether the migration was executed or not", 23 | ) -------------------------------------------------------------------------------- /backend/app/migrations/schema.py: -------------------------------------------------------------------------------- 1 | from enum import Enum 2 | 3 | 4 | class StreamType(Enum): 5 | HEART_RATE = 1 6 | POWER = 2 7 | CADENCE = 3 8 | ELEVATION = 4 9 | SPEED = 5 10 | PACE = 6 11 | LATLONG = 7 12 | -------------------------------------------------------------------------------- /backend/app/profile/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/backend/app/profile/__init__.py -------------------------------------------------------------------------------- /backend/app/server_images/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/backend/app/server_images/__init__.py -------------------------------------------------------------------------------- /backend/app/server_settings/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/backend/app/server_settings/__init__.py -------------------------------------------------------------------------------- /backend/app/server_settings/public_router.py: -------------------------------------------------------------------------------- 1 | from typing import Annotated 2 | 3 | from fastapi import APIRouter, Depends 4 | from sqlalchemy.orm import Session 5 | 6 | import server_settings.schema as server_settings_schema 7 | import server_settings.crud as server_settings_crud 8 | 9 | import core.database as core_database 10 | 11 | # Define the API router 12 | router = APIRouter() 13 | 14 | 15 | @router.get("", response_model=server_settings_schema.ServerSettings) 16 | async def read_public_server_settings( 17 | db: Annotated[ 18 | Session, 19 | Depends(core_database.get_db), 20 | ], 21 | ): 22 | # Get the server_settings from the database 23 | return server_settings_crud.get_server_settings(db) 24 | -------------------------------------------------------------------------------- /backend/app/server_settings/schema.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel 2 | 3 | 4 | class ServerSettings(BaseModel): 5 | id: int 6 | units: int 7 | public_shareable_links: bool 8 | public_shareable_links_user_info: bool 9 | login_photo_set: bool 10 | 11 | class Config: 12 | orm_mode = True -------------------------------------------------------------------------------- /backend/app/session/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/backend/app/session/__init__.py -------------------------------------------------------------------------------- /backend/app/strava/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/backend/app/strava/__init__.py -------------------------------------------------------------------------------- /backend/app/strava/schema.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel 2 | 3 | 4 | class StravaClient(BaseModel): 5 | client_id: int | None 6 | client_secret: str | None 7 | -------------------------------------------------------------------------------- /backend/app/user_images/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/backend/app/user_images/__init__.py -------------------------------------------------------------------------------- /backend/app/users/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/backend/app/users/__init__.py -------------------------------------------------------------------------------- /backend/app/users/user/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/backend/app/users/user/__init__.py -------------------------------------------------------------------------------- /backend/app/users/user/dependencies.py: -------------------------------------------------------------------------------- 1 | import core.dependencies as core_dependencies 2 | 3 | 4 | def validate_user_id(user_id: int): 5 | # Check if id higher than 0 6 | core_dependencies.validate_id(id=user_id, min=0, message="Invalid user ID") 7 | 8 | 9 | def validate_target_user_id(target_user_id: int): 10 | # Check if id higher than 0 11 | core_dependencies.validate_id( 12 | id=target_user_id, min=0, message="Invalid target user ID" 13 | ) 14 | -------------------------------------------------------------------------------- /backend/app/users/user/public_router.py: -------------------------------------------------------------------------------- 1 | from typing import Annotated, Callable 2 | 3 | from fastapi import APIRouter, Depends 4 | from sqlalchemy.orm import Session 5 | 6 | import users.user.schema as users_schema 7 | import users.user.crud as users_crud 8 | import users.user.dependencies as users_dependencies 9 | 10 | import core.database as core_database 11 | 12 | # Define the API router 13 | router = APIRouter() 14 | 15 | 16 | @router.get("/id/{user_id}", response_model=users_schema.User) 17 | async def read_users_id( 18 | user_id: int, 19 | validate_id: Annotated[Callable, Depends(users_dependencies.validate_user_id)], 20 | db: Annotated[ 21 | Session, 22 | Depends(core_database.get_db), 23 | ], 24 | ): 25 | # Get the users from the database by id 26 | return users_crud.get_user_by_id_if_is_public(user_id, db) -------------------------------------------------------------------------------- /backend/app/users/user_default_gear/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/backend/app/users/user_default_gear/__init__.py -------------------------------------------------------------------------------- /backend/app/users/user_default_gear/schema.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel 2 | 3 | 4 | class UserDefaultGear(BaseModel): 5 | id: int | None 6 | user_id: int 7 | run_gear_id: int | None 8 | trail_run_gear_id: int | None 9 | virtual_run_gear_id: int | None 10 | ride_gear_id: int | None 11 | gravel_ride_gear_id: int | None 12 | mtb_ride_gear_id: int | None 13 | virtual_ride_gear_id: int | None 14 | ows_gear_id: int | None 15 | walk_gear_id: int | None 16 | hike_gear_id: int | None 17 | tennis_gear_id: int | None 18 | 19 | class Config: 20 | orm_mode = True -------------------------------------------------------------------------------- /backend/app/users/user_integrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/backend/app/users/user_integrations/__init__.py -------------------------------------------------------------------------------- /backend/app/users/user_integrations/schema.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel 2 | 3 | 4 | class UsersIntegrations(BaseModel): 5 | id: int 6 | user_id: int 7 | strava_client_id: str | None = None 8 | strava_client_secret: str | None = None 9 | strava_state: str | None = None 10 | strava_token: str | None = None 11 | strava_refresh_token: str | None = None 12 | strava_token_expires_at: str | None = None 13 | strava_sync_gear: bool 14 | garminconnect_oauth1: dict | None = None 15 | garminconnect_oauth2: dict | None = None 16 | garminconnect_sync_gear: bool 17 | 18 | class Config: 19 | from_attributes = True 20 | -------------------------------------------------------------------------------- /backend/app/websocket/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/backend/app/websocket/__init__.py -------------------------------------------------------------------------------- /backend/app/websocket/router.py: -------------------------------------------------------------------------------- 1 | from typing import Annotated 2 | 3 | from fastapi import APIRouter, Depends, WebSocket, WebSocketDisconnect 4 | import websocket.schema as websocket_schema 5 | 6 | # Define the API router 7 | router = APIRouter() 8 | 9 | 10 | @router.websocket("/{user_id}") 11 | async def websocket_endpoint( 12 | user_id: int, 13 | websocket: WebSocket, 14 | websocket_manager: Annotated[ 15 | websocket_schema.WebSocketManager, 16 | Depends(websocket_schema.get_websocket_manager), 17 | ], 18 | ): 19 | # Connect and manage WebSocket connections using the manager 20 | await websocket_manager.connect(user_id, websocket) 21 | 22 | try: 23 | while True: 24 | # Handle incoming messages if necessary (currently just keeping connection alive) 25 | data = await websocket.receive_json() 26 | except WebSocketDisconnect: 27 | # Disconnect using the manager 28 | websocket_manager.disconnect(user_id) 29 | -------------------------------------------------------------------------------- /docs/CNAME: -------------------------------------------------------------------------------- 1 | docs.endurain.com -------------------------------------------------------------------------------- /docs/assets/developer-guide/npm_run_dev.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/docs/assets/developer-guide/npm_run_dev.png -------------------------------------------------------------------------------- /docs/assets/gallery/screenshot_activity_page_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/docs/assets/gallery/screenshot_activity_page_1.png -------------------------------------------------------------------------------- /docs/assets/gallery/screenshot_activity_page_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/docs/assets/gallery/screenshot_activity_page_2.png -------------------------------------------------------------------------------- /docs/assets/gallery/screenshot_gear_page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/docs/assets/gallery/screenshot_gear_page.png -------------------------------------------------------------------------------- /docs/assets/gallery/screenshot_gears_page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/docs/assets/gallery/screenshot_gears_page.png -------------------------------------------------------------------------------- /docs/assets/gallery/screenshot_health_home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/docs/assets/gallery/screenshot_health_home.png -------------------------------------------------------------------------------- /docs/assets/gallery/screenshot_health_weight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/docs/assets/gallery/screenshot_health_weight.png -------------------------------------------------------------------------------- /docs/assets/gallery/screenshot_home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/docs/assets/gallery/screenshot_home.png -------------------------------------------------------------------------------- /docs/assets/gallery/screenshot_profile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/docs/assets/gallery/screenshot_profile.png -------------------------------------------------------------------------------- /docs/assets/gallery/screenshot_settings_general.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/docs/assets/gallery/screenshot_settings_general.png -------------------------------------------------------------------------------- /docs/assets/gallery/screenshot_settings_integrations.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/docs/assets/gallery/screenshot_settings_integrations.png -------------------------------------------------------------------------------- /docs/assets/gallery/screenshot_settings_profile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/docs/assets/gallery/screenshot_settings_profile.png -------------------------------------------------------------------------------- /docs/assets/gallery/screenshot_settings_security.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/docs/assets/gallery/screenshot_settings_security.png -------------------------------------------------------------------------------- /docs/assets/gallery/screenshot_settings_server_settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/docs/assets/gallery/screenshot_settings_server_settings.png -------------------------------------------------------------------------------- /docs/assets/gallery/screenshot_settings_user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/docs/assets/gallery/screenshot_settings_user.png -------------------------------------------------------------------------------- /docs/integrations/3rd-party-apps.md: -------------------------------------------------------------------------------- 1 | # 3rd party apps 2 | 3 | --- 4 | 5 | ## RunnerUp Integration 6 | 7 | [RunnerUp](https://github.com/jonasoreland/runnerup) an app for tracking your sport activities with your Android phone, can automatically sync your activities recorded with it to your Endurain instance. 8 | 9 | RunnerUp is supported until version v0.5.3 of Endurain. An [issue](https://github.com/jonasoreland/runnerup/issues/1205) is opened to get support for v0.6.0+. -------------------------------------------------------------------------------- /frontend/app/.env: -------------------------------------------------------------------------------- 1 | VITE_ENDURAIN_HOST=MY_APP_ENDURAIN_HOST -------------------------------------------------------------------------------- /frontend/app/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | require('@rushstack/eslint-patch/modern-module-resolution') 3 | 4 | module.exports = { 5 | root: true, 6 | 'extends': [ 7 | 'plugin:vue/vue3-essential', 8 | 'eslint:recommended', 9 | '@vue/eslint-config-prettier/skip-formatting' 10 | ], 11 | parserOptions: { 12 | ecmaVersion: 'latest' 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /frontend/app/.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/prettierrc", 3 | "semi": false, 4 | "tabWidth": 2, 5 | "singleQuote": true, 6 | "printWidth": 100, 7 | "trailingComma": "none" 8 | } -------------------------------------------------------------------------------- /frontend/app/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "Vue.volar", 4 | "Vue.vscode-typescript-vue-plugin", 5 | "dbaeumer.vscode-eslint", 6 | "esbenp.prettier-vscode" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /frontend/app/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "paths": { 4 | "@/*": ["./src/*"] 5 | } 6 | }, 7 | "exclude": ["node_modules", "dist"] 8 | } 9 | -------------------------------------------------------------------------------- /frontend/app/public/logo/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/frontend/app/public/logo/apple-touch-icon.png -------------------------------------------------------------------------------- /frontend/app/public/logo/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/frontend/app/public/logo/favicon-16x16.png -------------------------------------------------------------------------------- /frontend/app/public/logo/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/frontend/app/public/logo/favicon-32x32.png -------------------------------------------------------------------------------- /frontend/app/public/logo/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/frontend/app/public/logo/favicon.ico -------------------------------------------------------------------------------- /frontend/app/public/logo/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/frontend/app/public/logo/logo.png -------------------------------------------------------------------------------- /frontend/app/public/logo/pwa-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/frontend/app/public/logo/pwa-192x192.png -------------------------------------------------------------------------------- /frontend/app/public/logo/pwa-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/frontend/app/public/logo/pwa-512x512.png -------------------------------------------------------------------------------- /frontend/app/public/logo/pwa-maskable-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/frontend/app/public/logo/pwa-maskable-192x192.png -------------------------------------------------------------------------------- /frontend/app/public/logo/pwa-maskable-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/frontend/app/public/logo/pwa-maskable-512x512.png -------------------------------------------------------------------------------- /frontend/app/src/assets/avatar/bicycle1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/frontend/app/src/assets/avatar/bicycle1.png -------------------------------------------------------------------------------- /frontend/app/src/assets/avatar/female1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/frontend/app/src/assets/avatar/female1.png -------------------------------------------------------------------------------- /frontend/app/src/assets/avatar/male1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/frontend/app/src/assets/avatar/male1.png -------------------------------------------------------------------------------- /frontend/app/src/assets/avatar/racquet1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/frontend/app/src/assets/avatar/racquet1.png -------------------------------------------------------------------------------- /frontend/app/src/assets/avatar/running_shoe1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/frontend/app/src/assets/avatar/running_shoe1.png -------------------------------------------------------------------------------- /frontend/app/src/assets/avatar/unspecified1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/frontend/app/src/assets/avatar/unspecified1.png -------------------------------------------------------------------------------- /frontend/app/src/assets/avatar/wetsuit1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/frontend/app/src/assets/avatar/wetsuit1.png -------------------------------------------------------------------------------- /frontend/app/src/assets/garminconnect/Garmin_Connect_app_1024x1024-02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/frontend/app/src/assets/garminconnect/Garmin_Connect_app_1024x1024-02.png -------------------------------------------------------------------------------- /frontend/app/src/assets/garminconnect/Garmin_connect_badge_print_RESOURCE_FILE-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/frontend/app/src/assets/garminconnect/Garmin_connect_badge_print_RESOURCE_FILE-01.png -------------------------------------------------------------------------------- /frontend/app/src/assets/login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/frontend/app/src/assets/login.png -------------------------------------------------------------------------------- /frontend/app/src/assets/strava/api_logo_cptblWith_strava_horiz_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/frontend/app/src/assets/strava/api_logo_cptblWith_strava_horiz_light.png -------------------------------------------------------------------------------- /frontend/app/src/assets/strava/api_logo_cptblWith_strava_stack_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/frontend/app/src/assets/strava/api_logo_cptblWith_strava_stack_light.png -------------------------------------------------------------------------------- /frontend/app/src/components/GeneralComponents/BackButtonComponent.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | -------------------------------------------------------------------------------- /frontend/app/src/components/GeneralComponents/LoadingComponent.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/app/src/components/GeneralComponents/NoItemsFoundComponents.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/app/src/components/Navbar/NavbarPipeComponent.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/app/src/components/Settings/SettingsGeneralZone.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | -------------------------------------------------------------------------------- /frontend/app/src/components/Settings/SettingsUsersZone/UsersPasswordRequirementsComponent.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/app/src/i18n/ca/activitiesView.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Activitats", 3 | "filterLabelType": "Tipus", 4 | "filterOptionAllTypes": "Tots els tipus", 5 | "filterLabelFromDate": "Des de", 6 | "filterLabelToDate": "Fins a", 7 | "filterLabelNameLocation": "Nom o Ubicació", 8 | "filterPlaceholderNameLocation": "p.ex. Carrera de Matí", 9 | "buttonClear": "Neteja", 10 | "buttonApply": "Aplica", 11 | "errorFailedFetchActivityTypes": "Error obtenint tipus d'activitats", 12 | "errorUpdatingActivities": "Error actualitzant activitats", 13 | "errorFetchingActivities": "Error obtenint activitats d'usuari" 14 | } 15 | -------------------------------------------------------------------------------- /frontend/app/src/i18n/ca/activityView.json: -------------------------------------------------------------------------------- 1 | { 2 | "labelGear": "Equipament", 3 | "labelGearNotSet": "No establert", 4 | "modalLabelDeleteGear": "Esborra equipament de l'activitat", 5 | "modalLabelDeleteGearBody": "Segur que vols esborrar l'equipament de l'activitat?", 6 | "modalLabelDeleteGearButton": "Esborra equipament", 7 | "successMessageGearAdded": "Equipament afegit a activitat", 8 | "successMessageGearDeleted": "Equipament esborat de l'activitat", 9 | "errorMessageDeleteGear": "Error esborrant equipament de l'activitat", 10 | "errorMessageActivityNotFound": "Activitat no trobada" 11 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/ca/components/activities/activitiesTableComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "headerType": "Tipus", 3 | "headerName": "Nom", 4 | "headerLocation": "Ubicació", 5 | "headerStartTime": "Data Inici", 6 | "headerDuration": "Durada", 7 | "headerDistance": "Distància", 8 | "headerPace": "Rit/Vel", 9 | "headerCalories": "Calories", 10 | "headerElevation": "Elevació", 11 | "headerAvgHr": "FC Mitja" 12 | } 13 | -------------------------------------------------------------------------------- /frontend/app/src/i18n/ca/components/activities/activityLapsComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "labelLapNumber": "Volta", 3 | "labelLapIntensity": "Intensitat", 4 | "labelLapDistance": "Distància", 5 | "labelLapTime": "Temps", 6 | "labelLapPace": "Ritme", 7 | "labelLapSpeed": "Velocitat", 8 | "labelLapElevation": "Elevació", 9 | "labelLapElev": "Elev", 10 | "labelLapAvgHr": "Freqüència cardíaca mitjana", 11 | "labelLapHR": "FC", 12 | "labelLapStrokeRate": "Freqüència batecs", 13 | "labelLapSR": "SR" 14 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/ca/components/activities/activityMandAbovePillsComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "labelPillGraphs": "Gràfics", 3 | "labelPillLaps": "Voltes", 4 | "labelPillWorkoutSets": "Sets", 5 | "labelGraph": "Gràfics d'Activitat", 6 | "labelGraphHR": "Freqüència cardíaca", 7 | "labelGraphPower": "Potència", 8 | "labelGraphCadence": "Cadència", 9 | "labelGraphElevation": "Elevació", 10 | "labelGraphVelocity": "Velocitat", 11 | "labelGraphPace": "Ritme", 12 | "labelDownsampling": "Dades reduïdes a ~200 punts", 13 | "errorMessageProcessingActivityStreams": "Error processant activitats de carrera", 14 | "labelGraphStrokeRate": "Freqüència batecs" 15 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/ca/components/activities/activityWorkoutStepsComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "labelWorkoutStepType": "Tipus pas", 3 | "labelWorkoutStepTime": "Temps pas", 4 | "labelWorkoutStepReps": "Reps passos", 5 | "labelWorkoutStepIntensity": "Intensitat", 6 | "labelWorkoutStepNotes": "Notes", 7 | "labelWorkoutStepExerciseName": "Nom del pas", 8 | "labelWorkoutStepExerciseWeight": "Pes", 9 | "labelWorkoutStepSwimStroke": "Braçada", 10 | "labelWorkoutSetType": "Tipus pas", 11 | "labelWorkoutSetTime": "Temps pas", 12 | "labelWorkoutSetReps": "Reps passos", 13 | "labelWorkoutSetExerciseName": "Nom del pas", 14 | "labelWorkoutSetExerciseWeight": "Estableix pes", 15 | "labelWorkoutSetTypeMobile": "Tipus", 16 | "labelWorkoutSetTimeMobile": "Temps", 17 | "labelWorkoutSetRepsMobile": "Reps", 18 | "labelWorkoutSetExerciseNameMobile": "Nom", 19 | "labelWorkoutSetExerciseWeightMobile": "Pes" 20 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/ca/components/activities/modals/addGearToActivityModalComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "modalLabelAddGear": "Afegir equipament a activitat", 3 | "modalLabelSelectGear": "Selecciona equipament", 4 | "modalButtonAddGear": "Afegir Equipament", 5 | "errorEditingGear": "Error editant equip" 6 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/ca/components/activities/userDistanceStatsComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "thisWeekDistancesTitle": "Top 3 setmanal", 3 | "thisMonthDistancesTitle": "Top 3 mensual" 4 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/ca/components/followers/followersListComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "requestAccepted": "Acceptat", 3 | "requestPending": "Sol·licitud pendent", 4 | "followingModalTitle": "Esborrar seguiment", 5 | "followingModalBody": "Segur que vols eliminar el seguiment de l'usuari ", 6 | "followerModalTitle": "Esborrar seguidor", 7 | "followerModalBody": "Segur que vols elimnar l'usuari seguidor ", 8 | "followerAcceptModalTitle": "Accepta petició de l'usuari", 9 | "followerAcceptModalBody": "Segur que vols acceptar la petició de seguiment de l'usuari ", 10 | "followerDeclineModalTitle": "Rebutja la petició de l'usuari ", 11 | "followerDeclineModalBody": "Segur que vols rebutjar la petició de seguiment de kl'usauri ", 12 | "errorDeleteFollowing": "Error esborrant seguidor", 13 | "errorDeleteFollower": "Error esborrant seguidor", 14 | "errorUpdateFollower": "Error actualitzant seguidor", 15 | "errorFetchingFollowersDetails": "Error obtenint detall de seguidors" 16 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/ca/components/gears/gearsListComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "gearListTypeLabel": "Tipus", 3 | "gearListTypeOption1": "Bici", 4 | "gearListTypeOption2": "Sabatilles", 5 | "gearListTypeOption3": "Neoprè", 6 | "gearListTypeOption4": "Raqueta", 7 | "gearListGearIsInactiveBadge": "Inactiu", 8 | "gearListGearFromStrava": "Strava", 9 | "gearListGearFromGarminConnect": "Garmin Connect", 10 | "gearListModalDeleteGearTitle": "Esborra Equipament", 11 | "gearListModalDeleteGearBody": "Segur que vols esborrar equipament ", 12 | "gearListGearDeleteSuccessMessage": "Equipament esborrat correctament", 13 | "gearListGearDeleteErrorMessage": "Error esborrant equip" 14 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/ca/components/health/healthDashboardZoneComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": "Pes", 3 | "noWeightData": "Sense dades de Pes", 4 | "noWeightTarget": "Cap objectiu de pes", 5 | "noHeightDefined": "Alçada no definida per l'usuari", 6 | "bmi": "IMC", 7 | "bmiUnderweight": "Molt prim", 8 | "bmiNormalWeight": "Pes normal", 9 | "bmiOverweight": "Sobrepès", 10 | "bmiObesityClass1": "Obesitat (Classe 1)", 11 | "bmiObesityClass2": "Obesitat (Classe 2)", 12 | "bmiObesityClass3": "Obessitat Extrema (Classe 3)" 13 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/ca/components/health/healthSideBarComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "dashboardSection": "Panell de control", 3 | "weightSection": "Pes" 4 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/ca/components/health/healthWeightZone/healthWeightAddEditModalComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "addWeightModalTitle": "Afegir pes", 3 | "editWeightModalTitle": "Editar pes", 4 | "addWeightWeightLabel": "Pes", 5 | "addWeightDateLabel": "Data", 6 | "successAddWeight": "Pes afegit", 7 | "errorAddWeight": "Error afegint pes" 8 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/ca/components/health/healthWeightZone/healthWeightListComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "labelGarminConnect": "Garmin Connect", 3 | "modalDeleteWeightTitle": "Esborrar pes", 4 | "modalDeleteWeightBody": "Segur que vols suprimir l'entrada de pes per ", 5 | "successDeleteWeight": "Pes esborrat", 6 | "errorDeleteWeight": "No s'ha pogut suprimir l'entrada de pes", 7 | "successEditWeight": "Pes editat", 8 | "errorEditWeight": "No s'ha pogut editar l'entrada de pes" 9 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/ca/components/health/healthWeightZoneComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "buttonAddWeight": "Afegir pes", 3 | "labelNumberOfHealthDataWeight1": "Hi ha un total de ", 4 | "labelNumberOfHealthDataWeight2": " mesure(s) de pes inserides (", 5 | "labelNumberOfHealthDataWeight3": " carregat):" 6 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/ca/components/navbar/navbarBottomMobileComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "home": "Inici", 3 | "activities": "Activitats", 4 | "search": "Cerca", 5 | "gear": "Equipament", 6 | "health": "Salut", 7 | "menu": "Menú" 8 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/ca/components/navbar/navbarComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "search": "Cerca", 3 | "activities": "Activitats", 4 | "gear": "Equipament", 5 | "health": "Salut", 6 | "profile": "Perfil", 7 | "settings": "Opcions", 8 | "login": "Login", 9 | "logout": "Tanca sessió", 10 | "errorLogout": "Error tancant sessió" 11 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/ca/components/noItemsFoundComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Ops...", 3 | "subtitle": "No s'han trobat registres" 4 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/ca/components/settings/settingsGeneralZone/settingsLanguageSwitcherComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "formLabel": "Idioma" 3 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/ca/components/settings/settingsGeneralZone/settingsThemeSwitcherComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "formLabel": "Tema", 3 | "themeLight": "Clar", 4 | "themeDark": "Fosc", 5 | "themeAuto": "Auto" 6 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/ca/components/settings/settingsIntegrationsZone/garminConnectLoginModalComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "garminConnectAuthModalTitle": "Eenllaçar el compte de Garmin Connect", 3 | "garminConnectAuthModalUsernameLabel": "Correu de Garmin Connect", 4 | "garminConnectAuthModalUsernamePlaceholder": "Correu de Garmin Connect", 5 | "garminConnectAuthModalPasswordLabel": "Contrasenya de Garmin Connect", 6 | "garminConnectAuthModalPasswordPlaceholder": "Contrasenya de Garmin Connect", 7 | "garminConnectAuthModalMfaCodeLabel": "Codi MFA", 8 | "garminConnectAuthModalMfaCodePlaceholder": "Codi MFA", 9 | "buttonSubmitMfaCode": "Entra codi MFA", 10 | "garminConnectAuthModalLoginButton": "Login", 11 | "processingMessageLinkGarminConnect": "Enllaçant el compte de Garmin Connect...", 12 | "successMessageLinkGarminConnect": "Compte de Garmin Connect enllaçat", 13 | "errorMessageUnableToLinkGarminConnect": "No es pot enllaçar el compte de Garmin Connect" 14 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/ca/components/settings/settingsSecurityZoneComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "subtitleChangePassword": "Canviar Contrasenya", 3 | "changeUserPasswordBodyLabel": "Canviar contrasenya per usuari ", 4 | "changeUserPasswordPasswordLabel": "Nova contrasenya", 5 | "changeUserPasswordPasswordConfirmationLabel": "Confirma nova contrasenya", 6 | "changeUserPasswordFeedbackLabel": "Contrasenya no compleix els requisits", 7 | "changeUserPasswordPasswordsDoNotMatchFeedbackLabel": "Contrassenyes no coincideixen", 8 | "subtitleMySessions": "Sessions", 9 | "userChangePasswordSuccessMessage": "Contrasenya canviada correctament", 10 | "userChangePasswordErrorMessage": "Error canviant contrasenya", 11 | "successDeleteSession": "Sessió eliminada correctament", 12 | "errorDeleteSession": "Error esborrant sessió" 13 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/ca/components/settings/settingsSideBarComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "usersSection": "Usuaris", 3 | "serverSettingsSection": "Opcions servidor", 4 | "generalSection": "General", 5 | "myProfileSection": "El meu perfil", 6 | "securitySection": "Seguretat", 7 | "integrationsSection": "Integracions" 8 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/ca/components/settings/settingsUserSessionsZone/userSessionsListComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "badgeCurrentSession": "Sessió Actual", 3 | "modalDeleteSessionTitle": "Eliminar sessió", 4 | "modalDeleteSessionBody": "Segur que vols esborrar l'activitat " 5 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/ca/components/settings/settingsUsersZone/usersChangeUserPasswordModalComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "modalChangeUserPasswordTitle": "Canvia la contrasenya de l'usuari", 3 | "modalChangeUserPasswordBodyLabel": "Canviar contrasenya per usuari ", 4 | "modalChangeUserPasswordPasswordLabel": "Nova contrasenya", 5 | "modalChangeUserPasswordPasswordConfirmationLabel": "Confirma la nova contrasenya", 6 | "modalChangeUserPasswordFeedbackLabel": "Contrasenya no compleix els requisits", 7 | "modalChangeUserPasswordPasswordsDoNotMatchFeedbackLabel": "Contrassenyes no coincideixen", 8 | "userChangePasswordSuccessMessage": "Contrasenya canviada correctament", 9 | "userChangePasswordErrorMessage": "Error canviant contrasenya" 10 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/ca/components/settings/settingsUsersZone/usersListComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "userListAccessTypeLabel": "Tipus d'accés: ", 3 | "userListAccessTypeOption1": "Usuari normal", 4 | "userListAccessTypeOption2": "Administrador", 5 | "userListUserIsMeBadge": "Jo", 6 | "userListUserIsAdminBadge": "Admin", 7 | "userListUserIsActiveBadge": "Actiu", 8 | "userListUserIsInactiveBadge": "Inactiu", 9 | "userEditErrorMessage": "Error editant usuari", 10 | "modalDeleteUserTitle": "Esborra usuari", 11 | "modalDeleteUserBody": "Segur que vols esborrar l'usuari ", 12 | "userListUserSessionsTitle": "Sessions d'usuari", 13 | "userSessionDeleteSuccessMessage": "Sessió eliminada correctament", 14 | "userSessionDeleteErrorMessage": "Error esborrant sessió" 15 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/ca/components/settings/settingsUsersZone/usersPasswordRequirementsComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "passwordRequirementsTitle": "Requeriments de password inclou:", 3 | "passwordCharacters": "- 8 caràcters;", 4 | "passwordCapitalLetters": "- 1 lletra majúscula;", 5 | "passwordNumbers": "- 1 número;", 6 | "passwordSpecialCharacters": "- 1 caràcter especial;" 7 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/ca/components/settings/settingsUsersZoneComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "buttonAddUser": "Afegir usuari", 3 | "labelSearchUsersByUsername": "Cerca usuaris per nom d'usuari", 4 | "labelNumberOfUsers1": "Hi ha un total de ", 5 | "labelNumberOfUsers2": " usuari(s) (", 6 | "labelNumberOfUsers3": " carregat):", 7 | "successUserAdded": "Usuari afegit correctament", 8 | "successUserDeleted": "Usuari esborrat correctament", 9 | "errorFetchingUsers": "Error obtenint usuaris" 10 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/ca/gears/gearView.json: -------------------------------------------------------------------------------- 1 | { 2 | "buttonEditGear": "Editar Equipament", 3 | "buttonDeleteGear": "Esborra Equipament", 4 | "modalDeleteGearBody1": "Segur que vols esborrar equipament", 5 | "modalDeleteGearBody2": "Aquesta acció no es pot desfer.", 6 | "gearIsActiveBadge": "Actiu", 7 | "gearIsInactiveBadge": "Inactiu", 8 | "gearTypeOption1": "Bici", 9 | "gearTypeOption2": "Sabatilles", 10 | "gearTypeOption3": "Neoprè", 11 | "gearTypeOption4": "Raqueta", 12 | "gearFromStrava": "Strava", 13 | "gearFromGarminConnect": "Garmin Connect", 14 | "labelBrand": "Marca", 15 | "labelModel": "Model", 16 | "labelDistance": "Distància", 17 | "labelDate": "Data", 18 | "title": "Activitats d'equipament", 19 | "subtitle": "(últimes 10 activitats)", 20 | "successGearEdited": "Equipament editat correctament", 21 | "errorGearDelete": "Error esborrant equip", 22 | "errorFetchingGears": "Error obtenint equips" 23 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/ca/gears/gearsView.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Equipament", 3 | "buttonAddGear": "Afegir Equipament", 4 | "subTitleSearchGearByNickname": "Cercar per àlies d'equipament", 5 | "placeholderSearchGearByNickname": "Àlies", 6 | "buttonSearchGear": "Cerca Equip", 7 | "displayUserNumberOfGears1": "Hi ha un total de ", 8 | "displayUserNumberOfGears2": " equipament(s) (", 9 | "displayUserNumberOfGears3": " carregat):", 10 | "successGearDeleted": "Equipament esborrat correctament", 11 | "errorGearNotFound": "Equipament no trobat", 12 | "errorFetchingGears": "Error obtenint equips" 13 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/ca/healthView.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Salut", 3 | "errorFetchingHealthData": "Error recollint dades de salut", 4 | "errorFetchingHealthTargets": "Error recollint objectius de salut" 5 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/ca/homeView.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Endurain", 3 | "buttonAddActivity": "Afegir Activitat", 4 | "fieldLabelUploadGPXFile": "Puja arxiu .gpx o .fit", 5 | "radioUserActivities": "Les meves Activitats", 6 | "radioFollowerActivities": "Activitats de seguidors", 7 | "successActivityAdded": "Activitat afegida correctament", 8 | "errorActivityAdded": "Error afegint activitat", 9 | "refreshingActivities": "Refrescant activitats desde serveis enllaçats", 10 | "successActivitiesRefreshed": "Acivitats refrescades correctament", 11 | "errorActivityNotFound": "Activitat no trobada", 12 | "processingActivity": "Processant activitat", 13 | "successActivityDeleted": "Activitat esborrada correctament", 14 | "errorFetchingUserStats": "Error recollint estadístiques d'usuari", 15 | "errorFetchingUserActivities": "Error recollint activitats d'usuari" 16 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/ca/loginView.json: -------------------------------------------------------------------------------- 1 | { 2 | "sessionExpired": "Sessió d'usuari expirada", 3 | "error401": "Nom d'usuari o contrasenya incorrectes", 4 | "error403": "No teniu permís per accedir a aquest recurs", 5 | "error500": "No s'ha pogut contactar amb el servidor. Intenta-ho de nou més tard", 6 | "errorUndefined": "No s'ha pogut contactar amb el servidor. Intenta-ho de nou més tard", 7 | "subtitle": "Inici de sessió", 8 | "username": "Nom d’usuari", 9 | "password": "Contrasenya", 10 | "neverExpires": "Recordar (no marcar si estàs utilitzant un ordinador compartit)", 11 | "signInButton": "Inicia la sessió", 12 | "signUpText": "Cercant el registre?", 13 | "signUpButton": "Registra't", 14 | "errorPublicActivityNotFound": "Activitat pública no trobada", 15 | "errorpublic_shareable_links": "No es permeten enllaços públics compartibles. Per veure l'activitat, has d'iniciar sessió" 16 | } 17 | -------------------------------------------------------------------------------- /frontend/app/src/i18n/ca/notFoundView.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Oops! Pàgina no trobada", 3 | "subTitle": "La pàgina que estàs cercant no existeix o s'ha mogut.", 4 | "backToHomeButton": "Tornar a l'inici" 5 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/ca/settingsView.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Opcions" 3 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/ca/strava/stravaCallbackView.json: -------------------------------------------------------------------------------- 1 | { 2 | "stravaCallbackViewTitle1": "Gestió devolució de Strava", 3 | "stravaCallbackViewTitle2": "Please wait while Strava is being linked to your account" 4 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/de/activitiesView.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Activities", 3 | "filterLabelType": "Type", 4 | "filterOptionAllTypes": "All Types", 5 | "filterLabelFromDate": "From Date", 6 | "filterLabelToDate": "To Date", 7 | "filterLabelNameLocation": "Name or Location", 8 | "filterPlaceholderNameLocation": "e.g., Morning Run", 9 | "buttonClear": "Clear", 10 | "buttonApply": "Apply", 11 | "errorFailedFetchActivityTypes": "Failed to fetch activity types", 12 | "errorUpdatingActivities": "Failed to updated activities", 13 | "errorFetchingActivities": "Failed to fetch user activities" 14 | } 15 | -------------------------------------------------------------------------------- /frontend/app/src/i18n/de/activityView.json: -------------------------------------------------------------------------------- 1 | { 2 | "labelGear": "Ausrüstung", 3 | "labelGearNotSet": "Nicht konfiguriert", 4 | "modalLabelDeleteGear": "Ausrüstung von Aktivität löschen", 5 | "modalLabelDeleteGearBody": "Bist du sicher, dass du die Ausrüstung von der Aktivität entfernen möchtest?", 6 | "modalLabelDeleteGearButton": "Ausrüstung löschen", 7 | "successMessageGearAdded": "Ausrüstung zur Aktivität hinzugefügt", 8 | "successMessageGearDeleted": "Ausrüstung von Aktivität gelöscht", 9 | "errorMessageDeleteGear": "Fehler beim Löschen der Ausrüstung aus der Aktivität", 10 | "errorMessageActivityNotFound": "Aktivität nicht gefunden" 11 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/de/components/activities/activitiesTableComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "headerType": "Type", 3 | "headerName": "Name", 4 | "headerLocation": "Location", 5 | "headerStartTime": "Start time", 6 | "headerDuration": "Duration", 7 | "headerDistance": "Distance", 8 | "headerPace": "Pace/Speed", 9 | "headerCalories": "Calories", 10 | "headerElevation": "Elevation", 11 | "headerAvgHr": "Avg HR" 12 | } 13 | -------------------------------------------------------------------------------- /frontend/app/src/i18n/de/components/activities/activityLapsComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "labelLapNumber": "Runde", 3 | "labelLapIntensity": "Intensität", 4 | "labelLapDistance": "Distanz", 5 | "labelLapTime": "Zeit", 6 | "labelLapPace": "Tempo", 7 | "labelLapSpeed": "Geschwindigkeit", 8 | "labelLapElevation": "Höhe", 9 | "labelLapElev": "Höhe", 10 | "labelLapAvgHr": "Durchschnittliche Herzfrequenz", 11 | "labelLapHR": "HF", 12 | "labelLapStrokeRate": "Stroke rate", 13 | "labelLapSR": "SR" 14 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/de/components/activities/activityMandAbovePillsComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "labelPillGraphs": "Graphs", 3 | "labelPillLaps": "Laps", 4 | "labelPillWorkoutSets": "Sets", 5 | "labelGraph": "Activity data graphs", 6 | "labelGraphHR": "Heart rate", 7 | "labelGraphPower": "Power", 8 | "labelGraphCadence": "Cadence", 9 | "labelGraphElevation": "Elevation", 10 | "labelGraphVelocity": "Velocity", 11 | "labelGraphPace": "Pace", 12 | "labelDownsampling": "Data downsampled to ~200 points", 13 | "errorMessageProcessingActivityStreams": "Error processing activity streams", 14 | "labelGraphStrokeRate": "Stroke rate" 15 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/de/components/activities/activityWorkoutStepsComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "labelWorkoutStepType": "Step type", 3 | "labelWorkoutStepTime": "Step time", 4 | "labelWorkoutStepReps": "Step reps", 5 | "labelWorkoutStepIntensity": "Intensity", 6 | "labelWorkoutStepNotes": "Notes", 7 | "labelWorkoutStepExerciseName": "Step name", 8 | "labelWorkoutStepExerciseWeight": "Weight", 9 | "labelWorkoutStepSwimStroke": "Step swim stroke", 10 | "labelWorkoutSetType": "Set type", 11 | "labelWorkoutSetTime": "Set time", 12 | "labelWorkoutSetReps": "Set reps", 13 | "labelWorkoutSetExerciseName": "Set name", 14 | "labelWorkoutSetExerciseWeight": "Set weight", 15 | "labelWorkoutSetTypeMobile": "Type", 16 | "labelWorkoutSetTimeMobile": "Time", 17 | "labelWorkoutSetRepsMobile": "Reps", 18 | "labelWorkoutSetExerciseNameMobile": "Name", 19 | "labelWorkoutSetExerciseWeightMobile": "Weight" 20 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/de/components/activities/modals/addGearToActivityModalComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "modalLabelAddGear": "Add gear to activity", 3 | "modalLabelSelectGear": "Select gear", 4 | "modalButtonAddGear": "Add gear", 5 | "errorEditingGear": "Error editing gear" 6 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/de/components/activities/userDistanceStatsComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "thisWeekDistancesTitle": "Woche Top 3", 3 | "thisMonthDistancesTitle": "Monat Top 3" 4 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/de/components/gears/gearsListComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "gearListTypeLabel": "Typ", 3 | "gearListTypeOption1": "Fahrrad", 4 | "gearListTypeOption2": "Schuhe", 5 | "gearListTypeOption3": "Neoprenanzug", 6 | "gearListTypeOption4": "Racquet", 7 | "gearListGearIsInactiveBadge": "Inaktiv", 8 | "gearListGearFromStrava": "Strava", 9 | "gearListGearFromGarminConnect": "Garmin Connect", 10 | "gearListModalDeleteGearTitle": "Ausrüstung löschen", 11 | "gearListModalDeleteGearBody": "Bist du sicher, dass du die Ausrüstung löschen möchtest? ", 12 | "gearListGearDeleteSuccessMessage": "Ausrüstung erfolgreich gelöscht", 13 | "gearListGearDeleteErrorMessage": "Fehler beim Löschen der Ausrüstung" 14 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/de/components/health/healthDashboardZoneComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": "Gewicht", 3 | "noWeightData": "Keine Gewichtsdaten", 4 | "noWeightTarget": "Kein Gewichtsziel", 5 | "noHeightDefined": "Keine Körpergröße für Nutzer definiert", 6 | "bmi": "BMI", 7 | "bmiUnderweight": "Untergewicht", 8 | "bmiNormalWeight": "Normalgewicht", 9 | "bmiOverweight": "Übergewichtig", 10 | "bmiObesityClass1": "Obesity (Class 1)", 11 | "bmiObesityClass2": "Obesity (Class 2)", 12 | "bmiObesityClass3": "Fettleibigkeit (Klasse 3)" 13 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/de/components/health/healthSideBarComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "dashboardSection": "Dashboard", 3 | "weightSection": "Gewicht" 4 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/de/components/health/healthWeightZone/healthWeightAddEditModalComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "addWeightModalTitle": "Gewicht hinzufügen", 3 | "editWeightModalTitle": "Gewicht bearbeiten", 4 | "addWeightWeightLabel": "Gewicht", 5 | "addWeightDateLabel": "Datum", 6 | "successAddWeight": "Gewicht hinzugefügt", 7 | "errorAddWeight": "Fehler beim hinzufügen des Gewichts" 8 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/de/components/health/healthWeightZone/healthWeightListComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "labelGarminConnect": "Garmin Connect", 3 | "modalDeleteWeightTitle": "Gewicht löschen", 4 | "modalDeleteWeightBody": "Bist du sicher, dass du den Gewichtseintrag für löschen möchtest ", 5 | "successDeleteWeight": "Gewicht gelöscht", 6 | "errorDeleteWeight": "Gewichtseintrag konnte nicht gelöscht werden", 7 | "successEditWeight": "Gewicht bearbeitet", 8 | "errorEditWeight": "Gewichtseintrag konnte nicht bearbeitet werden" 9 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/de/components/health/healthWeightZoneComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "buttonAddWeight": "Gewicht hinzufügen", 3 | "labelNumberOfHealthDataWeight1": "Insgesamt ", 4 | "labelNumberOfHealthDataWeight2": " Gewichtsmessung(en) hinzugefügt (", 5 | "labelNumberOfHealthDataWeight3": " geladen):" 6 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/de/components/navbar/navbarBottomMobileComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "home": "Startseite", 3 | "activities": "Aktivitäten", 4 | "search": "Suchen", 5 | "gear": "Ausrüstung", 6 | "health": "Gesundheit", 7 | "menu": "Menü" 8 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/de/components/navbar/navbarComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "search": "Suche", 3 | "activities": "Aktivitäten", 4 | "gear": "Ausrüstung", 5 | "health": "Gesundheit", 6 | "profile": "Profil", 7 | "settings": "Einstellungen", 8 | "login": "Anmelden", 9 | "logout": "Abmelden", 10 | "errorLogout": "Fehler beim Ausloggen" 11 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/de/components/noItemsFoundComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Ups...", 3 | "subtitle": "Kein Datensatz gefunden" 4 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/de/components/settings/settingsGeneralZone/settingsLanguageSwitcherComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "formLabel": "Sprache" 3 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/de/components/settings/settingsGeneralZone/settingsThemeSwitcherComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "formLabel": "Design", 3 | "themeLight": "Hell", 4 | "themeDark": "Dunkel", 5 | "themeAuto": "Automatisch" 6 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/de/components/settings/settingsIntegrationsZone/garminConnectLoginModalComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "garminConnectAuthModalTitle": "Garmin Connect Konto verbinden", 3 | "garminConnectAuthModalUsernameLabel": "Garmin Connect E-Mail", 4 | "garminConnectAuthModalUsernamePlaceholder": "Garmin Connect E-Mail", 5 | "garminConnectAuthModalPasswordLabel": "Garmin Connect Passwort", 6 | "garminConnectAuthModalPasswordPlaceholder": "Garmin Connect Passwort", 7 | "garminConnectAuthModalMfaCodeLabel": "MFA-Code", 8 | "garminConnectAuthModalMfaCodePlaceholder": "MFA-Code", 9 | "buttonSubmitMfaCode": "MFA-Code absenden", 10 | "garminConnectAuthModalLoginButton": "Anmelden", 11 | "processingMessageLinkGarminConnect": "Verknüpfe Garmin Connect Konto...", 12 | "successMessageLinkGarminConnect": "Garmin Connect Konto verknüpft", 13 | "errorMessageUnableToLinkGarminConnect": "Die Verbindung zum Garmin Connect Konto konnte nicht getrennt werden" 14 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/de/components/settings/settingsSecurityZoneComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "subtitleChangePassword": "Passwort ändern", 3 | "changeUserPasswordBodyLabel": "Change password for user ", 4 | "changeUserPasswordPasswordLabel": "New password", 5 | "changeUserPasswordPasswordConfirmationLabel": "Confirm new password", 6 | "changeUserPasswordFeedbackLabel": "Password does not meet requirements", 7 | "changeUserPasswordPasswordsDoNotMatchFeedbackLabel": "Passwords do not match", 8 | "subtitleMySessions": "My sessions", 9 | "userChangePasswordSuccessMessage": "Password changed successfully", 10 | "userChangePasswordErrorMessage": "Error changing password", 11 | "successDeleteSession": "Session deleted successfully", 12 | "errorDeleteSession": "Error deleting session" 13 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/de/components/settings/settingsSideBarComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "usersSection": "Benutzer", 3 | "serverSettingsSection": "Server Settings", 4 | "generalSection": "Allgemein", 5 | "myProfileSection": "Mein Profil", 6 | "securitySection": "Sicherheit", 7 | "integrationsSection": "Integrationen" 8 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/de/components/settings/settingsUserSessionsZone/userSessionsListComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "badgeCurrentSession": "Current Session", 3 | "modalDeleteSessionTitle": "Delete Session", 4 | "modalDeleteSessionBody": "Are you sure you want to delete session " 5 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/de/components/settings/settingsUsersZone/usersChangeUserPasswordModalComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "modalChangeUserPasswordTitle": "Change user password", 3 | "modalChangeUserPasswordBodyLabel": "Change password for user ", 4 | "modalChangeUserPasswordPasswordLabel": "New password", 5 | "modalChangeUserPasswordPasswordConfirmationLabel": "Confirm new password", 6 | "modalChangeUserPasswordFeedbackLabel": "Password does not meet requirements", 7 | "modalChangeUserPasswordPasswordsDoNotMatchFeedbackLabel": "Passwords do not match", 8 | "userChangePasswordSuccessMessage": "Password changed successfully", 9 | "userChangePasswordErrorMessage": "Error changing password" 10 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/de/components/settings/settingsUsersZone/usersListComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "userListAccessTypeLabel": "Zugangsart: ", 3 | "userListAccessTypeOption1": "Regulärer Benutzer", 4 | "userListAccessTypeOption2": "Administrator", 5 | "userListUserIsMeBadge": "Ich", 6 | "userListUserIsAdminBadge": "Admin", 7 | "userListUserIsActiveBadge": "Aktiv", 8 | "userListUserIsInactiveBadge": "Inaktiv", 9 | "userEditErrorMessage": "Fehler beim Bearbeiten des Benutzers", 10 | "modalDeleteUserTitle": "Benutzer löschen", 11 | "modalDeleteUserBody": "Sicher, dass du Benutzer löschen möchtest ", 12 | "userListUserSessionsTitle": "User sessions", 13 | "userSessionDeleteSuccessMessage": "Session deleted successfully", 14 | "userSessionDeleteErrorMessage": "Error deleting session" 15 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/de/components/settings/settingsUsersZone/usersPasswordRequirementsComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "passwordRequirementsTitle": "Password requirements includes:", 3 | "passwordCharacters": "- 8 characters;", 4 | "passwordCapitalLetters": "- 1 capital letter;", 5 | "passwordNumbers": "- 1 number;", 6 | "passwordSpecialCharacters": "- 1 special character;" 7 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/de/components/settings/settingsUsersZoneComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "buttonAddUser": "Benutzer hinzufügen", 3 | "labelSearchUsersByUsername": "Benutzer nach Benutzername suchen", 4 | "labelNumberOfUsers1": "Es gibt insgesamt ", 5 | "labelNumberOfUsers2": " Benutzer (", 6 | "labelNumberOfUsers3": " geladen):", 7 | "successUserAdded": "Benutzer erfolgreich hinzugefügt", 8 | "successUserDeleted": "Benutzer wurde erfolgreich gelöscht", 9 | "errorFetchingUsers": "Fehler beim Laden der Benutzer" 10 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/de/gears/gearsView.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Ausrüstung", 3 | "buttonAddGear": "Ausrüstung hinzufügen", 4 | "subTitleSearchGearByNickname": "Suche Ausrüstung nach Spitzname", 5 | "placeholderSearchGearByNickname": "Spitzname", 6 | "buttonSearchGear": "Suche Ausrüstung", 7 | "displayUserNumberOfGears1": "Insgesamt ", 8 | "displayUserNumberOfGears2": " Ausrüstung(en) (", 9 | "displayUserNumberOfGears3": " geladen):", 10 | "successGearDeleted": "Ausrüstung erfolgreich gelöscht", 11 | "errorGearNotFound": "Ausrüstung nicht gefunden", 12 | "errorFetchingGears": "Fehler beim Abrufen der Ausrüstung" 13 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/de/healthView.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Gesundheit", 3 | "errorFetchingHealthData": "Fehler beim Laden der Gesundheitsdaten", 4 | "errorFetchingHealthTargets": "Fehler beim Laden der Gesundheitsziele" 5 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/de/homeView.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Endurain", 3 | "buttonAddActivity": "Aktivität hinzufügen", 4 | "fieldLabelUploadGPXFile": ".gpx oder .fit Datei hochladen", 5 | "radioUserActivities": "Meine Aktivitäten", 6 | "radioFollowerActivities": "Follower Aktivitäten", 7 | "successActivityAdded": "Aktivität erfolgreich hinzugefügt", 8 | "errorActivityAdded": "Fehler beim Hinzufügen der Aktivität", 9 | "refreshingActivities": "Refreshing activities from linked services", 10 | "successActivitiesRefreshed": "Activities refreshed successfully", 11 | "errorActivityNotFound": "Aktivität nicht gefunden", 12 | "processingActivity": "Verarbeite Aktivität", 13 | "successActivityDeleted": "Die Aktivität wurde erfolgreich gelöscht", 14 | "errorFetchingUserStats": "Fehler beim Abrufen der Benutzerstatistiken", 15 | "errorFetchingUserActivities": "Fehler beim Abrufen der Benutzeraktivitäten" 16 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/de/loginView.json: -------------------------------------------------------------------------------- 1 | { 2 | "sessionExpired": "Benutzersitzung abgelaufen", 3 | "error401": "Benutzername oder Passwort ungültig", 4 | "error403": "Du hast keine Berechtigung auf diese Ressource", 5 | "error500": "Es war nicht möglich, sich mit dem Server zu verbinden. Bitte versuche es später erneut", 6 | "errorUndefined": "Es war nicht möglich, sich mit dem Server zu verbinden. Bitte versuche es später erneut", 7 | "subtitle": "Unten anmelden", 8 | "username": "Benutzername", 9 | "password": "Passwort", 10 | "neverExpires": "Anmeldung merken (Aktiviere dieses Kontrollkästchen nicht, wenn du einen gemeinsam genutzten Computer verwendest)", 11 | "signInButton": "Anmelden", 12 | "signUpText": "Möchtest du dich anmelden?", 13 | "signUpButton": "Registrieren", 14 | "errorPublicActivityNotFound": "Öffentliche Aktivität nicht gefunden", 15 | "errorpublic_shareable_links": "Öffentliche Links sind nicht erlaubt. Um diese Aktivität anzuzeigen, müssen Sie angemeldet sein" 16 | } 17 | -------------------------------------------------------------------------------- /frontend/app/src/i18n/de/notFoundView.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Oops! Seite nicht gefunden", 3 | "subTitle": "Die gesuchte Seite existiert nicht oder sie wurde geändert.", 4 | "backToHomeButton": "Zurück zur Startseite" 5 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/de/settingsView.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Einstellungen" 3 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/de/strava/stravaCallbackView.json: -------------------------------------------------------------------------------- 1 | { 2 | "stravaCallbackViewTitle1": "Verarbeiten des Strava-Callbacks", 3 | "stravaCallbackViewTitle2": "Please wait while Strava is being linked to your account" 4 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/es/activitiesView.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Activities", 3 | "filterLabelType": "Type", 4 | "filterOptionAllTypes": "All Types", 5 | "filterLabelFromDate": "From Date", 6 | "filterLabelToDate": "To Date", 7 | "filterLabelNameLocation": "Name or Location", 8 | "filterPlaceholderNameLocation": "e.g., Morning Run", 9 | "buttonClear": "Clear", 10 | "buttonApply": "Apply", 11 | "errorFailedFetchActivityTypes": "Failed to fetch activity types", 12 | "errorUpdatingActivities": "Failed to updated activities", 13 | "errorFetchingActivities": "Failed to fetch user activities" 14 | } 15 | -------------------------------------------------------------------------------- /frontend/app/src/i18n/es/activityView.json: -------------------------------------------------------------------------------- 1 | { 2 | "labelGear": "Equipo", 3 | "labelGearNotSet": "No establecido", 4 | "modalLabelDeleteGear": "Eliminar equipo de la actividad", 5 | "modalLabelDeleteGearBody": "¿Está seguro que desea eliminar el equipo de la actividad?", 6 | "modalLabelDeleteGearButton": "Eliminar equipo", 7 | "successMessageGearAdded": "Equipo añadido a la actividad", 8 | "successMessageGearDeleted": "Equipo eliminado de la actividad", 9 | "errorMessageDeleteGear": "Error al eliminar el equipo de la actividad", 10 | "errorMessageActivityNotFound": "Actividad no encontrada" 11 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/es/components/activities/activitiesTableComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "headerType": "Type", 3 | "headerName": "Name", 4 | "headerLocation": "Location", 5 | "headerStartTime": "Start time", 6 | "headerDuration": "Duration", 7 | "headerDistance": "Distance", 8 | "headerPace": "Pace/Speed", 9 | "headerCalories": "Calories", 10 | "headerElevation": "Elevation", 11 | "headerAvgHr": "Avg HR" 12 | } 13 | -------------------------------------------------------------------------------- /frontend/app/src/i18n/es/components/activities/activityLapsComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "labelLapNumber": "Vuelta", 3 | "labelLapIntensity": "Intensidad", 4 | "labelLapDistance": "Distancia", 5 | "labelLapTime": "Tiempo", 6 | "labelLapPace": "Ritmo", 7 | "labelLapSpeed": "Velocidad", 8 | "labelLapElevation": "Altura", 9 | "labelLapElev": "Alt", 10 | "labelLapAvgHr": "Ritmo cardíaco medio", 11 | "labelLapHR": "RC", 12 | "labelLapStrokeRate": "Stroke rate", 13 | "labelLapSR": "SR" 14 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/es/components/activities/activityMandAbovePillsComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "labelPillGraphs": "Gráficas", 3 | "labelPillLaps": "Vueltas", 4 | "labelPillWorkoutSets": "Sets", 5 | "labelGraph": "Gráficos de datos de actividad", 6 | "labelGraphHR": "Frecuencia cardíaca", 7 | "labelGraphPower": "Potencia", 8 | "labelGraphCadence": "Cadencia", 9 | "labelGraphElevation": "Altura", 10 | "labelGraphVelocity": "Velocidad", 11 | "labelGraphPace": "Ritmo", 12 | "labelDownsampling": "Datos reducidos a ~200 puntos", 13 | "errorMessageProcessingActivityStreams": "Error al procesar los flujos de actividad", 14 | "labelGraphStrokeRate": "Stroke rate" 15 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/es/components/activities/activityWorkoutStepsComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "labelWorkoutStepType": "Tipo de paso", 3 | "labelWorkoutStepTime": "Tiempo de paso", 4 | "labelWorkoutStepReps": "Repeticiones de paso", 5 | "labelWorkoutStepIntensity": "Intensidad", 6 | "labelWorkoutStepNotes": "Notas", 7 | "labelWorkoutStepExerciseName": "Nombre del paso", 8 | "labelWorkoutStepExerciseWeight": "Peso", 9 | "labelWorkoutStepSwimStroke": "Paso de brazada", 10 | "labelWorkoutSetType": "Establecer tipo", 11 | "labelWorkoutSetTime": "Establecer tiempo", 12 | "labelWorkoutSetReps": "Establecer repeticiones", 13 | "labelWorkoutSetExerciseName": "Establecer nombre", 14 | "labelWorkoutSetExerciseWeight": "Establecer peso", 15 | "labelWorkoutSetTypeMobile": "Tipo", 16 | "labelWorkoutSetTimeMobile": "Tiempo", 17 | "labelWorkoutSetRepsMobile": "Repeticiones", 18 | "labelWorkoutSetExerciseNameMobile": "Nombre", 19 | "labelWorkoutSetExerciseWeightMobile": "Peso" 20 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/es/components/activities/modals/addGearToActivityModalComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "modalLabelAddGear": "Añadir equipo a la actividad", 3 | "modalLabelSelectGear": "Seleccionar equipo", 4 | "modalButtonAddGear": "Añadir equipo", 5 | "errorEditingGear": "Error al editar el equipo" 6 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/es/components/activities/userDistanceStatsComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "thisWeekDistancesTitle": "Top 3 semanal", 3 | "thisMonthDistancesTitle": "Top 3 mensual" 4 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/es/components/gears/gearsListComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "gearListTypeLabel": "Tipo", 3 | "gearListTypeOption1": "Bicicleta", 4 | "gearListTypeOption2": "Calzado", 5 | "gearListTypeOption3": "Traje de neopreno", 6 | "gearListTypeOption4": "Raqueta", 7 | "gearListGearIsInactiveBadge": "Inactivo", 8 | "gearListGearFromStrava": "Strava", 9 | "gearListGearFromGarminConnect": "Garmin Connect", 10 | "gearListModalDeleteGearTitle": "Eliminar equipo", 11 | "gearListModalDeleteGearBody": "¿Está seguro que desea eliminar el equipo?", 12 | "gearListGearDeleteSuccessMessage": "Equipo eliminado correctamente", 13 | "gearListGearDeleteErrorMessage": "Error al eliminar el equipo" 14 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/es/components/health/healthDashboardZoneComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": "Peso", 3 | "noWeightData": "Sin datos de peso", 4 | "noWeightTarget": "Sin objetivo de peso", 5 | "noHeightDefined": "Altura no definida para el usuario", 6 | "bmi": "IMC", 7 | "bmiUnderweight": "Inferior al peso adecuado", 8 | "bmiNormalWeight": "Peso normal", 9 | "bmiOverweight": "Sobrepeso", 10 | "bmiObesityClass1": "Obesidad (Clase 1)", 11 | "bmiObesityClass2": "Obesidad (Clase 2)", 12 | "bmiObesityClass3": "Obesidad extrema (Clase 3)" 13 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/es/components/health/healthSideBarComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "dashboardSection": "Panel", 3 | "weightSection": "Peso" 4 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/es/components/health/healthWeightZone/healthWeightAddEditModalComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "addWeightModalTitle": "Añadir peso", 3 | "editWeightModalTitle": "Editar peso", 4 | "addWeightWeightLabel": "Peso", 5 | "addWeightDateLabel": "Fecha", 6 | "successAddWeight": "Peso agregado", 7 | "errorAddWeight": "Error al añadir peso" 8 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/es/components/health/healthWeightZone/healthWeightListComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "labelGarminConnect": "Garmin Connect", 3 | "modalDeleteWeightTitle": "Eliminar peso", 4 | "modalDeleteWeightBody": "¿Está seguro que desea eliminar la entrada de peso para ", 5 | "successDeleteWeight": "Peso eliminado", 6 | "errorDeleteWeight": "No fue posible eliminar la entrada de peso", 7 | "successEditWeight": "Peso modificado", 8 | "errorEditWeight": "No fue posible editar la entrada de peso" 9 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/es/components/health/healthWeightZoneComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "buttonAddWeight": "Añadir peso", 3 | "labelNumberOfHealthDataWeight1": "Hay un total de ", 4 | "labelNumberOfHealthDataWeight2": " medición(es) de peso insertado(s) (", 5 | "labelNumberOfHealthDataWeight3": " cargado):" 6 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/es/components/navbar/navbarBottomMobileComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "home": "Inicio", 3 | "activities": "Activities", 4 | "search": "Buscar", 5 | "gear": "Equipo", 6 | "health": "Salud", 7 | "menu": "Menú" 8 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/es/components/navbar/navbarComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "search": "Buscar", 3 | "activities": "Activities", 4 | "gear": "Equipo", 5 | "health": "Salud", 6 | "profile": "Perfil", 7 | "settings": "Ajustes", 8 | "login": "Iniciar sesión", 9 | "logout": "Cerrar sesión", 10 | "errorLogout": "Error al cerrar sesión" 11 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/es/components/noItemsFoundComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Ups...", 3 | "subtitle": "No se encontraron registros" 4 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/es/components/settings/settingsGeneralZone/settingsLanguageSwitcherComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "formLabel": "Idioma" 3 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/es/components/settings/settingsGeneralZone/settingsThemeSwitcherComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "formLabel": "Tema", 3 | "themeLight": "Claro", 4 | "themeDark": "Oscuro", 5 | "themeAuto": "Automático" 6 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/es/components/settings/settingsIntegrationsZone/garminConnectLoginModalComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "garminConnectAuthModalTitle": "Vincular cuenta de Garmin Connect", 3 | "garminConnectAuthModalUsernameLabel": "Email de Garmin Connect", 4 | "garminConnectAuthModalUsernamePlaceholder": "Email de Garmin Connect", 5 | "garminConnectAuthModalPasswordLabel": "Contraseña de Garmin Connect", 6 | "garminConnectAuthModalPasswordPlaceholder": "Contraseña de Garmin Connect", 7 | "garminConnectAuthModalMfaCodeLabel": "Código MFA", 8 | "garminConnectAuthModalMfaCodePlaceholder": "Código MFA", 9 | "buttonSubmitMfaCode": "Enviar código MFA", 10 | "garminConnectAuthModalLoginButton": "Iniciar sesión", 11 | "processingMessageLinkGarminConnect": "Vinculando cuenta Garmin Connect...", 12 | "successMessageLinkGarminConnect": "Cuenta de Garmin Connect vinculada", 13 | "errorMessageUnableToLinkGarminConnect": "No se pudo vincular la cuenta de Garmin Connect" 14 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/es/components/settings/settingsSecurityZoneComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "subtitleChangePassword": "Cambiar contraseña", 3 | "changeUserPasswordBodyLabel": "Cambiar contraseña del usuario ", 4 | "changeUserPasswordPasswordLabel": "Nueva contraseña", 5 | "changeUserPasswordPasswordConfirmationLabel": "Confirmar nueva contraseña", 6 | "changeUserPasswordFeedbackLabel": "La contraseña no cumple con los requisitos", 7 | "changeUserPasswordPasswordsDoNotMatchFeedbackLabel": "Las contraseñas no coinciden", 8 | "subtitleMySessions": "Mis sesiones", 9 | "userChangePasswordSuccessMessage": "La contraseña ha sido cambiada correctamente", 10 | "userChangePasswordErrorMessage": "Error al cambiar la contraseña", 11 | "successDeleteSession": "Sesión eliminada exitosamente", 12 | "errorDeleteSession": "Error al eliminar la sesión" 13 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/es/components/settings/settingsSideBarComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "usersSection": "Usuarios", 3 | "serverSettingsSection": "Ajustes del Servidor", 4 | "generalSection": "General", 5 | "myProfileSection": "Mi perfil", 6 | "securitySection": "Seguridad", 7 | "integrationsSection": "Integraciones" 8 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/es/components/settings/settingsUserSessionsZone/userSessionsListComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "badgeCurrentSession": "Sesión actual", 3 | "modalDeleteSessionTitle": "Eliminar sesión", 4 | "modalDeleteSessionBody": "¿Está seguro que desea eliminar la sesión?" 5 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/es/components/settings/settingsUsersZone/usersChangeUserPasswordModalComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "modalChangeUserPasswordTitle": "Cambiar contraseña de usuario", 3 | "modalChangeUserPasswordBodyLabel": "Cambiar la contraseña del usuario ", 4 | "modalChangeUserPasswordPasswordLabel": "Nueva contraseña", 5 | "modalChangeUserPasswordPasswordConfirmationLabel": "Confirme la nueva contraseña", 6 | "modalChangeUserPasswordFeedbackLabel": "La contraseña no cumple con los requisitos", 7 | "modalChangeUserPasswordPasswordsDoNotMatchFeedbackLabel": "Las contraseñas no coinciden", 8 | "userChangePasswordSuccessMessage": "La contraseña ha sido cambiada correctamente", 9 | "userChangePasswordErrorMessage": "Error al cambiar la contraseña" 10 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/es/components/settings/settingsUsersZone/usersListComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "userListAccessTypeLabel": "Tipo de acceso: ", 3 | "userListAccessTypeOption1": "Usuario regular", 4 | "userListAccessTypeOption2": "Administrador", 5 | "userListUserIsMeBadge": "Yo", 6 | "userListUserIsAdminBadge": "Administrador", 7 | "userListUserIsActiveBadge": "Activo", 8 | "userListUserIsInactiveBadge": "Inactivo", 9 | "userEditErrorMessage": "Error al editar el usuario", 10 | "modalDeleteUserTitle": "Eliminar usuario", 11 | "modalDeleteUserBody": "¿Está seguro de que desea eliminar el usuario?", 12 | "userListUserSessionsTitle": "Sesiones de usuario", 13 | "userSessionDeleteSuccessMessage": "Sesión eliminada exitosamente", 14 | "userSessionDeleteErrorMessage": "Error al eliminar la sesión" 15 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/es/components/settings/settingsUsersZone/usersPasswordRequirementsComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "passwordRequirementsTitle": "Los requisitos de contraseña incluyen:", 3 | "passwordCharacters": "- 8 caracteres;", 4 | "passwordCapitalLetters": "- 1 letra mayúscula;", 5 | "passwordNumbers": "- 1 número;", 6 | "passwordSpecialCharacters": "- 1 carácter especial;" 7 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/es/components/settings/settingsUsersZoneComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "buttonAddUser": "Agregar usuario", 3 | "labelSearchUsersByUsername": "Búsqueda de usuarios por nombre de usuario", 4 | "labelNumberOfUsers1": "Hay un total de ", 5 | "labelNumberOfUsers2": " usuario(s) (", 6 | "labelNumberOfUsers3": " cargado):", 7 | "successUserAdded": "Usuario añadido con éxito", 8 | "successUserDeleted": "Usuario eliminado con éxito", 9 | "errorFetchingUsers": "Error al obtener usuarios" 10 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/es/gears/gearView.json: -------------------------------------------------------------------------------- 1 | { 2 | "buttonEditGear": "Editar equipo", 3 | "buttonDeleteGear": "Eliminar equipo", 4 | "modalDeleteGearBody1": "¿Está seguro que desea eliminar el equipo?", 5 | "modalDeleteGearBody2": "Esta acción no se puede deshacer.", 6 | "gearIsActiveBadge": "Activo", 7 | "gearIsInactiveBadge": "Inactivo", 8 | "gearTypeOption1": "Bicicleta", 9 | "gearTypeOption2": "Calzado", 10 | "gearTypeOption3": "Traje de neopreno", 11 | "gearTypeOption4": "Raqueta", 12 | "gearFromStrava": "Strava", 13 | "gearFromGarminConnect": "Garmin Connect", 14 | "labelBrand": "Marca", 15 | "labelModel": "Modelo", 16 | "labelDistance": "Distancia", 17 | "labelDate": "Fecha", 18 | "title": "Actividades del equipo", 19 | "subtitle": "(últimas 10 actividades)", 20 | "successGearEdited": "Equipo editado con éxito", 21 | "errorGearDelete": "Error al eliminar el equipo", 22 | "errorFetchingGears": "Error obteniendo equipos" 23 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/es/gears/gearsView.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Equipo", 3 | "buttonAddGear": "Añadir equipo", 4 | "subTitleSearchGearByNickname": "Buscar equipo por apodo", 5 | "placeholderSearchGearByNickname": "Apodo", 6 | "buttonSearchGear": "Buscar equipo", 7 | "displayUserNumberOfGears1": "Hay un total de ", 8 | "displayUserNumberOfGears2": " equipo(s) (", 9 | "displayUserNumberOfGears3": " cargado):", 10 | "successGearDeleted": "Equipo eliminado correctamente", 11 | "errorGearNotFound": "No se encontró el equipo", 12 | "errorFetchingGears": "Error obteniendo equipos" 13 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/es/healthView.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Salud", 3 | "errorFetchingHealthData": "Error obteniendo datos de salud", 4 | "errorFetchingHealthTargets": "Error obteniendo objetivos de salud" 5 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/es/homeView.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Resistencia", 3 | "buttonAddActivity": "Agregar Actividad", 4 | "fieldLabelUploadGPXFile": "Subir archivo .gpx o .fit", 5 | "radioUserActivities": "Mis actividades", 6 | "radioFollowerActivities": "Actividades de seguidores", 7 | "successActivityAdded": "Actividad agregada correctamente", 8 | "errorActivityAdded": "Error al añadir actividad", 9 | "refreshingActivities": "Refreshing activities from linked services", 10 | "successActivitiesRefreshed": "Activities refreshed successfully", 11 | "errorActivityNotFound": "Actividad no encontrada", 12 | "processingActivity": "Procesando actividad", 13 | "successActivityDeleted": "Actividad eliminada correctamente", 14 | "errorFetchingUserStats": "Error obteniendo las estadísticas del usuario", 15 | "errorFetchingUserActivities": "Error obteniendo las actividades del usuario" 16 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/es/loginView.json: -------------------------------------------------------------------------------- 1 | { 2 | "sessionExpired": "Sesión de usuario expirada", 3 | "error401": "Nombre de usuario o contraseña inválidos", 4 | "error403": "No tiene permiso para acceder a este recurso", 5 | "error500": "No se pudo conectar al servidor. Por favor, inténtalo de nuevo más tarde", 6 | "errorUndefined": "No se pudo conectar al servidor. Por favor, inténtalo de nuevo más tarde", 7 | "subtitle": "Iniciar sesión abajo", 8 | "username": "Usuario", 9 | "password": "Contraseña", 10 | "neverExpires": "Recordarme (no marque esta casilla si está usando una computadora compartida)", 11 | "signInButton": "Registrarse", 12 | "signUpText": "¿Buscando registrarse?", 13 | "signUpButton": "Registrarse", 14 | "errorPublicActivityNotFound": "Actividad pública no encontrada", 15 | "errorpublic_shareable_links": "Los enlaces públicos no están permitidos. Para ver esta actividad, debes iniciar sesión" 16 | } 17 | -------------------------------------------------------------------------------- /frontend/app/src/i18n/es/notFoundView.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "¡Ups! Página no encontrada", 3 | "subTitle": "La página que buscas no existe o ha sido cambiada.", 4 | "backToHomeButton": "Volver al inicio" 5 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/es/settingsView.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Ajustes" 3 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/es/strava/stravaCallbackView.json: -------------------------------------------------------------------------------- 1 | { 2 | "stravaCallbackViewTitle1": "Gestionando devolución de Strava", 3 | "stravaCallbackViewTitle2": "Por favor, espere mientras Strava está siendo vinculado a su cuenta. No actualice esta página." 4 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/fr/activitiesView.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Activities", 3 | "filterLabelType": "Type", 4 | "filterOptionAllTypes": "All Types", 5 | "filterLabelFromDate": "From Date", 6 | "filterLabelToDate": "To Date", 7 | "filterLabelNameLocation": "Name or Location", 8 | "filterPlaceholderNameLocation": "e.g., Morning Run", 9 | "buttonClear": "Clear", 10 | "buttonApply": "Apply", 11 | "errorFailedFetchActivityTypes": "Failed to fetch activity types", 12 | "errorUpdatingActivities": "Failed to updated activities", 13 | "errorFetchingActivities": "Failed to fetch user activities" 14 | } 15 | -------------------------------------------------------------------------------- /frontend/app/src/i18n/fr/activityView.json: -------------------------------------------------------------------------------- 1 | { 2 | "labelGear": "Équipement", 3 | "labelGearNotSet": "Non défini", 4 | "modalLabelDeleteGear": "Supprimer un équipement de l'activité", 5 | "modalLabelDeleteGearBody": "Êtes-vous sûr de vouloir retirer l'équipement de l'activité?", 6 | "modalLabelDeleteGearButton": "Supprimer l'équipement", 7 | "successMessageGearAdded": "Équipement ajouté à l'activité", 8 | "successMessageGearDeleted": "Équipement supprimé de l'activité", 9 | "errorMessageDeleteGear": "Erreur lors de la suppression de l'équipement de l'activité", 10 | "errorMessageActivityNotFound": "Activité non trouvée" 11 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/fr/components/activities/activitiesTableComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "headerType": "Type", 3 | "headerName": "Name", 4 | "headerLocation": "Location", 5 | "headerStartTime": "Start time", 6 | "headerDuration": "Duration", 7 | "headerDistance": "Distance", 8 | "headerPace": "Pace/Speed", 9 | "headerCalories": "Calories", 10 | "headerElevation": "Elevation", 11 | "headerAvgHr": "Avg HR" 12 | } 13 | -------------------------------------------------------------------------------- /frontend/app/src/i18n/fr/components/activities/activityLapsComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "labelLapNumber": "Intervalle", 3 | "labelLapIntensity": "Intensité", 4 | "labelLapDistance": "Distance", 5 | "labelLapTime": "Temps", 6 | "labelLapPace": "Allure", 7 | "labelLapSpeed": "Vitesse", 8 | "labelLapElevation": "Élévation", 9 | "labelLapElev": "Élév.", 10 | "labelLapAvgHr": "Fréq. cardiaque moy.", 11 | "labelLapHR": "FC", 12 | "labelLapStrokeRate": "Stroke rate", 13 | "labelLapSR": "SR" 14 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/fr/components/activities/activityMandAbovePillsComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "labelPillGraphs": "Graphiques", 3 | "labelPillLaps": "Intervalle", 4 | "labelPillWorkoutSets": "Ensembles", 5 | "labelGraph": "Graphiques des données d'activité", 6 | "labelGraphHR": "Fréquence cardiaque", 7 | "labelGraphPower": "Puissance", 8 | "labelGraphCadence": "Cadence", 9 | "labelGraphElevation": "Élévation", 10 | "labelGraphVelocity": "Vitesse ", 11 | "labelGraphPace": "Allure", 12 | "labelDownsampling": "Données abaissées à ~200 points", 13 | "errorMessageProcessingActivityStreams": "Erreur lors du traitement des flux d'activité", 14 | "labelGraphStrokeRate": "Stroke rate" 15 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/fr/components/activities/activityWorkoutStepsComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "labelWorkoutStepType": "Step type", 3 | "labelWorkoutStepTime": "Step time", 4 | "labelWorkoutStepReps": "Step reps", 5 | "labelWorkoutStepIntensity": "Intensity", 6 | "labelWorkoutStepNotes": "Notes", 7 | "labelWorkoutStepExerciseName": "Step name", 8 | "labelWorkoutStepExerciseWeight": "Weight", 9 | "labelWorkoutStepSwimStroke": "Step swim stroke", 10 | "labelWorkoutSetType": "Set type", 11 | "labelWorkoutSetTime": "Set time", 12 | "labelWorkoutSetReps": "Set reps", 13 | "labelWorkoutSetExerciseName": "Set name", 14 | "labelWorkoutSetExerciseWeight": "Set weight", 15 | "labelWorkoutSetTypeMobile": "Type", 16 | "labelWorkoutSetTimeMobile": "Time", 17 | "labelWorkoutSetRepsMobile": "Reps", 18 | "labelWorkoutSetExerciseNameMobile": "Name", 19 | "labelWorkoutSetExerciseWeightMobile": "Weight" 20 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/fr/components/activities/modals/addGearToActivityModalComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "modalLabelAddGear": "Ajouter un équipement à l'activité", 3 | "modalLabelSelectGear": "Sélectionner un équipement", 4 | "modalButtonAddGear": "Ajouter un équipement", 5 | "errorEditingGear": "Erreur lors de l'édition de l'équipement" 6 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/fr/components/activities/userDistanceStatsComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "thisWeekDistancesTitle": "Top 3 de la semaine", 3 | "thisMonthDistancesTitle": "Top 3 du mois" 4 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/fr/components/gears/gearsListComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "gearListTypeLabel": "Type", 3 | "gearListTypeOption1": "Vélo", 4 | "gearListTypeOption2": "Chaussures", 5 | "gearListTypeOption3": "Combinaison", 6 | "gearListTypeOption4": "Racquet", 7 | "gearListGearIsInactiveBadge": "Inactif", 8 | "gearListGearFromStrava": "Strava", 9 | "gearListGearFromGarminConnect": "Garmin Connect", 10 | "gearListModalDeleteGearTitle": "Supprimer l'équipement", 11 | "gearListModalDeleteGearBody": "Êtes-vous sûr de vouloir supprimer l'équipement ", 12 | "gearListGearDeleteSuccessMessage": "Équipement supprimé avec succès", 13 | "gearListGearDeleteErrorMessage": "Erreur lors de l'édition de l'équipement" 14 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/fr/components/health/healthDashboardZoneComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": "Poids", 3 | "noWeightData": "Aucune donnée de poids", 4 | "noWeightTarget": "Aucune cible de poids", 5 | "noHeightDefined": "Aucune taille définie pour l'utilisateur", 6 | "bmi": "IMC", 7 | "bmiUnderweight": "Sous-poids", 8 | "bmiNormalWeight": "Poids normal", 9 | "bmiOverweight": "Surpoids", 10 | "bmiObesityClass1": "Obésité (classe 1)", 11 | "bmiObesityClass2": "Obésité (classe 2)", 12 | "bmiObesityClass3": "Obésité morbide (classe 3)" 13 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/fr/components/health/healthSideBarComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "dashboardSection": "Tableau de Bord", 3 | "weightSection": "Poids" 4 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/fr/components/health/healthWeightZone/healthWeightAddEditModalComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "addWeightModalTitle": "Ajouter un poids", 3 | "editWeightModalTitle": "Modifier le poids", 4 | "addWeightWeightLabel": "Poids", 5 | "addWeightDateLabel": "Date", 6 | "successAddWeight": "Poids ajouté", 7 | "errorAddWeight": "Erreur lors de l'ajout du poids" 8 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/fr/components/health/healthWeightZone/healthWeightListComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "labelGarminConnect": "Garmin Connect", 3 | "modalDeleteWeightTitle": "Supprimer le poids", 4 | "modalDeleteWeightBody": "Êtes-vous sûr de vouloir supprimer la saisie de poids pour ", 5 | "successDeleteWeight": "Poids supprimé", 6 | "errorDeleteWeight": "Impossible de supprimer la saisie de poids", 7 | "successEditWeight": "Poids modifié", 8 | "errorEditWeight": "Impossible de modifier la saisie du poids" 9 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/fr/components/health/healthWeightZoneComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "buttonAddWeight": "Ajouter un poids", 3 | "labelNumberOfHealthDataWeight1": "Il y a un total de ", 4 | "labelNumberOfHealthDataWeight2": " mesure(s) de poids insérée(s) (", 5 | "labelNumberOfHealthDataWeight3": " chargé(e)(s) ):" 6 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/fr/components/navbar/navbarBottomMobileComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "home": "Accueil", 3 | "activities": "Activities", 4 | "search": "Rechercher", 5 | "gear": "Équipement", 6 | "health": "Santé", 7 | "menu": "Menu" 8 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/fr/components/navbar/navbarComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "search": "Rechercher", 3 | "activities": "Activities", 4 | "gear": "Équipement", 5 | "health": "Santé", 6 | "profile": "Profil", 7 | "settings": "Paramètres", 8 | "login": "Connexion", 9 | "logout": "Déconnexion", 10 | "errorLogout": "Erreur de déconnexion" 11 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/fr/components/noItemsFoundComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Oups...", 3 | "subtitle": "Aucun enregistrement trouvé" 4 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/fr/components/settings/settingsGeneralZone/settingsLanguageSwitcherComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "formLabel": "Langue" 3 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/fr/components/settings/settingsGeneralZone/settingsThemeSwitcherComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "formLabel": "Thème", 3 | "themeLight": "Clair", 4 | "themeDark": "Sombre", 5 | "themeAuto": "Automatique" 6 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/fr/components/settings/settingsIntegrationsZone/garminConnectLoginModalComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "garminConnectAuthModalTitle": "Associer le compte Garmin Connect", 3 | "garminConnectAuthModalUsernameLabel": "E-mail Garmin Connect", 4 | "garminConnectAuthModalUsernamePlaceholder": "E-mail Garmin Connect", 5 | "garminConnectAuthModalPasswordLabel": "Mot de passe Garmin Connect", 6 | "garminConnectAuthModalPasswordPlaceholder": "Mot de passe Garmin Connect", 7 | "garminConnectAuthModalMfaCodeLabel": "Code MFA", 8 | "garminConnectAuthModalMfaCodePlaceholder": "Code MFA", 9 | "buttonSubmitMfaCode": "Envoyer le code MFA", 10 | "garminConnectAuthModalLoginButton": "Connexion", 11 | "processingMessageLinkGarminConnect": "Connexion du compte Garmin Connect...", 12 | "successMessageLinkGarminConnect": "Compte Garmin Connect associé", 13 | "errorMessageUnableToLinkGarminConnect": "Impossible de relier le compte Garmin Connect" 14 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/fr/components/settings/settingsSecurityZoneComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "subtitleChangePassword": "Modifier le mot de passe", 3 | "changeUserPasswordBodyLabel": "Changer le mot de passe pour l'utilisateur ", 4 | "changeUserPasswordPasswordLabel": "Nouveau mot de passe", 5 | "changeUserPasswordPasswordConfirmationLabel": "Confirmer le nouveau mot de passe", 6 | "changeUserPasswordFeedbackLabel": "Le mot de passe ne répond pas aux exigences", 7 | "changeUserPasswordPasswordsDoNotMatchFeedbackLabel": "Les mots de passe ne correspondent pas", 8 | "subtitleMySessions": "Mes sessions", 9 | "userChangePasswordSuccessMessage": "Le mot de passe a bien été modifié", 10 | "userChangePasswordErrorMessage": "Erreur lors de la modification du mot de passe", 11 | "successDeleteSession": "Session supprimée avec succès", 12 | "errorDeleteSession": "Erreur lors de la suppression de session" 13 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/fr/components/settings/settingsSideBarComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "usersSection": "Utilisateurs", 3 | "serverSettingsSection": "Paramètres du serveur", 4 | "generalSection": "Général", 5 | "myProfileSection": "Mon profil", 6 | "securitySection": "Sécurité", 7 | "integrationsSection": "Intégrations" 8 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/fr/components/settings/settingsUserSessionsZone/userSessionsListComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "badgeCurrentSession": "Session en cours", 3 | "modalDeleteSessionTitle": "Supprimer la session", 4 | "modalDeleteSessionBody": "Êtes-vous sûr de vouloir supprimer la session " 5 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/fr/components/settings/settingsUsersZone/usersChangeUserPasswordModalComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "modalChangeUserPasswordTitle": "Changer le mot de passe de l'utilisateur", 3 | "modalChangeUserPasswordBodyLabel": "Changer le mot de passe pour l'utilisateur ", 4 | "modalChangeUserPasswordPasswordLabel": "Nouveau mot de passe", 5 | "modalChangeUserPasswordPasswordConfirmationLabel": "Confirmer le nouveau mot de passe", 6 | "modalChangeUserPasswordFeedbackLabel": "Le mot de passe ne répond pas aux exigences", 7 | "modalChangeUserPasswordPasswordsDoNotMatchFeedbackLabel": "Les mots de passe ne correspondent pas", 8 | "userChangePasswordSuccessMessage": "Le mot de passe a bien été modifié", 9 | "userChangePasswordErrorMessage": "Erreur lors de la modification du mot de passe" 10 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/fr/components/settings/settingsUsersZone/usersListComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "userListAccessTypeLabel": "Type d'accès : ", 3 | "userListAccessTypeOption1": "Utilisateur standard", 4 | "userListAccessTypeOption2": "Administrateur", 5 | "userListUserIsMeBadge": "Moi", 6 | "userListUserIsAdminBadge": "Administrateur", 7 | "userListUserIsActiveBadge": "Actif", 8 | "userListUserIsInactiveBadge": "Inactif", 9 | "userEditErrorMessage": "Erreur lors de la modification de l'utilisateur", 10 | "modalDeleteUserTitle": "Supprimer l’utilisateur", 11 | "modalDeleteUserBody": "Êtes-vous sûr de vouloir supprimer l'utilisateur ", 12 | "userListUserSessionsTitle": "Sessions de l'utilisateur", 13 | "userSessionDeleteSuccessMessage": "Session supprimée avec succès", 14 | "userSessionDeleteErrorMessage": "Erreur lors de la suppression de session" 15 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/fr/components/settings/settingsUsersZone/usersPasswordRequirementsComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "passwordRequirementsTitle": "Les exigences de mot de passe comprennent :", 3 | "passwordCharacters": "- 8 caractères ;", 4 | "passwordCapitalLetters": "- 1 lettre majuscule ;", 5 | "passwordNumbers": "- 1 chiffre ;", 6 | "passwordSpecialCharacters": "- 1 caractère spécial ;" 7 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/fr/components/settings/settingsUsersZoneComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "buttonAddUser": "Ajouter l'utilisateur", 3 | "labelSearchUsersByUsername": "Rechercher des utilisateurs par nom d'utilisateur", 4 | "labelNumberOfUsers1": "Il y a un total de ", 5 | "labelNumberOfUsers2": " utilisateur(s) (", 6 | "labelNumberOfUsers3": " chargé(s) ):", 7 | "successUserAdded": "L’utilisateur a bien été ajouté", 8 | "successUserDeleted": "L’utilisateur a bien été supprimé", 9 | "errorFetchingUsers": "Erreur lors de la recherche d'utilisateur" 10 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/fr/gears/gearView.json: -------------------------------------------------------------------------------- 1 | { 2 | "buttonEditGear": "Edit Gear", 3 | "buttonDeleteGear": "Delete Gear", 4 | "modalDeleteGearBody1": "Êtes-vous sûr de vouloir supprimer l'équipement", 5 | "modalDeleteGearBody2": "Cette action est irréversible.", 6 | "gearIsActiveBadge": "Actif", 7 | "gearIsInactiveBadge": "Inactif", 8 | "gearTypeOption1": "Vélo", 9 | "gearTypeOption2": "Chaussures", 10 | "gearTypeOption3": "Combinaison", 11 | "gearTypeOption4": "Racquet", 12 | "gearFromStrava": "Strava", 13 | "gearFromGarminConnect": "Garmin Connect", 14 | "labelBrand": "Marque", 15 | "labelModel": "Modèle", 16 | "labelDistance": "Distance", 17 | "labelDate": "Date", 18 | "title": "Activités de l'équipement", 19 | "subtitle": "(10 dernières activités)", 20 | "successGearEdited": "L'équipement a bien été modifié", 21 | "errorGearDelete": "Erreur lors de la suppression de l'équipement", 22 | "errorFetchingGears": "Erreur lors de la recherche des équipements" 23 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/fr/gears/gearsView.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Équipement", 3 | "buttonAddGear": "Ajouter un équipement", 4 | "subTitleSearchGearByNickname": "Rechercher un équipement par surnom", 5 | "placeholderSearchGearByNickname": "Surnom", 6 | "buttonSearchGear": "Rechercher un équipement", 7 | "displayUserNumberOfGears1": "Il y a un total de ", 8 | "displayUserNumberOfGears2": " équipement(s) (", 9 | "displayUserNumberOfGears3": " chargé(s) ):", 10 | "successGearDeleted": "Équipement supprimé avec succès", 11 | "errorGearNotFound": "Équipement introuvable", 12 | "errorFetchingGears": "Erreur lors de la recherche d'utilisateur" 13 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/fr/healthView.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Santé", 3 | "errorFetchingHealthData": "Erreur lors de la récupération des données de santé", 4 | "errorFetchingHealthTargets": "Erreur lors de la récupération des objectifs de santé" 5 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/fr/homeView.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Endurain", 3 | "buttonAddActivity": "Ajouter une activité", 4 | "fieldLabelUploadGPXFile": "Charger un fichier .gpx ou .fit", 5 | "radioUserActivities": "Mes activités", 6 | "radioFollowerActivities": "Activités des abonnés", 7 | "successActivityAdded": "Activité ajoutée avec succès", 8 | "errorActivityAdded": "Erreur lors de l'ajout de l'activité", 9 | "refreshingActivities": "Refreshing activities from linked services", 10 | "successActivitiesRefreshed": "Activities refreshed successfully", 11 | "errorActivityNotFound": "Activité non trouvée", 12 | "processingActivity": "Traitement de l'activité", 13 | "successActivityDeleted": "Activité supprimée avec succès", 14 | "errorFetchingUserStats": "Erreur lors de la récupération des statistiques de l'utilisateur", 15 | "errorFetchingUserActivities": "Erreur lors de la récupération des activités de l'utilisateur" 16 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/fr/loginView.json: -------------------------------------------------------------------------------- 1 | { 2 | "sessionExpired": "Session utilisateur expirée", 3 | "error401": "Identifiant ou mot de passe incorrect", 4 | "error403": "Vous n’avez pas la permission d’accéder à cette ressource", 5 | "error500": "Impossible de se connecter au serveur. Veuillez réessayer plus tard", 6 | "errorUndefined": "Impossible de se connecter au serveur. Veuillez réessayer plus tard", 7 | "subtitle": "Connectez-vous ci-dessous", 8 | "username": "Identifiant", 9 | "password": "Mot de passe", 10 | "neverExpires": "Se souvenir de moi (ne cochez pas cette case si vous utilisez un ordinateur partagé)", 11 | "signInButton": "S'inscrire", 12 | "signUpText": "Vous cherchez à vous inscrire ?", 13 | "signUpButton": "S'inscrire", 14 | "errorPublicActivityNotFound": "Activité publique introuvable", 15 | "errorpublic_shareable_links": "Les liens publics partageables ne sont pas autorisés. Pour voir cette activité, vous devez être connecté" 16 | } 17 | -------------------------------------------------------------------------------- /frontend/app/src/i18n/fr/notFoundView.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Oups ! Page introuvable", 3 | "subTitle": "La page que vous cherchez n'existe pas ou a été modifiée.", 4 | "backToHomeButton": "Retour à l'accueil" 5 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/fr/settingsView.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Paramètres" 3 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/fr/strava/stravaCallbackView.json: -------------------------------------------------------------------------------- 1 | { 2 | "stravaCallbackViewTitle1": "Gestion du callback de Strava", 3 | "stravaCallbackViewTitle2": "Veuillez patienter pendant que Strava est lié à votre compte. Ne rafraîchissez pas cette page." 4 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/nl/activitiesView.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Activiteiten", 3 | "filterLabelType": "Type", 4 | "filterOptionAllTypes": "Alle types", 5 | "filterLabelFromDate": "Vanaf datum", 6 | "filterLabelToDate": "Tot datum", 7 | "filterLabelNameLocation": "Naam van de Locatie", 8 | "filterPlaceholderNameLocation": "bv. Ochtend loop", 9 | "buttonClear": "Wissen", 10 | "buttonApply": "Toepassen", 11 | "errorFailedFetchActivityTypes": "Kon activiteitstypes niet ophalen", 12 | "errorUpdatingActivities": "Kon activiteiten niet vernieuwen", 13 | "errorFetchingActivities": "Kon gebruikers activiteiten niet ophalen" 14 | } 15 | -------------------------------------------------------------------------------- /frontend/app/src/i18n/nl/activityView.json: -------------------------------------------------------------------------------- 1 | { 2 | "labelGear": "Uitrusting", 3 | "labelGearNotSet": "Niet ingesteld", 4 | "modalLabelDeleteGear": "Verwijder uitrusting uit activiteit", 5 | "modalLabelDeleteGearBody": "Weet je zeker dat je de uitrusting uit de activiteit wilt verwijderen?", 6 | "modalLabelDeleteGearButton": "Verwijder uitrusting", 7 | "successMessageGearAdded": "Uitrusting toegevoegd aan activiteit", 8 | "successMessageGearDeleted": "Uitrusting verwijderd uit activiteit", 9 | "errorMessageDeleteGear": "Fout bij verwijderen van uitrusting uit activiteit", 10 | "errorMessageActivityNotFound": "Activiteit niet gevonden" 11 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/nl/components/activities/activitiesTableComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "headerType": "Type", 3 | "headerName": "Naam", 4 | "headerLocation": "Locatie", 5 | "headerStartTime": "Start tijd", 6 | "headerDuration": "Duur", 7 | "headerDistance": "Afstand", 8 | "headerPace": "Tempo/Snelheid", 9 | "headerCalories": "Calorieën", 10 | "headerElevation": "Hoogte", 11 | "headerAvgHr": "Gem. HS" 12 | } 13 | -------------------------------------------------------------------------------- /frontend/app/src/i18n/nl/components/activities/activityLapsComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "labelLapNumber": "Ronde", 3 | "labelLapIntensity": "Intensiteit", 4 | "labelLapDistance": "Afstand", 5 | "labelLapTime": "Tijd", 6 | "labelLapPace": "Tempo", 7 | "labelLapSpeed": "Snelheid", 8 | "labelLapElevation": "Hoogte", 9 | "labelLapElev": "Hoogte", 10 | "labelLapAvgHr": "Gem hartslag", 11 | "labelLapHR": "HS", 12 | "labelLapStrokeRate": "Stroke rate", 13 | "labelLapSR": "SR" 14 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/nl/components/activities/activityMandAbovePillsComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "labelPillGraphs": "Grafieken", 3 | "labelPillLaps": "Rondes", 4 | "labelPillWorkoutSets": "Sets", 5 | "labelGraph": "Activiteit data grafieken", 6 | "labelGraphHR": "Hartslag", 7 | "labelGraphPower": "Vermogen", 8 | "labelGraphCadence": "Cadans", 9 | "labelGraphElevation": "Hoogte", 10 | "labelGraphVelocity": "Snelheid", 11 | "labelGraphPace": "Tempo", 12 | "labelDownsampling": "Gegevens teruggeschaald naar ~200 punten", 13 | "errorMessageProcessingActivityStreams": "Fout bij verwerken activiteit streams", 14 | "labelGraphStrokeRate": "Stroke rate" 15 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/nl/components/activities/activityWorkoutStepsComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "labelWorkoutStepType": "Stap type", 3 | "labelWorkoutStepTime": "Stap tijd", 4 | "labelWorkoutStepReps": "Stap repetities", 5 | "labelWorkoutStepIntensity": "Intensiteit", 6 | "labelWorkoutStepNotes": "Notities", 7 | "labelWorkoutStepExerciseName": "Stap naam", 8 | "labelWorkoutStepExerciseWeight": "Gewicht", 9 | "labelWorkoutStepSwimStroke": "Stap zwem slag", 10 | "labelWorkoutSetType": "Stel type in", 11 | "labelWorkoutSetTime": "Stel tijd in", 12 | "labelWorkoutSetReps": "Stel repetities in", 13 | "labelWorkoutSetExerciseName": "Stel naam in", 14 | "labelWorkoutSetExerciseWeight": "Stel gewicht in", 15 | "labelWorkoutSetTypeMobile": "Type", 16 | "labelWorkoutSetTimeMobile": "Tijd", 17 | "labelWorkoutSetRepsMobile": "Repetities", 18 | "labelWorkoutSetExerciseNameMobile": "Naam", 19 | "labelWorkoutSetExerciseWeightMobile": "Gewicht" 20 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/nl/components/activities/modals/addGearToActivityModalComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "modalLabelAddGear": "Voeg uitrusting toe aan activiteit", 3 | "modalLabelSelectGear": "Selecteer uitrusting", 4 | "modalButtonAddGear": "Voeg Uitrusting toe", 5 | "errorEditingGear": "Fout bij bewerken uitrusting" 6 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/nl/components/activities/userDistanceStatsComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "thisWeekDistancesTitle": "Week top 3", 3 | "thisMonthDistancesTitle": "Maand top 3" 4 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/nl/components/gears/gearsListComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "gearListTypeLabel": "Soort", 3 | "gearListTypeOption1": "Fiets", 4 | "gearListTypeOption2": "Schoenen", 5 | "gearListTypeOption3": "Wetsuit", 6 | "gearListTypeOption4": "Raket", 7 | "gearListGearIsInactiveBadge": "Inactief", 8 | "gearListGearFromStrava": "Strava", 9 | "gearListGearFromGarminConnect": "Garmin Connect", 10 | "gearListModalDeleteGearTitle": "Verwijder uitrusting", 11 | "gearListModalDeleteGearBody": "Weet u zeker dat u de uitrusting wilt verwijderen? ", 12 | "gearListGearDeleteSuccessMessage": "Uitrusting succesvol verwijderd", 13 | "gearListGearDeleteErrorMessage": "Fout bij verwijderen uitrusting" 14 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/nl/components/health/healthDashboardZoneComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": "Gewicht", 3 | "noWeightData": "Geen gewichtsgegevens", 4 | "noWeightTarget": "Geen gewichtsdoel", 5 | "noHeightDefined": "Geen hoogte gedefinieerd voor de gebruiker", 6 | "bmi": "BMI", 7 | "bmiUnderweight": "Ondergewicht", 8 | "bmiNormalWeight": "Normaal gewicht", 9 | "bmiOverweight": "Overgewicht", 10 | "bmiObesityClass1": "Obesitas (klasse 1)", 11 | "bmiObesityClass2": "Obesitas (klasse 2)", 12 | "bmiObesityClass3": "Extreme obesitas (klasse 3)" 13 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/nl/components/health/healthSideBarComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "dashboardSection": "Dashboard", 3 | "weightSection": "Gewicht" 4 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/nl/components/health/healthWeightZone/healthWeightAddEditModalComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "addWeightModalTitle": "Gewicht Toevoegen", 3 | "editWeightModalTitle": "Gewicht Wijzigen", 4 | "addWeightWeightLabel": "Gewicht", 5 | "addWeightDateLabel": "Datum", 6 | "successAddWeight": "Gewicht toegevoegd", 7 | "errorAddWeight": "Fout bij gewicht toevoegen" 8 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/nl/components/health/healthWeightZone/healthWeightListComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "labelGarminConnect": "Garmin Connect", 3 | "modalDeleteWeightTitle": "Gewicht verwijderen", 4 | "modalDeleteWeightBody": "Weet u zeker dat u gewicht wilt verwijderen voor ", 5 | "successDeleteWeight": "Gewicht verwijderd", 6 | "errorDeleteWeight": "Het was niet mogelijk om uw gewicht te verwijderen", 7 | "successEditWeight": "Gewicht bewerkt", 8 | "errorEditWeight": "Het was niet mogelijk om uw gewicht aan te passen" 9 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/nl/components/health/healthWeightZoneComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "buttonAddWeight": "Gewicht Toevoegen", 3 | "labelNumberOfHealthDataWeight1": "Er is een totaal van ", 4 | "labelNumberOfHealthDataWeight2": " gewicht afmeting(en) ingevoegd (", 5 | "labelNumberOfHealthDataWeight3": " geladen):" 6 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/nl/components/navbar/navbarBottomMobileComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "home": "Thuis", 3 | "activities": "Activiteiten", 4 | "search": "Zoeken", 5 | "gear": "Uitrusting", 6 | "health": "Gezondheid", 7 | "menu": "Menu" 8 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/nl/components/navbar/navbarComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "search": "Zoeken", 3 | "activities": "Activiteiten", 4 | "gear": "Uitrusting", 5 | "health": "Gezondheid", 6 | "profile": "Profiel", 7 | "settings": "Instellingen", 8 | "login": "Inloggen", 9 | "logout": "Uitloggen", 10 | "errorLogout": "Fout bij uitloggen" 11 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/nl/components/noItemsFoundComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Oeps...", 3 | "subtitle": "Geen gegevens gevonden" 4 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/nl/components/settings/settingsGeneralZone/settingsLanguageSwitcherComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "formLabel": "Taal" 3 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/nl/components/settings/settingsGeneralZone/settingsThemeSwitcherComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "formLabel": "Thema", 3 | "themeLight": "Licht", 4 | "themeDark": "Donker", 5 | "themeAuto": "Automatisch" 6 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/nl/components/settings/settingsIntegrationsZone/garminConnectLoginModalComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "garminConnectAuthModalTitle": "Garmin Connect account koppelen", 3 | "garminConnectAuthModalUsernameLabel": "Garmin Connect e-mail", 4 | "garminConnectAuthModalUsernamePlaceholder": "Garmin Connect e-mail", 5 | "garminConnectAuthModalPasswordLabel": "Garmin Connect wachtwoord", 6 | "garminConnectAuthModalPasswordPlaceholder": "Garmin Connect wachtwoord", 7 | "garminConnectAuthModalMfaCodeLabel": "MFA code", 8 | "garminConnectAuthModalMfaCodePlaceholder": "MFA code", 9 | "buttonSubmitMfaCode": "MFA code versturen", 10 | "garminConnectAuthModalLoginButton": "Inloggen", 11 | "processingMessageLinkGarminConnect": "Garmin Connect account koppelen...", 12 | "successMessageLinkGarminConnect": "Garmin Connect account gekoppeld", 13 | "errorMessageUnableToLinkGarminConnect": "Kan Garmin Connect account niet koppelen" 14 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/nl/components/settings/settingsSecurityZoneComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "subtitleChangePassword": "Wachtwoord wijzigen", 3 | "changeUserPasswordBodyLabel": "Wijzig wachtwoord voor gebruiker ", 4 | "changeUserPasswordPasswordLabel": "Nieuw wachtwoord", 5 | "changeUserPasswordPasswordConfirmationLabel": "Bevestig nieuw wachtwoord", 6 | "changeUserPasswordFeedbackLabel": "Wachtwoord voldoet niet aan de eisen", 7 | "changeUserPasswordPasswordsDoNotMatchFeedbackLabel": "Wachtwoorden komen niet overeen", 8 | "subtitleMySessions": "Mijn sessies", 9 | "userChangePasswordSuccessMessage": "Wachtwoord met succes gewijzigd", 10 | "userChangePasswordErrorMessage": "Fout opgetreden bij wijzigen van wachtwoord", 11 | "successDeleteSession": "Sessie succesvol verwijderd", 12 | "errorDeleteSession": "Fout bij verwijderen sessie" 13 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/nl/components/settings/settingsSideBarComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "usersSection": "Gebruikers", 3 | "serverSettingsSection": "Serverinstellingen", 4 | "generalSection": "Algemeen", 5 | "myProfileSection": "Mijn profiel", 6 | "securitySection": "Beveiliging", 7 | "integrationsSection": "Integraties" 8 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/nl/components/settings/settingsUserSessionsZone/userSessionsListComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "badgeCurrentSession": "Huidige Sessie", 3 | "modalDeleteSessionTitle": "Sessie verwijderen", 4 | "modalDeleteSessionBody": "Weet u zeker dat u de sessie wilt verwijderen? " 5 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/nl/components/settings/settingsUsersZone/usersChangeUserPasswordModalComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "modalChangeUserPasswordTitle": "Wachtwoord gebruiker wijzigen", 3 | "modalChangeUserPasswordBodyLabel": "Wijzig wachtwoord voor gebruiker ", 4 | "modalChangeUserPasswordPasswordLabel": "Nieuw wachtwoord", 5 | "modalChangeUserPasswordPasswordConfirmationLabel": "Bevestig nieuw wachtwoord", 6 | "modalChangeUserPasswordFeedbackLabel": "Wachtwoord voldoet niet aan de eisen", 7 | "modalChangeUserPasswordPasswordsDoNotMatchFeedbackLabel": "Wachtwoorden komen niet overeen", 8 | "userChangePasswordSuccessMessage": "Wachtwoord met succes gewijzigd", 9 | "userChangePasswordErrorMessage": "Fout opgetreden bij wijzigen van wachtwoord" 10 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/nl/components/settings/settingsUsersZone/usersListComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "userListAccessTypeLabel": "Toegang type: ", 3 | "userListAccessTypeOption1": "Reguliere gebruiker", 4 | "userListAccessTypeOption2": "Beheerder", 5 | "userListUserIsMeBadge": "Ik", 6 | "userListUserIsAdminBadge": "Admin", 7 | "userListUserIsActiveBadge": "Actief", 8 | "userListUserIsInactiveBadge": "Inactief", 9 | "userEditErrorMessage": "Fout bij bewerken gebruiker", 10 | "modalDeleteUserTitle": "Gebruiker verwijderen", 11 | "modalDeleteUserBody": "Weet u zeker dat u gebruiker wilt verwijderen? ", 12 | "userListUserSessionsTitle": "Gebruikerssessies", 13 | "userSessionDeleteSuccessMessage": "Sessie succesvol verwijderd", 14 | "userSessionDeleteErrorMessage": "Fout bij verwijderen sessie" 15 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/nl/components/settings/settingsUsersZone/usersPasswordRequirementsComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "passwordRequirementsTitle": "Wachtwoordvereisten omvatten:", 3 | "passwordCharacters": "- 8 tekens;", 4 | "passwordCapitalLetters": "- 1 hoofdletter;", 5 | "passwordNumbers": "- 1 nummer;", 6 | "passwordSpecialCharacters": "- 1 speciaal teken;" 7 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/nl/components/settings/settingsUsersZoneComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "buttonAddUser": "Gebruiker toevoegen", 3 | "labelSearchUsersByUsername": "Gebruikers zoeken op gebruikersnaam", 4 | "labelNumberOfUsers1": "Er is een totaal van ", 5 | "labelNumberOfUsers2": " gebruiker(s) (", 6 | "labelNumberOfUsers3": " geladen):", 7 | "successUserAdded": "Gebruiker succesvol toegevoegd", 8 | "successUserDeleted": "Gebruiker succesvol verwijderd", 9 | "errorFetchingUsers": "Fout bij ophalen gebruikers" 10 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/nl/gears/gearView.json: -------------------------------------------------------------------------------- 1 | { 2 | "buttonEditGear": "Bewerk uitrusting", 3 | "buttonDeleteGear": "Verwijder uitrusting", 4 | "modalDeleteGearBody1": "Weet u zeker dat u de uitrusting wilt verwijderen", 5 | "modalDeleteGearBody2": "Deze actie kan niet ongedaan worden gemaakt.", 6 | "gearIsActiveBadge": "Actief", 7 | "gearIsInactiveBadge": "Inactief", 8 | "gearTypeOption1": "Fiets", 9 | "gearTypeOption2": "Schoenen", 10 | "gearTypeOption3": "Wetsuit", 11 | "gearTypeOption4": "Raket", 12 | "gearFromStrava": "Strava", 13 | "gearFromGarminConnect": "Garmin Connect", 14 | "labelBrand": "Merk", 15 | "labelModel": "Model", 16 | "labelDistance": "Afstand", 17 | "labelDate": "Datum", 18 | "title": "Uitrusting activiteiten", 19 | "subtitle": "(laatste 10 activiteiten)", 20 | "successGearEdited": "Uitrusting met succes bewerkt", 21 | "errorGearDelete": "Fout bij verwijderen uitrusting", 22 | "errorFetchingGears": "Fout bij ophalen van uitrusting" 23 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/nl/gears/gearsView.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Uitrusting", 3 | "buttonAddGear": "Voeg Uitrusting toe", 4 | "subTitleSearchGearByNickname": "Zoek uitrusting op bijnaam", 5 | "placeholderSearchGearByNickname": "Bijnaam", 6 | "buttonSearchGear": "Zoek Uitrusting", 7 | "displayUserNumberOfGears1": "Er is een totaal van ", 8 | "displayUserNumberOfGears2": " uitrusting(en) (", 9 | "displayUserNumberOfGears3": " geladen):", 10 | "successGearDeleted": "Uitrusting succesvol verwijderd", 11 | "errorGearNotFound": "Uitrusting niet gevonden", 12 | "errorFetchingGears": "Fout bij ophalen van uitrusting" 13 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/nl/healthView.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Gezondheid", 3 | "errorFetchingHealthData": "Fout bij het ophalen van gezondheidsgegevens", 4 | "errorFetchingHealthTargets": "Fout bij ophalen van gezondheidsdoelen" 5 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/nl/homeView.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Endurain", 3 | "buttonAddActivity": "Activiteit toevoegen", 4 | "fieldLabelUploadGPXFile": "Upload .gpx of .fit bestand", 5 | "radioUserActivities": "Mijn activiteiten", 6 | "radioFollowerActivities": "Activiteiten volgers", 7 | "successActivityAdded": "Activiteit succesvol toegevoegd", 8 | "errorActivityAdded": "Fout bij toevoegen activiteit", 9 | "refreshingActivities": "Activiteiten vernieuwen van gekoppelde services", 10 | "successActivitiesRefreshed": "Activiteiten succesvol vernieuwd", 11 | "errorActivityNotFound": "Activiteit niet gevonden", 12 | "processingActivity": "Activiteit verwerken", 13 | "successActivityDeleted": "Activiteit succesvol verwijderd", 14 | "errorFetchingUserStats": "Fout bij ophalen gebruikersstatistieken", 15 | "errorFetchingUserActivities": "Fout bij ophalen gebruikersactiviteiten" 16 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/nl/loginView.json: -------------------------------------------------------------------------------- 1 | { 2 | "sessionExpired": "Gebruikerssessie verlopen", 3 | "error401": "Gebruikersnaam of wachtwoord ongeldig", 4 | "error403": "U bent niet gemachtigd voor toegang tot deze bron", 5 | "error500": "Het was niet mogelijk om verbinding te maken met de server. Probeer het later opnieuw", 6 | "errorUndefined": "Het was niet mogelijk om verbinding te maken met de server. Probeer het later opnieuw", 7 | "subtitle": "Login hieronder", 8 | "username": "Gebruikersnaam", 9 | "password": "Wachtwoord", 10 | "neverExpires": "Onthoud mij (vink dit vakje niet aan als je een gedeelde computer gebruikt)", 11 | "signInButton": "Inloggen", 12 | "signUpText": "Op zoek naar Aanmelden?", 13 | "signUpButton": "Aanmelden", 14 | "errorPublicActivityNotFound": "Openbare activiteit niet gevonden", 15 | "errorpublic_shareable_links": "Openbare deelbare links zijn niet toegestaan. Om deze activiteit te bekijken moet u aangemeld zijn" 16 | } 17 | -------------------------------------------------------------------------------- /frontend/app/src/i18n/nl/notFoundView.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Oeps! Pagina niet gevonden", 3 | "subTitle": "De pagina die u zoekt bestaat niet of is gewijzigd.", 4 | "backToHomeButton": "Terug naar de hoofdpagina" 5 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/nl/settingsView.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Instellingen" 3 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/nl/strava/stravaCallbackView.json: -------------------------------------------------------------------------------- 1 | { 2 | "stravaCallbackViewTitle1": "Handling Strava callback", 3 | "stravaCallbackViewTitle2": "Een ogenblik geduld, Strava wordt gekoppeld aan uw account. Vernieuw deze pagina niet." 4 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/pt/activitiesView.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Atividades", 3 | "filterLabelType": "Tipo", 4 | "filterOptionAllTypes": "Todos os tipos", 5 | "filterLabelFromDate": "Data de início", 6 | "filterLabelToDate": "Data de fim", 7 | "filterLabelNameLocation": "Nome ou localização", 8 | "filterPlaceholderNameLocation": "ex., Corrida da Manhã", 9 | "buttonClear": "Limpar", 10 | "buttonApply": "Aplicar", 11 | "errorFailedFetchActivityTypes": "Falha ao buscar tipos de atividades", 12 | "errorUpdatingActivities": "Falha ao atualizar as atividades", 13 | "errorFetchingActivities": "Falha ao atualizar as atividades do utilizador" 14 | } 15 | -------------------------------------------------------------------------------- /frontend/app/src/i18n/pt/activityView.json: -------------------------------------------------------------------------------- 1 | { 2 | "labelGear": "Equipamento", 3 | "labelGearNotSet": "Não definido", 4 | "modalLabelDeleteGear": "Remover equipamento da atividade", 5 | "modalLabelDeleteGearBody": "Tem certeza que deseja remover o equipamento da atividade?", 6 | "modalLabelDeleteGearButton": "Eliminar equipamento", 7 | "successMessageGearAdded": "Equipamento adicionado à atividade", 8 | "successMessageGearDeleted": "Equipamento eliminado da atividade", 9 | "errorMessageDeleteGear": "Erro ao eliminar equipamento da atividade", 10 | "errorMessageActivityNotFound": "Atividade não encontrada" 11 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/pt/components/activities/activitiesTableComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "headerType": "Tipo", 3 | "headerName": "Nome", 4 | "headerLocation": "Local", 5 | "headerStartTime": "Hora de início", 6 | "headerDuration": "Duração", 7 | "headerDistance": "Distância", 8 | "headerPace": "Ritmo/Velocidade", 9 | "headerCalories": "Calorias", 10 | "headerElevation": "Elevação", 11 | "headerAvgHr": "Média de FC" 12 | } 13 | -------------------------------------------------------------------------------- /frontend/app/src/i18n/pt/components/activities/activityLapsComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "labelLapNumber": "Volta", 3 | "labelLapIntensity": "Intensidade", 4 | "labelLapDistance": "Distância", 5 | "labelLapTime": "Tempo", 6 | "labelLapPace": "Ritmo", 7 | "labelLapSpeed": "Velocidade", 8 | "labelLapElevation": "Elevação", 9 | "labelLapElev": "Elev", 10 | "labelLapAvgHr": "Freq. cardíaca média", 11 | "labelLapHR": "FC", 12 | "labelLapStrokeRate": "Velocidade de braçada", 13 | "labelLapSR": "VB" 14 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/pt/components/activities/activityMandAbovePillsComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "labelPillGraphs": "Gráficos", 3 | "labelPillLaps": "Voltas", 4 | "labelPillWorkoutSets": "Jogos", 5 | "labelGraph": "Gráficos de dados da atividade", 6 | "labelGraphHR": "Frequência cardíaca", 7 | "labelGraphPower": "Potência", 8 | "labelGraphCadence": "Cadência", 9 | "labelGraphElevation": "Elevação", 10 | "labelGraphVelocity": "Velocidade", 11 | "labelGraphPace": "Ritmo", 12 | "labelDownsampling": "Dados downsampled para ~200 pontos", 13 | "errorMessageProcessingActivityStreams": "Erro ao processar fluxos de atividade", 14 | "labelGraphStrokeRate": "Velocidade de braçada" 15 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/pt/components/activities/activityWorkoutStepsComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "labelWorkoutStepType": "Tipo etapa", 3 | "labelWorkoutStepTime": "Tempo etapa", 4 | "labelWorkoutStepReps": "Reps etapa", 5 | "labelWorkoutStepIntensity": "Intensidade", 6 | "labelWorkoutStepNotes": "Notas", 7 | "labelWorkoutStepExerciseName": "Nome etapa", 8 | "labelWorkoutStepExerciseWeight": "Peso", 9 | "labelWorkoutStepSwimStroke": "Estilo etapa", 10 | "labelWorkoutSetType": "Tipo jogo", 11 | "labelWorkoutSetTime": "Tempo jogo", 12 | "labelWorkoutSetReps": "Reps jogo", 13 | "labelWorkoutSetExerciseName": "Nome jogo", 14 | "labelWorkoutSetExerciseWeight": "Peso jogo", 15 | "labelWorkoutSetTypeMobile": "Tipo", 16 | "labelWorkoutSetTimeMobile": "Tempo", 17 | "labelWorkoutSetRepsMobile": "Reps", 18 | "labelWorkoutSetExerciseNameMobile": "Nome", 19 | "labelWorkoutSetExerciseWeightMobile": "Peso" 20 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/pt/components/activities/modals/addGearToActivityModalComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "modalLabelAddGear": "Adicionar equipamento à atividade", 3 | "modalLabelSelectGear": "Selecionar equipamento", 4 | "modalButtonAddGear": "Adicionar equipamento", 5 | "errorEditingGear": "Erro ao editar equipamento" 6 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/pt/components/activities/userDistanceStatsComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "thisWeekDistancesTitle": "Top 3 da semana", 3 | "thisMonthDistancesTitle": "Top 3 do mês" 4 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/pt/components/gears/gearsListComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "gearListTypeLabel": "Tipo", 3 | "gearListTypeOption1": "Bicicleta", 4 | "gearListTypeOption2": "Sapatilhas", 5 | "gearListTypeOption3": "Fato de neoprene", 6 | "gearListTypeOption4": "Raqueta", 7 | "gearListGearIsInactiveBadge": "Inativo", 8 | "gearListGearFromStrava": "Strava", 9 | "gearListGearFromGarminConnect": "Garmin Connect", 10 | "gearListModalDeleteGearTitle": "Eliminar equipamento", 11 | "gearListModalDeleteGearBody": "Tem a certeza que deseja eliminar o equipamento ", 12 | "gearListGearDeleteSuccessMessage": "Equipamento eliminado com sucesso", 13 | "gearListGearDeleteErrorMessage": "Erro ao eliminar equipamento" 14 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/pt/components/health/healthDashboardZoneComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": "Peso", 3 | "noWeightData": "Sem dados de peso", 4 | "noWeightTarget": "Sem meta de peso", 5 | "noHeightDefined": "Altura não definida para utilizador", 6 | "bmi": "IMC", 7 | "bmiUnderweight": "Abaixo do peso", 8 | "bmiNormalWeight": "Peso normal", 9 | "bmiOverweight": "Acima do peso", 10 | "bmiObesityClass1": "Obesidade (Classe 1)", 11 | "bmiObesityClass2": "Obesidade (Classe 2)", 12 | "bmiObesityClass3": "Obesidade extrema (Classe 3)" 13 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/pt/components/health/healthSideBarComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "dashboardSection": "Painel de controlo", 3 | "weightSection": "Peso" 4 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/pt/components/health/healthWeightZone/healthWeightAddEditModalComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "addWeightModalTitle": "Adicionar peso", 3 | "editWeightModalTitle": "Editar peso", 4 | "addWeightWeightLabel": "Peso", 5 | "addWeightDateLabel": "Data", 6 | "successAddWeight": "Peso adicionado", 7 | "errorAddWeight": "Erro ao adicionar peso" 8 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/pt/components/health/healthWeightZone/healthWeightListComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "labelGarminConnect": "Garmin Connect", 3 | "modalDeleteWeightTitle": "Apagar peso", 4 | "modalDeleteWeightBody": "Tem a certeza que deseja eliminar a entrada de peso para ", 5 | "successDeleteWeight": "Peso eliminado", 6 | "errorDeleteWeight": "Não foi possível eliminar a entrada de peso", 7 | "successEditWeight": "Peso editado", 8 | "errorEditWeight": "Não foi possível editar a entrada de peso" 9 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/pt/components/health/healthWeightZoneComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "buttonAddWeight": "Adicionar peso", 3 | "labelNumberOfHealthDataWeight1": "Existe um total de ", 4 | "labelNumberOfHealthDataWeight2": " medida(s) de peso inserida(s) (", 5 | "labelNumberOfHealthDataWeight3": " carregada(s)):" 6 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/pt/components/navbar/navbarBottomMobileComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "home": "Início", 3 | "activities": "Atividades", 4 | "search": "Procurar", 5 | "gear": "Equipamento", 6 | "health": "Saúde", 7 | "menu": "Menu" 8 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/pt/components/navbar/navbarComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "search": "Procurar", 3 | "activities": "Atividades", 4 | "gear": "Equipamento", 5 | "health": "Saúde", 6 | "profile": "Perfil", 7 | "settings": "Definições", 8 | "login": "Iniciar sessão", 9 | "logout": "Encerrar sessão", 10 | "errorLogout": "Erro ao terminar sessão" 11 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/pt/components/noItemsFoundComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Ops...", 3 | "subtitle": "Nenhum registo encontrado" 4 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/pt/components/settings/settingsGeneralZone/settingsLanguageSwitcherComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "formLabel": "Língua" 3 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/pt/components/settings/settingsGeneralZone/settingsThemeSwitcherComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "formLabel": "Tema", 3 | "themeLight": "Claro", 4 | "themeDark": "Escuro", 5 | "themeAuto": "Automático" 6 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/pt/components/settings/settingsIntegrationsZone/garminConnectLoginModalComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "garminConnectAuthModalTitle": "Associar conta do Garmin Connect", 3 | "garminConnectAuthModalUsernameLabel": "E-mail do Garmin Connect", 4 | "garminConnectAuthModalUsernamePlaceholder": "E-mail do Garmin Connect", 5 | "garminConnectAuthModalPasswordLabel": "Palavra-passe do Garmin Connect", 6 | "garminConnectAuthModalPasswordPlaceholder": "Palavra-passe do Garmin Connect", 7 | "garminConnectAuthModalMfaCodeLabel": "Código MFA", 8 | "garminConnectAuthModalMfaCodePlaceholder": "Código MFA", 9 | "buttonSubmitMfaCode": "Enviar código MFA", 10 | "garminConnectAuthModalLoginButton": "Iniciar sessão", 11 | "processingMessageLinkGarminConnect": "A associar conta do Garmin Connect...", 12 | "successMessageLinkGarminConnect": "Conta do Garmin Connect associada", 13 | "errorMessageUnableToLinkGarminConnect": "Não foi possível associar a conta do Garmin Connect" 14 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/pt/components/settings/settingsSecurityZoneComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "subtitleChangePassword": "Alterar palavra-passe", 3 | "changeUserPasswordBodyLabel": "Alterar palavra-passe do utilizador ", 4 | "changeUserPasswordPasswordLabel": "Nova palavra-passe", 5 | "changeUserPasswordPasswordConfirmationLabel": "Confirmar a nova palavra-passe", 6 | "changeUserPasswordFeedbackLabel": "Palavra-passe não cumpre os requisitos", 7 | "changeUserPasswordPasswordsDoNotMatchFeedbackLabel": "Palavras-passe não coincidem", 8 | "subtitleMySessions": "As minhas sessões", 9 | "userChangePasswordSuccessMessage": "Palavra-passe alterada com sucesso", 10 | "userChangePasswordErrorMessage": "Erro ao alterar palavra-passe", 11 | "successDeleteSession": "Sessão eliminada com sucesso", 12 | "errorDeleteSession": "Erro ao eliminar sessão" 13 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/pt/components/settings/settingsSideBarComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "usersSection": "Utilizadores", 3 | "serverSettingsSection": "Definições do Servidor", 4 | "generalSection": "Geral", 5 | "myProfileSection": "O meu perfil", 6 | "securitySection": "Segurança", 7 | "integrationsSection": "Integrações" 8 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/pt/components/settings/settingsUserSessionsZone/userSessionsListComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "badgeCurrentSession": "Sessão atual", 3 | "modalDeleteSessionTitle": "Eliminar sessão", 4 | "modalDeleteSessionBody": "Tem a certeza que deseja eliminar a sessão " 5 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/pt/components/settings/settingsUsersZone/usersChangeUserPasswordModalComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "modalChangeUserPasswordTitle": "Alterar a palavra-passe do utilizador", 3 | "modalChangeUserPasswordBodyLabel": "Alterar palavra-passe do utilizador ", 4 | "modalChangeUserPasswordPasswordLabel": "Nova palavra-passe", 5 | "modalChangeUserPasswordPasswordConfirmationLabel": "Confirmar a nova palavra-passe", 6 | "modalChangeUserPasswordFeedbackLabel": "Palavra-passe não cumpre os requisitos", 7 | "modalChangeUserPasswordPasswordsDoNotMatchFeedbackLabel": "Palavras-passe não coincidem", 8 | "userChangePasswordSuccessMessage": "Palavra-passe alterada com sucesso", 9 | "userChangePasswordErrorMessage": "Erro ao alterar palavra-passe" 10 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/pt/components/settings/settingsUsersZone/usersListComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "userListAccessTypeLabel": "Tipo de acesso: ", 3 | "userListAccessTypeOption1": "Normal", 4 | "userListAccessTypeOption2": "Administrador", 5 | "userListUserIsMeBadge": "Eu", 6 | "userListUserIsAdminBadge": "Administrador", 7 | "userListUserIsActiveBadge": "Ativo", 8 | "userListUserIsInactiveBadge": "Inativo", 9 | "userEditErrorMessage": "Erro ao editar utilizador", 10 | "modalDeleteUserTitle": "Eliminar utilizador", 11 | "modalDeleteUserBody": "Tem certeza de que deseja eliminar o utilizador ", 12 | "userListUserSessionsTitle": "Sessões do utilizador", 13 | "userSessionDeleteSuccessMessage": "Sessão eliminada com sucesso", 14 | "userSessionDeleteErrorMessage": "Erro ao eliminar sessão" 15 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/pt/components/settings/settingsUsersZone/usersPasswordRequirementsComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "passwordRequirementsTitle": "Os requisitos da palavra-passe incluem:", 3 | "passwordCharacters": "- 8 caracteres;", 4 | "passwordCapitalLetters": "- 1 letra maiúscula;", 5 | "passwordNumbers": "- 1 número;", 6 | "passwordSpecialCharacters": "- 1 carácter especial;" 7 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/pt/components/settings/settingsUsersZoneComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "buttonAddUser": "Adicionar utilizador", 3 | "labelSearchUsersByUsername": "Procurar utilizadores por nome de utilizador", 4 | "labelNumberOfUsers1": "Existe um total de ", 5 | "labelNumberOfUsers2": " utilizador(es) (", 6 | "labelNumberOfUsers3": " carregado(s)):", 7 | "successUserAdded": "Utilizador adicionado com sucesso", 8 | "successUserDeleted": "Utilizador eliminado com sucesso", 9 | "errorFetchingUsers": "Erro ao procurar utilizadores" 10 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/pt/gears/gearView.json: -------------------------------------------------------------------------------- 1 | { 2 | "buttonEditGear": "Editar equipamento", 3 | "buttonDeleteGear": "Eliminar equipamento", 4 | "modalDeleteGearBody1": "Tem a certeza que deseja eliminar o equipamento ", 5 | "modalDeleteGearBody2": "Esta ação não pode ser revertida.", 6 | "gearIsActiveBadge": "Ativo", 7 | "gearIsInactiveBadge": "Inativo", 8 | "gearTypeOption1": "Bicicleta", 9 | "gearTypeOption2": "Sapatilhas", 10 | "gearTypeOption3": "Fato de neoprene", 11 | "gearTypeOption4": "Raqueta", 12 | "gearFromStrava": "Strava", 13 | "gearFromGarminConnect": "Garmin Connect", 14 | "labelBrand": "Marca", 15 | "labelModel": "Modelo", 16 | "labelDistance": "Distância", 17 | "labelDate": "Data", 18 | "title": "Atividades com este equipamento", 19 | "subtitle": "(últimas 10 atividades)", 20 | "successGearEdited": "Equipamento editado com sucesso", 21 | "errorGearDelete": "Erro ao eliminar equipamento", 22 | "errorFetchingGears": "Erro ao procurar equipamentos" 23 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/pt/gears/gearsView.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Equipamento", 3 | "buttonAddGear": "Adicionar equipamento", 4 | "subTitleSearchGearByNickname": "Procurar equipamento por alcunha", 5 | "placeholderSearchGearByNickname": "Alcunha", 6 | "buttonSearchGear": "Procurar equipamento", 7 | "displayUserNumberOfGears1": "Existe um total de ", 8 | "displayUserNumberOfGears2": " equipamento(s) (", 9 | "displayUserNumberOfGears3": " carregado(s)):", 10 | "successGearDeleted": "Equipamento eliminado com sucesso", 11 | "errorGearNotFound": "Equipamento não encontrado", 12 | "errorFetchingGears": "Erro ao procurar equipamentos" 13 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/pt/healthView.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Saúde", 3 | "errorFetchingHealthData": "Erro ao obter dados de saúde", 4 | "errorFetchingHealthTargets": "Erro ao obter metas de saúde" 5 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/pt/homeView.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Endurain", 3 | "buttonAddActivity": "Adicionar atividade", 4 | "fieldLabelUploadGPXFile": "Carregar ficheiro .gpx ou .fit", 5 | "radioUserActivities": "Minhas atividades", 6 | "radioFollowerActivities": "Atividades de seguidores", 7 | "successActivityAdded": "Atividade adicionada com sucesso", 8 | "errorActivityAdded": "Erro ao adicionar atividade", 9 | "refreshingActivities": "A atualizar atividades de serviços conectados", 10 | "successActivitiesRefreshed": "Atividades atualizadas com sucesso", 11 | "errorActivityNotFound": "Atividade não encontrada", 12 | "processingActivity": "A processar atividade", 13 | "successActivityDeleted": "Atividade eliminada com sucesso", 14 | "errorFetchingUserStats": "Erro ao obter estatísticas do utilizador", 15 | "errorFetchingUserActivities": "Erro ao obter atividades do utilizador" 16 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/pt/loginView.json: -------------------------------------------------------------------------------- 1 | { 2 | "sessionExpired": "Sessão expirou", 3 | "error401": "Nome de utilizador ou palavra-passe inválidos", 4 | "error403": "Não tem permissões para aceder a este recurso", 5 | "error500": "Não foi possível comunicar com o servidor. Tente novamente mais tarde", 6 | "errorUndefined": "Não foi possível comunicar com o servidor. Tente novamente mais tarde", 7 | "subtitle": "Iniciar sessão abaixo", 8 | "username": "Nome de utilizador", 9 | "password": "Palavra-passe", 10 | "neverExpires": "Lembrar-me (não marque esta caixa se estiver a usar um computador partilhado)", 11 | "signInButton": "Iniciar sessão", 12 | "signUpText": "À procura de um novo registo?", 13 | "signUpButton": "Registar", 14 | "errorPublicActivityNotFound": "Atividade pública não encontrada", 15 | "errorpublic_shareable_links": "Links públicos não são permitidos. Para ver esta atividade, autentique-se" 16 | } 17 | -------------------------------------------------------------------------------- /frontend/app/src/i18n/pt/notFoundView.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Oops! Página não encontrada", 3 | "subTitle": "A página que procura não existe ou foi alterada.", 4 | "backToHomeButton": "Voltar à página inicial" 5 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/pt/settingsView.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Definições" 3 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/pt/strava/stravaCallbackView.json: -------------------------------------------------------------------------------- 1 | { 2 | "stravaCallbackViewTitle1": "A processar retorno da chamada de Strava", 3 | "stravaCallbackViewTitle2": "Por favor aguarde enquanto o Strava está a ser ligado à sua conta. Não atualize esta página." 4 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/us/activitiesView.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Activities", 3 | "filterLabelType": "Type", 4 | "filterOptionAllTypes": "All Types", 5 | "filterLabelFromDate": "From Date", 6 | "filterLabelToDate": "To Date", 7 | "filterLabelNameLocation": "Name or Location", 8 | "filterPlaceholderNameLocation": "e.g., Morning Run", 9 | "buttonClear": "Clear", 10 | "buttonApply": "Apply", 11 | "errorFailedFetchActivityTypes": "Failed to fetch activity types", 12 | "errorUpdatingActivities": "Failed to updated activities", 13 | "errorFetchingActivities": "Failed to fetch user activities" 14 | } 15 | -------------------------------------------------------------------------------- /frontend/app/src/i18n/us/activityView.json: -------------------------------------------------------------------------------- 1 | { 2 | "labelGear": "Gear", 3 | "labelGearNotSet": "Not set", 4 | "modalLabelDeleteGear": "Delete gear from activity", 5 | "modalLabelDeleteGearBody": "Are you sure you want to remove the gear from the activity?", 6 | "modalLabelDeleteGearButton": "Delete gear", 7 | "successMessageGearAdded": "Gear added to activity", 8 | "successMessageGearDeleted": "Gear deleted from activity", 9 | "errorMessageDeleteGear": "Error deleting gear from activity", 10 | "errorMessageActivityNotFound": "Activity not found" 11 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/us/components/activities/activitiesTableComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "headerType": "Type", 3 | "headerName": "Name", 4 | "headerLocation": "Location", 5 | "headerStartTime": "Start time", 6 | "headerDuration": "Duration", 7 | "headerDistance": "Distance", 8 | "headerPace": "Pace/Speed", 9 | "headerCalories": "Calories", 10 | "headerElevation": "Elevation", 11 | "headerAvgHr": "Avg HR" 12 | } 13 | -------------------------------------------------------------------------------- /frontend/app/src/i18n/us/components/activities/activityLapsComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "labelLapNumber": "Lap", 3 | "labelLapIntensity": "Intensity", 4 | "labelLapDistance": "Distance", 5 | "labelLapTime": "Time", 6 | "labelLapPace": "Pace", 7 | "labelLapSpeed": "Speed", 8 | "labelLapElevation": "Elevation", 9 | "labelLapElev": "Elev", 10 | "labelLapAvgHr": "Avg heart rate", 11 | "labelLapHR": "HR", 12 | "labelLapStrokeRate": "Stroke rate", 13 | "labelLapSR": "SR" 14 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/us/components/activities/activityMandAbovePillsComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "labelPillGraphs": "Graphs", 3 | "labelPillLaps": "Laps", 4 | "labelPillWorkoutSets": "Sets", 5 | "labelGraph": "Activity data graphs", 6 | "labelGraphHR": "Heart rate", 7 | "labelGraphPower": "Power", 8 | "labelGraphCadence": "Cadence", 9 | "labelGraphElevation": "Elevation", 10 | "labelGraphVelocity": "Velocity", 11 | "labelGraphPace": "Pace", 12 | "labelDownsampling": "Data downsampled to ~200 points", 13 | "errorMessageProcessingActivityStreams": "Error processing activity streams", 14 | "labelGraphStrokeRate": "Stroke rate" 15 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/us/components/activities/activityWorkoutStepsComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "labelWorkoutStepType": "Step type", 3 | "labelWorkoutStepTime": "Step time", 4 | "labelWorkoutStepReps": "Step reps", 5 | "labelWorkoutStepIntensity": "Intensity", 6 | "labelWorkoutStepNotes": "Notes", 7 | "labelWorkoutStepExerciseName": "Step name", 8 | "labelWorkoutStepExerciseWeight": "Weight", 9 | "labelWorkoutStepSwimStroke": "Step swim stroke", 10 | "labelWorkoutSetType": "Set type", 11 | "labelWorkoutSetTime": "Set time", 12 | "labelWorkoutSetReps": "Set reps", 13 | "labelWorkoutSetExerciseName": "Set name", 14 | "labelWorkoutSetExerciseWeight": "Set weight", 15 | "labelWorkoutSetTypeMobile": "Type", 16 | "labelWorkoutSetTimeMobile": "Time", 17 | "labelWorkoutSetRepsMobile": "Reps", 18 | "labelWorkoutSetExerciseNameMobile": "Name", 19 | "labelWorkoutSetExerciseWeightMobile": "Weight" 20 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/us/components/activities/modals/addGearToActivityModalComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "modalLabelAddGear": "Add gear to activity", 3 | "modalLabelSelectGear": "Select gear", 4 | "modalButtonAddGear": "Add gear", 5 | "errorEditingGear": "Error editing gear" 6 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/us/components/activities/userDistanceStatsComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "thisWeekDistancesTitle": "Week top 3", 3 | "thisMonthDistancesTitle": "Month top 3" 4 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/us/components/followers/followersListComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "requestAccepted": "Accepted", 3 | "requestPending": "Request pending", 4 | "followingModalTitle": "Delete following", 5 | "followingModalBody": "Are you sure you want to delete following user ", 6 | "followerModalTitle": "Delete follower", 7 | "followerModalBody": "Are you sure you want to delete follower user ", 8 | "followerAcceptModalTitle": "Accept user request", 9 | "followerAcceptModalBody": "Are you sure you want to accept follow request from user ", 10 | "followerDeclineModalTitle": "Decline user request ", 11 | "followerDeclineModalBody": "Are you sure you want to decline follow request from user ", 12 | "errorDeleteFollowing": "Error deleting following", 13 | "errorDeleteFollower": "Error deleting follower", 14 | "errorUpdateFollower": "Error updating follower", 15 | "errorFetchingFollowersDetails": "Error fetching followers details" 16 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/us/components/gears/gearsListComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "gearListTypeLabel": "Type", 3 | "gearListTypeOption1": "Bike", 4 | "gearListTypeOption2": "Shoes", 5 | "gearListTypeOption3": "Wetsuit", 6 | "gearListTypeOption4": "Racquet", 7 | "gearListGearIsInactiveBadge": "Inactive", 8 | "gearListGearFromStrava": "Strava", 9 | "gearListGearFromGarminConnect": "Garmin Connect", 10 | "gearListModalDeleteGearTitle": "Delete gear", 11 | "gearListModalDeleteGearBody": "Are you sure you want to delete gear ", 12 | "gearListGearDeleteSuccessMessage": "Gear deleted successfully", 13 | "gearListGearDeleteErrorMessage": "Error deleting gear" 14 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/us/components/health/healthDashboardZoneComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": "Weight", 3 | "noWeightData": "No weight data", 4 | "noWeightTarget": "No weight target", 5 | "noHeightDefined": "No height defined for user", 6 | "bmi": "BMI", 7 | "bmiUnderweight": "Underweight", 8 | "bmiNormalWeight": "Normal weight", 9 | "bmiOverweight": "Overweight", 10 | "bmiObesityClass1": "Obesity (Class 1)", 11 | "bmiObesityClass2": "Obesity (Class 2)", 12 | "bmiObesityClass3": "Extreme Obesity (Class 3)" 13 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/us/components/health/healthSideBarComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "dashboardSection": "Dashboard", 3 | "weightSection": "Weight" 4 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/us/components/health/healthWeightZone/healthWeightAddEditModalComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "addWeightModalTitle": "Add weight", 3 | "editWeightModalTitle": "Edit weight", 4 | "addWeightWeightLabel": "Weight", 5 | "addWeightDateLabel": "Date", 6 | "successAddWeight": "Weight added", 7 | "errorAddWeight": "Error adding weight" 8 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/us/components/health/healthWeightZone/healthWeightListComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "labelGarminConnect": "Garmin Connect", 3 | "modalDeleteWeightTitle": "Delete weight", 4 | "modalDeleteWeightBody": "Are you sure you want to delete weight entry for ", 5 | "successDeleteWeight": "Weight deleted", 6 | "errorDeleteWeight": "It was not possible to delete weight entry", 7 | "successEditWeight": "Weight edited", 8 | "errorEditWeight": "It was not possible to edit weight entry" 9 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/us/components/health/healthWeightZoneComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "buttonAddWeight": "Add weight", 3 | "labelNumberOfHealthDataWeight1": "There is a total of ", 4 | "labelNumberOfHealthDataWeight2": " weight measure(s) inserted (", 5 | "labelNumberOfHealthDataWeight3": " loaded):" 6 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/us/components/navbar/navbarBottomMobileComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "home": "Home", 3 | "activities": "Activities", 4 | "search": "Search", 5 | "gear": "Gear", 6 | "health": "Health", 7 | "menu": "Menu" 8 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/us/components/navbar/navbarComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "search": "Search", 3 | "activities": "Activities", 4 | "gear": "Gear", 5 | "health": "Health", 6 | "profile": "Profile", 7 | "settings": "Settings", 8 | "login": "Login", 9 | "logout": "Logout", 10 | "errorLogout": "Error logging out" 11 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/us/components/noItemsFoundComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Ops...", 3 | "subtitle": "No records found" 4 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/us/components/settings/settingsGeneralZone/settingsLanguageSwitcherComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "formLabel": "Language" 3 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/us/components/settings/settingsGeneralZone/settingsThemeSwitcherComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "formLabel": "Theme", 3 | "themeLight": "Light", 4 | "themeDark": "Dark", 5 | "themeAuto": "Auto" 6 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/us/components/settings/settingsIntegrationsZone/garminConnectLoginModalComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "garminConnectAuthModalTitle": "Link Garmin Connect account", 3 | "garminConnectAuthModalUsernameLabel": "Garmin Connect email", 4 | "garminConnectAuthModalUsernamePlaceholder": "Garmin Connect email", 5 | "garminConnectAuthModalPasswordLabel": "Garmin Connect password", 6 | "garminConnectAuthModalPasswordPlaceholder": "Garmin Connect password", 7 | "garminConnectAuthModalMfaCodeLabel": "MFA code", 8 | "garminConnectAuthModalMfaCodePlaceholder": "MFA code", 9 | "buttonSubmitMfaCode": "Submit MFA code", 10 | "garminConnectAuthModalLoginButton": "Login", 11 | "processingMessageLinkGarminConnect": "Linking Garmin Connect account...", 12 | "successMessageLinkGarminConnect": "Garmin Connect account linked", 13 | "errorMessageUnableToLinkGarminConnect": "Unable to link Garmin Connect account" 14 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/us/components/settings/settingsSecurityZoneComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "subtitleChangePassword": "Change password", 3 | "changeUserPasswordBodyLabel": "Change password for user ", 4 | "changeUserPasswordPasswordLabel": "New password", 5 | "changeUserPasswordPasswordConfirmationLabel": "Confirm new password", 6 | "changeUserPasswordFeedbackLabel": "Password does not meet requirements", 7 | "changeUserPasswordPasswordsDoNotMatchFeedbackLabel": "Passwords do not match", 8 | "subtitleMySessions": "My sessions", 9 | "userChangePasswordSuccessMessage": "Password changed successfully", 10 | "userChangePasswordErrorMessage": "Error changing password", 11 | "successDeleteSession": "Session deleted successfully", 12 | "errorDeleteSession": "Error deleting session" 13 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/us/components/settings/settingsSideBarComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "usersSection": "Users", 3 | "serverSettingsSection": "Server Settings", 4 | "generalSection": "General", 5 | "myProfileSection": "My Profile", 6 | "securitySection": "Security", 7 | "integrationsSection": "Integrations" 8 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/us/components/settings/settingsUserSessionsZone/userSessionsListComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "badgeCurrentSession": "Current Session", 3 | "modalDeleteSessionTitle": "Delete Session", 4 | "modalDeleteSessionBody": "Are you sure you want to delete session " 5 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/us/components/settings/settingsUsersZone/usersChangeUserPasswordModalComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "modalChangeUserPasswordTitle": "Change user password", 3 | "modalChangeUserPasswordBodyLabel": "Change password for user ", 4 | "modalChangeUserPasswordPasswordLabel": "New password", 5 | "modalChangeUserPasswordPasswordConfirmationLabel": "Confirm new password", 6 | "modalChangeUserPasswordFeedbackLabel": "Password does not meet requirements", 7 | "modalChangeUserPasswordPasswordsDoNotMatchFeedbackLabel": "Passwords do not match", 8 | "userChangePasswordSuccessMessage": "Password changed successfully", 9 | "userChangePasswordErrorMessage": "Error changing password" 10 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/us/components/settings/settingsUsersZone/usersListComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "userListAccessTypeLabel": "Access type: ", 3 | "userListAccessTypeOption1": "Regular user", 4 | "userListAccessTypeOption2": "Administrator", 5 | "userListUserIsMeBadge": "Me", 6 | "userListUserIsAdminBadge": "Admin", 7 | "userListUserIsActiveBadge": "Active", 8 | "userListUserIsInactiveBadge": "Inactive", 9 | "userEditErrorMessage": "Error editing user", 10 | "modalDeleteUserTitle": "Delete user", 11 | "modalDeleteUserBody": "Are you sure you want to delete user ", 12 | "userListUserSessionsTitle": "User sessions", 13 | "userSessionDeleteSuccessMessage": "Session deleted successfully", 14 | "userSessionDeleteErrorMessage": "Error deleting session" 15 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/us/components/settings/settingsUsersZone/usersPasswordRequirementsComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "passwordRequirementsTitle": "Password requirements includes:", 3 | "passwordCharacters": "- 8 characters;", 4 | "passwordCapitalLetters": "- 1 capital letter;", 5 | "passwordNumbers": "- 1 number;", 6 | "passwordSpecialCharacters": "- 1 special character;" 7 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/us/components/settings/settingsUsersZoneComponent.json: -------------------------------------------------------------------------------- 1 | { 2 | "buttonAddUser": "Add user", 3 | "labelSearchUsersByUsername": "Search users by username", 4 | "labelNumberOfUsers1": "There is a total of ", 5 | "labelNumberOfUsers2": " user(s) (", 6 | "labelNumberOfUsers3": " loaded):", 7 | "successUserAdded": "User added successfully", 8 | "successUserDeleted": "User deleted successfully", 9 | "errorFetchingUsers": "Error fetching users" 10 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/us/gears/gearView.json: -------------------------------------------------------------------------------- 1 | { 2 | "buttonEditGear": "Edit gear", 3 | "buttonDeleteGear": "Delete gear", 4 | "modalDeleteGearBody1": "Are you sure you want to delete gear", 5 | "modalDeleteGearBody2": "This action cannot be undone.", 6 | "gearIsActiveBadge": "Active", 7 | "gearIsInactiveBadge": "Inactive", 8 | "gearTypeOption1": "Bike", 9 | "gearTypeOption2": "Shoes", 10 | "gearTypeOption3": "Wetsuit", 11 | "gearTypeOption4": "Racquet", 12 | "gearFromStrava": "Strava", 13 | "gearFromGarminConnect": "Garmin Connect", 14 | "labelBrand": "Brand", 15 | "labelModel": "Model", 16 | "labelDistance": "Distance", 17 | "labelDate": "Date", 18 | "title": "Gear activities", 19 | "subtitle": "(last 10 activities)", 20 | "successGearEdited": "Gear edited successfully", 21 | "errorGearDelete": "Error deleting gear", 22 | "errorFetchingGears": "Error fetching gears" 23 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/us/gears/gearsView.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Gear", 3 | "buttonAddGear": "Add Gear", 4 | "subTitleSearchGearByNickname": "Search gear by nickname", 5 | "placeholderSearchGearByNickname": "Nickname", 6 | "buttonSearchGear": "Search Gear", 7 | "displayUserNumberOfGears1": "There is a total of ", 8 | "displayUserNumberOfGears2": " gear(s) (", 9 | "displayUserNumberOfGears3": " loaded):", 10 | "successGearDeleted": "Gear deleted successfully", 11 | "errorGearNotFound": "Gear not found", 12 | "errorFetchingGears": "Error fetching gears" 13 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/us/healthView.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Health", 3 | "errorFetchingHealthData": "Error fetching health data", 4 | "errorFetchingHealthTargets": "Error fetching health targets" 5 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/us/homeView.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Endurain", 3 | "buttonAddActivity": "Add Activity", 4 | "fieldLabelUploadGPXFile": "Upload .gpx or .fit file", 5 | "radioUserActivities": "My activities", 6 | "radioFollowerActivities": "Followers activities", 7 | "successActivityAdded": "Activity added successfully", 8 | "errorActivityAdded": "Error adding activity", 9 | "refreshingActivities": "Refreshing activities from linked services", 10 | "successActivitiesRefreshed": "Activities refreshed successfully", 11 | "errorActivityNotFound": "Activity not found", 12 | "processingActivity": "Processing activity", 13 | "successActivityDeleted": "Activity deleted successfully", 14 | "errorFetchingUserStats": "Error fetching user stats", 15 | "errorFetchingUserActivities": "Error fetching user activities" 16 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/us/loginView.json: -------------------------------------------------------------------------------- 1 | { 2 | "sessionExpired": "User session expired", 3 | "error401": "Invalid username or password", 4 | "error403": "You do not have permission to access this resource", 5 | "error500": "It was not possible to connect to the server. Please try again later", 6 | "errorUndefined": "It was not possible to connect to the server. Please try again later", 7 | "subtitle": "Sign-in below", 8 | "username": "Username", 9 | "password": "Password", 10 | "neverExpires": "Remember me (do not tick this box if you are using a shared computer)", 11 | "signInButton": "Sign in", 12 | "signUpText": "Looking for signing up?", 13 | "signUpButton": "Sign up", 14 | "errorPublicActivityNotFound": "Public activity not found", 15 | "errorpublic_shareable_links": "Public shareable links are not allowed. To view this activity, you must be signed in" 16 | } 17 | -------------------------------------------------------------------------------- /frontend/app/src/i18n/us/notFoundView.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Oops! Page not found", 3 | "subTitle": "The page you are looking for does not exist or it was changed.", 4 | "backToHomeButton": "Back to home" 5 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/us/settingsView.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Settings" 3 | } -------------------------------------------------------------------------------- /frontend/app/src/i18n/us/strava/stravaCallbackView.json: -------------------------------------------------------------------------------- 1 | { 2 | "stravaCallbackViewTitle1": "Handling Strava callback", 3 | "stravaCallbackViewTitle2": "Please wait while Strava is being linked to your account. Do not refresh this page." 4 | } -------------------------------------------------------------------------------- /frontend/app/src/services/activityExerciseTitlesService.js: -------------------------------------------------------------------------------- 1 | import { fetchGetRequest } from '@/utils/serviceUtils'; 2 | import { fetchPublicGetRequest } from '@/utils/servicePublicUtils'; 3 | 4 | export const activityExerciseTitles = { 5 | // Activity exercise titles authenticated 6 | async getActivityExerciseTitlesAll() { 7 | return fetchGetRequest("activities/exercise_titles/all"); 8 | }, 9 | // Activity exercise titles public 10 | async getPublicActivityExerciseTitlesAll() { 11 | return fetchPublicGetRequest("public/activities/exercise_titles/all"); 12 | }, 13 | }; -------------------------------------------------------------------------------- /frontend/app/src/services/activityLapsService.js: -------------------------------------------------------------------------------- 1 | import { fetchGetRequest } from '@/utils/serviceUtils'; 2 | import { fetchPublicGetRequest } from '@/utils/servicePublicUtils'; 3 | 4 | export const activityLaps = { 5 | // Activity laps authenticated 6 | async getActivityLapsByActivityId(activityId) { 7 | return fetchGetRequest(`activities/laps/activity_id/${activityId}/all`); 8 | }, 9 | // Activity laps public 10 | async getPublicActivityLapsByActivityId(activityId) { 11 | return fetchPublicGetRequest(`public/activities/laps/activity_id/${activityId}/all`); 12 | }, 13 | }; -------------------------------------------------------------------------------- /frontend/app/src/services/activitySetsService.js: -------------------------------------------------------------------------------- 1 | import { fetchGetRequest } from '@/utils/serviceUtils'; 2 | import { fetchPublicGetRequest } from '@/utils/servicePublicUtils'; 3 | 4 | export const activitySets = { 5 | // Activity sets authenticated 6 | async getActivitySetsByActivityId(activityId) { 7 | return fetchGetRequest(`activities/sets/activity_id/${activityId}/all`); 8 | }, 9 | // Activity sets public 10 | async getPublicActivitySetsByActivityId(activityId) { 11 | return fetchPublicGetRequest(`public/activities/sets/activity_id/${activityId}/all`); 12 | }, 13 | }; -------------------------------------------------------------------------------- /frontend/app/src/services/activityStreams.js: -------------------------------------------------------------------------------- 1 | import { fetchGetRequest } from '@/utils/serviceUtils'; 2 | import { fetchPublicGetRequest } from '@/utils/servicePublicUtils'; 3 | 4 | export const activityStreams = { 5 | // Activity streams authenticated 6 | async getActivitySteamsByActivityId(activityId) { 7 | return fetchGetRequest(`activities/streams/activity_id/${activityId}/all`); 8 | }, 9 | async getActivitySteamByStreamTypeByActivityId(activityId, streamType) { 10 | return fetchGetRequest(`activities/streams/activity_id/${activityId}/stream_type/${streamType}`); 11 | }, 12 | // Activity streams public 13 | async getPublicActivityStreamsByActivityId(activityId) { 14 | return fetchPublicGetRequest(`public/activities/streams/activity_id/${activityId}/all`); 15 | }, 16 | async getPublicActivitySteamByStreamTypeByActivityId(activityId, streamType) { 17 | return fetchPublicGetRequest(`public/activities/streams/activity_id/${activityId}/stream_type/${streamType}`); 18 | }, 19 | }; -------------------------------------------------------------------------------- /frontend/app/src/services/activityWorkoutStepsService.js: -------------------------------------------------------------------------------- 1 | import { fetchGetRequest } from '@/utils/serviceUtils'; 2 | import { fetchPublicGetRequest } from '@/utils/servicePublicUtils'; 3 | 4 | export const activityWorkoutSteps = { 5 | // Activity workout_steps authenticated 6 | async getActivityWorkoutStepsByActivityId(activityId) { 7 | return fetchGetRequest(`activities/workout_steps/activity_id/${activityId}/all`); 8 | }, 9 | // Activity workout_steps public 10 | async getPublicActivityWorkoutStepsByActivityId(activityId) { 11 | return fetchPublicGetRequest(`public/activities/workout_steps/activity_id/${activityId}/all`); 12 | }, 13 | }; -------------------------------------------------------------------------------- /frontend/app/src/services/health_dataService.js: -------------------------------------------------------------------------------- 1 | import { fetchGetRequest, fetchPostRequest, fetchPutRequest, fetchDeleteRequest } from '@/utils/serviceUtils'; 2 | 3 | export const health_data = { 4 | getUserHealthDataNumber() { 5 | return fetchGetRequest('health/number'); 6 | }, 7 | getUserHealthData() { 8 | return fetchGetRequest('health'); 9 | }, 10 | getUserHealthDataWithPagination(pageNumber, numRecords) { 11 | return fetchGetRequest(`health/page_number/${pageNumber}/num_records/${numRecords}`); 12 | }, 13 | createHealthData(data) { 14 | return fetchPostRequest('health', data) 15 | }, 16 | editHealthData(data) { 17 | return fetchPutRequest('health', data) 18 | } 19 | }; -------------------------------------------------------------------------------- /frontend/app/src/services/health_targetsService.js: -------------------------------------------------------------------------------- 1 | import { fetchGetRequest, fetchPostRequest, fetchPutRequest, fetchDeleteRequest } from '@/utils/serviceUtils'; 2 | 3 | export const health_targets = { 4 | getUserHealthTargets() { 5 | return fetchGetRequest(`health_targets/`); 6 | }, 7 | }; -------------------------------------------------------------------------------- /frontend/app/src/services/profileService.js: -------------------------------------------------------------------------------- 1 | import { fetchGetRequest, fetchPostRequest, fetchPutRequest, fetchDeleteRequest, fetchPostFileRequest } from '@/utils/serviceUtils'; 2 | 3 | export const profile = { 4 | getProfileInfo() { 5 | return fetchGetRequest('profile'); 6 | }, 7 | getProfileSessions() { 8 | return fetchGetRequest('profile/sessions'); 9 | }, 10 | uploadProfileImage(file) { 11 | const formData = new FormData(); 12 | formData.append('file', file); 13 | 14 | return fetchPostFileRequest('profile/image', formData); 15 | }, 16 | editProfile(data) { 17 | return fetchPutRequest('profile', data) 18 | }, 19 | editProfilePassword(data) { 20 | return fetchPutRequest('profile/password', data) 21 | }, 22 | deleteProfilePhoto() { 23 | return fetchPutRequest('profile/photo'); 24 | }, 25 | deleteProfileSession(session_id) { 26 | return fetchDeleteRequest(`profile/sessions/${session_id}`); 27 | } 28 | }; -------------------------------------------------------------------------------- /frontend/app/src/services/serverSettingsService.js: -------------------------------------------------------------------------------- 1 | import { fetchGetRequest, fetchPostRequest, fetchPutRequest, fetchDeleteRequest, fetchPostFileRequest } from '@/utils/serviceUtils'; 2 | import { fetchPublicGetRequest } from '@/utils/servicePublicUtils'; 3 | 4 | export const serverSettings = { 5 | // Server settings public 6 | getPublicServerSettings() { 7 | return fetchPublicGetRequest('public/server_settings'); 8 | }, 9 | // Server settings authenticated 10 | editServerSettings(data) { 11 | return fetchPutRequest('server_settings', data); 12 | }, 13 | uploadLoginPhotoFile(formData) { 14 | return fetchPostFileRequest('server_settings/upload/login', formData); 15 | }, 16 | deleteLoginPhotoFile() { 17 | return fetchDeleteRequest('server_settings/upload/login'); 18 | } 19 | }; -------------------------------------------------------------------------------- /frontend/app/src/services/sessionService.js: -------------------------------------------------------------------------------- 1 | import { fetchGetRequest, fetchPostRequest, fetchPostFormUrlEncoded, fetchDeleteRequest } from '@/utils/serviceUtils'; 2 | 3 | export const session = { 4 | getUserSessions(userId) { 5 | return fetchGetRequest(`sessions/user/${userId}`); 6 | }, 7 | deleteSession(sessionId, userId) { 8 | return fetchDeleteRequest(`sessions/${sessionId}/user/${userId}`); 9 | }, 10 | authenticateUser(formData) { 11 | return fetchPostFormUrlEncoded('token', formData); 12 | }, 13 | logoutUser() { 14 | return fetchPostRequest('logout', null); 15 | }, 16 | }; -------------------------------------------------------------------------------- /frontend/app/src/services/userDefaultGear.js: -------------------------------------------------------------------------------- 1 | import { fetchGetRequest, fetchPostRequest, fetchPutRequest, fetchDeleteRequest, fetchPostFileRequest } from '@/utils/serviceUtils'; 2 | 3 | export const userDefaultGear = { 4 | getUserDefaultGear() { 5 | return fetchGetRequest('profile/default_gear'); 6 | }, 7 | editUserDefaultGear(data) { 8 | return fetchPutRequest('profile/default_gear', data) 9 | }, 10 | }; -------------------------------------------------------------------------------- /frontend/app/src/stores/themeStore.js: -------------------------------------------------------------------------------- 1 | import { defineStore } from 'pinia'; 2 | 3 | export const useThemeStore = defineStore('theme', { 4 | state: () => ({ 5 | theme: 'auto', 6 | }), 7 | actions: { 8 | setTheme(theme) { 9 | this.theme = theme; 10 | localStorage.setItem('theme', theme); 11 | }, 12 | loadThemeFromStorage() { 13 | const storedTheme = localStorage.getItem('theme'); 14 | if (storedTheme) { 15 | this.theme = storedTheme; 16 | }else{ 17 | this.setTheme('auto'); 18 | } 19 | }, 20 | }, 21 | }); -------------------------------------------------------------------------------- /frontend/app/src/utils/servicePublicUtils.js: -------------------------------------------------------------------------------- 1 | import { attemptFetch } from './serviceUtils'; 2 | 3 | export async function fetchPublicGetRequest(url) { 4 | const options = { 5 | method: 'GET', 6 | headers: { 7 | 'Content-Type': 'application/json', 8 | 'X-Client-Type': 'web', 9 | }, 10 | }; 11 | return attemptFetch(url, options); 12 | } -------------------------------------------------------------------------------- /frontend/app/src/views/NotFoundView.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/app/vitest.config.js: -------------------------------------------------------------------------------- 1 | import { fileURLToPath } from 'node:url' 2 | import { mergeConfig, defineConfig, configDefaults } from 'vitest/config' 3 | import viteConfig from './vite.config' 4 | 5 | export default mergeConfig( 6 | viteConfig, 7 | defineConfig({ 8 | test: { 9 | environment: 'jsdom', 10 | exclude: [...configDefaults.exclude, 'e2e/*'], 11 | root: fileURLToPath(new URL('./', import.meta.url)) 12 | } 13 | }) 14 | ) -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: Endurain documentation 2 | repo_url: https://github.com/joaovitoriasilva/endurain 3 | theme: 4 | name: mkdocs 5 | color_mode: auto 6 | user_color_mode_toggle: true 7 | nav: 8 | - Home: index.md 9 | - Getting started: getting-started.md 10 | - Integrations: 11 | - 3rd party apps: integrations/3rd-party-apps.md 12 | - 3rd party services: integrations/3rd-party-services.md 13 | - Developer guide: developer-guide.md 14 | - Gallery: gallery.md -------------------------------------------------------------------------------- /screenshot_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaovitoriasilva/endurain/1938a943d915397a458a08a1d8f07bead8d3894c/screenshot_01.png --------------------------------------------------------------------------------