diff --git a/src/app/components/Account/AccountCard.tsx b/src/app/components/Account/AccountCard.tsx index 416d440..ebbc3f5 100644 --- a/src/app/components/Account/AccountCard.tsx +++ b/src/app/components/Account/AccountCard.tsx @@ -22,15 +22,17 @@ interface AccountTotals { totalExtractors: number; } -const calculateAlertState = (planetDetails: PlanetCalculations): AlertState => { +const calculateAlertState = (planetDetails: PlanetCalculations, minExtractionRate: number): AlertState => { const hasLowStorage = planetDetails.storageInfo.some(storage => storage.fillRate > 60); const hasLowImports = planetDetails.importDepletionTimes.some(depletion => depletion.hoursUntilDepletion < 24); - + const hasLowExtractionRate = planetDetails.extractorAverages.length > 0 && minExtractionRate > 0 && planetDetails.extractorAverages.some(avg => avg.averagePerHour < minExtractionRate); + return { expired: planetDetails.expired, hasLowStorage, hasLowImports, - hasLargeExtractorDifference: planetDetails.hasLargeExtractorDifference + hasLargeExtractorDifference: planetDetails.hasLargeExtractorDifference, + hasLowExtractionRate }; }; @@ -228,7 +230,7 @@ const calculateAccountTotals = (characters: AccessToken[], piPrices: EvePraisalR export const AccountCard = ({ characters, isCollapsed: propIsCollapsed }: { characters: AccessToken[], isCollapsed?: boolean }) => { const theme = useTheme(); const [localIsCollapsed, setLocalIsCollapsed] = useState(false); - const { planMode, piPrices, alertMode, balanceThreshold } = useContext(SessionContext); + const { planMode, piPrices, alertMode, balanceThreshold, minExtractionRate } = useContext(SessionContext); const { monthlyEstimate, storageValue, planetCount, characterCount, runningExtractors, totalExtractors } = calculateAccountTotals(characters, piPrices); // Calculate planet details and alert states for each planet @@ -237,7 +239,7 @@ export const AccountCard = ({ characters, isCollapsed: propIsCollapsed }: { char const details = calculatePlanetDetails(planet, piPrices, balanceThreshold); acc[`${character.character.characterId}-${planet.planet_id}`] = { ...details, - alertState: calculateAlertState(details) + alertState: calculateAlertState(details, minExtractionRate) }; }); return acc; @@ -254,16 +256,18 @@ export const AccountCard = ({ characters, isCollapsed: propIsCollapsed }: { char if (alertState.hasLowStorage) return 'visible'; if (alertState.hasLowImports) return 'visible'; if (alertState.hasLargeExtractorDifference) return 'visible'; + if (alertState.hasLowExtractionRate) return 'visible'; return 'hidden'; }; // Check if any planet in the account has alerts const hasAnyAlerts = Object.values(planetDetails).some(details => { - const alertState = calculateAlertState(details); - return alertState.expired || - alertState.hasLowStorage || - alertState.hasLowImports || - alertState.hasLargeExtractorDifference; + const alertState = calculateAlertState(details, minExtractionRate); + return alertState.expired || + alertState.hasLowStorage || + alertState.hasLowImports || + alertState.hasLargeExtractorDifference || + alertState.hasLowExtractionRate; }); // If in alert mode and no alerts, hide the entire card diff --git a/src/app/components/PlanetaryInteraction/ExtractionSimulationTooltip.tsx b/src/app/components/PlanetaryInteraction/ExtractionSimulationTooltip.tsx index 9c6f315..87185c9 100644 --- a/src/app/components/PlanetaryInteraction/ExtractionSimulationTooltip.tsx +++ b/src/app/components/PlanetaryInteraction/ExtractionSimulationTooltip.tsx @@ -1,8 +1,9 @@ -import React from 'react'; +import React, { useContext } from 'react'; import { Box, Paper, Typography, Stack } from '@mui/material'; import { Line } from 'react-chartjs-2'; import { getProgramOutputPrediction } from './ExtractionSimulation'; import { PI_TYPES_MAP } from '@/const'; +import { SessionContext } from '@/app/context/Context'; import { Chart as ChartJS, CategoryScale, @@ -41,6 +42,7 @@ interface ExtractionSimulationTooltipProps { export const ExtractionSimulationTooltip: React.FC = ({ extractors }) => { + const { minExtractionRate } = useContext(SessionContext); const CYCLE_TIME = 30 * 60; // 30 minutes in seconds // Calculate program duration and cycles for each extractor @@ -159,8 +161,15 @@ export const ExtractionSimulationTooltip: React.FC • Average per Cycle: {(totalOutput / cycles).toFixed(1)} units - - • Average per hour: {(totalOutput / cycles * 2).toFixed(1)} units + 0 && (extractors[idx].baseValue * 3600) / extractors[idx].cycleTime < minExtractionRate + ? 'error' + : 'inherit' + } + > + • Average per hour: {((extractors[idx].baseValue * 3600) / extractors[idx].cycleTime).toFixed(1)} units • Expires in: diff --git a/src/app/components/PlanetaryInteraction/PlanetCard.tsx b/src/app/components/PlanetaryInteraction/PlanetCard.tsx index 92737ef..4b50cf7 100644 --- a/src/app/components/PlanetaryInteraction/PlanetCard.tsx +++ b/src/app/components/PlanetaryInteraction/PlanetCard.tsx @@ -8,7 +8,7 @@ import { PlanetCalculations } from "@/types/planet"; import React, { useContext } from "react"; import { DateTime } from "luxon"; import Countdown from "react-countdown"; -import { ColorContext } from "@/app/context/Context"; +import { ColorContext, SessionContext } from "@/app/context/Context"; import { ExtractionSimulationTooltip } from "./ExtractionSimulationTooltip"; import { timeColor } from "./alerts"; @@ -40,6 +40,7 @@ export const PlanetCard = ({ }) => { const theme = useTheme(); const { colors } = useContext(ColorContext); + const { minExtractionRate } = useContext(SessionContext); const extractorConfigs: ExtractorConfig[] = planetDetails.extractors .filter(e => e.extractor_details?.product_type_id && e.extractor_details?.qty_per_cycle) @@ -51,6 +52,8 @@ export const PlanetCard = ({ expiryTime: e.expiry_time ?? "" })); + const hasLowExtractionRate = planetDetails.extractorAverages.length > 0 && minExtractionRate > 0 && planetDetails.extractorAverages.some(avg => avg.averagePerHour < minExtractionRate); + return ( )}
- + {planet.infoUniverse?.name} + {planetDetails.hasLargeExtractorDifference && ( + + off-balance + + )} + {hasLowExtractionRate && ( + + low-extraction + + )} {planetDetails.extractors.map((e, idx) => { const average = planetDetails.extractorAverages[idx]; return ( diff --git a/src/app/components/PlanetaryInteraction/PlanetTableRow.tsx b/src/app/components/PlanetaryInteraction/PlanetTableRow.tsx index 4f66507..b659a52 100644 --- a/src/app/components/PlanetaryInteraction/PlanetTableRow.tsx +++ b/src/app/components/PlanetaryInteraction/PlanetTableRow.tsx @@ -55,7 +55,7 @@ export const PlanetTableRow = ({ planetDetails: PlanetCalculations; }) => { const theme = useTheme(); - const { showProductIcons, extractionTimeMode, alertMode } = useContext(SessionContext); + const { showProductIcons, extractionTimeMode, alertMode, minExtractionRate } = useContext(SessionContext); const { colors } = useContext(ColorContext); const [planetRenderOpen, setPlanetRenderOpen] = useState(false); @@ -103,11 +103,13 @@ export const PlanetTableRow = ({ }; // Check if there are any alerts + const hasLowExtractionRate = planetDetails.extractorAverages.length > 0 && minExtractionRate > 0 && planetDetails.extractorAverages.some(avg => avg.averagePerHour < minExtractionRate); const hasAlerts = alertMode && ( planetDetails.expired || planetDetails.storageInfo.some(storage => storage.fillRate > 60) || planetDetails.importDepletionTimes.some(depletion => depletion.hoursUntilDepletion < 24) || - planetDetails.hasLargeExtractorDifference + planetDetails.hasLargeExtractorDifference || + hasLowExtractionRate ); // If in alert mode and no alerts, hide the row @@ -225,14 +227,14 @@ export const PlanetTableRow = ({ }} > - {planetInfoUniverse?.name} {planetDetails.hasLargeExtractorDifference && ( - )} + {hasLowExtractionRate && ( + + low-extraction + + )}
diff --git a/src/app/components/Settings/SettingsButtons.tsx b/src/app/components/Settings/SettingsButtons.tsx index cc79a77..7be4f44 100644 --- a/src/app/components/Settings/SettingsButtons.tsx +++ b/src/app/components/Settings/SettingsButtons.tsx @@ -21,7 +21,7 @@ import React, { useState, useContext } from "react"; export const SettingsButton = () => { const { colors, setColors } = useContext(ColorContext); - const { balanceThreshold, setBalanceThreshold, showProductIcons, setShowProductIcons } = useContext(SessionContext); + const { balanceThreshold, setBalanceThreshold, minExtractionRate, setMinExtractionRate, showProductIcons, setShowProductIcons } = useContext(SessionContext); const [open, setOpen] = useState(false); const handleClickOpen = () => { @@ -51,6 +51,13 @@ export const SettingsButton = () => { setShowProductIcons(event.target.checked); }; + const handleMinExtractionRateChange = (event: React.ChangeEvent) => { + const value = parseInt(event.target.value); + if (!isNaN(value) && value >= 0 && value <= 100000) { + setMinExtractionRate(value); + } + }; + return ( <> @@ -93,6 +100,19 @@ export const SettingsButton = () => { error={balanceThreshold < 0 || balanceThreshold > 100000} /> + + Minimum Extraction Rate + 100000} + /> + {Object.keys(colors).map((key) => { return (
diff --git a/src/app/context/Context.tsx b/src/app/context/Context.tsx index bdfb394..9e0d21b 100644 --- a/src/app/context/Context.tsx +++ b/src/app/context/Context.tsx @@ -39,6 +39,8 @@ export const SessionContext = createContext<{ }) => PlanetConfig; balanceThreshold: number; setBalanceThreshold: Dispatch>; + minExtractionRate: number; + setMinExtractionRate: Dispatch>; showProductIcons: boolean; setShowProductIcons: (show: boolean) => void; }>({ @@ -68,6 +70,8 @@ export const SessionContext = createContext<{ }, balanceThreshold: 1000, setBalanceThreshold: () => {}, + minExtractionRate: 0, + setMinExtractionRate: () => {}, showProductIcons: false, setShowProductIcons: () => {}, }); diff --git a/src/app/page.tsx b/src/app/page.tsx index 2d4aa12..f246ef5 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -46,6 +46,7 @@ const Home = () => { undefined, ); const [balanceThreshold, setBalanceThreshold] = useState(1000); + const [minExtractionRate, setMinExtractionRate] = useState(0); const [showProductIcons, setShowProductIcons] = useState(false); const [extractionTimeMode, setExtractionTimeMode] = useState(false); @@ -305,6 +306,8 @@ const Home = () => { readPlanetConfig, balanceThreshold, setBalanceThreshold, + minExtractionRate, + setMinExtractionRate, showProductIcons, setShowProductIcons, }} diff --git a/src/types/planet.ts b/src/types/planet.ts index 843ec43..e91768a 100644 --- a/src/types/planet.ts +++ b/src/types/planet.ts @@ -32,6 +32,7 @@ export interface AlertState { hasLowStorage: boolean; hasLowImports: boolean; hasLargeExtractorDifference: boolean; + hasLowExtractionRate: boolean; } export interface ExtractorAverage {