mirror of
https://github.com/calli-eve/eve-pi.git
synced 2026-02-12 02:38:48 +01:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
741b2480b9 | ||
|
|
b185e5d044 | ||
|
|
f0d4708b43 | ||
|
|
0f33a7ff0c | ||
|
|
bbdcece163 | ||
|
|
2a1e74ca79 |
@@ -43,11 +43,6 @@ module.exports = withSentryConfig(
|
||||
// Transpiles SDK to be compatible with IE11 (increases bundle size)
|
||||
transpileClientSDK: true,
|
||||
|
||||
// Route browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers.
|
||||
// This can increase your server load as well as your hosting bill.
|
||||
// Note: Check that the configured route will not match with your Next.js middleware, otherwise reporting of client-
|
||||
// side errors will fail.
|
||||
tunnelRoute: "/monitoring",
|
||||
|
||||
// Hides source maps from generated client bundles
|
||||
hideSourceMaps: true,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
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 { PlanetaryInteractionRow } from "../PlanetaryInteraction/PlanetaryInteractionRow";
|
||||
import { SessionContext } from "@/app/context/Context";
|
||||
@@ -14,17 +14,36 @@ import { STORAGE_IDS } from "@/const";
|
||||
interface AccountTotals {
|
||||
monthlyEstimate: number;
|
||||
storageValue: number;
|
||||
planetCount: number;
|
||||
characterCount: number;
|
||||
runningExtractors: number;
|
||||
totalExtractors: number;
|
||||
}
|
||||
|
||||
const calculateAccountTotals = (characters: AccessToken[], piPrices: EvePraisalResult | undefined): AccountTotals => {
|
||||
let totalMonthlyEstimate = 0;
|
||||
let totalStorageValue = 0;
|
||||
let totalPlanetCount = 0;
|
||||
let totalCharacterCount = characters.length;
|
||||
let runningExtractors = 0;
|
||||
let totalExtractors = 0;
|
||||
|
||||
characters.forEach((character) => {
|
||||
totalPlanetCount += character.planets.length;
|
||||
character.planets.forEach((planet) => {
|
||||
const { localExports } = planetCalculations(planet);
|
||||
const { localExports, extractors } = planetCalculations(planet);
|
||||
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
|
||||
if (!planetConfig?.excludeFromTotals) {
|
||||
localExports.forEach((exportItem) => {
|
||||
@@ -56,7 +75,11 @@ const calculateAccountTotals = (characters: AccessToken[], piPrices: EvePraisalR
|
||||
|
||||
return {
|
||||
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 [localIsCollapsed, setLocalIsCollapsed] = useState(false);
|
||||
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
|
||||
useEffect(() => {
|
||||
@@ -116,26 +139,62 @@ export const AccountCard = ({ characters, isCollapsed: propIsCollapsed }: { char
|
||||
? `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 sx={{
|
||||
display: 'flex',
|
||||
gap: 2,
|
||||
flexWrap: 'wrap',
|
||||
mt: 1,
|
||||
alignItems: 'center'
|
||||
}}>
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: "0.8rem",
|
||||
color: theme.palette.text.secondary,
|
||||
}}
|
||||
>
|
||||
Monthly: {monthlyEstimate >= 1000
|
||||
? `${(monthlyEstimate / 1000).toFixed(2)} B`
|
||||
: `${monthlyEstimate.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,
|
||||
}}
|
||||
>
|
||||
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>
|
||||
<IconButton
|
||||
size="small"
|
||||
|
||||
@@ -170,7 +170,7 @@ export const ExtractionSimulationDisplay: React.FC<ExtractionSimulationDisplayPr
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Paper sx={{ p: 2 }}>
|
||||
{extractors.length > 0 ? <Paper sx={{ p: 2 }}>
|
||||
<Typography variant="h6" gutterBottom>
|
||||
Extraction Simulation
|
||||
</Typography>
|
||||
@@ -210,7 +210,7 @@ export const ExtractionSimulationDisplay: React.FC<ExtractionSimulationDisplayPr
|
||||
<div style={{ height: '300px' }}>
|
||||
<Line data={chartData} options={chartOptions} />
|
||||
</div>
|
||||
</Paper>
|
||||
</Paper> : null}
|
||||
|
||||
<ProductionChainVisualization
|
||||
extractedTypeIds={extractedTypeIds}
|
||||
|
||||
@@ -102,9 +102,11 @@ export const PlanetCard = ({
|
||||
return (
|
||||
<Tooltip
|
||||
title={
|
||||
<ExtractionSimulationTooltip
|
||||
extractors={extractors}
|
||||
/>
|
||||
extractors.length > 0 ? (
|
||||
<ExtractionSimulationTooltip
|
||||
extractors={extractors}
|
||||
/>
|
||||
) : null
|
||||
}
|
||||
componentsProps={{
|
||||
tooltip: {
|
||||
|
||||
@@ -165,11 +165,8 @@ export const PlanetTableRow = ({
|
||||
}
|
||||
}}
|
||||
onClick={(e) => {
|
||||
// Only trigger if clicking a cell with the clickable-cell class
|
||||
if (!(e.target as HTMLElement).closest('.clickable-cell')) return;
|
||||
if (extractors.length > 0) {
|
||||
setSimulationOpen(!simulationOpen);
|
||||
}
|
||||
setSimulationOpen(!simulationOpen);
|
||||
}}
|
||||
>
|
||||
<TableCell component="th" scope="row" className="clickable-cell">
|
||||
@@ -190,17 +187,19 @@ export const PlanetTableRow = ({
|
||||
<Tooltip
|
||||
placement="right"
|
||||
title={
|
||||
<ExtractionSimulationTooltip
|
||||
extractors={extractors
|
||||
.filter(e => e.extractor_details?.product_type_id && e.extractor_details?.qty_per_cycle)
|
||||
.map(e => ({
|
||||
typeId: e.extractor_details!.product_type_id!,
|
||||
baseValue: e.extractor_details!.qty_per_cycle!,
|
||||
cycleTime: e.extractor_details!.cycle_time || 3600,
|
||||
installTime: e.install_time ?? "",
|
||||
expiryTime: e.expiry_time ?? ""
|
||||
}))}
|
||||
/>
|
||||
extractors.length > 0 ? (
|
||||
<ExtractionSimulationTooltip
|
||||
extractors={extractors
|
||||
.filter(e => e.extractor_details?.product_type_id && e.extractor_details?.qty_per_cycle)
|
||||
.map(e => ({
|
||||
typeId: e.extractor_details!.product_type_id!,
|
||||
baseValue: e.extractor_details!.qty_per_cycle!,
|
||||
cycleTime: e.extractor_details!.cycle_time || 3600,
|
||||
installTime: e.install_time ?? "",
|
||||
expiryTime: e.expiry_time ?? ""
|
||||
}))}
|
||||
/>
|
||||
) : null
|
||||
}
|
||||
componentsProps={{
|
||||
tooltip: {
|
||||
@@ -291,7 +290,7 @@ export const PlanetTableRow = ({
|
||||
key={`import-${character.character.characterId}-${planet.planet_id}-${i.type_id}`}
|
||||
fontSize={theme.custom.smallText}
|
||||
>
|
||||
{PI_TYPES_MAP[i.type_id].name} ({i.quantity}/h)
|
||||
{PI_TYPES_MAP[i.type_id].name} ({i.quantity * i.factoryCount}/h)
|
||||
</Typography>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -51,18 +51,22 @@ export const Summary = ({ characters }: { characters: AccessToken[] }) => {
|
||||
const [sortDirection, setSortDirection] = useState<SortDirection>("asc");
|
||||
const [sortBy, setSortBy] = useState<SortBy>("name");
|
||||
const [startDate, setStartDate] = useState<string>(DateTime.now().startOf('day').toISO());
|
||||
const [activityPercentage, setActivityPercentage] = useState<number>(() => {
|
||||
const saved = localStorage.getItem('activityPercentage');
|
||||
return saved ? parseFloat(saved) : 100;
|
||||
});
|
||||
const [activityPercentage, setActivityPercentage] = useState<number>(100);
|
||||
|
||||
// Load saved values from localStorage on mount
|
||||
useEffect(() => {
|
||||
const savedDate = localStorage.getItem('productionStartDate');
|
||||
if (savedDate) {
|
||||
setStartDate(savedDate);
|
||||
}
|
||||
|
||||
const savedActivity = localStorage.getItem('activityPercentage');
|
||||
if (savedActivity) {
|
||||
setActivityPercentage(parseFloat(savedActivity));
|
||||
}
|
||||
}, []);
|
||||
|
||||
// Save values to localStorage when they change
|
||||
useEffect(() => {
|
||||
localStorage.setItem('productionStartDate', startDate);
|
||||
}, [startDate]);
|
||||
|
||||
@@ -94,7 +94,13 @@ export const planetCalculations = (planet: PlanetWithInfo) => {
|
||||
![...locallyProduced, ...locallyExcavated].some(
|
||||
(lp) => lp === p.type_id,
|
||||
),
|
||||
);
|
||||
).map((p) => ({
|
||||
...p,
|
||||
factoryCount: planetInfo.pins
|
||||
.filter((f) => f.schematic_id === p.schematic_id)
|
||||
.length,
|
||||
}));
|
||||
|
||||
|
||||
const localExports = locallyProduced
|
||||
.filter((p) => !locallyConsumed.some((lp) => lp === p))
|
||||
|
||||
Reference in New Issue
Block a user