Playerbase overview page layout

- Moved some files
This commit is contained in:
Aurora Lahtela 2022-05-23 18:58:06 +03:00
parent b942078485
commit 7e1bd7f4a6
32 changed files with 428 additions and 319 deletions

View File

@ -4,12 +4,12 @@ import './style/style.css';
import {BrowserRouter, Navigate, Route, Routes} from "react-router-dom";
import React from "react";
import PlayerPage from "./views/PlayerPage";
import PlayerOverview from "./views/PlayerOverview";
import PlayerSessions from "./views/PlayerSessions";
import PlayerPvpPve from "./views/PlayerPvpPve";
import PlayerServers from "./views/PlayerServers";
import PlayerPluginData from "./views/PlayerPluginData";
import PlayerPage from "./views/layout/PlayerPage";
import PlayerOverview from "./views/player/PlayerOverview";
import PlayerSessions from "./views/player/PlayerSessions";
import PlayerPvpPve from "./views/player/PlayerPvpPve";
import PlayerServers from "./views/player/PlayerServers";
import PlayerPluginData from "./views/player/PlayerPluginData";
import {ThemeContextProvider} from "./hooks/themeHook";
import axios from "axios";
import ErrorView from "./views/ErrorView";
@ -17,13 +17,13 @@ import {faMapSigns} from "@fortawesome/free-solid-svg-icons";
import {MetadataContextProvider} from "./hooks/metadataHook";
import {AuthenticationContextProvider} from "./hooks/authenticationHook";
import {NavigationContextProvider} from "./hooks/navigationHook";
import ServerPage from "./views/ServerPage";
import ServerOverview from "./views/ServerOverview";
import ServerPage from "./views/layout/ServerPage";
import ServerOverview from "./views/server/ServerOverview";
import MainPageRedirect from "./components/navigation/MainPageRedirect";
import ServerOnlineActivity from "./views/ServerOnlineActivity";
import ServerSessions from "./views/ServerSessions";
import ServerPvpPve from "./views/ServerPvpPve";
import ServerPlayerbaseOverview from "./views/ServerPlayerbaseOverview";
import OnlineActivity from "./views/server/OnlineActivity";
import ServerSessions from "./views/server/ServerSessions";
import ServerPvpPve from "./views/server/ServerPvpPve";
import PlayerbaseOverview from "./views/server/PlayerbaseOverview";
const OverviewRedirect = () => {
return (<Navigate to={"overview"} replace={true}/>)
@ -67,10 +67,10 @@ function App() {
<Route path="/server/:identifier" element={<ServerPage/>}>
<Route path="" element={<OverviewRedirect/>}/>
<Route path="overview" element={<ServerOverview/>}/>
<Route path="online-activity" element={<ServerOnlineActivity/>}/>
<Route path="online-activity" element={<OnlineActivity/>}/>
<Route path="sessions" element={<ServerSessions/>}/>
<Route path="pvppve" element={<ServerPvpPve/>}/>
<Route path="playerbase" element={<ServerPlayerbaseOverview/>}/>
<Route path="playerbase" element={<PlayerbaseOverview/>}/>
<Route path="retention" element={<></>}/>
<Route path="players" element={<></>}/>
<Route path="geolocations" element={<></>}/>

View File

@ -5,14 +5,14 @@ const End = ({children}) => (
<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 extraLabel = valueLabel ? ` (${valueLabel})` : '';
const extraLabel = valueLabel instanceof String ? ` (${valueLabel})` : '';
const colorClass = color && color.startsWith("col-") ? color : "col-" + color;
return (
<p title={title ? title : name + " is " + value}>
<Fa icon={icon} className={colorClass}/> {boldTitle ? <b>{name}</b> : name}
{value !== undefined ? <End>{displayedValue} {extraLabel}</End> : ''}
{icon && <Fa icon={icon} className={colorClass}/>} {boldTitle ? <b>{name}</b> : name}
{value !== undefined ? <End>{displayedValue} {extraLabel}{trend}</End> : ''}
</p>
);
}

View File

@ -1,8 +1,8 @@
import React from "react";
import {useParams} from "react-router-dom";
import {useDataRequest} from "../../../hooks/dataFetchHook";
import {fetchPlayerbaseDevelopmentGraph} from "../../../service/serverService";
import {ErrorViewBody} from "../../../views/ErrorView";
import {useDataRequest} from "../../../../hooks/dataFetchHook";
import {fetchPlayerbaseDevelopmentGraph} from "../../../../service/serverService";
import {ErrorViewBody} from "../../../../views/ErrorView";
import {useTranslation} from "react-i18next";
import {Card} from "react-bootstrap-v5";
import {FontAwesomeIcon as Fa} from "@fortawesome/react-fontawesome";

View File

@ -1,12 +1,12 @@
import {useTranslation} from "react-i18next";
import {useParams} from "react-router-dom";
import {useDataRequest} from "../../../hooks/dataFetchHook";
import {fetchPlayersOnlineGraph} from "../../../service/serverService";
import {ErrorViewCard} from "../../../views/ErrorView";
import {useDataRequest} from "../../../../hooks/dataFetchHook";
import {fetchPlayersOnlineGraph} from "../../../../service/serverService";
import {ErrorViewCard} from "../../../../views/ErrorView";
import {Card} from "react-bootstrap-v5";
import {FontAwesomeIcon as Fa} from "@fortawesome/react-fontawesome";
import {faChartArea} from "@fortawesome/free-solid-svg-icons";
import PlayersOnlineGraph from "../../graphs/PlayersOnlineGraph";
import PlayersOnlineGraph from "../../../graphs/PlayersOnlineGraph";
import React from "react";
const OnlineActivityCard = () => {

View File

@ -1,21 +1,21 @@
import {useParams} from "react-router-dom";
import {useDataRequest} from "../../../hooks/dataFetchHook";
import {useDataRequest} from "../../../../hooks/dataFetchHook";
import {
fetchDayByDayGraph,
fetchHourByHourGraph,
fetchPunchCardGraph,
fetchServerCalendarGraph
} from "../../../service/serverService";
import {ErrorViewBody} from "../../../views/ErrorView";
import PunchCard from "../../graphs/PunchCard";
} from "../../../../service/serverService";
import {ErrorViewBody} from "../../../../views/ErrorView";
import PunchCard from "../../../graphs/PunchCard";
import {useTranslation} from "react-i18next";
import {Card} from "react-bootstrap-v5";
import CardTabs from "../../CardTabs";
import CardTabs from "../../../CardTabs";
import {faBraille, faChartArea} from "@fortawesome/free-solid-svg-icons";
import {faCalendar} from "@fortawesome/free-regular-svg-icons";
import React from "react";
import TimeByTimeGraph from "../../graphs/TimeByTimeGraph";
import ServerCalendar from "../../calendar/ServerCalendar";
import TimeByTimeGraph from "../../../graphs/TimeByTimeGraph";
import ServerCalendar from "../../../calendar/ServerCalendar";
const DayByDayTab = () => {
const {identifier} = useParams();

View File

@ -1,12 +1,12 @@
import {useTranslation} from "react-i18next";
import {useParams} from "react-router-dom";
import {useDataRequest} from "../../../hooks/dataFetchHook";
import {fetchPlayerbaseDevelopmentGraph} from "../../../service/serverService";
import {ErrorViewCard} from "../../../views/ErrorView";
import {useDataRequest} from "../../../../hooks/dataFetchHook";
import {fetchPlayerbaseDevelopmentGraph} from "../../../../service/serverService";
import {ErrorViewCard} from "../../../../views/ErrorView";
import {Card} from "react-bootstrap-v5";
import {FontAwesomeIcon as Fa} from "@fortawesome/react-fontawesome";
import {faChartLine} from "@fortawesome/free-solid-svg-icons";
import PlayersOnlineGraph from "../../graphs/PlayersOnlineGraph";
import PlayersOnlineGraph from "../../../graphs/PlayersOnlineGraph";
import React from "react";
const PlayerbaseDevelopmentCard = () => {

View File

@ -1,9 +1,9 @@
import React from "react";
import WorldPieCard from "../common/WorldPieCard";
import WorldPieCard from "../../common/WorldPieCard";
import {useParams} from "react-router-dom";
import {useDataRequest} from "../../../hooks/dataFetchHook";
import {fetchWorldPie} from "../../../service/serverService";
import {ErrorViewBody} from "../../../views/ErrorView";
import {useDataRequest} from "../../../../hooks/dataFetchHook";
import {fetchWorldPie} from "../../../../service/serverService";
import {ErrorViewBody} from "../../../../views/ErrorView";
const ServerWorldPieCard = () => {
const {identifier} = useParams();

View File

@ -1,5 +1,5 @@
import React from "react";
import InsightsFor30DaysCard from "../common/InsightsFor30DaysCard";
import InsightsFor30DaysCard from "../../common/InsightsFor30DaysCard";
const OnlineActivityInsightsCard = () => {
return (

View File

@ -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;

View File

@ -1,5 +1,5 @@
import React from "react";
import InsightsFor30DaysCard from "../common/InsightsFor30DaysCard";
import InsightsFor30DaysCard from "../../common/InsightsFor30DaysCard";
const PvpPveInsightsCard = () => {
return (

View File

@ -1,5 +1,5 @@
import React from "react";
import InsightsFor30DaysCard from "../common/InsightsFor30DaysCard";
import InsightsFor30DaysCard from "../../common/InsightsFor30DaysCard";
const SessionInsightsCard = () => {
return (

View File

@ -3,7 +3,7 @@ import {Card} from "react-bootstrap-v5";
import {FontAwesomeIcon as Fa} from "@fortawesome/react-fontawesome";
import {faBookOpen} from "@fortawesome/free-solid-svg-icons";
import React from "react";
import OnlineActivityAsNumbersTable from "../../table/OnlineActivityAsNumbersTable";
import OnlineActivityAsNumbersTable from "../../../table/OnlineActivityAsNumbersTable";
const OnlineActivityAsNumbersCard = () => {
const {t} = useTranslation();

View File

@ -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

View File

@ -3,7 +3,7 @@ import {Card} from "react-bootstrap-v5";
import {FontAwesomeIcon as Fa} from "@fortawesome/react-fontawesome";
import {faCampground} from "@fortawesome/free-solid-svg-icons";
import React from "react";
import ServerPvpPveAsNumbersTable from "../../table/ServerPvpPveAsNumbersTable";
import ServerPvpPveAsNumbersTable from "../../../table/ServerPvpPveAsNumbersTable";
const PvpPveAsNumbersCard = ({kill_data}) => {
const {t} = useTranslation();

View File

@ -1,9 +1,9 @@
import React from "react";
import {useParams} from "react-router-dom";
import {useDataRequest} from "../../../hooks/dataFetchHook";
import {fetchSessions} from "../../../service/serverService";
import {ErrorViewBody} from "../../../views/ErrorView";
import RecentSessionsCard from "../common/RecentSessionsCard";
import {useDataRequest} from "../../../../hooks/dataFetchHook";
import {fetchSessions} from "../../../../service/serverService";
import {ErrorViewBody} from "../../../../views/ErrorView";
import RecentSessionsCard from "../../common/RecentSessionsCard";
const ServerRecentSessionsCard = () => {

View File

@ -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

View File

@ -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;

View File

@ -11,7 +11,7 @@ const LineGraph = ({id, series}) => {
useEffect(() => {
NoDataDisplay(Highcharts);
Highcharts.setOptions({lang: {noData: t('html.labels.noDataToDisplay')}})
Highcharts.setOptions({lang: {noData: t('html.label.noDataToDisplay')}})
Highcharts.setOptions(graphTheming);
Highcharts.stockChart(id, {
rangeSelector: {

View File

@ -2,11 +2,11 @@ import React from "react";
import {FontAwesomeIcon as Fa} from "@fortawesome/react-fontawesome";
import {faCaretDown, faCaretRight, faCaretUp} from "@fortawesome/free-solid-svg-icons";
const TrendUpGood = ({value}) => <Fa icon={faCaretUp} className="badge bg-success" title={value}/>;
const TrendUpBad = ({value}) => <Fa icon={faCaretUp} className="badge bg-danger" title={value}/>;
const TrendDownBad = ({value}) => <Fa icon={faCaretDown} className="badge bg-danger" title={value}/>;
const TrendDownGood = ({value}) => <Fa icon={faCaretDown} className="badge bg-success" title={value}/>;
const TrendSame = ({value}) => <Fa icon={faCaretRight} className="badge bg-warning" title={value}/>;
const TrendUpGood = ({value}) => <Fa icon={faCaretUp} className="text-success" title={value}/>;
const TrendUpBad = ({value}) => <Fa icon={faCaretUp} className="text-danger" title={value}/>;
const TrendDownBad = ({value}) => <Fa icon={faCaretDown} className="text-danger" title={value}/>;
const TrendDownGood = ({value}) => <Fa icon={faCaretDown} className="text-success" title={value}/>;
const TrendSame = ({value}) => <Fa icon={faCaretRight} className="text-warning" title={value}/>;
const SmallTrend = ({trend}) => {

View File

@ -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;

View File

@ -1,17 +1,17 @@
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 ColorSelectorModal from "../components/modal/ColorSelectorModal";
import {NightModeCss} from "../hooks/themeHook";
import {fetchPlayer} from "../service/playerService";
import ErrorView from "./ErrorView";
import ColorSelectorModal from "../../components/modal/ColorSelectorModal";
import {NightModeCss} from "../../hooks/themeHook";
import {fetchPlayer} from "../../service/playerService";
import ErrorView from "../ErrorView";
import {faCampground, faCubes, faInfoCircle, faNetworkWired} from "@fortawesome/free-solid-svg-icons";
import {useAuth} from "../hooks/authenticationHook";
import Header from "../components/navigation/Header";
import {useNavigation} from "../hooks/navigationHook";
import {useAuth} from "../../hooks/authenticationHook";
import Header from "../../components/navigation/Header";
import {useNavigation} from "../../hooks/navigationHook";
import {useTranslation} from "react-i18next";
import {faCalendarCheck} from "@fortawesome/free-regular-svg-icons";
import {useDataRequest} from "../hooks/dataFetchHook";
import {useDataRequest} from "../../hooks/dataFetchHook";
const PlayerPage = () => {

View File

@ -1,7 +1,7 @@
import React, {useEffect, useState} from "react";
import {useTranslation} from "react-i18next";
import {Outlet} from "react-router-dom";
import {useNavigation} from "../hooks/navigationHook";
import {useNavigation} from "../../hooks/navigationHook";
import {
faCampground,
faChartArea,
@ -15,13 +15,13 @@ import {
faUsers,
faUsersViewfinder
} from "@fortawesome/free-solid-svg-icons";
import {useAuth} from "../hooks/authenticationHook";
import {NightModeCss} from "../hooks/themeHook";
import Sidebar from "../components/navigation/Sidebar";
import Header from "../components/navigation/Header";
import ErrorView from "./ErrorView";
import ColorSelectorModal from "../components/modal/ColorSelectorModal";
import {useMetadata} from "../hooks/metadataHook";
import {useAuth} from "../../hooks/authenticationHook";
import {NightModeCss} from "../../hooks/themeHook";
import Sidebar from "../../components/navigation/Sidebar";
import Header from "../../components/navigation/Header";
import ErrorView from "../ErrorView";
import ColorSelectorModal from "../../components/modal/ColorSelectorModal";
import {useMetadata} from "../../hooks/metadataHook";
import {faCalendarCheck} from "@fortawesome/free-regular-svg-icons";
const ServerPage = () => {

View File

@ -18,15 +18,15 @@ import {
faWifi
} from "@fortawesome/free-solid-svg-icons";
import {faSuperpowers} from "@fortawesome/free-brands-svg-icons";
import Scrollable from "../components/Scrollable";
import PunchCard from "../components/graphs/PunchCard";
import Datapoint from "../components/Datapoint";
import AsNumbersTable, {TableRow} from "../components/table/AsNumbersTable";
import {useTheme} from "../hooks/themeHook";
import {usePlayer} from "./PlayerPage";
import {useMetadata} from "../hooks/metadataHook";
import Scrollable from "../../components/Scrollable";
import PunchCard from "../../components/graphs/PunchCard";
import Datapoint from "../../components/Datapoint";
import AsNumbersTable, {TableRow} from "../../components/table/AsNumbersTable";
import {useTheme} from "../../hooks/themeHook";
import {usePlayer} from "../layout/PlayerPage";
import {useMetadata} from "../../hooks/metadataHook";
import {useTranslation} from "react-i18next";
import NicknamesCard from "../components/cards/player/NicknamesCard";
import NicknamesCard from "../../components/cards/player/NicknamesCard";
const PlayerOverviewCard = ({player}) => {
const {t} = useTranslation();

View File

@ -1,9 +1,9 @@
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 {useParams} from "react-router-dom";
import Masonry from "masonry-layout";
import {usePlayer} from "./PlayerPage";
import {usePlayer} from "../layout/PlayerPage";
const PlayerPluginData = () => {
const {player} = usePlayer();

View File

@ -3,12 +3,12 @@ import {Card, Col, Row} from "react-bootstrap-v5";
import {FontAwesomeIcon as Fa} from "@fortawesome/react-fontawesome";
import {faLifeRing} from "@fortawesome/free-regular-svg-icons";
import {faKhanda, faSkull} from "@fortawesome/free-solid-svg-icons";
import Datapoint from "../components/Datapoint";
import KillsTable from "../components/table/KillsTable";
import {usePlayer} from "./PlayerPage";
import Datapoint from "../../components/Datapoint";
import KillsTable from "../../components/table/KillsTable";
import {usePlayer} from "../layout/PlayerPage";
import {useTranslation} from "react-i18next";
import PvpPveAsNumbersCard from "../components/cards/player/PvpPveAsNumbersCard";
import PvpKillsTableCard from "../components/cards/common/PvpKillsTableCard";
import PvpPveAsNumbersCard from "../../components/cards/player/PvpPveAsNumbersCard";
import PvpKillsTableCard from "../../components/cards/common/PvpKillsTableCard";
const InsightsCard = ({player}) => {
const {t} = useTranslation();

View File

@ -2,13 +2,13 @@ import React from "react";
import {Card, Col, Row} from "react-bootstrap-v5";
import {FontAwesomeIcon as Fa} from "@fortawesome/react-fontawesome";
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 ServerPie from "../components/graphs/ServerPie";
import ServerAccordion from "../components/accordion/ServerAccordion";
import {usePlayer} from "./PlayerPage";
import ServerPie from "../../components/graphs/ServerPie";
import ServerAccordion from "../../components/accordion/ServerAccordion";
import {usePlayer} from "../layout/PlayerPage";
import {useTranslation} from "react-i18next";
import PingGraph from "../components/graphs/PingGraph";
import PingGraph from "../../components/graphs/PingGraph";
const PingGraphCard = ({player}) => {
const {t} = useTranslation();

View File

@ -2,11 +2,11 @@ import React from "react";
import {Card, Col, Row} from "react-bootstrap-v5";
import {FontAwesomeIcon as Fa} from "@fortawesome/react-fontawesome";
import {faCalendarAlt} from "@fortawesome/free-regular-svg-icons";
import PlayerSessionCalendar from "../components/calendar/PlayerSessionCalendar";
import {usePlayer} from "./PlayerPage";
import PlayerSessionCalendar from "../../components/calendar/PlayerSessionCalendar";
import {usePlayer} from "../layout/PlayerPage";
import {useTranslation} from "react-i18next";
import PlayerWorldPieCard from "../components/cards/player/PlayerWorldPieCard";
import PlayerRecentSessionsCard from "../components/cards/player/PlayerRecentSessionsCard";
import PlayerWorldPieCard from "../../components/cards/player/PlayerWorldPieCard";
import PlayerRecentSessionsCard from "../../components/cards/player/PlayerRecentSessionsCard";
const SessionCalendarCard = ({player}) => {
const {t} = useTranslation();

View File

@ -1,14 +1,14 @@
import React from "react";
import {Col, Row} from "react-bootstrap-v5";
import OnlineActivityGraphsCard from "../components/cards/server/OnlineActivityGraphsCard";
import OnlineActivityAsNumbersCard from "../components/cards/server/OnlineActivityAsNumbersCard";
import OnlineActivityGraphsCard from "../../components/cards/server/graphs/OnlineActivityGraphsCard";
import OnlineActivityAsNumbersCard from "../../components/cards/server/tables/OnlineActivityAsNumbersCard";
import {useParams} from "react-router-dom";
import {useDataRequest} from "../hooks/dataFetchHook";
import {fetchOnlineActivityOverview} from "../service/serverService";
import {ErrorViewBody} from "./ErrorView";
import OnlineActivityInsightsCard from "../components/cards/server/OnlineActivityInsightsCard";
import {useDataRequest} from "../../hooks/dataFetchHook";
import {fetchOnlineActivityOverview} from "../../service/serverService";
import {ErrorViewBody} from "../ErrorView";
import OnlineActivityInsightsCard from "../../components/cards/server/insights/OnlineActivityInsightsCard";
const ServerOnlineActivity = () => {
const OnlineActivity = () => {
const {identifier} = useParams();
const {data, loadingError} = useDataRequest(fetchOnlineActivityOverview, [identifier])
@ -35,4 +35,4 @@ const ServerOnlineActivity = () => {
)
}
export default ServerOnlineActivity
export default OnlineActivity

View File

@ -1,13 +1,15 @@
import {Col, Row} from "react-bootstrap-v5";
import React from "react";
import PlayerbaseDevelopmentCard from "../components/cards/server/PlayerbaseDevelopmentCard";
import CurrentPlayerbaseCard from "../components/cards/server/CurrentPlayerbaseCard";
import PlayerbaseDevelopmentCard from "../../components/cards/server/graphs/PlayerbaseDevelopmentCard";
import CurrentPlayerbaseCard from "../../components/cards/server/graphs/CurrentPlayerbaseCard";
import {useParams} from "react-router-dom";
import {useDataRequest} from "../hooks/dataFetchHook";
import {fetchPlayerbaseOverview} from "../service/serverService";
import ErrorView from "./ErrorView";
import {useDataRequest} from "../../hooks/dataFetchHook";
import {fetchPlayerbaseOverview} from "../../service/serverService";
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 {data, loadingError} = useDataRequest(fetchPlayerbaseOverview, [identifier]);
@ -27,10 +29,10 @@ const ServerPlayerbaseOverview = () => {
</Row>
<Row>
<Col lg={8}>
<PlayerbaseTrendsCard data={data?.trends}/>
</Col>
<Col lg={4}>
<PlayerbaseInsightsCard data={data?.insights}/>
</Col>
</Row>
</section>
@ -38,4 +40,4 @@ const ServerPlayerbaseOverview = () => {
)
}
export default ServerPlayerbaseOverview;
export default PlayerbaseOverview;

View 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;

View File

@ -1,8 +1,8 @@
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 PvpKillsTableCard from "../components/cards/common/PvpKillsTableCard";
import PvpPveInsightsCard from "../components/cards/server/PvpPveInsightsCard";
import PvpKillsTableCard from "../../components/cards/common/PvpKillsTableCard";
import PvpPveInsightsCard from "../../components/cards/server/insights/PvpPveInsightsCard";
const ServerPvpPve = () => {
return (

View File

@ -1,8 +1,8 @@
import {Col, Row} from "react-bootstrap-v5";
import React from "react";
import ServerWorldPieCard from "../components/cards/server/ServerWorldPieCard";
import ServerRecentSessionsCard from "../components/cards/server/ServerRecentSessionsCard";
import SessionInsightsCard from "../components/cards/server/SessionInsightsCard";
import ServerWorldPieCard from "../../components/cards/server/graphs/ServerWorldPieCard";
import ServerRecentSessionsCard from "../../components/cards/server/tables/ServerRecentSessionsCard";
import SessionInsightsCard from "../../components/cards/server/insights/SessionInsightsCard";
const ServerSessions = () => {
return (