import { ColorContext, SessionContext } from "@/app/context/Context"; import { PI_TYPES_MAP, STORAGE_IDS, STORAGE_CAPACITIES, PI_PRODUCT_VOLUMES } from "@/const"; import { planetCalculations } from "@/planets"; import { AccessToken, PlanetWithInfo } from "@/types"; import CloseIcon from "@mui/icons-material/Close"; import MoreVertIcon from '@mui/icons-material/MoreVert'; import { Button, Tooltip, Typography, useTheme, Menu, MenuItem, IconButton, Checkbox, FormControlLabel } from "@mui/material"; import AppBar from "@mui/material/AppBar"; import Dialog from "@mui/material/Dialog"; import Slide from "@mui/material/Slide"; import TableCell from "@mui/material/TableCell"; import TableRow from "@mui/material/TableRow"; import Toolbar from "@mui/material/Toolbar"; import { TransitionProps } from "@mui/material/transitions"; import { DateTime } from "luxon"; import Image from "next/image"; import React, { forwardRef, useContext, useState } from "react"; import Countdown from "react-countdown"; import { PlanetConfigDialog } from "../PlanetConfig/PlanetConfigDialog"; import PinsCanvas3D from "./PinsCanvas3D"; import { alertModeVisibility, timeColor } from "./timeColors"; import { ExtractionSimulationDisplay } from './ExtractionSimulationDisplay'; import { ExtractionSimulationTooltip } from './ExtractionSimulationTooltip'; import { ProductionNode } from './ExtractionSimulation'; import { Collapse, Box, Stack } from "@mui/material"; import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; import ExpandLessIcon from '@mui/icons-material/ExpandLess'; const Transition = forwardRef(function Transition( props: TransitionProps & { children: React.ReactElement; }, ref: React.Ref, ) { return ; }); export const PlanetTableRow = ({ planet, character, }: { planet: PlanetWithInfo; character: AccessToken; }) => { const theme = useTheme(); const [planetRenderOpen, setPlanetRenderOpen] = useState(false); const [planetConfigOpen, setPlanetConfigOpen] = useState(false); const [simulationOpen, setSimulationOpen] = useState(false); const [menuAnchorEl, setMenuAnchorEl] = useState(null); const handleMenuOpen = (event: React.MouseEvent) => { setMenuAnchorEl(event.currentTarget); }; const handleMenuClose = () => { setMenuAnchorEl(null); }; const handle3DrenderOpen = () => { setPlanetRenderOpen(true); }; const handle3DrenderClose = () => { setPlanetRenderOpen(false); }; const handlePlanetConfigOpen = () => { setPlanetConfigOpen(true); }; const handlePlanetConfigClose = () => { setPlanetConfigOpen(false); }; const { piPrices, alertMode, updatePlanetConfig, readPlanetConfig } = useContext(SessionContext); const planetInfo = planet.info; const planetInfoUniverse = planet.infoUniverse; const { expired, extractors, localProduction, localImports, localExports } = planetCalculations(planet); const planetConfig = readPlanetConfig({ characterId: character.character.characterId, planetId: planet.planet_id, }); const { colors } = useContext(ColorContext); // Convert local production to ProductionNode array for simulation const productionNodes: ProductionNode[] = Array.from(localProduction).map(([schematicId, schematic]) => ({ schematicId: schematicId, typeId: schematic.outputs[0].type_id, name: schematic.name, inputs: schematic.inputs.map(input => ({ typeId: input.type_id, quantity: input.quantity })), outputs: schematic.outputs.map(output => ({ typeId: output.type_id, quantity: output.quantity })), cycleTime: schematic.cycle_time, factoryCount: schematic.count || 1 })); const storageFacilities = planetInfo.pins.filter(pin => STORAGE_IDS().some(storage => storage.type_id === pin.type_id) ); const getStorageInfo = (pin: any) => { if (!pin || !pin.contents) return null; const storageType = PI_TYPES_MAP[pin.type_id].name; const storageCapacity = STORAGE_CAPACITIES[pin.type_id] || 0; 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, value: totalValue }; }; const handleExcludeChange = (event: React.ChangeEvent) => { updatePlanetConfig({ ...planetConfig, excludeFromTotals: event.target.checked, }); }; return ( <>
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 ?? "" }))} /> } componentsProps={{ tooltip: { sx: { bgcolor: 'background.paper', '& .MuiTooltip-arrow': { color: 'background.paper', }, maxWidth: 'none', width: 'fit-content' } } }} > {planetInfoUniverse?.name}
{planet.upgrade_level}
{extractors.map((e, idx) => { return (
{e ? ( ) : ( "STOPPED" )} { PI_TYPES_MAP[e.extractor_details?.product_type_id ?? 0] ?.name }
); })}
{Array.from(localProduction).map((schematic, idx) => { return ( {schematic[1].name} ); })}
{localImports.map((i) => ( {PI_TYPES_MAP[i.type_id].name} ({i.quantity}/h) ))}
{localExports.map((exports) => ( {PI_TYPES_MAP[exports.typeId].name} ))}
{localExports.map((exports) => ( } label="" /> ))}
{localExports.map((exports) => ( {exports.amount} ))}
{localExports.map((e) => { const valueInMillions = (((piPrices?.appraisal.items.find((a) => a.typeID === e.typeId) ?.prices.sell.min ?? 0) * e.amount) / 1000000) * 24 * 30; const displayValue = valueInMillions >= 1000 ? `${(valueInMillions / 1000).toFixed(2)} B` : `${valueInMillions.toFixed(2)} M`; return ( {displayValue} ); })}
{storageFacilities .sort((a, b) => { const isALaunchpad = a.type_id === 2256 || a.type_id === 2542 || a.type_id === 2543 || a.type_id === 2544 || a.type_id === 2552 || a.type_id === 2555 || a.type_id === 2556 || a.type_id === 2557; const isBLaunchpad = b.type_id === 2256 || b.type_id === 2542 || b.type_id === 2543 || b.type_id === 2544 || b.type_id === 2552 || b.type_id === 2555 || b.type_id === 2556 || b.type_id === 2557; return isALaunchpad === isBLaunchpad ? 0 : isALaunchpad ? -1 : 1; }) .map((storage) => { const storageInfo = getStorageInfo(storage); if (!storageInfo) return null; const isLaunchpad = storage.type_id === 2256 || storage.type_id === 2542 || storage.type_id === 2543 || storage.type_id === 2544 || storage.type_id === 2552 || storage.type_id === 2555 || storage.type_id === 2556 || storage.type_id === 2557; const fillRate = storageInfo.fillRate; const color = fillRate > 95 ? '#ff0000' : fillRate > 80 ? '#ffd700' : 'inherit'; return (
{isLaunchpad ? 'L' : 'S'} {fillRate.toFixed(1)}% {storageInfo.value > 0 && ( ({Math.round(storageInfo.value / 1000000)}M) )}
); })}
{ handlePlanetConfigOpen(); handleMenuClose(); }}> Configure Planet {extractors.length > 0 && ( { setSimulationOpen(!simulationOpen); handleMenuClose(); }}> {simulationOpen ? 'Hide Extraction Simulation' : 'Show Extraction Simulation'} )} { handle3DrenderOpen(); handleMenuClose(); }}> Show 3D View
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 ?? "" }))} /> } componentsProps={{ tooltip: { sx: { bgcolor: 'background.paper', '& .MuiTooltip-arrow': { color: 'background.paper', }, } } }} >
{planetInfoUniverse?.name}
{planetInfoUniverse?.name} Planet configuration: {planetInfoUniverse?.name} ); };