Planet config dialog
This commit is contained in:
211
src/app/components/PlanetConfig/PlanetConfigDialog.tsx
Normal file
211
src/app/components/PlanetConfig/PlanetConfigDialog.tsx
Normal file
@@ -0,0 +1,211 @@
|
||||
import { PI_TYPES_MAP } from "@/const";
|
||||
import { planetCalculations } from "@/planets";
|
||||
import { AccessToken, PlanetWithInfo } from "@/types";
|
||||
import {
|
||||
Card,
|
||||
Checkbox,
|
||||
FormControlLabel,
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableRow,
|
||||
Tooltip,
|
||||
Typography,
|
||||
useTheme,
|
||||
} from "@mui/material";
|
||||
import { DateTime } from "luxon";
|
||||
import Countdown from "react-countdown";
|
||||
import { timeColor } from "../PlanetaryInteraction/timeColors";
|
||||
import Image from "next/image";
|
||||
import { ColorContext, SessionContext } from "@/app/context/Context";
|
||||
import { useContext } from "react";
|
||||
|
||||
export type PlanetConfig = {
|
||||
characterId: number;
|
||||
planetId: number;
|
||||
excludeFromTotals: boolean;
|
||||
};
|
||||
|
||||
export const PlanetConfigDialog = ({
|
||||
planet,
|
||||
character,
|
||||
}: {
|
||||
planet: PlanetWithInfo;
|
||||
character: AccessToken;
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
const { colors } = useContext(ColorContext);
|
||||
const { piPrices, readPlanetConfig, updatePlanetConfig } =
|
||||
useContext(SessionContext);
|
||||
const { extractors, localProduction, localImports, localExports } =
|
||||
planetCalculations(planet);
|
||||
const planetConfig = readPlanetConfig({
|
||||
characterId: character.character.characterId,
|
||||
planetId: planet.planet_id,
|
||||
});
|
||||
|
||||
return (
|
||||
<Card style={{ padding: "1rem", margin: "1rem" }}>
|
||||
<Table>
|
||||
<TableBody>
|
||||
<TableRow>
|
||||
<TableCell scope="row">
|
||||
<Tooltip
|
||||
title={`${
|
||||
planet.planet_type.charAt(0).toUpperCase() +
|
||||
planet.planet_type.slice(1)
|
||||
} planet.`}
|
||||
>
|
||||
<div style={{ display: "flex", minWidth: "8em" }}>
|
||||
<Image
|
||||
src={`/${planet.planet_type}.png`}
|
||||
alt=""
|
||||
width={theme.custom.cardImageSize / 6}
|
||||
height={theme.custom.cardImageSize / 6}
|
||||
style={{ marginRight: "5px" }}
|
||||
/>
|
||||
{planet.infoUniverse?.name}
|
||||
</div>
|
||||
</Tooltip>
|
||||
</TableCell>
|
||||
<TableCell>{planet.upgrade_level}</TableCell>
|
||||
<TableCell>
|
||||
<div style={{ display: "flex", flexDirection: "column" }}>
|
||||
{extractors.map((e, idx) => {
|
||||
return (
|
||||
<div key={`${e}-${idx}`} style={{ display: "flex" }}>
|
||||
<Typography
|
||||
color={timeColor(e.expiry_time, colors)}
|
||||
fontSize={theme.custom.smallText}
|
||||
paddingRight={1}
|
||||
>
|
||||
{e ? (
|
||||
<Countdown
|
||||
overtime={true}
|
||||
date={DateTime.fromISO(
|
||||
e.expiry_time ?? "",
|
||||
).toMillis()}
|
||||
/>
|
||||
) : (
|
||||
"STOPPED"
|
||||
)}
|
||||
</Typography>
|
||||
<Typography fontSize={theme.custom.smallText}>
|
||||
{
|
||||
PI_TYPES_MAP[
|
||||
e.extractor_details?.product_type_id ?? 0
|
||||
]?.name
|
||||
}
|
||||
</Typography>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<div style={{ display: "flex", flexDirection: "column" }}>
|
||||
{Array.from(localProduction).map((schematic, idx) => {
|
||||
return (
|
||||
<Typography
|
||||
key={`prod-${planet.planet_id}-${idx}`}
|
||||
fontSize={theme.custom.smallText}
|
||||
>
|
||||
{schematic[1].name}
|
||||
</Typography>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<div style={{ display: "flex", flexDirection: "column" }}>
|
||||
{localImports.map((i) => (
|
||||
<Typography
|
||||
key={`import-${planet.planet_id}-${i.type_id}`}
|
||||
fontSize={theme.custom.smallText}
|
||||
>
|
||||
{PI_TYPES_MAP[i.type_id].name}
|
||||
</Typography>
|
||||
))}
|
||||
</div>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<div style={{ display: "flex", flexDirection: "column" }}>
|
||||
{localExports.map((exports) => (
|
||||
<Typography
|
||||
key={`export-${planet.planet_id}-${exports.typeId}`}
|
||||
fontSize={theme.custom.smallText}
|
||||
>
|
||||
{PI_TYPES_MAP[exports.typeId].name}
|
||||
</Typography>
|
||||
))}
|
||||
</div>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<div style={{ display: "flex", flexDirection: "column" }}>
|
||||
{localExports.map((exports) => (
|
||||
<Typography
|
||||
key={`export-uph-${exports.typeId}`}
|
||||
fontSize={theme.custom.smallText}
|
||||
>
|
||||
{exports.amount}
|
||||
</Typography>
|
||||
))}
|
||||
</div>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
minWidth: "4em",
|
||||
textAlign: "end",
|
||||
}}
|
||||
>
|
||||
{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 (
|
||||
<Typography
|
||||
key={`export-praisal-${planet.planet_id}-${e.typeId}`}
|
||||
fontSize={theme.custom.smallText}
|
||||
>
|
||||
{displayValue}
|
||||
</Typography>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
<Card style={{ marginTop: "1rem" }}>
|
||||
<Typography>Planet configuration</Typography>
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Checkbox
|
||||
checked={planetConfig.excludeFromTotals}
|
||||
onChange={() =>
|
||||
updatePlanetConfig({
|
||||
...planetConfig,
|
||||
excludeFromTotals: !planetConfig.excludeFromTotals,
|
||||
})
|
||||
}
|
||||
/>
|
||||
}
|
||||
label="Consumed by production chain"
|
||||
/>
|
||||
</Card>
|
||||
</Card>
|
||||
);
|
||||
};
|
@@ -18,6 +18,7 @@ import React, { forwardRef, useContext, useState } from "react";
|
||||
import Countdown from "react-countdown";
|
||||
import PinsCanvas3D from "./PinsCanvas3D";
|
||||
import { timeColor, alertModeVisibility } from "./timeColors";
|
||||
import { PlanetConfigDialog } from "../PlanetConfig/PlanetConfigDialog";
|
||||
|
||||
const Transition = forwardRef(function Transition(
|
||||
props: TransitionProps & {
|
||||
@@ -38,6 +39,7 @@ export const PlanetTableRow = ({
|
||||
const theme = useTheme();
|
||||
|
||||
const [planetRenderOpen, setPlanetRenderOpen] = useState(false);
|
||||
const [planetConfigOpen, setPlanetConfigOpen] = useState(false);
|
||||
|
||||
const handle3DrenderOpen = () => {
|
||||
setPlanetRenderOpen(true);
|
||||
@@ -47,6 +49,14 @@ export const PlanetTableRow = ({
|
||||
setPlanetRenderOpen(false);
|
||||
};
|
||||
|
||||
const handlePlanetConfigOpen = () => {
|
||||
setPlanetConfigOpen(true);
|
||||
};
|
||||
|
||||
const handlePlanetConfigClose = () => {
|
||||
setPlanetConfigOpen(false);
|
||||
};
|
||||
|
||||
const { piPrices, alertMode } = useContext(SessionContext);
|
||||
const planetInfo = planet.info;
|
||||
const planetInfoUniverse = planet.infoUniverse;
|
||||
@@ -194,6 +204,14 @@ export const PlanetTableRow = ({
|
||||
})}
|
||||
</div>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Tooltip title="Open planet configuration">
|
||||
<Button variant="contained" onClick={handlePlanetConfigOpen}>
|
||||
Config
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</TableCell>
|
||||
|
||||
<TableCell>
|
||||
<Tooltip title="Open 3D render of this planet">
|
||||
<Button variant="contained" onClick={handle3DrenderOpen}>
|
||||
@@ -227,6 +245,32 @@ export const PlanetTableRow = ({
|
||||
</AppBar>
|
||||
<PinsCanvas3D planetInfo={planetInfo} />
|
||||
</Dialog>
|
||||
<Dialog
|
||||
fullScreen
|
||||
open={planetConfigOpen}
|
||||
onClose={handlePlanetConfigClose}
|
||||
TransitionComponent={Transition}
|
||||
>
|
||||
<AppBar sx={{ position: "relative" }}>
|
||||
<Toolbar>
|
||||
<IconButton
|
||||
edge="start"
|
||||
color="inherit"
|
||||
onClick={handlePlanetConfigClose}
|
||||
aria-label="close"
|
||||
>
|
||||
<CloseIcon />
|
||||
</IconButton>
|
||||
<Typography sx={{ ml: 2, flex: 1 }} variant="h6" component="div">
|
||||
Planet configuration: {planetInfoUniverse?.name}
|
||||
</Typography>
|
||||
<Button autoFocus color="inherit" onClick={handlePlanetConfigClose}>
|
||||
Close
|
||||
</Button>
|
||||
</Toolbar>
|
||||
</AppBar>
|
||||
<PlanetConfigDialog planet={planet} character={character} />
|
||||
</Dialog>
|
||||
</TableRow>
|
||||
);
|
||||
};
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import { EvePraisalResult } from "@/eve-praisal";
|
||||
import { AccessToken, CharacterUpdate } from "@/types";
|
||||
import { Dispatch, SetStateAction, createContext } from "react";
|
||||
import { PlanetConfig } from "../components/PlanetConfig/PlanetConfigDialog";
|
||||
|
||||
export const CharacterContext = createContext<{
|
||||
characters: AccessToken[];
|
||||
@@ -27,6 +28,14 @@ export const SessionContext = createContext<{
|
||||
alertMode: boolean;
|
||||
toggleAlertMode: () => void;
|
||||
piPrices: EvePraisalResult | undefined;
|
||||
updatePlanetConfig: (config: PlanetConfig) => void;
|
||||
readPlanetConfig: ({
|
||||
characterId,
|
||||
planetId,
|
||||
}: {
|
||||
characterId: number;
|
||||
planetId: number;
|
||||
}) => PlanetConfig;
|
||||
}>({
|
||||
sessionReady: false,
|
||||
refreshSession: () => {},
|
||||
@@ -40,6 +49,16 @@ export const SessionContext = createContext<{
|
||||
alertMode: false,
|
||||
toggleAlertMode: () => {},
|
||||
piPrices: undefined,
|
||||
updatePlanetConfig: () => {},
|
||||
readPlanetConfig: ({
|
||||
planetId,
|
||||
characterId,
|
||||
}: {
|
||||
planetId: number;
|
||||
characterId: number;
|
||||
}) => {
|
||||
return { characterId, planetId, excludeFromTotals: true };
|
||||
},
|
||||
});
|
||||
export type ColorSelectionType = {
|
||||
defaultColor: string;
|
||||
|
@@ -17,6 +17,7 @@ import {
|
||||
import { useSearchParams } from "next/navigation";
|
||||
import { EvePraisalResult, fetchAllPrices } from "@/eve-praisal";
|
||||
import { getPlanet, getPlanetUniverse, getPlanets } from "@/planets";
|
||||
import { PlanetConfig } from "./components/PlanetConfig/PlanetConfigDialog";
|
||||
|
||||
const Home = () => {
|
||||
const [characters, setCharacters] = useState<AccessToken[]>([]);
|
||||
@@ -27,6 +28,7 @@ const Home = () => {
|
||||
const [piPrices, setPiPrices] = useState<EvePraisalResult | undefined>(
|
||||
undefined,
|
||||
);
|
||||
|
||||
const [colors, setColors] = useState<ColorSelectionType>(defaultColors);
|
||||
const [alertMode, setAlertMode] = useState(false);
|
||||
const searchParams = useSearchParams();
|
||||
@@ -126,6 +128,22 @@ const Home = () => {
|
||||
setAlertMode(!alertMode);
|
||||
};
|
||||
|
||||
const updatePlanetConfig = (config: PlanetConfig) => {
|
||||
console.log("poop");
|
||||
};
|
||||
|
||||
const readPlanetConfig = ({
|
||||
planetId,
|
||||
characterId,
|
||||
}: {
|
||||
planetId: number;
|
||||
characterId: number;
|
||||
}): PlanetConfig => {
|
||||
const defaultConfig = { planetId, characterId, excludeFromTotals: false };
|
||||
|
||||
return defaultConfig;
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const storedCompactMode = localStorage.getItem("compactMode");
|
||||
if (!storedCompactMode) return;
|
||||
@@ -156,7 +174,6 @@ const Home = () => {
|
||||
localStorage.setItem("colors", JSON.stringify(colors));
|
||||
}, [colors]);
|
||||
|
||||
// Initialize EVE PI
|
||||
useEffect(() => {
|
||||
fetch("api/env")
|
||||
.then((r) => r.json())
|
||||
@@ -207,6 +224,8 @@ const Home = () => {
|
||||
piPrices,
|
||||
alertMode,
|
||||
toggleAlertMode,
|
||||
updatePlanetConfig,
|
||||
readPlanetConfig,
|
||||
}}
|
||||
>
|
||||
<CharacterContext.Provider
|
||||
|
Reference in New Issue
Block a user