add account level statistics

This commit is contained in:
calli
2025-04-23 17:41:09 +03:00
parent b185e5d044
commit 741b2480b9

View File

@@ -1,5 +1,5 @@
import { AccessToken } from "@/types"; import { AccessToken } from "@/types";
import { Box, Stack, Typography, useTheme, Paper, IconButton } from "@mui/material"; import { Box, Stack, Typography, useTheme, Paper, IconButton, Divider } from "@mui/material";
import { CharacterRow } from "../Characters/CharacterRow"; import { CharacterRow } from "../Characters/CharacterRow";
import { PlanetaryInteractionRow } from "../PlanetaryInteraction/PlanetaryInteractionRow"; import { PlanetaryInteractionRow } from "../PlanetaryInteraction/PlanetaryInteractionRow";
import { SessionContext } from "@/app/context/Context"; import { SessionContext } from "@/app/context/Context";
@@ -14,17 +14,36 @@ import { STORAGE_IDS } from "@/const";
interface AccountTotals { interface AccountTotals {
monthlyEstimate: number; monthlyEstimate: number;
storageValue: number; storageValue: number;
planetCount: number;
characterCount: number;
runningExtractors: number;
totalExtractors: number;
} }
const calculateAccountTotals = (characters: AccessToken[], piPrices: EvePraisalResult | undefined): AccountTotals => { const calculateAccountTotals = (characters: AccessToken[], piPrices: EvePraisalResult | undefined): AccountTotals => {
let totalMonthlyEstimate = 0; let totalMonthlyEstimate = 0;
let totalStorageValue = 0; let totalStorageValue = 0;
let totalPlanetCount = 0;
let totalCharacterCount = characters.length;
let runningExtractors = 0;
let totalExtractors = 0;
characters.forEach((character) => { characters.forEach((character) => {
totalPlanetCount += character.planets.length;
character.planets.forEach((planet) => { character.planets.forEach((planet) => {
const { localExports } = planetCalculations(planet); const { localExports, extractors } = planetCalculations(planet);
const planetConfig = character.planetConfig.find(p => p.planetId === planet.planet_id); const planetConfig = character.planetConfig.find(p => p.planetId === planet.planet_id);
// Count running and total extractors
if (!planetConfig?.excludeFromTotals) {
extractors.forEach(extractor => {
totalExtractors++;
if (extractor.expiry_time && new Date(extractor.expiry_time) > new Date()) {
runningExtractors++;
}
});
}
// Calculate monthly estimate // Calculate monthly estimate
if (!planetConfig?.excludeFromTotals) { if (!planetConfig?.excludeFromTotals) {
localExports.forEach((exportItem) => { localExports.forEach((exportItem) => {
@@ -56,7 +75,11 @@ const calculateAccountTotals = (characters: AccessToken[], piPrices: EvePraisalR
return { return {
monthlyEstimate: totalMonthlyEstimate, monthlyEstimate: totalMonthlyEstimate,
storageValue: totalStorageValue storageValue: totalStorageValue,
planetCount: totalPlanetCount,
characterCount: totalCharacterCount,
runningExtractors,
totalExtractors
}; };
}; };
@@ -64,7 +87,7 @@ export const AccountCard = ({ characters, isCollapsed: propIsCollapsed }: { char
const theme = useTheme(); const theme = useTheme();
const [localIsCollapsed, setLocalIsCollapsed] = useState(false); const [localIsCollapsed, setLocalIsCollapsed] = useState(false);
const { planMode, piPrices } = useContext(SessionContext); const { planMode, piPrices } = useContext(SessionContext);
const { monthlyEstimate, storageValue } = calculateAccountTotals(characters, piPrices); const { monthlyEstimate, storageValue, planetCount, characterCount, runningExtractors, totalExtractors } = calculateAccountTotals(characters, piPrices);
// Update local collapse state when prop changes // Update local collapse state when prop changes
useEffect(() => { useEffect(() => {
@@ -116,26 +139,62 @@ export const AccountCard = ({ characters, isCollapsed: propIsCollapsed }: { char
? `Account: ${characters[0].account}` ? `Account: ${characters[0].account}`
: "No account name"} : "No account name"}
</Typography> </Typography>
<Typography <Box sx={{
sx={{ display: 'flex',
fontSize: "0.8rem", gap: 2,
color: theme.palette.text.secondary, flexWrap: 'wrap',
}} mt: 1,
> alignItems: 'center'
Monthly Estimate: {monthlyEstimate >= 1000 }}>
? `${(monthlyEstimate / 1000).toFixed(2)} B` <Typography
: `${monthlyEstimate.toFixed(2)} M`} ISK sx={{
</Typography> fontSize: "0.8rem",
<Typography color: theme.palette.text.secondary,
sx={{ }}
fontSize: "0.8rem", >
color: theme.palette.text.secondary, Monthly: {monthlyEstimate >= 1000
}} ? `${(monthlyEstimate / 1000).toFixed(2)} B`
> : `${monthlyEstimate.toFixed(2)} M`} ISK
Storage Value: {storageValue >= 1000 </Typography>
? `${(storageValue / 1000).toFixed(2)} B` <Divider orientation="vertical" flexItem sx={{ height: 16, borderColor: theme.palette.divider }} />
: `${storageValue.toFixed(2)} M`} ISK <Typography
</Typography> sx={{
fontSize: "0.8rem",
color: theme.palette.text.secondary,
}}
>
Storage: {storageValue >= 1000
? `${(storageValue / 1000).toFixed(2)} B`
: `${storageValue.toFixed(2)} M`} ISK
</Typography>
<Divider orientation="vertical" flexItem sx={{ height: 16, borderColor: theme.palette.divider }} />
<Typography
sx={{
fontSize: "0.8rem",
color: theme.palette.text.secondary,
}}
>
Planets: {planetCount}
</Typography>
<Divider orientation="vertical" flexItem sx={{ height: 16, borderColor: theme.palette.divider }} />
<Typography
sx={{
fontSize: "0.8rem",
color: theme.palette.text.secondary,
}}
>
Characters: {characterCount}
</Typography>
<Divider orientation="vertical" flexItem sx={{ height: 16, borderColor: theme.palette.divider }} />
<Typography
sx={{
fontSize: "0.8rem",
color: runningExtractors < totalExtractors ? theme.palette.error.main : theme.palette.text.secondary,
}}
>
Extractors: {runningExtractors}/{totalExtractors}
</Typography>
</Box>
</Box> </Box>
<IconButton <IconButton
size="small" size="small"