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