From 565b0dfd8c4f3fcd3961f3206dd57eb929e07513 Mon Sep 17 00:00:00 2001 From: Spythere Date: Fri, 6 Feb 2026 03:20:25 +0100 Subject: [PATCH] chore(profile): journal history list design --- src/composables/time.ts | 31 ++++++++++++++ src/views/PlayerProfileView.vue | 75 ++++++++++++++++++++++++++++++--- 2 files changed, 100 insertions(+), 6 deletions(-) create mode 100644 src/composables/time.ts diff --git a/src/composables/time.ts b/src/composables/time.ts new file mode 100644 index 0000000..2f882b3 --- /dev/null +++ b/src/composables/time.ts @@ -0,0 +1,31 @@ +import { useI18n } from 'vue-i18n'; + +export function calculateDuration(timestampMs: number) { + const secondsTotal = Math.floor(timestampMs / 1000); + const minsTotal = Math.round(timestampMs / 60000); + const hoursTotal = Math.floor(minsTotal / 60); + const minsInHour = minsTotal % 60; + + return { + secondsTotal, + minsTotal, + hoursTotal, + minsInHour + }; +} + +export function humanizeDuration(timestampMs: number, showSeconds = false) { + const { t } = useI18n(); + + const duration = calculateDuration(timestampMs); + + return duration.minsTotal >= 60 + ? `${t('journal.hours', { value: duration.hoursTotal }, duration.hoursTotal)} ${t( + 'journal.minutes', + { value: duration.minsInHour }, + duration.minsInHour + )}` + : showSeconds && duration.secondsTotal <= 60 + ? t('journal.seconds', { value: duration.secondsTotal }, duration.secondsTotal) + : t('journal.minutes', { value: duration.minsTotal }, duration.minsTotal); +} diff --git a/src/views/PlayerProfileView.vue b/src/views/PlayerProfileView.vue index 96dcaec..06eecde 100644 --- a/src/views/PlayerProfileView.vue +++ b/src/views/PlayerProfileView.vue @@ -34,7 +34,7 @@
- clock icon + user icon

STATYSTYKI DYŻURNEGO RUCHU


@@ -62,7 +62,7 @@
-
train icon
+
spawn icon

5500

POKONANYCH
@@ -71,7 +71,7 @@
-
train icon
+
user icon

15

SŁUŻB
@@ -80,7 +80,7 @@
-
train icon
+
timetable icon

12

WYSTAWIONYCH
@@ -104,7 +104,54 @@
    -
  • {{ entry.type }} - {{ entry.date }}
  • +
  • + user icon + + train icon + + timetable icon + + + {{ + entry.date.toLocaleString('pl-PL', { dateStyle: 'long', timeStyle: 'short' }) + }} + + + + + + {{ entry.value.trainCategoryCode }} {{ entry.value.trainNo }} + + + dla: {{ entry.value.driverName }} + + {{ ' ' }} + {{ entry.value.route.replace('|', ' > ') }} + {{ ' ' }} + ({{ entry.value.currentDistance }} / {{ entry.value.routeDistance }}km) + + + + + {{ entry.value.stationName }} + {{ ' - ' }} + {{ + humanizeDuration( + (entry.value.timestampTo || Date.now()) - entry.value.timestampFrom + ) + }} + +
@@ -117,6 +164,8 @@ import { computed, onMounted, reactive, ref } from 'vue'; import { useRoute } from 'vue-router'; import { useApiStore } from '../store/apiStore'; import { API } from '../typings/api'; +import { useI18n } from 'vue-i18n'; +import { humanizeDuration } from '../composables/time'; type JournalEntryType = 'Timetable' | 'Dispatcher' | 'IssuedTimetable'; @@ -128,6 +177,7 @@ interface JournalEntry { const apiStore = useApiStore(); const route = useRoute(); +const { t } = useI18n(); const playerName = ref(''); const playerInfo = ref(null); @@ -210,7 +260,8 @@ async function fetchPlayerJournal() { try { const response = await apiStore.client.get('api/getPlayerJournal', { params: { - playerId: playerId + playerId: playerId, + countLimit: 15 } }); @@ -335,6 +386,18 @@ $tileColor: #181818; overflow: auto; height: 650px; margin-top: 1em; + + & > ul > li { + display: flex; + align-items: center; + gap: 0.25em; + + background-color: $tileColor; + padding: 0.5em; + + margin-bottom: 0.5em; + text-align: initial; + } } @include responsive.midScreen {