mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2024-09-29 06:57:40 +02:00
Playerbase overview page layout
- Moved some files
This commit is contained in:
parent
b942078485
commit
7e1bd7f4a6
@ -4,12 +4,12 @@ import './style/style.css';
|
|||||||
|
|
||||||
import {BrowserRouter, Navigate, Route, Routes} from "react-router-dom";
|
import {BrowserRouter, Navigate, Route, Routes} from "react-router-dom";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import PlayerPage from "./views/PlayerPage";
|
import PlayerPage from "./views/layout/PlayerPage";
|
||||||
import PlayerOverview from "./views/PlayerOverview";
|
import PlayerOverview from "./views/player/PlayerOverview";
|
||||||
import PlayerSessions from "./views/PlayerSessions";
|
import PlayerSessions from "./views/player/PlayerSessions";
|
||||||
import PlayerPvpPve from "./views/PlayerPvpPve";
|
import PlayerPvpPve from "./views/player/PlayerPvpPve";
|
||||||
import PlayerServers from "./views/PlayerServers";
|
import PlayerServers from "./views/player/PlayerServers";
|
||||||
import PlayerPluginData from "./views/PlayerPluginData";
|
import PlayerPluginData from "./views/player/PlayerPluginData";
|
||||||
import {ThemeContextProvider} from "./hooks/themeHook";
|
import {ThemeContextProvider} from "./hooks/themeHook";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import ErrorView from "./views/ErrorView";
|
import ErrorView from "./views/ErrorView";
|
||||||
@ -17,13 +17,13 @@ import {faMapSigns} from "@fortawesome/free-solid-svg-icons";
|
|||||||
import {MetadataContextProvider} from "./hooks/metadataHook";
|
import {MetadataContextProvider} from "./hooks/metadataHook";
|
||||||
import {AuthenticationContextProvider} from "./hooks/authenticationHook";
|
import {AuthenticationContextProvider} from "./hooks/authenticationHook";
|
||||||
import {NavigationContextProvider} from "./hooks/navigationHook";
|
import {NavigationContextProvider} from "./hooks/navigationHook";
|
||||||
import ServerPage from "./views/ServerPage";
|
import ServerPage from "./views/layout/ServerPage";
|
||||||
import ServerOverview from "./views/ServerOverview";
|
import ServerOverview from "./views/server/ServerOverview";
|
||||||
import MainPageRedirect from "./components/navigation/MainPageRedirect";
|
import MainPageRedirect from "./components/navigation/MainPageRedirect";
|
||||||
import ServerOnlineActivity from "./views/ServerOnlineActivity";
|
import OnlineActivity from "./views/server/OnlineActivity";
|
||||||
import ServerSessions from "./views/ServerSessions";
|
import ServerSessions from "./views/server/ServerSessions";
|
||||||
import ServerPvpPve from "./views/ServerPvpPve";
|
import ServerPvpPve from "./views/server/ServerPvpPve";
|
||||||
import ServerPlayerbaseOverview from "./views/ServerPlayerbaseOverview";
|
import PlayerbaseOverview from "./views/server/PlayerbaseOverview";
|
||||||
|
|
||||||
const OverviewRedirect = () => {
|
const OverviewRedirect = () => {
|
||||||
return (<Navigate to={"overview"} replace={true}/>)
|
return (<Navigate to={"overview"} replace={true}/>)
|
||||||
@ -67,10 +67,10 @@ function App() {
|
|||||||
<Route path="/server/:identifier" element={<ServerPage/>}>
|
<Route path="/server/:identifier" element={<ServerPage/>}>
|
||||||
<Route path="" element={<OverviewRedirect/>}/>
|
<Route path="" element={<OverviewRedirect/>}/>
|
||||||
<Route path="overview" element={<ServerOverview/>}/>
|
<Route path="overview" element={<ServerOverview/>}/>
|
||||||
<Route path="online-activity" element={<ServerOnlineActivity/>}/>
|
<Route path="online-activity" element={<OnlineActivity/>}/>
|
||||||
<Route path="sessions" element={<ServerSessions/>}/>
|
<Route path="sessions" element={<ServerSessions/>}/>
|
||||||
<Route path="pvppve" element={<ServerPvpPve/>}/>
|
<Route path="pvppve" element={<ServerPvpPve/>}/>
|
||||||
<Route path="playerbase" element={<ServerPlayerbaseOverview/>}/>
|
<Route path="playerbase" element={<PlayerbaseOverview/>}/>
|
||||||
<Route path="retention" element={<></>}/>
|
<Route path="retention" element={<></>}/>
|
||||||
<Route path="players" element={<></>}/>
|
<Route path="players" element={<></>}/>
|
||||||
<Route path="geolocations" element={<></>}/>
|
<Route path="geolocations" element={<></>}/>
|
||||||
|
@ -5,14 +5,14 @@ const End = ({children}) => (
|
|||||||
<span className="float-end">{children}</span>
|
<span className="float-end">{children}</span>
|
||||||
)
|
)
|
||||||
|
|
||||||
const Datapoint = ({icon, color, name, value, valueLabel, bold, boldTitle, title}) => {
|
const Datapoint = ({icon, color, name, value, valueLabel, bold, boldTitle, title, trend}) => {
|
||||||
const displayedValue = bold ? <b>{value}</b> : value;
|
const displayedValue = bold ? <b>{value}</b> : value;
|
||||||
const extraLabel = valueLabel ? ` (${valueLabel})` : '';
|
const extraLabel = valueLabel instanceof String ? ` (${valueLabel})` : '';
|
||||||
const colorClass = color && color.startsWith("col-") ? color : "col-" + color;
|
const colorClass = color && color.startsWith("col-") ? color : "col-" + color;
|
||||||
return (
|
return (
|
||||||
<p title={title ? title : name + " is " + value}>
|
<p title={title ? title : name + " is " + value}>
|
||||||
<Fa icon={icon} className={colorClass}/> {boldTitle ? <b>{name}</b> : name}
|
{icon && <Fa icon={icon} className={colorClass}/>} {boldTitle ? <b>{name}</b> : name}
|
||||||
{value !== undefined ? <End>{displayedValue} {extraLabel}</End> : ''}
|
{value !== undefined ? <End>{displayedValue} {extraLabel}{trend}</End> : ''}
|
||||||
</p>
|
</p>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import {useParams} from "react-router-dom";
|
import {useParams} from "react-router-dom";
|
||||||
import {useDataRequest} from "../../../hooks/dataFetchHook";
|
import {useDataRequest} from "../../../../hooks/dataFetchHook";
|
||||||
import {fetchPlayerbaseDevelopmentGraph} from "../../../service/serverService";
|
import {fetchPlayerbaseDevelopmentGraph} from "../../../../service/serverService";
|
||||||
import {ErrorViewBody} from "../../../views/ErrorView";
|
import {ErrorViewBody} from "../../../../views/ErrorView";
|
||||||
import {useTranslation} from "react-i18next";
|
import {useTranslation} from "react-i18next";
|
||||||
import {Card} from "react-bootstrap-v5";
|
import {Card} from "react-bootstrap-v5";
|
||||||
import {FontAwesomeIcon as Fa} from "@fortawesome/react-fontawesome";
|
import {FontAwesomeIcon as Fa} from "@fortawesome/react-fontawesome";
|
@ -1,12 +1,12 @@
|
|||||||
import {useTranslation} from "react-i18next";
|
import {useTranslation} from "react-i18next";
|
||||||
import {useParams} from "react-router-dom";
|
import {useParams} from "react-router-dom";
|
||||||
import {useDataRequest} from "../../../hooks/dataFetchHook";
|
import {useDataRequest} from "../../../../hooks/dataFetchHook";
|
||||||
import {fetchPlayersOnlineGraph} from "../../../service/serverService";
|
import {fetchPlayersOnlineGraph} from "../../../../service/serverService";
|
||||||
import {ErrorViewCard} from "../../../views/ErrorView";
|
import {ErrorViewCard} from "../../../../views/ErrorView";
|
||||||
import {Card} from "react-bootstrap-v5";
|
import {Card} from "react-bootstrap-v5";
|
||||||
import {FontAwesomeIcon as Fa} from "@fortawesome/react-fontawesome";
|
import {FontAwesomeIcon as Fa} from "@fortawesome/react-fontawesome";
|
||||||
import {faChartArea} from "@fortawesome/free-solid-svg-icons";
|
import {faChartArea} from "@fortawesome/free-solid-svg-icons";
|
||||||
import PlayersOnlineGraph from "../../graphs/PlayersOnlineGraph";
|
import PlayersOnlineGraph from "../../../graphs/PlayersOnlineGraph";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
const OnlineActivityCard = () => {
|
const OnlineActivityCard = () => {
|
@ -1,21 +1,21 @@
|
|||||||
import {useParams} from "react-router-dom";
|
import {useParams} from "react-router-dom";
|
||||||
import {useDataRequest} from "../../../hooks/dataFetchHook";
|
import {useDataRequest} from "../../../../hooks/dataFetchHook";
|
||||||
import {
|
import {
|
||||||
fetchDayByDayGraph,
|
fetchDayByDayGraph,
|
||||||
fetchHourByHourGraph,
|
fetchHourByHourGraph,
|
||||||
fetchPunchCardGraph,
|
fetchPunchCardGraph,
|
||||||
fetchServerCalendarGraph
|
fetchServerCalendarGraph
|
||||||
} from "../../../service/serverService";
|
} from "../../../../service/serverService";
|
||||||
import {ErrorViewBody} from "../../../views/ErrorView";
|
import {ErrorViewBody} from "../../../../views/ErrorView";
|
||||||
import PunchCard from "../../graphs/PunchCard";
|
import PunchCard from "../../../graphs/PunchCard";
|
||||||
import {useTranslation} from "react-i18next";
|
import {useTranslation} from "react-i18next";
|
||||||
import {Card} from "react-bootstrap-v5";
|
import {Card} from "react-bootstrap-v5";
|
||||||
import CardTabs from "../../CardTabs";
|
import CardTabs from "../../../CardTabs";
|
||||||
import {faBraille, faChartArea} from "@fortawesome/free-solid-svg-icons";
|
import {faBraille, faChartArea} from "@fortawesome/free-solid-svg-icons";
|
||||||
import {faCalendar} from "@fortawesome/free-regular-svg-icons";
|
import {faCalendar} from "@fortawesome/free-regular-svg-icons";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import TimeByTimeGraph from "../../graphs/TimeByTimeGraph";
|
import TimeByTimeGraph from "../../../graphs/TimeByTimeGraph";
|
||||||
import ServerCalendar from "../../calendar/ServerCalendar";
|
import ServerCalendar from "../../../calendar/ServerCalendar";
|
||||||
|
|
||||||
const DayByDayTab = () => {
|
const DayByDayTab = () => {
|
||||||
const {identifier} = useParams();
|
const {identifier} = useParams();
|
@ -1,12 +1,12 @@
|
|||||||
import {useTranslation} from "react-i18next";
|
import {useTranslation} from "react-i18next";
|
||||||
import {useParams} from "react-router-dom";
|
import {useParams} from "react-router-dom";
|
||||||
import {useDataRequest} from "../../../hooks/dataFetchHook";
|
import {useDataRequest} from "../../../../hooks/dataFetchHook";
|
||||||
import {fetchPlayerbaseDevelopmentGraph} from "../../../service/serverService";
|
import {fetchPlayerbaseDevelopmentGraph} from "../../../../service/serverService";
|
||||||
import {ErrorViewCard} from "../../../views/ErrorView";
|
import {ErrorViewCard} from "../../../../views/ErrorView";
|
||||||
import {Card} from "react-bootstrap-v5";
|
import {Card} from "react-bootstrap-v5";
|
||||||
import {FontAwesomeIcon as Fa} from "@fortawesome/react-fontawesome";
|
import {FontAwesomeIcon as Fa} from "@fortawesome/react-fontawesome";
|
||||||
import {faChartLine} from "@fortawesome/free-solid-svg-icons";
|
import {faChartLine} from "@fortawesome/free-solid-svg-icons";
|
||||||
import PlayersOnlineGraph from "../../graphs/PlayersOnlineGraph";
|
import PlayersOnlineGraph from "../../../graphs/PlayersOnlineGraph";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
const PlayerbaseDevelopmentCard = () => {
|
const PlayerbaseDevelopmentCard = () => {
|
@ -1,9 +1,9 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import WorldPieCard from "../common/WorldPieCard";
|
import WorldPieCard from "../../common/WorldPieCard";
|
||||||
import {useParams} from "react-router-dom";
|
import {useParams} from "react-router-dom";
|
||||||
import {useDataRequest} from "../../../hooks/dataFetchHook";
|
import {useDataRequest} from "../../../../hooks/dataFetchHook";
|
||||||
import {fetchWorldPie} from "../../../service/serverService";
|
import {fetchWorldPie} from "../../../../service/serverService";
|
||||||
import {ErrorViewBody} from "../../../views/ErrorView";
|
import {ErrorViewBody} from "../../../../views/ErrorView";
|
||||||
|
|
||||||
const ServerWorldPieCard = () => {
|
const ServerWorldPieCard = () => {
|
||||||
const {identifier} = useParams();
|
const {identifier} = useParams();
|
@ -1,5 +1,5 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import InsightsFor30DaysCard from "../common/InsightsFor30DaysCard";
|
import InsightsFor30DaysCard from "../../common/InsightsFor30DaysCard";
|
||||||
|
|
||||||
const OnlineActivityInsightsCard = () => {
|
const OnlineActivityInsightsCard = () => {
|
||||||
return (
|
return (
|
@ -0,0 +1,42 @@
|
|||||||
|
import React from "react";
|
||||||
|
import InsightsFor30DaysCard from "../../common/InsightsFor30DaysCard";
|
||||||
|
import {useTranslation} from "react-i18next";
|
||||||
|
import {FontAwesomeIcon as Fa} from "@fortawesome/react-fontawesome";
|
||||||
|
import Datapoint from "../../../Datapoint";
|
||||||
|
import {faLongArrowAltRight, faUser} from "@fortawesome/free-solid-svg-icons";
|
||||||
|
import SmallTrend from "../../../trend/SmallTrend";
|
||||||
|
|
||||||
|
const TwoPlayerChange = ({colorBefore, labelBefore, colorAfter, labelAfter}) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Fa icon={faUser} className={`col-${colorBefore}`}/>{' '}{labelBefore}
|
||||||
|
{' '}<Fa icon={faLongArrowAltRight}/>{' '}
|
||||||
|
<Fa icon={faUser} className={`col-${colorAfter}`}/>{' '}{labelAfter}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const PlayerbaseInsightsCard = ({data}) => {
|
||||||
|
const {t} = useTranslation();
|
||||||
|
if (!data) return <></>;
|
||||||
|
return (
|
||||||
|
<InsightsFor30DaysCard>
|
||||||
|
<Datapoint name={<TwoPlayerChange colorBefore={'light-green'}
|
||||||
|
labelBefore={t('html.label.new')}
|
||||||
|
colorAfter={'lime'}
|
||||||
|
labelAfter={t('html.label.regular')}/>}
|
||||||
|
value={data.new_to_regular}
|
||||||
|
trend={<SmallTrend trend={data.new_to_regular_trend}/>}
|
||||||
|
/>
|
||||||
|
<Datapoint name={<TwoPlayerChange colorBefore={'lime'}
|
||||||
|
labelBefore={t('html.label.regular')}
|
||||||
|
colorAfter={'bluegray'}
|
||||||
|
labelAfter={t('html.label.inactive')}/>}
|
||||||
|
value={data.regular_to_inactive}
|
||||||
|
trend={<SmallTrend trend={data.regular_to_inactive_trend}/>}
|
||||||
|
/>
|
||||||
|
</InsightsFor30DaysCard>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PlayerbaseInsightsCard;
|
@ -1,5 +1,5 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import InsightsFor30DaysCard from "../common/InsightsFor30DaysCard";
|
import InsightsFor30DaysCard from "../../common/InsightsFor30DaysCard";
|
||||||
|
|
||||||
const PvpPveInsightsCard = () => {
|
const PvpPveInsightsCard = () => {
|
||||||
return (
|
return (
|
@ -1,5 +1,5 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import InsightsFor30DaysCard from "../common/InsightsFor30DaysCard";
|
import InsightsFor30DaysCard from "../../common/InsightsFor30DaysCard";
|
||||||
|
|
||||||
const SessionInsightsCard = () => {
|
const SessionInsightsCard = () => {
|
||||||
return (
|
return (
|
@ -3,7 +3,7 @@ import {Card} from "react-bootstrap-v5";
|
|||||||
import {FontAwesomeIcon as Fa} from "@fortawesome/react-fontawesome";
|
import {FontAwesomeIcon as Fa} from "@fortawesome/react-fontawesome";
|
||||||
import {faBookOpen} from "@fortawesome/free-solid-svg-icons";
|
import {faBookOpen} from "@fortawesome/free-solid-svg-icons";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import OnlineActivityAsNumbersTable from "../../table/OnlineActivityAsNumbersTable";
|
import OnlineActivityAsNumbersTable from "../../../table/OnlineActivityAsNumbersTable";
|
||||||
|
|
||||||
const OnlineActivityAsNumbersCard = () => {
|
const OnlineActivityAsNumbersCard = () => {
|
||||||
const {t} = useTranslation();
|
const {t} = useTranslation();
|
@ -0,0 +1,52 @@
|
|||||||
|
import {useTranslation} from "react-i18next";
|
||||||
|
import {Card} from "react-bootstrap-v5";
|
||||||
|
import {FontAwesomeIcon as Fa} from "@fortawesome/react-fontawesome";
|
||||||
|
import {faExchangeAlt, faUsers} from "@fortawesome/free-solid-svg-icons";
|
||||||
|
import ComparisonTable from "../../../table/ComparisonTable";
|
||||||
|
import {TableRow} from "../../../table/AsNumbersTable";
|
||||||
|
import BigTrend from "../../../trend/BigTrend";
|
||||||
|
import React from "react";
|
||||||
|
import {faClock} from "@fortawesome/free-regular-svg-icons";
|
||||||
|
|
||||||
|
const PlayerbaseTrendsCard = ({data}) => {
|
||||||
|
const {t} = useTranslation();
|
||||||
|
if (!data) return <></>;
|
||||||
|
return (
|
||||||
|
<Card>
|
||||||
|
<Card.Header>
|
||||||
|
<h6 className="col-black">
|
||||||
|
<Fa icon={faExchangeAlt} className="col-amber"/> {t('html.label.trends30days')}
|
||||||
|
</h6>
|
||||||
|
</Card.Header>
|
||||||
|
<ComparisonTable comparisonHeader={t('html.text.comparing30daysAgo')}
|
||||||
|
headers={[t('html.label.thirtyDaysAgo'), t('html.label.now'), t('html.label.trend')]}>
|
||||||
|
<TableRow icon={faUsers} color="black" text={t('html.label.totalPlayers')}
|
||||||
|
values={[data.total_players_now, data.total_players_then,
|
||||||
|
<BigTrend trend={data.total_players_trend}/>]}/>
|
||||||
|
<TableRow icon={faUsers} color="lime" text={t('html.label.regularPlayers')}
|
||||||
|
values={[data.regular_players_now, data.regular_players_then,
|
||||||
|
<BigTrend trend={data.regular_players_trend}/>]}/>
|
||||||
|
<TableRow icon={faClock} color="green"
|
||||||
|
text={t('html.label.averagePlaytime') + ' ' + t('html.label.perPlayer')}
|
||||||
|
values={[data.playtime_avg_now, data.playtime_avg_then,
|
||||||
|
<BigTrend trend={data.playtime_avg_trend}/>]}/>
|
||||||
|
<TableRow icon={faClock} color="gray" text={t('html.label.afk') + ' ' + t('html.label.perPlayer')}
|
||||||
|
values={[data.afk_now, data.afk_then, <BigTrend trend={data.afk_trend}/>]}/>
|
||||||
|
<TableRow icon={faClock} color="green"
|
||||||
|
text={t('html.label.averagePlaytime') + ' ' + t('html.label.perRegularPlayer')}
|
||||||
|
values={[data.regular_playtime_avg_now, data.regular_playtime_avg_then,
|
||||||
|
<BigTrend trend={data.regular_playtime_avg_trend}/>]}/>
|
||||||
|
<TableRow icon={faClock} color="teal"
|
||||||
|
text={t('html.label.averageSessionLength') + ' ' + t('html.label.perRegularPlayer')}
|
||||||
|
values={[data.regular_session_avg_now, data.regular_session_avg_then,
|
||||||
|
<BigTrend trend={data.regular_session_avg_trend}/>]}/>
|
||||||
|
<TableRow icon={faClock} color="gray"
|
||||||
|
text={t('html.label.afk') + ' ' + t('html.label.perRegularPlayer')}
|
||||||
|
values={[data.regular_afk_avg_now, data.regular_afk_avg_then,
|
||||||
|
<BigTrend trend={data.regular_afk_avg_trend}/>]}/>
|
||||||
|
</ComparisonTable>
|
||||||
|
</Card>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PlayerbaseTrendsCard
|
@ -3,7 +3,7 @@ import {Card} from "react-bootstrap-v5";
|
|||||||
import {FontAwesomeIcon as Fa} from "@fortawesome/react-fontawesome";
|
import {FontAwesomeIcon as Fa} from "@fortawesome/react-fontawesome";
|
||||||
import {faCampground} from "@fortawesome/free-solid-svg-icons";
|
import {faCampground} from "@fortawesome/free-solid-svg-icons";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import ServerPvpPveAsNumbersTable from "../../table/ServerPvpPveAsNumbersTable";
|
import ServerPvpPveAsNumbersTable from "../../../table/ServerPvpPveAsNumbersTable";
|
||||||
|
|
||||||
const PvpPveAsNumbersCard = ({kill_data}) => {
|
const PvpPveAsNumbersCard = ({kill_data}) => {
|
||||||
const {t} = useTranslation();
|
const {t} = useTranslation();
|
@ -1,9 +1,9 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import {useParams} from "react-router-dom";
|
import {useParams} from "react-router-dom";
|
||||||
import {useDataRequest} from "../../../hooks/dataFetchHook";
|
import {useDataRequest} from "../../../../hooks/dataFetchHook";
|
||||||
import {fetchSessions} from "../../../service/serverService";
|
import {fetchSessions} from "../../../../service/serverService";
|
||||||
import {ErrorViewBody} from "../../../views/ErrorView";
|
import {ErrorViewBody} from "../../../../views/ErrorView";
|
||||||
import RecentSessionsCard from "../common/RecentSessionsCard";
|
import RecentSessionsCard from "../../common/RecentSessionsCard";
|
||||||
|
|
||||||
const ServerRecentSessionsCard = () => {
|
const ServerRecentSessionsCard = () => {
|
||||||
|
|
@ -0,0 +1,49 @@
|
|||||||
|
import {useTranslation} from "react-i18next";
|
||||||
|
import {Card} from "react-bootstrap-v5";
|
||||||
|
import {FontAwesomeIcon as Fa} from "@fortawesome/react-fontawesome";
|
||||||
|
import {faCrosshairs, faExchangeAlt, faSkull, faUsers} from "@fortawesome/free-solid-svg-icons";
|
||||||
|
import ComparisonTable from "../../../table/ComparisonTable";
|
||||||
|
import {TableRow} from "../../../table/AsNumbersTable";
|
||||||
|
import BigTrend from "../../../trend/BigTrend";
|
||||||
|
import {faCalendarCheck, faClock} from "@fortawesome/free-regular-svg-icons";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
const ServerWeekComparisonCard = ({data}) => {
|
||||||
|
const {t} = useTranslation();
|
||||||
|
if (!data) return <></>;
|
||||||
|
return (
|
||||||
|
<Card>
|
||||||
|
<Card.Header>
|
||||||
|
<h6 className="col-black">
|
||||||
|
<Fa icon={faExchangeAlt}/> {t('html.label.weekComparison')}
|
||||||
|
</h6>
|
||||||
|
</Card.Header>
|
||||||
|
<ComparisonTable comparisonHeader={t('html.label.comparing7days')}
|
||||||
|
headers={[data.start + ' - ' + data.midpoint, data.midpoint + ' - ' + data.end, t('html.label.trend')]}>
|
||||||
|
<TableRow icon={faUsers} color="blue" text={t('html.label.uniquePlayers')}
|
||||||
|
values={[data.unique_before, data.unique_after, <BigTrend trend={data.unique_trend}/>]}/>
|
||||||
|
<TableRow icon={faUsers} color="light-green" text={t('html.label.newPlayers')}
|
||||||
|
values={[data.new_before, data.new_after, <BigTrend trend={data.new_trend}/>]}/>
|
||||||
|
<TableRow icon={faUsers} color="lime" text={t('html.label.regularPlayers')}
|
||||||
|
values={[data.regular_before, data.regular_after, <BigTrend trend={data.regular_trend}/>]}/>
|
||||||
|
<TableRow icon={faClock} color="green"
|
||||||
|
text={t('html.label.averagePlaytime') + ' ' + t('html.label.perPlayer')}
|
||||||
|
values={[data.average_playtime_before, data.average_playtime_after,
|
||||||
|
<BigTrend trend={data.average_playtime_trend}/>]}/>
|
||||||
|
<TableRow icon={faCalendarCheck} color="teal" text={t('html.label.sessions')}
|
||||||
|
values={[data.sessions_before, data.sessions_after,
|
||||||
|
<BigTrend trend={data.sessions_trend}/>]}/>
|
||||||
|
<TableRow icon={faCrosshairs} color="red" text={t('html.label.playerKills')}
|
||||||
|
values={[data.player_kills_before, data.player_kills_after,
|
||||||
|
<BigTrend trend={data.player_kills_trend}/>]}/>
|
||||||
|
<TableRow icon={faCrosshairs} color="green" text={t('html.label.mobKills')}
|
||||||
|
values={[data.mob_kills_before, data.mob_kills_after,
|
||||||
|
<BigTrend trend={data.mob_kills_trend}/>]}/>
|
||||||
|
<TableRow icon={faSkull} color="black" text={t('html.label.deaths')}
|
||||||
|
values={[data.deaths_before, data.deaths_after, <BigTrend trend={data.deaths_trend}/>]}/>
|
||||||
|
</ComparisonTable>
|
||||||
|
</Card>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ServerWeekComparisonCard
|
@ -0,0 +1,75 @@
|
|||||||
|
import {useTranslation} from "react-i18next";
|
||||||
|
import {Card} from "react-bootstrap-v5";
|
||||||
|
import {FontAwesomeIcon as Fa} from "@fortawesome/react-fontawesome";
|
||||||
|
import {
|
||||||
|
faBookOpen,
|
||||||
|
faChartLine,
|
||||||
|
faCrosshairs,
|
||||||
|
faPowerOff,
|
||||||
|
faSkull,
|
||||||
|
faUser,
|
||||||
|
faUsers
|
||||||
|
} from "@fortawesome/free-solid-svg-icons";
|
||||||
|
import Datapoint from "../../../Datapoint";
|
||||||
|
import {faCalendarCheck, faClock} from "@fortawesome/free-regular-svg-icons";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
const ServerAsNumbersCard = ({data}) => {
|
||||||
|
const {t} = useTranslation();
|
||||||
|
|
||||||
|
if (!data) return <></>;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Card>
|
||||||
|
<Card.Header>
|
||||||
|
<h6 className="col-black">
|
||||||
|
<Fa icon={faBookOpen}/> {t('html.label.serverAsNumberse')}
|
||||||
|
</h6>
|
||||||
|
</Card.Header>
|
||||||
|
<Card.Body>
|
||||||
|
<Datapoint name={t('html.label.currentUptime')}
|
||||||
|
color={'light-green'} icon={faPowerOff}
|
||||||
|
value={data.current_uptime}/>
|
||||||
|
<hr/>
|
||||||
|
<Datapoint name={t('html.label.totalPlayers')}
|
||||||
|
color={'black'} icon={faUsers}
|
||||||
|
value={data.total_players} bold/>
|
||||||
|
<Datapoint name={t('html.label.regularPlayers')}
|
||||||
|
color={'lime'} icon={faUsers}
|
||||||
|
value={data.regular_players} bold/>
|
||||||
|
<Datapoint name={t('html.label.playersOnline')}
|
||||||
|
color={'blue'} icon={faUser}
|
||||||
|
value={data.online_players} bold/>
|
||||||
|
<hr/>
|
||||||
|
<Datapoint name={t('html.label.lastPeak') + ' (' + data.last_peak_date + ')'}
|
||||||
|
color={'blue'} icon={faChartLine}
|
||||||
|
value={data.last_peak_players} valueLabel={t('html.unit.players')} bold/>
|
||||||
|
<Datapoint name={t('html.label.bestPeak') + ' (' + data.best_peak_date + ')'}
|
||||||
|
color={'light-green'} icon={faChartLine}
|
||||||
|
value={data.best_peak_players} valueLabel={t('html.unit.players')} bold/>
|
||||||
|
<hr/>
|
||||||
|
<Datapoint name={t('html.label.totalPlaytime')}
|
||||||
|
color={'green'} icon={faClock}
|
||||||
|
value={data.playtime}/>
|
||||||
|
<Datapoint name={t('html.label.averagePlaytime') + ' ' + t('html.label.perPlayer')}
|
||||||
|
color={'green'} icon={faClock}
|
||||||
|
value={data.player_playtime}/>
|
||||||
|
<Datapoint name={t('html.label.sessions')}
|
||||||
|
color={'teal'} icon={faCalendarCheck}
|
||||||
|
value={data.sessions} bold/>
|
||||||
|
<hr/>
|
||||||
|
<Datapoint name={t('html.label.playerKills')}
|
||||||
|
color={'red'} icon={faCrosshairs}
|
||||||
|
value={data.player_kills} bold/>
|
||||||
|
<Datapoint name={t('html.label.mobKills')}
|
||||||
|
color={'green'} icon={faCrosshairs}
|
||||||
|
value={data.mob_kills} bold/>
|
||||||
|
<Datapoint name={t('html.label.deaths')}
|
||||||
|
color={'black'} icon={faSkull}
|
||||||
|
value={data.deaths} bold/>
|
||||||
|
</Card.Body>
|
||||||
|
</Card>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ServerAsNumbersCard;
|
@ -11,7 +11,7 @@ const LineGraph = ({id, series}) => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
NoDataDisplay(Highcharts);
|
NoDataDisplay(Highcharts);
|
||||||
Highcharts.setOptions({lang: {noData: t('html.labels.noDataToDisplay')}})
|
Highcharts.setOptions({lang: {noData: t('html.label.noDataToDisplay')}})
|
||||||
Highcharts.setOptions(graphTheming);
|
Highcharts.setOptions(graphTheming);
|
||||||
Highcharts.stockChart(id, {
|
Highcharts.stockChart(id, {
|
||||||
rangeSelector: {
|
rangeSelector: {
|
||||||
|
@ -2,11 +2,11 @@ import React from "react";
|
|||||||
import {FontAwesomeIcon as Fa} from "@fortawesome/react-fontawesome";
|
import {FontAwesomeIcon as Fa} from "@fortawesome/react-fontawesome";
|
||||||
import {faCaretDown, faCaretRight, faCaretUp} from "@fortawesome/free-solid-svg-icons";
|
import {faCaretDown, faCaretRight, faCaretUp} from "@fortawesome/free-solid-svg-icons";
|
||||||
|
|
||||||
const TrendUpGood = ({value}) => <Fa icon={faCaretUp} className="badge bg-success" title={value}/>;
|
const TrendUpGood = ({value}) => <Fa icon={faCaretUp} className="text-success" title={value}/>;
|
||||||
const TrendUpBad = ({value}) => <Fa icon={faCaretUp} className="badge bg-danger" title={value}/>;
|
const TrendUpBad = ({value}) => <Fa icon={faCaretUp} className="text-danger" title={value}/>;
|
||||||
const TrendDownBad = ({value}) => <Fa icon={faCaretDown} className="badge bg-danger" title={value}/>;
|
const TrendDownBad = ({value}) => <Fa icon={faCaretDown} className="text-danger" title={value}/>;
|
||||||
const TrendDownGood = ({value}) => <Fa icon={faCaretDown} className="badge bg-success" title={value}/>;
|
const TrendDownGood = ({value}) => <Fa icon={faCaretDown} className="text-success" title={value}/>;
|
||||||
const TrendSame = ({value}) => <Fa icon={faCaretRight} className="badge bg-warning" title={value}/>;
|
const TrendSame = ({value}) => <Fa icon={faCaretRight} className="text-warning" title={value}/>;
|
||||||
|
|
||||||
|
|
||||||
const SmallTrend = ({trend}) => {
|
const SmallTrend = ({trend}) => {
|
||||||
|
@ -1,200 +0,0 @@
|
|||||||
import React from "react";
|
|
||||||
|
|
||||||
import {Card, Col, Row} from "react-bootstrap-v5";
|
|
||||||
import {FontAwesomeIcon as Fa} from "@fortawesome/react-fontawesome";
|
|
||||||
import {
|
|
||||||
faBookOpen,
|
|
||||||
faChartLine,
|
|
||||||
faCrosshairs,
|
|
||||||
faExchangeAlt,
|
|
||||||
faExclamationCircle,
|
|
||||||
faPowerOff,
|
|
||||||
faSkull,
|
|
||||||
faTachometerAlt,
|
|
||||||
faUser,
|
|
||||||
faUsers
|
|
||||||
} from "@fortawesome/free-solid-svg-icons";
|
|
||||||
import Datapoint from "../components/Datapoint";
|
|
||||||
import {useTranslation} from "react-i18next";
|
|
||||||
import {useParams} from "react-router-dom";
|
|
||||||
import {fetchServerOverview} from "../service/serverService";
|
|
||||||
import {faCalendarCheck, faClock} from "@fortawesome/free-regular-svg-icons";
|
|
||||||
import {TableRow} from "../components/table/AsNumbersTable";
|
|
||||||
import ComparisonTable from "../components/table/ComparisonTable";
|
|
||||||
import BigTrend from "../components/trend/BigTrend";
|
|
||||||
import ErrorView from "./ErrorView";
|
|
||||||
import {useDataRequest} from "../hooks/dataFetchHook";
|
|
||||||
import OnlineActivityCard from "../components/cards/server/OnlineActivityCard";
|
|
||||||
|
|
||||||
const Last7DaysCard = ({data}) => {
|
|
||||||
const {t} = useTranslation();
|
|
||||||
|
|
||||||
if (!data) return <></>;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Card>
|
|
||||||
<Card.Header>
|
|
||||||
<h6 className="col-black">
|
|
||||||
{t('html.label.last7days')}
|
|
||||||
</h6>
|
|
||||||
</Card.Header>
|
|
||||||
<Card.Body>
|
|
||||||
<Datapoint name={t('html.label.uniquePlayers')}
|
|
||||||
color={'blue'} icon={faUsers}
|
|
||||||
value={data.unique_players} bold/>
|
|
||||||
<Datapoint name={t('html.label.uniquePlayers') + ' ' + t('html.label.perDay')}
|
|
||||||
color={'blue'} icon={faUser}
|
|
||||||
value={data.unique_players_day} bold/>
|
|
||||||
<Datapoint name={t('html.label.newPlayers')}
|
|
||||||
color={'light-green'} icon={faUsers}
|
|
||||||
value={data.new_players} bold/>
|
|
||||||
<Datapoint name={t('html.label.newPlayers')}
|
|
||||||
color={'light-green'} icon={faUsers}
|
|
||||||
value={data.new_players_retention_perc}
|
|
||||||
valueLabel={data.new_players_retention + '/' + data.new_players} bold/>
|
|
||||||
<hr/>
|
|
||||||
<Datapoint name={t('html.label.averageTps')}
|
|
||||||
color={'orange'} icon={faTachometerAlt}
|
|
||||||
value={data.average_tps} bold/>
|
|
||||||
<Datapoint name={t('html.label.lowTpsSpikes')}
|
|
||||||
color={'red'} icon={faExclamationCircle}
|
|
||||||
value={data.low_tps_spikes} bold/>
|
|
||||||
<Datapoint name={t('html.label.downtime')}
|
|
||||||
color={'red'} icon={faPowerOff}
|
|
||||||
value={data.downtime}/>
|
|
||||||
</Card.Body>
|
|
||||||
</Card>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const ServerAsNumbersCard = ({data}) => {
|
|
||||||
const {t} = useTranslation();
|
|
||||||
|
|
||||||
if (!data) return <></>;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Card>
|
|
||||||
<Card.Header>
|
|
||||||
<h6 className="col-black">
|
|
||||||
<Fa icon={faBookOpen}/> {t('html.label.serverAsNumberse')}
|
|
||||||
</h6>
|
|
||||||
</Card.Header>
|
|
||||||
<Card.Body>
|
|
||||||
<Datapoint name={t('html.label.currentUptime')}
|
|
||||||
color={'light-green'} icon={faPowerOff}
|
|
||||||
value={data.current_uptime}/>
|
|
||||||
<hr/>
|
|
||||||
<Datapoint name={t('html.label.totalPlayers')}
|
|
||||||
color={'black'} icon={faUsers}
|
|
||||||
value={data.total_players} bold/>
|
|
||||||
<Datapoint name={t('html.label.regularPlayers')}
|
|
||||||
color={'lime'} icon={faUsers}
|
|
||||||
value={data.regular_players} bold/>
|
|
||||||
<Datapoint name={t('html.label.playersOnline')}
|
|
||||||
color={'blue'} icon={faUser}
|
|
||||||
value={data.online_players} bold/>
|
|
||||||
<hr/>
|
|
||||||
<Datapoint name={t('html.label.lastPeak') + ' (' + data.last_peak_date + ')'}
|
|
||||||
color={'blue'} icon={faChartLine}
|
|
||||||
value={data.last_peak_players} valueLabel={t('html.unit.players')} bold/>
|
|
||||||
<Datapoint name={t('html.label.bestPeak') + ' (' + data.best_peak_date + ')'}
|
|
||||||
color={'light-green'} icon={faChartLine}
|
|
||||||
value={data.best_peak_players} valueLabel={t('html.unit.players')} bold/>
|
|
||||||
<hr/>
|
|
||||||
<Datapoint name={t('html.label.totalPlaytime')}
|
|
||||||
color={'green'} icon={faClock}
|
|
||||||
value={data.playtime}/>
|
|
||||||
<Datapoint name={t('html.label.averagePlaytime') + ' ' + t('html.label.perPlayer')}
|
|
||||||
color={'green'} icon={faClock}
|
|
||||||
value={data.player_playtime}/>
|
|
||||||
<Datapoint name={t('html.label.sessions')}
|
|
||||||
color={'teal'} icon={faCalendarCheck}
|
|
||||||
value={data.sessions} bold/>
|
|
||||||
<hr/>
|
|
||||||
<Datapoint name={t('html.label.playerKills')}
|
|
||||||
color={'red'} icon={faCrosshairs}
|
|
||||||
value={data.player_kills} bold/>
|
|
||||||
<Datapoint name={t('html.label.mobKills')}
|
|
||||||
color={'green'} icon={faCrosshairs}
|
|
||||||
value={data.mob_kills} bold/>
|
|
||||||
<Datapoint name={t('html.label.deaths')}
|
|
||||||
color={'black'} icon={faSkull}
|
|
||||||
value={data.deaths} bold/>
|
|
||||||
</Card.Body>
|
|
||||||
</Card>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const WeekComparisonCard = ({data}) => {
|
|
||||||
const {t} = useTranslation();
|
|
||||||
if (!data) return <></>;
|
|
||||||
return (
|
|
||||||
<Card>
|
|
||||||
<Card.Header>
|
|
||||||
<h6 className="col-black">
|
|
||||||
<Fa icon={faExchangeAlt}/> {t('html.label.weekComparison')}
|
|
||||||
</h6>
|
|
||||||
</Card.Header>
|
|
||||||
<ComparisonTable comparisonHeader={t('html.label.comparing7days')}
|
|
||||||
headers={[data.start + ' - ' + data.midpoint, data.midpoint + ' - ' + data.end, t('html.label.trend')]}>
|
|
||||||
<TableRow icon={faUsers} color="blue" text={t('html.label.uniquePlayers')}
|
|
||||||
values={[data.unique_before, data.unique_after, <BigTrend trend={data.unique_trend}/>]}/>
|
|
||||||
<TableRow icon={faUsers} color="light-green" text={t('html.label.newPlayers')}
|
|
||||||
values={[data.new_before, data.new_after, <BigTrend trend={data.new_trend}/>]}/>
|
|
||||||
<TableRow icon={faUsers} color="lime" text={t('html.label.regularPlayers')}
|
|
||||||
values={[data.regular_before, data.regular_after, <BigTrend trend={data.regular_trend}/>]}/>
|
|
||||||
<TableRow icon={faClock} color="green"
|
|
||||||
text={t('html.label.averagePlaytime') + ' ' + t('html.label.perPlayer')}
|
|
||||||
values={[data.average_playtime_before, data.average_playtime_after,
|
|
||||||
<BigTrend trend={data.average_playtime_trend}/>]}/>
|
|
||||||
<TableRow icon={faCalendarCheck} color="teal" text={t('html.label.sessions')}
|
|
||||||
values={[data.sessions_before, data.sessions_after,
|
|
||||||
<BigTrend trend={data.sessions_trend}/>]}/>
|
|
||||||
<TableRow icon={faCrosshairs} color="red" text={t('html.label.playerKills')}
|
|
||||||
values={[data.player_kills_before, data.player_kills_after,
|
|
||||||
<BigTrend trend={data.player_kills_trend}/>]}/>
|
|
||||||
<TableRow icon={faCrosshairs} color="green" text={t('html.label.mobKills')}
|
|
||||||
values={[data.mob_kills_before, data.mob_kills_after,
|
|
||||||
<BigTrend trend={data.mob_kills_trend}/>]}/>
|
|
||||||
<TableRow icon={faSkull} color="black" text={t('html.label.deaths')}
|
|
||||||
values={[data.deaths_before, data.deaths_after, <BigTrend trend={data.deaths_trend}/>]}/>
|
|
||||||
</ComparisonTable>
|
|
||||||
</Card>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const ServerOverview = () => {
|
|
||||||
const {identifier} = useParams();
|
|
||||||
|
|
||||||
const {data, loadingError} = useDataRequest(
|
|
||||||
fetchServerOverview,
|
|
||||||
[identifier])
|
|
||||||
|
|
||||||
if (loadingError) {
|
|
||||||
return <ErrorView error={loadingError}/>
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<section className="server_overview">
|
|
||||||
<Row>
|
|
||||||
<Col lg={9}>
|
|
||||||
<OnlineActivityCard/>
|
|
||||||
</Col>
|
|
||||||
<Col lg={3}>
|
|
||||||
<Last7DaysCard data={data ? data.last_7_days : undefined}/>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
<Row>
|
|
||||||
<Col lg={4}>
|
|
||||||
<ServerAsNumbersCard data={data ? data.numbers : undefined}/>
|
|
||||||
</Col>
|
|
||||||
<Col lg={8}>
|
|
||||||
<WeekComparisonCard data={data ? data.weeks : undefined}/>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
</section>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ServerOverview;
|
|
@ -1,17 +1,17 @@
|
|||||||
import React, {useEffect, useState} from "react";
|
import React, {useEffect, useState} from "react";
|
||||||
import Sidebar from "../components/navigation/Sidebar";
|
import Sidebar from "../../components/navigation/Sidebar";
|
||||||
import {Outlet, useOutletContext, useParams} from "react-router-dom";
|
import {Outlet, useOutletContext, useParams} from "react-router-dom";
|
||||||
import ColorSelectorModal from "../components/modal/ColorSelectorModal";
|
import ColorSelectorModal from "../../components/modal/ColorSelectorModal";
|
||||||
import {NightModeCss} from "../hooks/themeHook";
|
import {NightModeCss} from "../../hooks/themeHook";
|
||||||
import {fetchPlayer} from "../service/playerService";
|
import {fetchPlayer} from "../../service/playerService";
|
||||||
import ErrorView from "./ErrorView";
|
import ErrorView from "../ErrorView";
|
||||||
import {faCampground, faCubes, faInfoCircle, faNetworkWired} from "@fortawesome/free-solid-svg-icons";
|
import {faCampground, faCubes, faInfoCircle, faNetworkWired} from "@fortawesome/free-solid-svg-icons";
|
||||||
import {useAuth} from "../hooks/authenticationHook";
|
import {useAuth} from "../../hooks/authenticationHook";
|
||||||
import Header from "../components/navigation/Header";
|
import Header from "../../components/navigation/Header";
|
||||||
import {useNavigation} from "../hooks/navigationHook";
|
import {useNavigation} from "../../hooks/navigationHook";
|
||||||
import {useTranslation} from "react-i18next";
|
import {useTranslation} from "react-i18next";
|
||||||
import {faCalendarCheck} from "@fortawesome/free-regular-svg-icons";
|
import {faCalendarCheck} from "@fortawesome/free-regular-svg-icons";
|
||||||
import {useDataRequest} from "../hooks/dataFetchHook";
|
import {useDataRequest} from "../../hooks/dataFetchHook";
|
||||||
|
|
||||||
|
|
||||||
const PlayerPage = () => {
|
const PlayerPage = () => {
|
@ -1,7 +1,7 @@
|
|||||||
import React, {useEffect, useState} from "react";
|
import React, {useEffect, useState} from "react";
|
||||||
import {useTranslation} from "react-i18next";
|
import {useTranslation} from "react-i18next";
|
||||||
import {Outlet} from "react-router-dom";
|
import {Outlet} from "react-router-dom";
|
||||||
import {useNavigation} from "../hooks/navigationHook";
|
import {useNavigation} from "../../hooks/navigationHook";
|
||||||
import {
|
import {
|
||||||
faCampground,
|
faCampground,
|
||||||
faChartArea,
|
faChartArea,
|
||||||
@ -15,13 +15,13 @@ import {
|
|||||||
faUsers,
|
faUsers,
|
||||||
faUsersViewfinder
|
faUsersViewfinder
|
||||||
} from "@fortawesome/free-solid-svg-icons";
|
} from "@fortawesome/free-solid-svg-icons";
|
||||||
import {useAuth} from "../hooks/authenticationHook";
|
import {useAuth} from "../../hooks/authenticationHook";
|
||||||
import {NightModeCss} from "../hooks/themeHook";
|
import {NightModeCss} from "../../hooks/themeHook";
|
||||||
import Sidebar from "../components/navigation/Sidebar";
|
import Sidebar from "../../components/navigation/Sidebar";
|
||||||
import Header from "../components/navigation/Header";
|
import Header from "../../components/navigation/Header";
|
||||||
import ErrorView from "./ErrorView";
|
import ErrorView from "../ErrorView";
|
||||||
import ColorSelectorModal from "../components/modal/ColorSelectorModal";
|
import ColorSelectorModal from "../../components/modal/ColorSelectorModal";
|
||||||
import {useMetadata} from "../hooks/metadataHook";
|
import {useMetadata} from "../../hooks/metadataHook";
|
||||||
import {faCalendarCheck} from "@fortawesome/free-regular-svg-icons";
|
import {faCalendarCheck} from "@fortawesome/free-regular-svg-icons";
|
||||||
|
|
||||||
const ServerPage = () => {
|
const ServerPage = () => {
|
@ -18,15 +18,15 @@ import {
|
|||||||
faWifi
|
faWifi
|
||||||
} from "@fortawesome/free-solid-svg-icons";
|
} from "@fortawesome/free-solid-svg-icons";
|
||||||
import {faSuperpowers} from "@fortawesome/free-brands-svg-icons";
|
import {faSuperpowers} from "@fortawesome/free-brands-svg-icons";
|
||||||
import Scrollable from "../components/Scrollable";
|
import Scrollable from "../../components/Scrollable";
|
||||||
import PunchCard from "../components/graphs/PunchCard";
|
import PunchCard from "../../components/graphs/PunchCard";
|
||||||
import Datapoint from "../components/Datapoint";
|
import Datapoint from "../../components/Datapoint";
|
||||||
import AsNumbersTable, {TableRow} from "../components/table/AsNumbersTable";
|
import AsNumbersTable, {TableRow} from "../../components/table/AsNumbersTable";
|
||||||
import {useTheme} from "../hooks/themeHook";
|
import {useTheme} from "../../hooks/themeHook";
|
||||||
import {usePlayer} from "./PlayerPage";
|
import {usePlayer} from "../layout/PlayerPage";
|
||||||
import {useMetadata} from "../hooks/metadataHook";
|
import {useMetadata} from "../../hooks/metadataHook";
|
||||||
import {useTranslation} from "react-i18next";
|
import {useTranslation} from "react-i18next";
|
||||||
import NicknamesCard from "../components/cards/player/NicknamesCard";
|
import NicknamesCard from "../../components/cards/player/NicknamesCard";
|
||||||
|
|
||||||
const PlayerOverviewCard = ({player}) => {
|
const PlayerOverviewCard = ({player}) => {
|
||||||
const {t} = useTranslation();
|
const {t} = useTranslation();
|
@ -1,9 +1,9 @@
|
|||||||
import React, {useEffect} from "react";
|
import React, {useEffect} from "react";
|
||||||
import ExtensionCard, {ExtensionCardWrapper} from "../components/extensions/ExtensionCard";
|
import ExtensionCard, {ExtensionCardWrapper} from "../../components/extensions/ExtensionCard";
|
||||||
import {Card, Row} from "react-bootstrap-v5";
|
import {Card, Row} from "react-bootstrap-v5";
|
||||||
import {useParams} from "react-router-dom";
|
import {useParams} from "react-router-dom";
|
||||||
import Masonry from "masonry-layout";
|
import Masonry from "masonry-layout";
|
||||||
import {usePlayer} from "./PlayerPage";
|
import {usePlayer} from "../layout/PlayerPage";
|
||||||
|
|
||||||
const PlayerPluginData = () => {
|
const PlayerPluginData = () => {
|
||||||
const {player} = usePlayer();
|
const {player} = usePlayer();
|
@ -3,12 +3,12 @@ import {Card, Col, Row} from "react-bootstrap-v5";
|
|||||||
import {FontAwesomeIcon as Fa} from "@fortawesome/react-fontawesome";
|
import {FontAwesomeIcon as Fa} from "@fortawesome/react-fontawesome";
|
||||||
import {faLifeRing} from "@fortawesome/free-regular-svg-icons";
|
import {faLifeRing} from "@fortawesome/free-regular-svg-icons";
|
||||||
import {faKhanda, faSkull} from "@fortawesome/free-solid-svg-icons";
|
import {faKhanda, faSkull} from "@fortawesome/free-solid-svg-icons";
|
||||||
import Datapoint from "../components/Datapoint";
|
import Datapoint from "../../components/Datapoint";
|
||||||
import KillsTable from "../components/table/KillsTable";
|
import KillsTable from "../../components/table/KillsTable";
|
||||||
import {usePlayer} from "./PlayerPage";
|
import {usePlayer} from "../layout/PlayerPage";
|
||||||
import {useTranslation} from "react-i18next";
|
import {useTranslation} from "react-i18next";
|
||||||
import PvpPveAsNumbersCard from "../components/cards/player/PvpPveAsNumbersCard";
|
import PvpPveAsNumbersCard from "../../components/cards/player/PvpPveAsNumbersCard";
|
||||||
import PvpKillsTableCard from "../components/cards/common/PvpKillsTableCard";
|
import PvpKillsTableCard from "../../components/cards/common/PvpKillsTableCard";
|
||||||
|
|
||||||
const InsightsCard = ({player}) => {
|
const InsightsCard = ({player}) => {
|
||||||
const {t} = useTranslation();
|
const {t} = useTranslation();
|
@ -2,13 +2,13 @@ import React from "react";
|
|||||||
import {Card, Col, Row} from "react-bootstrap-v5";
|
import {Card, Col, Row} from "react-bootstrap-v5";
|
||||||
import {FontAwesomeIcon as Fa} from "@fortawesome/react-fontawesome";
|
import {FontAwesomeIcon as Fa} from "@fortawesome/react-fontawesome";
|
||||||
import {faHandPointer} from "@fortawesome/free-regular-svg-icons";
|
import {faHandPointer} from "@fortawesome/free-regular-svg-icons";
|
||||||
import Scrollable from "../components/Scrollable";
|
import Scrollable from "../../components/Scrollable";
|
||||||
import {faNetworkWired, faSignal} from "@fortawesome/free-solid-svg-icons";
|
import {faNetworkWired, faSignal} from "@fortawesome/free-solid-svg-icons";
|
||||||
import ServerPie from "../components/graphs/ServerPie";
|
import ServerPie from "../../components/graphs/ServerPie";
|
||||||
import ServerAccordion from "../components/accordion/ServerAccordion";
|
import ServerAccordion from "../../components/accordion/ServerAccordion";
|
||||||
import {usePlayer} from "./PlayerPage";
|
import {usePlayer} from "../layout/PlayerPage";
|
||||||
import {useTranslation} from "react-i18next";
|
import {useTranslation} from "react-i18next";
|
||||||
import PingGraph from "../components/graphs/PingGraph";
|
import PingGraph from "../../components/graphs/PingGraph";
|
||||||
|
|
||||||
const PingGraphCard = ({player}) => {
|
const PingGraphCard = ({player}) => {
|
||||||
const {t} = useTranslation();
|
const {t} = useTranslation();
|
@ -2,11 +2,11 @@ import React from "react";
|
|||||||
import {Card, Col, Row} from "react-bootstrap-v5";
|
import {Card, Col, Row} from "react-bootstrap-v5";
|
||||||
import {FontAwesomeIcon as Fa} from "@fortawesome/react-fontawesome";
|
import {FontAwesomeIcon as Fa} from "@fortawesome/react-fontawesome";
|
||||||
import {faCalendarAlt} from "@fortawesome/free-regular-svg-icons";
|
import {faCalendarAlt} from "@fortawesome/free-regular-svg-icons";
|
||||||
import PlayerSessionCalendar from "../components/calendar/PlayerSessionCalendar";
|
import PlayerSessionCalendar from "../../components/calendar/PlayerSessionCalendar";
|
||||||
import {usePlayer} from "./PlayerPage";
|
import {usePlayer} from "../layout/PlayerPage";
|
||||||
import {useTranslation} from "react-i18next";
|
import {useTranslation} from "react-i18next";
|
||||||
import PlayerWorldPieCard from "../components/cards/player/PlayerWorldPieCard";
|
import PlayerWorldPieCard from "../../components/cards/player/PlayerWorldPieCard";
|
||||||
import PlayerRecentSessionsCard from "../components/cards/player/PlayerRecentSessionsCard";
|
import PlayerRecentSessionsCard from "../../components/cards/player/PlayerRecentSessionsCard";
|
||||||
|
|
||||||
const SessionCalendarCard = ({player}) => {
|
const SessionCalendarCard = ({player}) => {
|
||||||
const {t} = useTranslation();
|
const {t} = useTranslation();
|
@ -1,14 +1,14 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import {Col, Row} from "react-bootstrap-v5";
|
import {Col, Row} from "react-bootstrap-v5";
|
||||||
import OnlineActivityGraphsCard from "../components/cards/server/OnlineActivityGraphsCard";
|
import OnlineActivityGraphsCard from "../../components/cards/server/graphs/OnlineActivityGraphsCard";
|
||||||
import OnlineActivityAsNumbersCard from "../components/cards/server/OnlineActivityAsNumbersCard";
|
import OnlineActivityAsNumbersCard from "../../components/cards/server/tables/OnlineActivityAsNumbersCard";
|
||||||
import {useParams} from "react-router-dom";
|
import {useParams} from "react-router-dom";
|
||||||
import {useDataRequest} from "../hooks/dataFetchHook";
|
import {useDataRequest} from "../../hooks/dataFetchHook";
|
||||||
import {fetchOnlineActivityOverview} from "../service/serverService";
|
import {fetchOnlineActivityOverview} from "../../service/serverService";
|
||||||
import {ErrorViewBody} from "./ErrorView";
|
import {ErrorViewBody} from "../ErrorView";
|
||||||
import OnlineActivityInsightsCard from "../components/cards/server/OnlineActivityInsightsCard";
|
import OnlineActivityInsightsCard from "../../components/cards/server/insights/OnlineActivityInsightsCard";
|
||||||
|
|
||||||
const ServerOnlineActivity = () => {
|
const OnlineActivity = () => {
|
||||||
const {identifier} = useParams();
|
const {identifier} = useParams();
|
||||||
|
|
||||||
const {data, loadingError} = useDataRequest(fetchOnlineActivityOverview, [identifier])
|
const {data, loadingError} = useDataRequest(fetchOnlineActivityOverview, [identifier])
|
||||||
@ -35,4 +35,4 @@ const ServerOnlineActivity = () => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ServerOnlineActivity
|
export default OnlineActivity
|
@ -1,13 +1,15 @@
|
|||||||
import {Col, Row} from "react-bootstrap-v5";
|
import {Col, Row} from "react-bootstrap-v5";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import PlayerbaseDevelopmentCard from "../components/cards/server/PlayerbaseDevelopmentCard";
|
import PlayerbaseDevelopmentCard from "../../components/cards/server/graphs/PlayerbaseDevelopmentCard";
|
||||||
import CurrentPlayerbaseCard from "../components/cards/server/CurrentPlayerbaseCard";
|
import CurrentPlayerbaseCard from "../../components/cards/server/graphs/CurrentPlayerbaseCard";
|
||||||
import {useParams} from "react-router-dom";
|
import {useParams} from "react-router-dom";
|
||||||
import {useDataRequest} from "../hooks/dataFetchHook";
|
import {useDataRequest} from "../../hooks/dataFetchHook";
|
||||||
import {fetchPlayerbaseOverview} from "../service/serverService";
|
import {fetchPlayerbaseOverview} from "../../service/serverService";
|
||||||
import ErrorView from "./ErrorView";
|
import ErrorView from "../ErrorView";
|
||||||
|
import PlayerbaseTrendsCard from "../../components/cards/server/tables/PlayerbaseTrendsCard";
|
||||||
|
import PlayerbaseInsightsCard from "../../components/cards/server/insights/PlayerbaseInsightsCard";
|
||||||
|
|
||||||
const ServerPlayerbaseOverview = () => {
|
const PlayerbaseOverview = () => {
|
||||||
const {identifier} = useParams();
|
const {identifier} = useParams();
|
||||||
|
|
||||||
const {data, loadingError} = useDataRequest(fetchPlayerbaseOverview, [identifier]);
|
const {data, loadingError} = useDataRequest(fetchPlayerbaseOverview, [identifier]);
|
||||||
@ -27,10 +29,10 @@ const ServerPlayerbaseOverview = () => {
|
|||||||
</Row>
|
</Row>
|
||||||
<Row>
|
<Row>
|
||||||
<Col lg={8}>
|
<Col lg={8}>
|
||||||
|
<PlayerbaseTrendsCard data={data?.trends}/>
|
||||||
</Col>
|
</Col>
|
||||||
<Col lg={4}>
|
<Col lg={4}>
|
||||||
|
<PlayerbaseInsightsCard data={data?.insights}/>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
</section>
|
</section>
|
||||||
@ -38,4 +40,4 @@ const ServerPlayerbaseOverview = () => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ServerPlayerbaseOverview;
|
export default PlayerbaseOverview;
|
89
Plan/react/dashboard/src/views/server/ServerOverview.js
Normal file
89
Plan/react/dashboard/src/views/server/ServerOverview.js
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
import {Card, Col, Row} from "react-bootstrap-v5";
|
||||||
|
import {faExclamationCircle, faPowerOff, faTachometerAlt, faUser, faUsers} from "@fortawesome/free-solid-svg-icons";
|
||||||
|
import Datapoint from "../../components/Datapoint";
|
||||||
|
import {useTranslation} from "react-i18next";
|
||||||
|
import {useParams} from "react-router-dom";
|
||||||
|
import {fetchServerOverview} from "../../service/serverService";
|
||||||
|
import ErrorView from "../ErrorView";
|
||||||
|
import {useDataRequest} from "../../hooks/dataFetchHook";
|
||||||
|
import OnlineActivityCard from "../../components/cards/server/graphs/OnlineActivityCard";
|
||||||
|
import ServerAsNumbersCard from "../../components/cards/server/values/ServerAsNumbersCard";
|
||||||
|
import ServerWeekComparisonCard from "../../components/cards/server/tables/ServerWeekComparisonCard";
|
||||||
|
|
||||||
|
const Last7DaysCard = ({data}) => {
|
||||||
|
const {t} = useTranslation();
|
||||||
|
|
||||||
|
if (!data) return <></>;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Card>
|
||||||
|
<Card.Header>
|
||||||
|
<h6 className="col-black">
|
||||||
|
{t('html.label.last7days')}
|
||||||
|
</h6>
|
||||||
|
</Card.Header>
|
||||||
|
<Card.Body>
|
||||||
|
<Datapoint name={t('html.label.uniquePlayers')}
|
||||||
|
color={'blue'} icon={faUsers}
|
||||||
|
value={data.unique_players} bold/>
|
||||||
|
<Datapoint name={t('html.label.uniquePlayers') + ' ' + t('html.label.perDay')}
|
||||||
|
color={'blue'} icon={faUser}
|
||||||
|
value={data.unique_players_day} bold/>
|
||||||
|
<Datapoint name={t('html.label.newPlayers')}
|
||||||
|
color={'light-green'} icon={faUsers}
|
||||||
|
value={data.new_players} bold/>
|
||||||
|
<Datapoint name={t('html.label.newPlayers')}
|
||||||
|
color={'light-green'} icon={faUsers}
|
||||||
|
value={data.new_players_retention_perc}
|
||||||
|
valueLabel={data.new_players_retention + '/' + data.new_players} bold/>
|
||||||
|
<hr/>
|
||||||
|
<Datapoint name={t('html.label.averageTps')}
|
||||||
|
color={'orange'} icon={faTachometerAlt}
|
||||||
|
value={data.average_tps} bold/>
|
||||||
|
<Datapoint name={t('html.label.lowTpsSpikes')}
|
||||||
|
color={'red'} icon={faExclamationCircle}
|
||||||
|
value={data.low_tps_spikes} bold/>
|
||||||
|
<Datapoint name={t('html.label.downtime')}
|
||||||
|
color={'red'} icon={faPowerOff}
|
||||||
|
value={data.downtime}/>
|
||||||
|
</Card.Body>
|
||||||
|
</Card>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const ServerOverview = () => {
|
||||||
|
const {identifier} = useParams();
|
||||||
|
|
||||||
|
const {data, loadingError} = useDataRequest(
|
||||||
|
fetchServerOverview,
|
||||||
|
[identifier])
|
||||||
|
|
||||||
|
if (loadingError) {
|
||||||
|
return <ErrorView error={loadingError}/>
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section className="server_overview">
|
||||||
|
<Row>
|
||||||
|
<Col lg={9}>
|
||||||
|
<OnlineActivityCard/>
|
||||||
|
</Col>
|
||||||
|
<Col lg={3}>
|
||||||
|
<Last7DaysCard data={data?.last_7_days}/>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Col lg={4}>
|
||||||
|
<ServerAsNumbersCard data={data?.numbers}/>
|
||||||
|
</Col>
|
||||||
|
<Col lg={8}>
|
||||||
|
<ServerWeekComparisonCard data={data?.weeks}/>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</section>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ServerOverview;
|
@ -1,8 +1,8 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import PvpPveAsNumbersCard from "../components/cards/server/PvpPveAsNumbersCard";
|
import PvpPveAsNumbersCard from "../../components/cards/server/tables/PvpPveAsNumbersCard";
|
||||||
import {Col, Row} from "react-bootstrap-v5";
|
import {Col, Row} from "react-bootstrap-v5";
|
||||||
import PvpKillsTableCard from "../components/cards/common/PvpKillsTableCard";
|
import PvpKillsTableCard from "../../components/cards/common/PvpKillsTableCard";
|
||||||
import PvpPveInsightsCard from "../components/cards/server/PvpPveInsightsCard";
|
import PvpPveInsightsCard from "../../components/cards/server/insights/PvpPveInsightsCard";
|
||||||
|
|
||||||
const ServerPvpPve = () => {
|
const ServerPvpPve = () => {
|
||||||
return (
|
return (
|
@ -1,8 +1,8 @@
|
|||||||
import {Col, Row} from "react-bootstrap-v5";
|
import {Col, Row} from "react-bootstrap-v5";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import ServerWorldPieCard from "../components/cards/server/ServerWorldPieCard";
|
import ServerWorldPieCard from "../../components/cards/server/graphs/ServerWorldPieCard";
|
||||||
import ServerRecentSessionsCard from "../components/cards/server/ServerRecentSessionsCard";
|
import ServerRecentSessionsCard from "../../components/cards/server/tables/ServerRecentSessionsCard";
|
||||||
import SessionInsightsCard from "../components/cards/server/SessionInsightsCard";
|
import SessionInsightsCard from "../../components/cards/server/insights/SessionInsightsCard";
|
||||||
|
|
||||||
const ServerSessions = () => {
|
const ServerSessions = () => {
|
||||||
return (
|
return (
|
Loading…
Reference in New Issue
Block a user