import React, { useMemo, useState } from "react"; import { Button, Checkbox, Divider, Select, Space, Table } from "antd"; import type { ColumnsType } from "antd/es/table"; import { PageHeader, PageLayout, useColumnSearch, useTableQueryState, useUsers } from "@clusterio/web_ui"; import { PlayerStatistics, userStatistics } from "../../messages.js"; import { usePlayerStatistics } from ".."; import { formatValue, statistics } from "../statistics"; const strcmp = new Intl.Collator(undefined, { numeric: true, sensitivity: "base" }).compare; const storageKey = "exp_player_statistics.columns"; const defaultColumns = [ "Playtime", "AfkTime", "MapsPlayed", "JoinCount", "ChatMessages", "RocketsLaunched", "ResearchCompleted", "MachinesBuilt", "Kills", "Deaths", ]; function loadColumns() { try { const stored = JSON.parse(localStorage.getItem(storageKey) ?? "null"); if (Array.isArray(stored)) { return stored.filter(name => statistics.some(([statistic]) => statistic === name)); } } catch { /* fall back to the defaults */ } return defaultColumns; } export default function StatisticsPage() { const [players, synced] = usePlayerStatistics(); const [users] = useUsers(); const [columns, setColumnsState] = useState(loadColumns); const tableState = useTableQueryState({ namespace: "statistics", defaultSortKey: "Playtime", defaultSortOrder: "descend", pagination: { defaultPageSize: 50 }, }); const playerSearch = useColumnSearch(tableState, "player", player => player.id, "Search players"); function setColumns(names: string[]) { // Keep the display order whatever order they were picked in const ordered = statistics.map(([name]) => name).filter(name => names.includes(name)); setColumnsState(ordered); localStorage.setItem(storageKey, JSON.stringify(ordered)); } const rows = useMemo(() => [...players.values()].map(player => new PlayerStatistics( player.id, { ...player.stats, ...userStatistics(users.get(player.id.toLowerCase()), player.stats) }, player.updatedAtMs, )), [players, users]); const tableColumns: ColumnsType = [ { title: "Player", key: "player", fixed: "left", render: (_, player) => player.id, sorter: (a, b) => strcmp(a.id, b.id), sortOrder: tableState.sortOrder("player"), filteredValue: tableState.filteredValue("player"), ...playerSearch, }, ...statistics.filter(([name]) => columns.includes(name)).map( ([name, title]): ColumnsType[number] => ({ title, key: name, align: "right", render: (_, player) => formatValue(name, player.stats[name] ?? 0), sorter: (a, b) => (a.stats[name] ?? 0) - (b.stats[name] ?? 0), sortDirections: ["descend", "ascend"], sortOrder: tableState.sortOrder(name), }) ), ]; const columnSelect =