/* * Copyright (C) 2025 Aleksander WilczyƄski (aleks@alekswilc.dev) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * See LICENSE for more. */ import { useState } from "react"; import { TProfileData, TProfilePlayer } from "../../../types/profile.ts"; import { useTranslation } from "react-i18next"; import { formatTime } from "../../../util/time.ts"; import { useAuth } from "../../../hooks/useAuth.tsx"; import { ConfirmModal } from "../../mini/modal/ConfirmModal.tsx"; import { post } from "../../../util/fetcher.ts"; import { toast } from "react-toastify"; import dayjs from "dayjs"; import { UserIcons } from "../../mini/icons/UserIcons.tsx"; import { StationStat } from '../../mini/profile/StationStat.tsx'; import { chunk } from '../../../util/chunk.ts'; import { Paginator } from '../../mini/util/Paginator.tsx'; import { TrainStat } from '../../mini/profile/TrainStat.tsx'; import { TImagesData } from '../../../types/images.ts'; const sortTrainsByList: Record = { [0]: 'time', [1]: 'score', [2]: 'distance', } export const ProfileCard = ({ data, images }: { data: TProfileData, images: TImagesData }) => { const [sortTrainsBy, setSortTrainsBy] = useState(0); const [sortTrainsBy2, setSortTrainsBy2] = useState(2); const [sortStationsBy, setSortStationsBy] = useState(0); const [hideLeaderboardStatsModal, setHideLeaderboardStatsModal] = useState(false); const [hideProfileModal, setHideProfileModal] = useState(false); const { isAdmin, token } = useAuth(); // #region ADMIN const adminToggleHideLeaderboardPlayerProfile = () => { post(`/admin/profile/${data.player.id}/${data.player.flags.includes("leaderboard_hidden") ? "showLeaderboard" : "hideLeaderboard"}`, {}, { "X-Auth-Token": token }) .then((response) => { if (response.code === 200) { toast.success(t("admin.hideLeaderboard.alert")); } }); }; const adminHidePlayerProfile = () => { post(`/admin/profile/${data.player.id}/hide`, {}, { "X-Auth-Token": token }) .then((response) => { if (response.code === 200) { toast.success(t("admin.hide.alert")); } }); }; const adminForceUpdate = () => { post(`/admin/profile/${data.player.id}/forceUpdate`, {}, { "X-Auth-Token": token }) .then((response) => { if (response.code === 200) { toast.success(t("admin.update.alert")); } }); }; // #endregion const sortStations = (a: keyof TProfilePlayer['dispatcherStats'], b: keyof TProfilePlayer['dispatcherStats']) => { if (sortStationsBy) { const _a = a; a = b; b = _a; } return data.player.dispatcherStats[b].time - data.player.dispatcherStats[a].time } const sortTrains = (a: keyof TProfilePlayer['trainStats'], b: keyof TProfilePlayer['trainStats']) => { if (sortTrainsBy2) { const _a = a; a = b; b = _a; } return data.player.trainStats[b][(sortTrainsByList[sortTrainsBy] ?? 'distance') as 'distance'] - data.player.trainStats[a][(sortTrainsByList[sortTrainsBy] ?? 'distance') as 'distance']; } const dispatcherStats = [...chunk(Object.keys(data.player.dispatcherStats), 8)]; const [dispatcherPage, setDispatcherPage] = useState(1); const trainStats = [...chunk(Object.keys(data.player.trainStats), 8)]; const [trainPage, setTrainPage] = useState(1); const { t } = useTranslation(); return <>
profile {data.active && }

{data.player.username}

{Math.floor(data.player.trainDistance / 1000)}km {t("profile.stats.distance")}
{formatTime(data.player.dispatcherTime)} {t("profile.stats.time")}
{data.active && data.active.type === "train" &&

{t("profile.active.train", { train: `${data.active.trainName} - ${data.active.trainNumber}`, server: data.active.server.toUpperCase() })}

} {data.active && data.active.type === "station" &&

{t("profile.active.station", { station: `${data.active.stationName} - ${data.active.stationShort}`, server: data.active.server.toUpperCase() })}

}

{t("profile.stations.header")}

{dispatcherStats[dispatcherPage - 1].sort(sortStations).map(stationName => { const station = data.player.dispatcherStats[stationName]; return })}
{/*
{t("profile.stations.station")}
{t("profile.stations.time")}
{Object.keys(data.player.dispatcherStats).sort((a, b) => data.player.dispatcherStats[b].time - data.player.dispatcherStats[a].time).map(stationName => { const station = data.player.dispatcherStats[stationName]; return

{stationName}

{formatTime(station.time)}

; })}
*/} {isAdmin && <>

{t("admin.header")}

{data.player.flags.includes("leaderboard_hidden") ? : }
}

{t("profile.info", { date: dayjs(data.player.createdAt).format("DD/MM/YYYY") })}

; };