mirror of
https://github.com/Spythere/stacjownik.git
synced 2026-05-03 05:18:11 +00:00
chore(profile): organized fetching data; added link to profile in scenery view
This commit is contained in:
@@ -8,10 +8,7 @@
|
||||
{{ onlineScenery.dispatcherExp > 1 ? onlineScenery.dispatcherExp : 'L' }}
|
||||
</span>
|
||||
|
||||
<router-link
|
||||
class="dispatcher-name"
|
||||
:to="`/journal/dispatchers?search-dispatcher=${onlineScenery.dispatcherName}`"
|
||||
>
|
||||
<router-link class="dispatcher-name" :to="`/profile?playerId=${onlineScenery.dispatcherId}`">
|
||||
<span
|
||||
class="text--donator"
|
||||
v-if="apiStore.donatorsData.includes(onlineScenery.dispatcherName)"
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
|
||||
--clr-donator: #f7a4ff;
|
||||
|
||||
--clr-success: springgreen;
|
||||
|
||||
--no-scroll-padding: 17px;
|
||||
--max-container-width: 1700px;
|
||||
|
||||
|
||||
@@ -118,6 +118,9 @@ export namespace API {
|
||||
|
||||
export namespace PlayerInfo {
|
||||
export interface Data {
|
||||
playerName: string | null;
|
||||
playerId: number | null;
|
||||
|
||||
currentActivity: PlayerActivity.Data;
|
||||
dispatcherStats: 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 interface Payload {
|
||||
activeSceneries: API.ActiveSceneries.Response;
|
||||
|
||||
@@ -1,19 +1,25 @@
|
||||
<template>
|
||||
<div class="profile-view">
|
||||
<div class="view-container">
|
||||
<div class="view-container" v-if="playerInfo">
|
||||
<div class="profile-sidebar">
|
||||
<div class="player-summary">
|
||||
<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"
|
||||
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 dyżurnego</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 class="player-stats">
|
||||
@@ -159,12 +165,13 @@
|
||||
</template>
|
||||
|
||||
<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 { useApiStore } from '../store/apiStore';
|
||||
import { API } from '../typings/api';
|
||||
import { API, Td2API } from '../typings/api';
|
||||
import { humanizeDuration } from '../composables/time';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import axios from 'axios';
|
||||
|
||||
type JournalEntryType = 'Timetable' | 'Dispatcher' | 'IssuedTimetable';
|
||||
|
||||
@@ -178,10 +185,9 @@ const { t } = useI18n();
|
||||
const apiStore = useApiStore();
|
||||
const route = useRoute();
|
||||
|
||||
const playerId = ref(-1);
|
||||
const playerName = ref('');
|
||||
const playerInfo = ref<API.PlayerInfo.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>>({
|
||||
Timetable: true,
|
||||
@@ -189,16 +195,19 @@ const activeFilterTypes = reactive<Record<JournalEntryType, boolean>>({
|
||||
IssuedTimetable: true
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
playerId.value = Number(route.query.playerId) || -1;
|
||||
playerName.value = route.query.playerName?.toString() || '';
|
||||
watch(
|
||||
computed(() => route.query.playerId),
|
||||
(v) => {
|
||||
fetchAllData();
|
||||
}
|
||||
);
|
||||
|
||||
fetchPlayerInfoData();
|
||||
fetchPlayerJournal();
|
||||
onMounted(() => {
|
||||
fetchAllData();
|
||||
});
|
||||
|
||||
const combinedJournal = computed<JournalEntry[]>(() => {
|
||||
if (!playerJournal.value) return [];
|
||||
if (!playerJournal.value || !playerInfo.value) return [];
|
||||
|
||||
const list = [
|
||||
...playerJournal.value.timetables,
|
||||
@@ -208,7 +217,7 @@ const combinedJournal = computed<JournalEntry[]>(() => {
|
||||
.reduce<JournalEntry[]>((acc, v) => {
|
||||
// Timetable or dispatcher type
|
||||
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['IssuedTimetable']) return acc;
|
||||
@@ -237,41 +246,83 @@ const combinedJournal = computed<JournalEntry[]>(() => {
|
||||
return list;
|
||||
});
|
||||
|
||||
async function fetchPlayerInfoData() {
|
||||
if (!apiStore.client || !playerId.value) return;
|
||||
async function fetchAllData() {
|
||||
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 {
|
||||
const response = await apiStore.client.get<API.PlayerInfo.Data>('api/getPlayerInfo', {
|
||||
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) {
|
||||
console.error(error);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
async function fetchPlayerJournal() {
|
||||
if (!apiStore.client || !playerId.value) return;
|
||||
async function fetchPlayerJournal(playerId: string) {
|
||||
if (!apiStore.client || !playerId) return null;
|
||||
|
||||
try {
|
||||
const response = await apiStore.client.get<API.PlayerJournal.Data>('api/getPlayerJournal', {
|
||||
params: {
|
||||
playerId: playerId.value,
|
||||
playerId: playerId,
|
||||
countLimit: 15
|
||||
}
|
||||
});
|
||||
|
||||
playerJournal.value = response.data;
|
||||
playerName.value =
|
||||
response.data.timetables.at(0)?.driverName ||
|
||||
response.data.duties.at(0)?.dispatcherName ||
|
||||
'';
|
||||
return response.data;
|
||||
} catch (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) {
|
||||
@@ -387,7 +438,7 @@ $tileColor: #181818;
|
||||
}
|
||||
|
||||
&[data-active='true'] {
|
||||
color: var(--clr-primary);
|
||||
color: var(--clr-success);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user