mirror of
https://github.com/Spythere/stacjownik.git
synced 2026-05-02 21:08:12 +00:00
chore(profile): organized fetching data; added link to profile in scenery view
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 2.4 KiB |
@@ -8,10 +8,7 @@
|
|||||||
{{ onlineScenery.dispatcherExp > 1 ? onlineScenery.dispatcherExp : 'L' }}
|
{{ onlineScenery.dispatcherExp > 1 ? onlineScenery.dispatcherExp : 'L' }}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<router-link
|
<router-link class="dispatcher-name" :to="`/profile?playerId=${onlineScenery.dispatcherId}`">
|
||||||
class="dispatcher-name"
|
|
||||||
:to="`/journal/dispatchers?search-dispatcher=${onlineScenery.dispatcherName}`"
|
|
||||||
>
|
|
||||||
<span
|
<span
|
||||||
class="text--donator"
|
class="text--donator"
|
||||||
v-if="apiStore.donatorsData.includes(onlineScenery.dispatcherName)"
|
v-if="apiStore.donatorsData.includes(onlineScenery.dispatcherName)"
|
||||||
|
|||||||
@@ -23,6 +23,8 @@
|
|||||||
|
|
||||||
--clr-donator: #f7a4ff;
|
--clr-donator: #f7a4ff;
|
||||||
|
|
||||||
|
--clr-success: springgreen;
|
||||||
|
|
||||||
--no-scroll-padding: 17px;
|
--no-scroll-padding: 17px;
|
||||||
--max-container-width: 1700px;
|
--max-container-width: 1700px;
|
||||||
|
|
||||||
|
|||||||
@@ -118,6 +118,9 @@ export namespace API {
|
|||||||
|
|
||||||
export namespace PlayerInfo {
|
export namespace PlayerInfo {
|
||||||
export interface Data {
|
export interface Data {
|
||||||
|
playerName: string | null;
|
||||||
|
playerId: number | null;
|
||||||
|
|
||||||
currentActivity: PlayerActivity.Data;
|
currentActivity: PlayerActivity.Data;
|
||||||
dispatcherStats: DispatcherStats.Data;
|
dispatcherStats: DispatcherStats.Data;
|
||||||
dispatcherStatsLastMonth: DispatcherStats.Data;
|
dispatcherStatsLastMonth: DispatcherStats.Data;
|
||||||
@@ -456,6 +459,62 @@ export namespace GithubAPI {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export namespace Td2API {
|
||||||
|
export namespace UsersInfoByName {
|
||||||
|
export interface UserStat {
|
||||||
|
variable: string;
|
||||||
|
value: number;
|
||||||
|
position: number;
|
||||||
|
server_total: number;
|
||||||
|
server_max: number;
|
||||||
|
server_min: number;
|
||||||
|
server_avg: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Levels {
|
||||||
|
driver: number;
|
||||||
|
dispatcher: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UserGroup {
|
||||||
|
id_group: number;
|
||||||
|
group_name: string;
|
||||||
|
description: string;
|
||||||
|
online_color: string;
|
||||||
|
min_posts: number;
|
||||||
|
max_messages: number;
|
||||||
|
stars: string;
|
||||||
|
group_type: number;
|
||||||
|
hidden: number;
|
||||||
|
id_parent: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UserInfo {
|
||||||
|
id_member: number;
|
||||||
|
id_group: number;
|
||||||
|
additional_groups: string;
|
||||||
|
member_name: string;
|
||||||
|
karma_bad: number;
|
||||||
|
karma_good: number;
|
||||||
|
date_registered: number;
|
||||||
|
last_login: number;
|
||||||
|
avatar: number;
|
||||||
|
lngfile: string;
|
||||||
|
user_stats: UserStat[];
|
||||||
|
levels: Levels;
|
||||||
|
user_groups: UserGroup[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Message = UserInfo[];
|
||||||
|
|
||||||
|
export interface Response {
|
||||||
|
success: boolean;
|
||||||
|
respCode: number;
|
||||||
|
message: Message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export namespace Websocket {
|
export namespace Websocket {
|
||||||
export interface Payload {
|
export interface Payload {
|
||||||
activeSceneries: API.ActiveSceneries.Response;
|
activeSceneries: API.ActiveSceneries.Response;
|
||||||
|
|||||||
@@ -1,19 +1,25 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="profile-view">
|
<div class="profile-view">
|
||||||
<div class="view-container">
|
<div class="view-container" v-if="playerInfo">
|
||||||
<div class="profile-sidebar">
|
<div class="profile-sidebar">
|
||||||
<div class="player-summary">
|
<div class="player-summary">
|
||||||
<img
|
<img
|
||||||
src="https://td2.info.pl/index.php?action=dlattach;attach=83477;type=avatar"
|
v-if="playerTD2Info"
|
||||||
|
:src="`https://td2.info.pl/index.php?action=dlattach;attach=${playerTD2Info.avatar};type=avatar`"
|
||||||
alt="player image"
|
alt="player image"
|
||||||
width="110"
|
width="100"
|
||||||
|
height="100"
|
||||||
|
@error="(e) => ((e.target as any).src = '/images/default-avatar.jpg')"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<h3>Spythere</h3>
|
<h3>{{ playerInfo.playerName }}</h3>
|
||||||
|
|
||||||
<p>12 poziom maszynisty</p>
|
<p>12 poziom maszynisty</p>
|
||||||
<p>12 poziom dyżurnego</p>
|
<p>12 poziom dyżurnego</p>
|
||||||
|
|
||||||
<p>Ostatnia aktywność: 02.02.2026 (DR)</p>
|
<p>Ostatnia aktywność: 02.02.2026 (DR)</p>
|
||||||
<p>Stacjosponsor od 01.01.2024</p>
|
|
||||||
|
<!-- <p>Stacjosponsor od 01.01.2024</p> -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="player-stats">
|
<div class="player-stats">
|
||||||
@@ -159,12 +165,13 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, onMounted, reactive, ref } from 'vue';
|
import { computed, onActivated, onMounted, reactive, 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 } from '../typings/api';
|
import { API, Td2API } from '../typings/api';
|
||||||
import { humanizeDuration } from '../composables/time';
|
import { humanizeDuration } from '../composables/time';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
type JournalEntryType = 'Timetable' | 'Dispatcher' | 'IssuedTimetable';
|
type JournalEntryType = 'Timetable' | 'Dispatcher' | 'IssuedTimetable';
|
||||||
|
|
||||||
@@ -178,10 +185,9 @@ const { t } = useI18n();
|
|||||||
const apiStore = useApiStore();
|
const apiStore = useApiStore();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
|
||||||
const playerId = ref(-1);
|
|
||||||
const playerName = ref('');
|
|
||||||
const playerInfo = ref<API.PlayerInfo.Data | null>(null);
|
const playerInfo = ref<API.PlayerInfo.Data | null>(null);
|
||||||
const playerJournal = ref<API.PlayerJournal.Data | null>(null);
|
const playerJournal = ref<API.PlayerJournal.Data | null>(null);
|
||||||
|
const playerTD2Info = ref<Td2API.UsersInfoByName.UserInfo | null>(null);
|
||||||
|
|
||||||
const activeFilterTypes = reactive<Record<JournalEntryType, boolean>>({
|
const activeFilterTypes = reactive<Record<JournalEntryType, boolean>>({
|
||||||
Timetable: true,
|
Timetable: true,
|
||||||
@@ -189,16 +195,19 @@ const activeFilterTypes = reactive<Record<JournalEntryType, boolean>>({
|
|||||||
IssuedTimetable: true
|
IssuedTimetable: true
|
||||||
});
|
});
|
||||||
|
|
||||||
onMounted(() => {
|
watch(
|
||||||
playerId.value = Number(route.query.playerId) || -1;
|
computed(() => route.query.playerId),
|
||||||
playerName.value = route.query.playerName?.toString() || '';
|
(v) => {
|
||||||
|
fetchAllData();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
fetchPlayerInfoData();
|
onMounted(() => {
|
||||||
fetchPlayerJournal();
|
fetchAllData();
|
||||||
});
|
});
|
||||||
|
|
||||||
const combinedJournal = computed<JournalEntry[]>(() => {
|
const combinedJournal = computed<JournalEntry[]>(() => {
|
||||||
if (!playerJournal.value) return [];
|
if (!playerJournal.value || !playerInfo.value) return [];
|
||||||
|
|
||||||
const list = [
|
const list = [
|
||||||
...playerJournal.value.timetables,
|
...playerJournal.value.timetables,
|
||||||
@@ -208,7 +217,7 @@ const combinedJournal = computed<JournalEntry[]>(() => {
|
|||||||
.reduce<JournalEntry[]>((acc, v) => {
|
.reduce<JournalEntry[]>((acc, v) => {
|
||||||
// Timetable or dispatcher type
|
// Timetable or dispatcher type
|
||||||
if ('trainNo' in v) {
|
if ('trainNo' in v) {
|
||||||
const isIssued = v.authorName == playerName.value;
|
const isIssued = v.authorName == playerInfo.value!.playerName;
|
||||||
|
|
||||||
if (!isIssued && !activeFilterTypes['Timetable']) return acc;
|
if (!isIssued && !activeFilterTypes['Timetable']) return acc;
|
||||||
if (isIssued && !activeFilterTypes['IssuedTimetable']) return acc;
|
if (isIssued && !activeFilterTypes['IssuedTimetable']) return acc;
|
||||||
@@ -237,41 +246,83 @@ const combinedJournal = computed<JournalEntry[]>(() => {
|
|||||||
return list;
|
return list;
|
||||||
});
|
});
|
||||||
|
|
||||||
async function fetchPlayerInfoData() {
|
async function fetchAllData() {
|
||||||
if (!apiStore.client || !playerId.value) return;
|
const playerId = route.query.playerId?.toString();
|
||||||
|
|
||||||
|
if (!playerId) return;
|
||||||
|
|
||||||
|
const playerInfoResponse = await fetchPlayerInfoData(playerId);
|
||||||
|
|
||||||
|
if (!playerInfoResponse || !playerInfoResponse.playerName) return;
|
||||||
|
|
||||||
|
const playerTd2InfoResponse = await fetchPlayerTD2Info(playerInfoResponse.playerName);
|
||||||
|
const playerJournalResponse = await fetchPlayerJournal(playerId);
|
||||||
|
|
||||||
|
playerInfo.value = playerInfoResponse;
|
||||||
|
playerTD2Info.value = playerTd2InfoResponse;
|
||||||
|
playerJournal.value = playerJournalResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fetchPlayerInfoData(playerId: string) {
|
||||||
|
if (!apiStore.client || !playerId) return null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await apiStore.client.get<API.PlayerInfo.Data>('api/getPlayerInfo', {
|
const response = await apiStore.client.get<API.PlayerInfo.Data>('api/getPlayerInfo', {
|
||||||
params: {
|
params: {
|
||||||
playerId: playerId.value
|
playerId: playerId
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
playerInfo.value = response.data;
|
if (response.data.playerName == null || response.data.playerId == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fetchPlayerJournal() {
|
async function fetchPlayerJournal(playerId: string) {
|
||||||
if (!apiStore.client || !playerId.value) return;
|
if (!apiStore.client || !playerId) return null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await apiStore.client.get<API.PlayerJournal.Data>('api/getPlayerJournal', {
|
const response = await apiStore.client.get<API.PlayerJournal.Data>('api/getPlayerJournal', {
|
||||||
params: {
|
params: {
|
||||||
playerId: playerId.value,
|
playerId: playerId,
|
||||||
countLimit: 15
|
countLimit: 15
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
playerJournal.value = response.data;
|
return response.data;
|
||||||
playerName.value =
|
|
||||||
response.data.timetables.at(0)?.driverName ||
|
|
||||||
response.data.duties.at(0)?.dispatcherName ||
|
|
||||||
'';
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fetchPlayerTD2Info(playerName: string) {
|
||||||
|
if (!apiStore.client || !playerName) return null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await axios.get<Td2API.UsersInfoByName.Response>('https://api.td2.info.pl', {
|
||||||
|
params: {
|
||||||
|
method: 'getUsersInfoByName',
|
||||||
|
name: playerName
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.data.success && response.data.message.length == 1) {
|
||||||
|
return response.data.message[0];
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleFilter(filterType: JournalEntryType) {
|
function toggleFilter(filterType: JournalEntryType) {
|
||||||
@@ -387,7 +438,7 @@ $tileColor: #181818;
|
|||||||
}
|
}
|
||||||
|
|
||||||
&[data-active='true'] {
|
&[data-active='true'] {
|
||||||
color: var(--clr-primary);
|
color: var(--clr-success);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user