mirror of
https://github.com/calli-eve/eve-pi.git
synced 2026-02-16 04:29:50 +01:00
refactor types and add account level totals
This commit is contained in:
@@ -7,11 +7,64 @@ import { useContext, useState } from "react";
|
||||
import { PlanRow } from "./PlanRow";
|
||||
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
|
||||
import KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp';
|
||||
import { planetCalculations } from "@/planets";
|
||||
import { EvePraisalResult } from "@/eve-praisal";
|
||||
import { STORAGE_IDS } from "@/const";
|
||||
|
||||
interface AccountTotals {
|
||||
monthlyEstimate: number;
|
||||
storageValue: number;
|
||||
}
|
||||
|
||||
const calculateAccountTotals = (characters: AccessToken[], piPrices: EvePraisalResult | undefined): AccountTotals => {
|
||||
let totalMonthlyEstimate = 0;
|
||||
let totalStorageValue = 0;
|
||||
|
||||
characters.forEach((character) => {
|
||||
character.planets.forEach((planet) => {
|
||||
const { localExports } = planetCalculations(planet);
|
||||
const planetConfig = character.planetConfig.find(p => p.planetId === planet.planet_id);
|
||||
|
||||
// Calculate monthly estimate
|
||||
if (!planetConfig?.excludeFromTotals) {
|
||||
localExports.forEach((exportItem) => {
|
||||
const valueInMillions = (((piPrices?.appraisal.items.find(
|
||||
(a) => a.typeID === exportItem.typeId,
|
||||
)?.prices.sell.min ?? 0) *
|
||||
exportItem.amount) /
|
||||
1000000) *
|
||||
24 *
|
||||
30;
|
||||
totalMonthlyEstimate += valueInMillions;
|
||||
});
|
||||
}
|
||||
|
||||
if (!planetConfig?.excludeFromTotals) {
|
||||
planet.info.pins
|
||||
.filter(pin => STORAGE_IDS().some(storage => storage.type_id === pin.type_id))
|
||||
.forEach(storage => {
|
||||
storage.contents?.forEach(content => {
|
||||
const valueInMillions = (piPrices?.appraisal.items.find(
|
||||
(a) => a.typeID === content.type_id,
|
||||
)?.prices.sell.min ?? 0) * content.amount / 1000000;
|
||||
totalStorageValue += valueInMillions;
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
monthlyEstimate: totalMonthlyEstimate,
|
||||
storageValue: totalStorageValue
|
||||
};
|
||||
};
|
||||
|
||||
export const AccountCard = ({ characters }: { characters: AccessToken[] }) => {
|
||||
const theme = useTheme();
|
||||
const [isCollapsed, setIsCollapsed] = useState(false);
|
||||
const { planMode } = useContext(SessionContext);
|
||||
const { planMode, piPrices } = useContext(SessionContext);
|
||||
const { monthlyEstimate, storageValue } = calculateAccountTotals(characters, piPrices);
|
||||
|
||||
return (
|
||||
<Paper
|
||||
@@ -46,17 +99,39 @@ export const AccountCard = ({ characters }: { characters: AccessToken[] }) => {
|
||||
justifyContent: 'space-between',
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: "0.9rem",
|
||||
fontWeight: 500,
|
||||
color: theme.palette.text.primary,
|
||||
}}
|
||||
>
|
||||
{characters.length > 0 && characters[0].account !== "-"
|
||||
? `Account: ${characters[0].account}`
|
||||
: "No account name"}
|
||||
</Typography>
|
||||
<Box>
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: "0.9rem",
|
||||
fontWeight: 500,
|
||||
color: theme.palette.text.primary,
|
||||
}}
|
||||
>
|
||||
{characters.length > 0 && characters[0].account !== "-"
|
||||
? `Account: ${characters[0].account}`
|
||||
: "No account name"}
|
||||
</Typography>
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: "0.8rem",
|
||||
color: theme.palette.text.secondary,
|
||||
}}
|
||||
>
|
||||
Monthly Estimate: {monthlyEstimate >= 1000
|
||||
? `${(monthlyEstimate / 1000).toFixed(2)} B`
|
||||
: `${monthlyEstimate.toFixed(2)} M`} ISK
|
||||
</Typography>
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: "0.8rem",
|
||||
color: theme.palette.text.secondary,
|
||||
}}
|
||||
>
|
||||
Storage Value: {storageValue >= 1000
|
||||
? `${(storageValue / 1000).toFixed(2)} B`
|
||||
: `${storageValue.toFixed(2)} M`} ISK
|
||||
</Typography>
|
||||
</Box>
|
||||
<IconButton
|
||||
size="small"
|
||||
onClick={() => setIsCollapsed(!isCollapsed)}
|
||||
|
||||
@@ -97,15 +97,6 @@ export const PlanetTableRow = ({
|
||||
cycleTime: schematic.cycle_time
|
||||
}));
|
||||
|
||||
// Convert Map to Array for schematic IDs
|
||||
const installedSchematicIds = Array.from(localProduction.values()).map(p => p.schematic_id);
|
||||
|
||||
// Get extractor head types safely
|
||||
const extractedTypeIds = extractors
|
||||
.map(e => e.extractor_details?.product_type_id)
|
||||
.filter((id): id is number => id !== undefined);
|
||||
|
||||
// Get storage facilities
|
||||
const storageFacilities = planetInfo.pins.filter(pin =>
|
||||
STORAGE_IDS().some(storage => storage.type_id === pin.type_id)
|
||||
);
|
||||
@@ -116,20 +107,26 @@ export const PlanetTableRow = ({
|
||||
const storageType = PI_TYPES_MAP[pin.type_id].name;
|
||||
const storageCapacity = STORAGE_CAPACITIES[pin.type_id] || 0;
|
||||
|
||||
// Calculate total volume of stored products for this specific pin
|
||||
const totalVolume = (pin.contents || [])
|
||||
.reduce((sum: number, item: any) => {
|
||||
const volume = PI_PRODUCT_VOLUMES[item.type_id] || 0;
|
||||
return sum + (item.amount * volume);
|
||||
}, 0);
|
||||
|
||||
const totalValue = (pin.contents || [])
|
||||
.reduce((sum: number, item: any) => {
|
||||
const price = piPrices?.appraisal.items.find((a) => a.typeID === item.type_id)?.prices.sell.min ?? 0;
|
||||
return sum + (item.amount * price);
|
||||
}, 0);
|
||||
|
||||
const fillRate = storageCapacity > 0 ? (totalVolume / storageCapacity) * 100 : 0;
|
||||
|
||||
return {
|
||||
type: storageType,
|
||||
capacity: storageCapacity,
|
||||
used: totalVolume,
|
||||
fillRate: fillRate
|
||||
fillRate: fillRate,
|
||||
value: totalValue
|
||||
};
|
||||
};
|
||||
|
||||
@@ -319,6 +316,11 @@ export const PlanetTableRow = ({
|
||||
<Typography fontSize={theme.custom.smallText} style={{ color }}>
|
||||
{fillRate.toFixed(1)}%
|
||||
</Typography>
|
||||
{storageInfo.value > 0 && (
|
||||
<Typography fontSize={theme.custom.smallText} style={{ marginLeft: "5px" }}>
|
||||
({Math.round(storageInfo.value / 1000000)}M)
|
||||
</Typography>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
|
||||
Reference in New Issue
Block a user