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 Countdown from "react-countdown";
|
||||||
import PinsCanvas3D from "./PinsCanvas3D";
|
import PinsCanvas3D from "./PinsCanvas3D";
|
||||||
import { timeColor, alertModeVisibility } from "./timeColors";
|
import { timeColor, alertModeVisibility } from "./timeColors";
|
||||||
|
import { PlanetConfigDialog } from "../PlanetConfig/PlanetConfigDialog";
|
||||||
|
|
||||||
const Transition = forwardRef(function Transition(
|
const Transition = forwardRef(function Transition(
|
||||||
props: TransitionProps & {
|
props: TransitionProps & {
|
||||||
@@ -38,6 +39,7 @@ export const PlanetTableRow = ({
|
|||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
const [planetRenderOpen, setPlanetRenderOpen] = useState(false);
|
const [planetRenderOpen, setPlanetRenderOpen] = useState(false);
|
||||||
|
const [planetConfigOpen, setPlanetConfigOpen] = useState(false);
|
||||||
|
|
||||||
const handle3DrenderOpen = () => {
|
const handle3DrenderOpen = () => {
|
||||||
setPlanetRenderOpen(true);
|
setPlanetRenderOpen(true);
|
||||||
@@ -47,6 +49,14 @@ export const PlanetTableRow = ({
|
|||||||
setPlanetRenderOpen(false);
|
setPlanetRenderOpen(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handlePlanetConfigOpen = () => {
|
||||||
|
setPlanetConfigOpen(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handlePlanetConfigClose = () => {
|
||||||
|
setPlanetConfigOpen(false);
|
||||||
|
};
|
||||||
|
|
||||||
const { piPrices, alertMode } = useContext(SessionContext);
|
const { piPrices, alertMode } = useContext(SessionContext);
|
||||||
const planetInfo = planet.info;
|
const planetInfo = planet.info;
|
||||||
const planetInfoUniverse = planet.infoUniverse;
|
const planetInfoUniverse = planet.infoUniverse;
|
||||||
@@ -194,6 +204,14 @@ export const PlanetTableRow = ({
|
|||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
<Tooltip title="Open planet configuration">
|
||||||
|
<Button variant="contained" onClick={handlePlanetConfigOpen}>
|
||||||
|
Config
|
||||||
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
|
</TableCell>
|
||||||
|
|
||||||
<TableCell>
|
<TableCell>
|
||||||
<Tooltip title="Open 3D render of this planet">
|
<Tooltip title="Open 3D render of this planet">
|
||||||
<Button variant="contained" onClick={handle3DrenderOpen}>
|
<Button variant="contained" onClick={handle3DrenderOpen}>
|
||||||
@@ -227,6 +245,32 @@ export const PlanetTableRow = ({
|
|||||||
</AppBar>
|
</AppBar>
|
||||||
<PinsCanvas3D planetInfo={planetInfo} />
|
<PinsCanvas3D planetInfo={planetInfo} />
|
||||||
</Dialog>
|
</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>
|
</TableRow>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
import { EvePraisalResult } from "@/eve-praisal";
|
import { EvePraisalResult } from "@/eve-praisal";
|
||||||
import { AccessToken, CharacterUpdate } from "@/types";
|
import { AccessToken, CharacterUpdate } from "@/types";
|
||||||
import { Dispatch, SetStateAction, createContext } from "react";
|
import { Dispatch, SetStateAction, createContext } from "react";
|
||||||
|
import { PlanetConfig } from "../components/PlanetConfig/PlanetConfigDialog";
|
||||||
|
|
||||||
export const CharacterContext = createContext<{
|
export const CharacterContext = createContext<{
|
||||||
characters: AccessToken[];
|
characters: AccessToken[];
|
||||||
@@ -27,6 +28,14 @@ export const SessionContext = createContext<{
|
|||||||
alertMode: boolean;
|
alertMode: boolean;
|
||||||
toggleAlertMode: () => void;
|
toggleAlertMode: () => void;
|
||||||
piPrices: EvePraisalResult | undefined;
|
piPrices: EvePraisalResult | undefined;
|
||||||
|
updatePlanetConfig: (config: PlanetConfig) => void;
|
||||||
|
readPlanetConfig: ({
|
||||||
|
characterId,
|
||||||
|
planetId,
|
||||||
|
}: {
|
||||||
|
characterId: number;
|
||||||
|
planetId: number;
|
||||||
|
}) => PlanetConfig;
|
||||||
}>({
|
}>({
|
||||||
sessionReady: false,
|
sessionReady: false,
|
||||||
refreshSession: () => {},
|
refreshSession: () => {},
|
||||||
@@ -40,6 +49,16 @@ export const SessionContext = createContext<{
|
|||||||
alertMode: false,
|
alertMode: false,
|
||||||
toggleAlertMode: () => {},
|
toggleAlertMode: () => {},
|
||||||
piPrices: undefined,
|
piPrices: undefined,
|
||||||
|
updatePlanetConfig: () => {},
|
||||||
|
readPlanetConfig: ({
|
||||||
|
planetId,
|
||||||
|
characterId,
|
||||||
|
}: {
|
||||||
|
planetId: number;
|
||||||
|
characterId: number;
|
||||||
|
}) => {
|
||||||
|
return { characterId, planetId, excludeFromTotals: true };
|
||||||
|
},
|
||||||
});
|
});
|
||||||
export type ColorSelectionType = {
|
export type ColorSelectionType = {
|
||||||
defaultColor: string;
|
defaultColor: string;
|
||||||
|
@@ -17,6 +17,7 @@ import {
|
|||||||
import { useSearchParams } from "next/navigation";
|
import { useSearchParams } from "next/navigation";
|
||||||
import { EvePraisalResult, fetchAllPrices } from "@/eve-praisal";
|
import { EvePraisalResult, fetchAllPrices } from "@/eve-praisal";
|
||||||
import { getPlanet, getPlanetUniverse, getPlanets } from "@/planets";
|
import { getPlanet, getPlanetUniverse, getPlanets } from "@/planets";
|
||||||
|
import { PlanetConfig } from "./components/PlanetConfig/PlanetConfigDialog";
|
||||||
|
|
||||||
const Home = () => {
|
const Home = () => {
|
||||||
const [characters, setCharacters] = useState<AccessToken[]>([]);
|
const [characters, setCharacters] = useState<AccessToken[]>([]);
|
||||||
@@ -27,6 +28,7 @@ const Home = () => {
|
|||||||
const [piPrices, setPiPrices] = useState<EvePraisalResult | undefined>(
|
const [piPrices, setPiPrices] = useState<EvePraisalResult | undefined>(
|
||||||
undefined,
|
undefined,
|
||||||
);
|
);
|
||||||
|
|
||||||
const [colors, setColors] = useState<ColorSelectionType>(defaultColors);
|
const [colors, setColors] = useState<ColorSelectionType>(defaultColors);
|
||||||
const [alertMode, setAlertMode] = useState(false);
|
const [alertMode, setAlertMode] = useState(false);
|
||||||
const searchParams = useSearchParams();
|
const searchParams = useSearchParams();
|
||||||
@@ -126,6 +128,22 @@ const Home = () => {
|
|||||||
setAlertMode(!alertMode);
|
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(() => {
|
useEffect(() => {
|
||||||
const storedCompactMode = localStorage.getItem("compactMode");
|
const storedCompactMode = localStorage.getItem("compactMode");
|
||||||
if (!storedCompactMode) return;
|
if (!storedCompactMode) return;
|
||||||
@@ -156,7 +174,6 @@ const Home = () => {
|
|||||||
localStorage.setItem("colors", JSON.stringify(colors));
|
localStorage.setItem("colors", JSON.stringify(colors));
|
||||||
}, [colors]);
|
}, [colors]);
|
||||||
|
|
||||||
// Initialize EVE PI
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetch("api/env")
|
fetch("api/env")
|
||||||
.then((r) => r.json())
|
.then((r) => r.json())
|
||||||
@@ -207,6 +224,8 @@ const Home = () => {
|
|||||||
piPrices,
|
piPrices,
|
||||||
alertMode,
|
alertMode,
|
||||||
toggleAlertMode,
|
toggleAlertMode,
|
||||||
|
updatePlanetConfig,
|
||||||
|
readPlanetConfig,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<CharacterContext.Provider
|
<CharacterContext.Provider
|
||||||
|
Reference in New Issue
Block a user