chore(profile): added i18n translation bindings & pl locale keys

This commit is contained in:
2026-02-14 02:27:03 +01:00
parent 72b3aef045
commit 84ecd3c175
5 changed files with 86 additions and 35 deletions
@@ -59,7 +59,7 @@
{{ entry.value.trainCategoryCode }} {{ entry.value.trainNo }}
</b>
<b class="text--grayed" v-if="entry.type == 'IssuedTimetable'">
dla: {{ entry.value.driverName }}
{{ ' ' }} {{ t('profile.list.for') }}: {{ entry.value.driverName }}
</b>
{{ ' ' }}
<b>{{ entry.value.route.replace('|', ' > ') }}</b>
@@ -72,7 +72,7 @@
<b class="text--primary">{{ entry.value.stationName }}</b>
{{ ' - ' }}
<b>
<span v-if="entry.value.isOnline">od </span>
<span v-if="entry.value.isOnline">{{ t('profile.list.since') }}: </span>
<span>{{
humanizeDuration(
(entry.value.timestampTo || Date.now()) - entry.value.timestampFrom
@@ -1,6 +1,6 @@
<template>
<section class="profile-recent-stats">
<h3 class="stats-header">STATYSTYKI AKTYWNOŚCI (30 OSTATNICH DNI)</h3>
<h3 class="stats-header">{{ t('profile.recent-stats.header') }}</h3>
<div class="month-stats-box">
<div class="month-stat">
@@ -8,7 +8,7 @@
<div>
<h3 class="text--primary">{{ playerInfo.driverStatsLastMonth.countAll }}</h3>
</div>
<div>ROZKŁADÓW JAZDY</div>
<div>{{ t('profile.recent-stats.timetables') }}</div>
</div>
<div class="month-stat">
@@ -18,7 +18,7 @@
{{ playerInfo.driverStatsLastMonth.currentDistanceTotal?.toFixed(2) || 0 }}
</h3>
</div>
<div>POKONANYCH KILOMETRÓW</div>
<div>{{ t('profile.recent-stats.distance') }}</div>
</div>
<div class="month-stat">
@@ -28,7 +28,7 @@
{{ playerInfo.dispatcherStatsLastMonth.services?.count || 0 }}
</h3>
</div>
<div>SŁUŻB DYŻURNEGO</div>
<div>{{ t('profile.recent-stats.duties') }}</div>
</div>
<div class="month-stat">
@@ -38,7 +38,7 @@
{{ playerInfo.dispatcherStatsLastMonth.issuedTimetables?.count || 0 }}
</h3>
</div>
<div>WYSTAWIONYCH ROZKŁADÓW</div>
<div>{{ t('profile.recent-stats.created-timetables') }}</div>
</div>
</div>
</section>
@@ -47,8 +47,11 @@
<script lang="ts" setup>
import { PropType } from 'vue';
import { API } from '../../typings/api';
import { useI18n } from 'vue-i18n';
const props = defineProps({
const { t } = useI18n();
defineProps({
playerInfo: {
type: Object as PropType<API.PlayerInfo.Data>,
required: true
@@ -29,7 +29,7 @@
playerInfo.driverStats.driverLevel > 1 ? playerInfo.driverStats.driverLevel : 'L'
}}
</span>
MASZYNISTA
{{ t('profile.stats.driver') }}
</div>
<div class="badge-container" v-if="playerInfo.dispatcherStats.dispatcherLevel != null">
@@ -43,14 +43,14 @@
: 'L'
}}
</span>
DYŻURNY RUCHU
{{ t('profile.stats.dispatcher') }}
</div>
</div>
</div>
</div>
<div class="info-activity" v-if="playerInfo.currentActivity.dispatcher.length > 0">
<b class="text--primary">ONLINE JAKO DR:</b>
<b class="text--primary">{{ t('profile.online-as-dispatcher') }}</b>
{{
playerInfo.currentActivity.dispatcher
.map((d) => `${d.stationName} (${d.stationHash})`)
@@ -62,8 +62,8 @@
class="info-activity"
v-if="playerInfo.currentActivity.driver && playerInfo.currentActivity.driver.length > 0"
>
<b>ONLINE JAKO MASZYNISTA:</b>
{{ playerInfo.currentActivity.driver.trainNo }} na scenerii
<b>{{ t('profile.online-as-driver') }}</b>
{{ playerInfo.currentActivity.driver.trainNo }} {{ t('profile.on-scenery') }}
{{ playerInfo.currentActivity.driver.currentStationName }}
</div>
@@ -74,7 +74,7 @@
<div class="player-stats">
<div class="stats-driver">
<img src="/images/icon-train.svg" width="35" alt="train icon" />
<h3>STATYSTYKI MASZYNISTY</h3>
<h3>{{ t('profile.stats.header-driver') }}</h3>
<hr />
<div v-if="playerInfo.driverStats.countAll > 0">
@@ -89,7 +89,7 @@
)
}}%)
</b>
- wypełnione rozkłady jazdy
- {{ t('profile.stats.fulfilled-timetables') }}
</div>
<div>
<b class="text--primary">
@@ -102,7 +102,7 @@
)
}}%)
</b>
- zatwierdzony kilometraż w RJ
- {{ t('profile.stats.route-distance') }}
</div>
<div>
<b class="text--primary">
@@ -115,22 +115,22 @@
)
}}%)
</b>
- potwierdzonych stacji w RJ
- {{ t('profile.stats.confirmed-stops') }}
</div>
<div>
<b class="text--primary">{{ playerInfo.driverStats.routeDistanceMax || 0 }}km</b> -
najdłuższy rozkład jazdy
{{ t('profile.stats.longest-timetable') }}
</div>
<div>
<b class="text--primary">
{{ playerInfo.driverStats.routeDistanceAvg?.toFixed(2) || 0 }}km
</b>
- średnia długość wszystkich rozkładów
- {{ t('profile.stats.avg-timetable-length') }}
</div>
</div>
<div class="text--grayed" v-else>
Ten użytkownik nie posiada statystyk maszynisty zarejestrowanych przez Stacjownik!
{{ t('profile.stats.no-timetable-stats') }}
</div>
</div>
@@ -139,41 +139,41 @@
v-if="playerInfo.dispatcherStats && playerInfo.dispatcherStats.services?.count"
>
<img src="/images/icon-user.svg" width="35" alt="user icon" />
<h3>STATYSTYKI DYŻURNEGO RUCHU</h3>
<h3>{{ t('profile.stats.header-dispatcher') }}</h3>
<hr />
<div>
<b class="text--primary">{{ playerInfo.dispatcherStats.services.count }}</b> - służby jako
dyżurny ruchu
<b class="text--primary">{{ playerInfo.dispatcherStats.services.count }}</b> -
{{ t('profile.stats.duties-count') }}
</div>
<div>
<b class="text--primary">{{
humanizeDuration(playerInfo.dispatcherStats.services.durationMax)
}}</b>
- najdłuższa służba
- {{ t('profile.stats.longest-duty') }}
</div>
<div v-if="playerInfo.dispatcherStats.issuedTimetables">
<div>
<b class="text--primary">{{ playerInfo.dispatcherStats.issuedTimetables.count }}</b>
- wystawione RJ jako dyżurny ruchu
- {{ t('profile.stats.created-timetables-count') }}
</div>
<div>
<b class="text--primary">
{{ playerInfo.dispatcherStats.issuedTimetables.distanceMax }}km
</b>
- najdłuższy wystawiony RJ
- {{ t('profile.stats.longest-created-timetable') }}
</div>
<div>
<b class="text--primary">
{{ playerInfo.dispatcherStats.issuedTimetables.distanceSum.toFixed(2) }}km
</b>
- suma długości wystawionych RJ
- {{ t('profile.stats.created-timetables-length-sum') }}
</div>
</div>
<div class="text--grayed" v-else>
Ten dyżurny nie wystawił jeszcze żadnego rozkładu jazdy
{{ t('profile.stats.no-dispatcher-stats') }}
</div>
</div>
</div>
@@ -187,10 +187,13 @@ import { calculateExpStyles } from '../../composables/badge';
import { getCountPercentage } from '../../utils/calcUtils';
import { humanizeDuration } from '../../composables/time';
import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
const route = useRoute();
const props = defineProps({
defineProps({
playerInfo: {
type: Object as PropType<API.PlayerInfo.Data>,
required: true
@@ -248,9 +251,10 @@ const props = defineProps({
display: flex;
justify-content: center;
align-items: center;
gap: 0.25em;
font-weight: bold;
& > .level-badge {
font-size: 1.15em;
}
+40
View File
@@ -606,10 +606,50 @@
},
"profile": {
"journal-button": "PROFIL GRACZA",
"no-player-found": "Nie znaleziono gracza! :/",
"return-to-main": "Powrót do strony głównej",
"filters": {
"Timetable": "ROZKŁADY JAZDY",
"Dispatcher": "SŁUŻBY DYŻURNEGO",
"IssuedTimetable": "WYSTAWIONE RJ"
},
"stats": {
"driver": "MASZYNISTA",
"dispatcher": "DYŻURNY RUCHU",
"online-as-driver": "ONLINE JAKO MASZYNISTA",
"online-as-dispatcher": "ONLINE JAKO DR",
"on-scenery": "na scenerii",
"header-driver": "STATYSTYKI MASZYNISTY",
"fulfilled-timetables": "wypełnione rozkłady jazdy",
"route-distance": "zatwierdzony kilometraż w RJ",
"confirmed-stops": "potwierdzonych stacji w RJ",
"longest-timetable": "najdłuższy rozkład jazdy",
"avg-timetable-length": "średnia długość wszystkich rozkładów",
"no-timetable-stats": "Ten użytkownik nie posiada statystyk maszynisty zarejestrowanych przez Stacjownik!",
"header-dispatcher": "STATYSTYKI DYŻURNEGO RUCHU",
"duties-count": "służby jako dyżurny ruchu",
"longest-duty": "najdłuższa służba",
"created-timetables-count": "wystawione RJ jako dyżurny ruchu",
"longest-created-timetable": "najdłuższy wystawiony RJ",
"created-timetables-length-sum": "suma długości wystawionych RJ",
"no-dispatcher-stats": "Ten dyżurny nie wystawił jeszcze żadnego rozkładu jazdy"
},
"recent-stats": {
"header": "STATYSTYKI AKTYWNOŚCI (30 DNI)",
"timetables": "ROZKŁADÓW JAZDY",
"distance": "POKONANYCH KILOMETRÓW",
"duties": "SŁUŻB DYŻURNEGO",
"created-timetables": "WYSTAWIONYCH ROZKŁADÓW"
},
"list": {
"for": "dla",
"since": "od"
}
}
}
+9 -5
View File
@@ -1,7 +1,7 @@
<template>
<div class="profile-view">
<div class="profile-wrapper" v-if="playerInfo && playerDataStatus == Status.Data.Loaded">
<ProfileSumary
<ProfileSummary
:playerInfo="playerInfo"
:playerTD2Info="playerTD2Info"
:playerName="playerName"
@@ -19,26 +19,30 @@
<div class="no-data-found" v-else>
<div>
<h3>Nie znaleziono gracza! :/</h3>
<router-link to="/" class="btn btn--text">Powrót do strony głównej</router-link>
<h3>{{ t('profile.no-player-found') }}</h3>
<router-link to="/" class="btn btn--text"> {{ t('profile.return-to-main') }}</router-link>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import axios from 'axios';
import { computed, onMounted, ref, watch } from 'vue';
import { useRoute } from 'vue-router';
import { useApiStore } from '../store/apiStore';
import { API, Td2API } from '../typings/api';
import axios from 'axios';
import { useI18n } from 'vue-i18n';
import { Status } from '../typings/common';
import Loading from '../components/Global/Loading.vue';
import ProfileSumary from '../components/PlayerProfileView/ProfileSumary.vue';
import ProfileSummary from '../components/PlayerProfileView/ProfileSummary.vue';
import ProfileRecentStats from '../components/PlayerProfileView/ProfileRecentStats.vue';
import ProfileHistoryList from '../components/PlayerProfileView/ProfileHistoryList.vue';
const { t } = useI18n();
const apiStore = useApiStore();
const route = useRoute();