mui-fy some modals

This commit is contained in:
Olivier Gagnon 2021-09-30 20:06:40 -04:00
parent f701cbffa7
commit 0d9caac455
31 changed files with 348 additions and 331 deletions

@ -0,0 +1,32 @@
import React from "react";
import { Company } from "../Company";
import { use } from "../../ui/Context";
import { Modal } from "../../ui/React/Modal";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
interface IProps {
open: boolean;
onClose: () => void;
locName: string;
company: Company;
onQuit: () => void;
}
export function QuitJobModal(props: IProps): React.ReactElement {
const player = use.Player();
function quit(): void {
player.quitJob(props.locName);
props.onQuit();
props.onClose();
}
return (
<Modal open={props.open} onClose={props.onClose}>
<Typography> Would you like to quit your job at {props.company.name}?</Typography>
<br />
<br />
<Button onClick={quit}>Quit</Button>
</Modal>
);
}

@ -1,31 +0,0 @@
import React from "react";
import { Company } from "../Company";
import { IPlayer } from "../../PersonObjects/IPlayer";
import { removePopup } from "../../ui/React/createPopup";
interface IProps {
locName: string;
company: Company;
player: IPlayer;
onQuit: () => void;
popupId: string;
}
export function QuitJobPopup(props: IProps): React.ReactElement {
function quit(): void {
props.player.quitJob(props.locName);
props.onQuit();
removePopup(props.popupId);
}
return (
<>
Would you like to quit your job at {props.company.name}?
<br />
<br />
<button autoFocus={true} className="std-button" onClick={quit}>
Quit
</button>
</>
);
}

@ -3,6 +3,8 @@ import React from "react";
import { Product } from "../Product";
import { Modal } from "../../ui/React/Modal";
import { useDivision } from "./Context";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
interface IProps {
open: boolean;
@ -22,13 +24,11 @@ export function DiscontinueProductModal(props: IProps): React.ReactElement {
return (
<Modal open={props.open} onClose={props.onClose}>
<p>
<Typography>
Are you sure you want to do this? Discontinuing a product removes it completely and permanently. You will no
longer produce this product and all of its existing stock will be removed and left unsold
</p>
<button className="popup-box-button" onClick={discontinue}>
Discontinue
</button>
</Typography>
<Button onClick={discontinue}>Discontinue</Button>
</Modal>
);
}

@ -19,11 +19,9 @@ export function IndustryProductEquation(props: IProps): React.ReactElement {
}
return (
<span className="text">
<MathComponent
display={false}
tex={reqs.join("+") + String.raw`\Rightarrow` + prod.map((p) => String.raw`1\text{ }${p}`).join("+")}
/>
</span>
<MathComponent
display={false}
tex={reqs.join("+") + String.raw`\Rightarrow` + prod.map((p) => String.raw`1\text{ }${p}`).join("+")}
/>
);
}

@ -2,6 +2,9 @@ import React, { useState } from "react";
import { Product } from "../Product";
import { LimitProductProduction } from "../Actions";
import { Modal } from "../../ui/React/Modal";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
import TextField from "@mui/material/TextField";
interface IProps {
open: boolean;
@ -32,26 +35,12 @@ export function LimitProductProductionModal(props: IProps): React.ReactElement {
return (
<Modal open={props.open} onClose={props.onClose}>
<p>
<Typography>
Enter a limit to the amount of this product you would like to product per second. Leave the box empty to set no
limit.
</p>
<input
autoFocus={true}
className="text-input"
style={{ margin: "5px" }}
placeholder="Limit"
type="number"
onChange={onChange}
onKeyDown={onKeyDown}
/>
<button
className="std-button"
style={{ margin: "5px", display: "inline-block" }}
onClick={limitProductProduction}
>
Limit production
</button>
</Typography>
<TextField autoFocus={true} placeholder="Limit" type="number" onChange={onChange} onKeyDown={onKeyDown} />
<Button onClick={limitProductProduction}>Limit production</Button>
</Modal>
);
}

@ -3,12 +3,19 @@ import { numeralWrapper } from "../../ui/numeralFormat";
import { Product } from "../Product";
import { Modal } from "../../ui/React/Modal";
import { useDivision } from "./Context";
import Typography from "@mui/material/Typography";
import TextField from "@mui/material/TextField";
import FormControlLabel from "@mui/material/FormControlLabel";
import Switch from "@mui/material/Switch";
import Tooltip from "@mui/material/Tooltip";
interface ITa2Props {
product: Product;
}
function MarketTA2(props: ITa2Props): React.ReactElement {
const division = useDivision();
if (!division.hasResearch("Market-TA.II")) return <></>;
const markupLimit = props.product.rat / props.product.mku;
const [value, setValue] = useState(props.product.pCost);
const setRerender = useState(false)[1];
@ -35,38 +42,35 @@ function MarketTA2(props: ITa2Props): React.ReactElement {
return (
<>
<p>
<br />
<u>
<strong>Market-TA.II</strong>
</u>
<br />
<Typography variant="h4">Market-TA.II</Typography>
<br />
<Typography>
If you sell at {numeralWrapper.formatMoney(sCost)}, then you will sell{" "}
{numeralWrapper.format(markup, "0.00000")}x as much compared to if you sold at market price.
</p>
<input className="text-input" onChange={onChange} value={value} type="number" style={{ marginTop: "4px" }} />
<div style={{ display: "block" }}>
<label className="tooltip" htmlFor="cmpy-mgmt-marketa2-checkbox" style={{ color: "white" }}>
Use Market-TA.II for Auto-Sale Price
<span className="tooltiptext">
If this is enabled, then this Product will automatically be sold at the optimal price such that the amount
sold matches the amount produced. (i.e. the highest possible price, while still ensuring that all produced
materials will be sold).
</span>
</label>
<input
className="text-input"
onChange={onCheckedChange}
id="cmpy-mgmt-marketa2-checkbox"
style={{ margin: "3px" }}
type="checkbox"
checked={props.product.marketTa2}
/>
</div>
<p>
</Typography>
<TextField type="number" onChange={onChange} value={value} />
<br />
<FormControlLabel
control={<Switch checked={props.product.marketTa2} onChange={onCheckedChange} />}
label={
<Tooltip
title={
<Typography>
If this is enabled, then this Material will automatically be sold at the optimal price such that the
amount sold matches the amount produced. (i.e. the highest possible price, while still ensuring that all
produced materials will be sold)
</Typography>
}
>
<Typography>Use Market-TA.II for Auto-Sale Price</Typography>
</Tooltip>
}
/>
<Typography>
Note that Market-TA.II overrides Market-TA.I. This means that if both are enabled, then Market-TA.II will take
effect, not Market-TA.I
</p>
</Typography>
</>
);
}
@ -93,35 +97,30 @@ export function ProductMarketTaModal(props: IProps): React.ReactElement {
return (
<Modal open={props.open} onClose={props.onClose}>
<>
<p>
<u>
<strong>Market-TA.I</strong>
</u>
<br />
The maximum sale price you can mark this up to is{" "}
{numeralWrapper.formatMoney(props.product.pCost + markupLimit)}. This means that if you set the sale price
higher than this, you will begin to experience a loss in number of sales.
</p>
<div style={{ display: "block" }}>
<label className="tooltip" htmlFor="cmpy-mgmt-marketa1-checkbox" style={{ color: "white" }}>
Use Market-TA.I for Auto-Sale Price
<span className="tooltiptext">
If this is enabled, then this Product will automatically be sold at the price identified by Market-TA.I
(i.e. the price shown above).
</span>
</label>
<input
onChange={onChange}
className="text-input"
id="cmpy-mgmt-marketa1-checkbox"
style={{ margin: "3px" }}
type="checkbox"
checked={props.product.marketTa1}
/>
</div>
{division.hasResearch("Market-TA.II") && <MarketTA2 product={props.product} />}
</>
<Typography variant="h4">Market-TA.I</Typography>
<Typography>
The maximum sale price you can mark this up to is{" "}
{numeralWrapper.formatMoney(props.product.pCost + markupLimit)}. This means that if you set the sale price
higher than this, you will begin to experience a loss in number of sales
</Typography>
<FormControlLabel
control={<Switch checked={props.product.marketTa1} onChange={onChange} />}
label={
<Tooltip
title={
<Typography>
If this is enabled, then this Material will automatically be sold at the price identified by Market-TA.I
(i.e. the price shown above)
</Typography>
}
>
<Typography>Use Market-TA.I for Auto-Sale Price</Typography>
</Tooltip>
}
/>
<MarketTA2 product={props.product} />
</Modal>
);
}

@ -8,6 +8,7 @@ import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
import Select, { SelectChangeEvent } from "@mui/material/Select";
import { IPlayer } from "../../PersonObjects/IPlayer";
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
import Typography from "@mui/material/Typography";
import MenuItem from "@mui/material/MenuItem";
import IconButton from "@mui/material/IconButton";
import ReplyAllIcon from "@mui/icons-material/ReplyAll";
@ -49,7 +50,7 @@ export function Augmentations(props: IProps): React.ReactElement {
<tbody>
<tr>
<td>
<span className="text">Aug:</span>
<Typography>Aug:</Typography>
</td>
<td>
<Select

@ -1,5 +1,6 @@
import React from "react";
import Typography from "@mui/material/Typography";
import Accordion from "@mui/material/Accordion";
import AccordionSummary from "@mui/material/AccordionSummary";
import AccordionDetails from "@mui/material/AccordionDetails";
@ -63,7 +64,7 @@ export function Bladeburner(props: IProps): React.ReactElement {
<tbody>
<tr>
<td>
<span className="text">Rank:</span>
<Typography>Rank:</Typography>
</td>
<td>
<Adjuster
@ -78,7 +79,7 @@ export function Bladeburner(props: IProps): React.ReactElement {
</tr>
<tr>
<td>
<span className="text">Cycles:</span>
<Typography>Cycles:</Typography>
</td>
<td>
<Adjuster

@ -5,6 +5,7 @@ import AccordionSummary from "@mui/material/AccordionSummary";
import AccordionDetails from "@mui/material/AccordionDetails";
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
import Select, { SelectChangeEvent } from "@mui/material/Select";
import { Companies as AllCompanies } from "../../Company/Companies";
@ -78,7 +79,7 @@ export function Companies(): React.ReactElement {
<tbody>
<tr>
<td>
<span className="text">Company:</span>
<Typography>Company:</Typography>
</td>
<td colSpan={3}>
<Select id="dev-companies-dropdown" onChange={setCompanyDropdown} value={company}>
@ -92,7 +93,7 @@ export function Companies(): React.ReactElement {
</tr>
<tr>
<td>
<span className="text">Reputation:</span>
<Typography>Reputation:</Typography>
</td>
<td>
<Adjuster
@ -107,7 +108,7 @@ export function Companies(): React.ReactElement {
</tr>
<tr>
<td>
<span className="text">Favor:</span>
<Typography>Favor:</Typography>
</td>
<td>
<Adjuster
@ -122,7 +123,7 @@ export function Companies(): React.ReactElement {
</tr>
<tr>
<td>
<span className="text">All Reputation:</span>
<Typography>All Reputation:</Typography>
</td>
<td>
<Button onClick={tonsOfRepCompanies}>Tons</Button>
@ -131,7 +132,7 @@ export function Companies(): React.ReactElement {
</tr>
<tr>
<td>
<span className="text">All Favor:</span>
<Typography>All Favor:</Typography>
</td>
<td>
<Button onClick={tonsOfFavorCompanies}>Tons</Button>

@ -5,6 +5,7 @@ import AccordionSummary from "@mui/material/AccordionSummary";
import AccordionDetails from "@mui/material/AccordionDetails";
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
import { Adjuster } from "./Adjuster";
import { IPlayer } from "../../PersonObjects/IPlayer";
@ -82,7 +83,7 @@ export function Corporation(props: IProps): React.ReactElement {
</tr>
<tr>
<td>
<span className="text">Cycles:</span>
<Typography>Cycles:</Typography>
</td>
<td>
<Adjuster

@ -5,6 +5,7 @@ import AccordionSummary from "@mui/material/AccordionSummary";
import AccordionDetails from "@mui/material/AccordionDetails";
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
import Select, { SelectChangeEvent } from "@mui/material/Select";
import { Adjuster } from "./Adjuster";
@ -106,7 +107,7 @@ export function Factions(props: IProps): React.ReactElement {
<tbody>
<tr>
<td>
<span className="text">Faction:</span>
<Typography>Faction:</Typography>
</td>
<td>
<FormControl>
@ -138,7 +139,7 @@ export function Factions(props: IProps): React.ReactElement {
</tr>
<tr>
<td>
<span className="text">Reputation:</span>
<Typography>Reputation:</Typography>
</td>
<td>
<Adjuster
@ -153,7 +154,7 @@ export function Factions(props: IProps): React.ReactElement {
</tr>
<tr>
<td>
<span className="text">Favor:</span>
<Typography>Favor:</Typography>
</td>
<td>
<Adjuster
@ -168,7 +169,7 @@ export function Factions(props: IProps): React.ReactElement {
</tr>
<tr>
<td>
<span className="text">All Reputation:</span>
<Typography>All Reputation:</Typography>
</td>
<td>
<Button onClick={tonsOfRep}>Tons</Button>
@ -177,7 +178,7 @@ export function Factions(props: IProps): React.ReactElement {
</tr>
<tr>
<td>
<span className="text">All Favor:</span>
<Typography>All Favor:</Typography>
</td>
<td>
<Button onClick={tonsOfFactionFavor}>Tons</Button>

@ -1,5 +1,6 @@
import React from "react";
import Typography from "@mui/material/Typography";
import Accordion from "@mui/material/Accordion";
import AccordionSummary from "@mui/material/AccordionSummary";
import AccordionDetails from "@mui/material/AccordionDetails";
@ -45,7 +46,7 @@ export function Gang(props: IProps): React.ReactElement {
<tbody>
<tr>
<td>
<span className="text">Cycles:</span>
<Typography>Cycles:</Typography>
</td>
<td>
<Adjuster

@ -5,6 +5,7 @@ import AccordionSummary from "@mui/material/AccordionSummary";
import AccordionDetails from "@mui/material/AccordionDetails";
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
import Select, { SelectChangeEvent } from "@mui/material/Select";
import { IPlayer } from "../../PersonObjects/IPlayer";
@ -44,7 +45,7 @@ export function Programs(props: IProps): React.ReactElement {
<tbody>
<tr>
<td>
<span className="text">Program:</span>
<Typography>Program:</Typography>
</td>
<td>
<Select onChange={setProgramDropdown} value={program}>
@ -58,7 +59,7 @@ export function Programs(props: IProps): React.ReactElement {
</tr>
<tr>
<td>
<span className="text">Add:</span>
<Typography>Add:</Typography>
</td>
<td>
<Button onClick={addProgram}>One</Button>

@ -5,6 +5,7 @@ import AccordionSummary from "@mui/material/AccordionSummary";
import AccordionDetails from "@mui/material/AccordionDetails";
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
import Select, { SelectChangeEvent } from "@mui/material/Select";
import { AllServers } from "../../Server/AllServers";
@ -84,7 +85,7 @@ export function Servers(): React.ReactElement {
<tbody>
<tr>
<td>
<span className="text">Server:</span>
<Typography>Server:</Typography>
</td>
<td colSpan={2}>
<Select id="dev-servers-dropdown" onChange={setServerDropdown} value={server}>
@ -98,7 +99,7 @@ export function Servers(): React.ReactElement {
</tr>
<tr>
<td>
<span className="text">Root:</span>
<Typography>Root:</Typography>
</td>
<td>
<Button onClick={rootServer}>Root one</Button>
@ -109,7 +110,7 @@ export function Servers(): React.ReactElement {
</tr>
<tr>
<td>
<span className="text">Security:</span>
<Typography>Security:</Typography>
</td>
<td>
<Button onClick={minSecurity}>Min one</Button>
@ -120,7 +121,7 @@ export function Servers(): React.ReactElement {
</tr>
<tr>
<td>
<span className="text">Money:</span>
<Typography>Money:</Typography>
</td>
<td>
<Button onClick={maxMoney}>Max one</Button>

@ -6,6 +6,7 @@ import AccordionDetails from "@mui/material/AccordionDetails";
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
import Button from "@mui/material/Button";
import Typography from "@mui/material/Typography";
import { IPlayer } from "../../PersonObjects/IPlayer";
interface IProps {
@ -47,7 +48,7 @@ export function Sleeves(props: IProps): React.ReactElement {
<tbody>
<tr>
<td>
<span className="text">Shock:</span>
<Typography>Shock:</Typography>
</td>
<td>
<Button onClick={sleeveMaxAllShock}>Max all</Button>
@ -58,7 +59,7 @@ export function Sleeves(props: IProps): React.ReactElement {
</tr>
<tr>
<td>
<span className="text">Sync:</span>
<Typography>Sync:</Typography>
</td>
<td>
<Button onClick={sleeveSyncMaxAll}>Max all</Button>

@ -5,6 +5,7 @@ import AccordionSummary from "@mui/material/AccordionSummary";
import AccordionDetails from "@mui/material/AccordionDetails";
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
import { PlayerOwnedSourceFile } from "../../SourceFile/PlayerOwnedSourceFile";
import { IPlayer } from "../../PersonObjects/IPlayer";
@ -60,7 +61,7 @@ export function SourceFiles(props: IProps): React.ReactElement {
<tbody>
<tr>
<td>
<span className="text">Exploits:</span>
<Typography>Exploits:</Typography>
</td>
<td>
<Button onClick={clearExploits}>Clear</Button>
@ -68,7 +69,7 @@ export function SourceFiles(props: IProps): React.ReactElement {
</tr>
<tr key={"sf-all"}>
<td>
<span className="text">All:</span>
<Typography>All:</Typography>
</td>
<td>
<ButtonGroup>
@ -90,7 +91,7 @@ export function SourceFiles(props: IProps): React.ReactElement {
{validSFN.map((i) => (
<tr key={"sf-" + i}>
<td>
<span className="text">SF-{i}:</span>
<Typography>SF-{i}:</Typography>
</td>
<td>
<ButtonGroup>

@ -5,6 +5,7 @@ import AccordionSummary from "@mui/material/AccordionSummary";
import AccordionDetails from "@mui/material/AccordionDetails";
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
import { Adjuster } from "./Adjuster";
import { IPlayer } from "../../PersonObjects/IPlayer";
@ -145,7 +146,7 @@ export function Stats(props: IProps): React.ReactElement {
<tbody>
<tr>
<td>
<span className="text text-center">All:</span>
<Typography>All:</Typography>
</td>
<td>
<Button onClick={tonsOfExp}>Tons of exp</Button>
@ -154,7 +155,7 @@ export function Stats(props: IProps): React.ReactElement {
</tr>
<tr>
<td>
<span className="text text-center">Hacking:</span>
<Typography>Hacking:</Typography>
</td>
<td>
<Adjuster
@ -169,7 +170,7 @@ export function Stats(props: IProps): React.ReactElement {
</tr>
<tr>
<td>
<span className="text text-center">Strength:</span>
<Typography>Strength:</Typography>
</td>
<td>
<Adjuster
@ -184,7 +185,7 @@ export function Stats(props: IProps): React.ReactElement {
</tr>
<tr>
<td>
<span className="text text-center">Defense:</span>
<Typography>Defense:</Typography>
</td>
<td>
<Adjuster
@ -199,7 +200,7 @@ export function Stats(props: IProps): React.ReactElement {
</tr>
<tr>
<td>
<span className="text text-center">Dexterity:</span>
<Typography>Dexterity:</Typography>
</td>
<td>
<Adjuster
@ -214,7 +215,7 @@ export function Stats(props: IProps): React.ReactElement {
</tr>
<tr>
<td>
<span className="text text-center">Agility:</span>
<Typography>Agility:</Typography>
</td>
<td>
<Adjuster
@ -229,7 +230,7 @@ export function Stats(props: IProps): React.ReactElement {
</tr>
<tr>
<td>
<span className="text text-center">Charisma:</span>
<Typography>Charisma:</Typography>
</td>
<td>
<Adjuster
@ -244,7 +245,7 @@ export function Stats(props: IProps): React.ReactElement {
</tr>
<tr>
<td>
<span className="text text-center">Intelligence:</span>
<Typography>Intelligence:</Typography>
</td>
<td>
<Adjuster
@ -265,7 +266,7 @@ export function Stats(props: IProps): React.ReactElement {
</tr>
<tr>
<td>
<span className="text text-center">Karma:</span>
<Typography>Karma:</Typography>
</td>
<td>
<Adjuster

@ -5,6 +5,7 @@ import AccordionSummary from "@mui/material/AccordionSummary";
import AccordionDetails from "@mui/material/AccordionDetails";
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
import TextField from "@mui/material/TextField";
import { Money } from "../../ui/React/Money";
@ -89,7 +90,7 @@ export function StockMarket(): React.ReactElement {
<tbody>
<tr>
<td>
<span className="text">Symbol:</span>
<Typography>Symbol:</Typography>
</td>
<td>
<TextField placeholder="symbol/'all'" onChange={setStockSymbolField} />
@ -97,7 +98,7 @@ export function StockMarket(): React.ReactElement {
</tr>
<tr>
<td>
<span className="text">Price:</span>
<Typography>Price:</Typography>
</td>
<td>
<TextField placeholder="$$$" onChange={setStockPriceField} />
@ -106,7 +107,7 @@ export function StockMarket(): React.ReactElement {
</tr>
<tr>
<td>
<span className="text">Caps:</span>
<Typography>Caps:</Typography>
</td>
<td>
<Button onClick={viewStockCaps}>View stock caps</Button>

@ -175,7 +175,7 @@ export function AugmentationsPage(props: IProps): React.ReactElement {
}
return (
<div>
<>
<Button onClick={props.routeToMainPage}>Back</Button>
<Typography variant="h4">Faction Augmentations</Typography>
<Typography>
@ -197,6 +197,6 @@ export function AugmentationsPage(props: IProps): React.ReactElement {
<Table size="small" padding="none">
<TableBody>{ownedElem}</TableBody>
</Table>
</div>
</>
);
}

@ -0,0 +1,55 @@
import React from "react";
import { Augmentation } from "../../Augmentation/Augmentation";
import { Faction } from "../Faction";
import { purchaseAugmentation } from "../FactionHelpers";
import { isRepeatableAug } from "../../Augmentation/AugmentationHelpers";
import { Money } from "../../ui/React/Money";
import { Modal } from "../../ui/React/Modal";
import { use } from "../../ui/Context";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
interface IProps {
open: boolean;
onClose: () => void;
faction: Faction;
aug: Augmentation;
rerender: () => void;
}
export function PurchaseAugmentationModal(props: IProps): React.ReactElement {
const player = use.Player();
const factionInfo = props.faction.getInfo();
function buy(): void {
if (!isRepeatableAug(props.aug) && player.hasAugmentation(props.aug)) {
return;
}
purchaseAugmentation(props.aug, props.faction);
props.rerender();
props.onClose();
}
return (
<Modal open={props.open} onClose={props.onClose}>
<Typography variant="h4">{props.aug.name}</Typography>
<Typography>
{props.aug.info}
<br />
<br />
{props.aug.stats}
<br />
<br />
Would you like to purchase the {props.aug.name} Augmentation for&nbsp;
<Money money={props.aug.baseCost * factionInfo.augmentationPriceMult} />?
<br />
<br />
</Typography>
<Button autoFocus onClick={buy}>
Purchase
</Button>
</Modal>
);
}

@ -1,51 +0,0 @@
import React from "react";
import { Augmentation } from "../../Augmentation/Augmentation";
import { Faction } from "../../Faction/Faction";
import { IPlayer } from "../../PersonObjects/IPlayer";
import { purchaseAugmentation } from "../FactionHelpers";
import { isRepeatableAug } from "../../Augmentation/AugmentationHelpers";
import { Money } from "../../ui/React/Money";
import { removePopup } from "../../ui/React/createPopup";
interface IProps {
player: IPlayer;
faction: Faction;
aug: Augmentation;
rerender: () => void;
popupId: string;
}
export function PurchaseAugmentationPopup(props: IProps): React.ReactElement {
const factionInfo = props.faction.getInfo();
function buy(): void {
if (!isRepeatableAug(props.aug) && props.player.hasAugmentation(props.aug)) {
return;
}
purchaseAugmentation(props.aug, props.faction);
props.rerender();
removePopup(props.popupId);
}
return (
<>
<h2>{props.aug.name}</h2>
<br />
{props.aug.info}
<br />
<br />
{props.aug.stats}
<br />
<br />
Would you like to purchase the {props.aug.name} Augmentation for&nbsp;
<Money money={props.aug.baseCost * factionInfo.augmentationPriceMult} />?
<br />
<br />
<button autoFocus={true} className="std-button" onClick={buy}>
Purchase
</button>
</>
);
}

@ -2,10 +2,10 @@
* React component for displaying a single augmentation for purchase through
* the faction UI
*/
import * as React from "react";
import React, { useState } from "react";
import { getNextNeurofluxLevel, hasAugmentationPrereqs, purchaseAugmentation } from "../FactionHelpers";
import { PurchaseAugmentationPopup } from "./PurchaseAugmentationPopup";
import { PurchaseAugmentationModal } from "./PurchaseAugmentationModal";
import { Augmentations } from "../../Augmentation/Augmentations";
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
@ -14,7 +14,6 @@ import { IPlayer } from "../../PersonObjects/IPlayer";
import { Settings } from "../../Settings/Settings";
import { Money } from "../../ui/React/Money";
import { Reputation } from "../../ui/React/Reputation";
import { createPopup } from "../../ui/React/createPopup";
import { Augmentation as AugFormat } from "../../ui/React/Augmentation";
import Button from "@mui/material/Button";
@ -74,6 +73,7 @@ interface IProps {
}
export function PurchaseableAugmentation(props: IProps): React.ReactElement {
const [open, setOpen] = useState(false);
const aug = Augmentations[props.augName];
if (aug == null) throw new Error(`aug ${props.augName} does not exists`);
@ -122,14 +122,7 @@ export function PurchaseableAugmentation(props: IProps): React.ReactElement {
function handleClick(): void {
if (color === "error") return;
if (!Settings.SuppressBuyAugmentationConfirmation) {
const popupId = "purchase-augmentation-popup";
createPopup(popupId, PurchaseAugmentationPopup, {
aug: aug,
faction: props.faction,
player: props.p,
rerender: props.rerender,
popupId: popupId,
});
setOpen(true);
} else {
purchaseAugmentation(aug, props.faction);
props.rerender();
@ -143,6 +136,13 @@ export function PurchaseableAugmentation(props: IProps): React.ReactElement {
<Button onClick={handleClick} color={color}>
Buy
</Button>
<PurchaseAugmentationModal
open={open}
onClose={() => setOpen(false)}
aug={aug}
faction={props.faction}
rerender={props.rerender}
/>
</TableCell>
)}
<TableCell key={1}>

@ -37,7 +37,6 @@ function LocationLetter(location: Location): React.ReactElement {
<span
aria-label={location.name}
key={location.name}
className="tooltip"
style={{
color: "white",
whiteSpace: "nowrap",

@ -23,7 +23,7 @@ import { Reputation } from "../../ui/React/Reputation";
import { Favor } from "../../ui/React/Favor";
import { createPopup } from "../../ui/React/createPopup";
import { use } from "../../ui/Context";
import { QuitJobPopup } from "../../Company/ui/QuitJobPopup";
import { QuitJobModal } from "../../Company/ui/QuitJobModal";
type IProps = {
locName: LocationName;
@ -32,6 +32,7 @@ type IProps = {
export function CompanyLocation(props: IProps): React.ReactElement {
const p = use.Player();
const router = use.Router();
const [quitOpen, setQuitOpen] = useState(false);
const setRerender = useState(false)[1];
function rerender(): void {
setRerender((old) => !old);
@ -179,18 +180,6 @@ export function CompanyLocation(props: IProps): React.ReactElement {
}
}
function quit(e: React.MouseEvent<HTMLElement>): void {
if (!e.isTrusted) return;
const popupId = `quit-job-popup`;
createPopup(popupId, QuitJobPopup, {
locName: props.locName,
company: company,
player: p,
onQuit: rerender,
popupId: popupId,
});
}
const isEmployedHere = jobTitle != null;
const favorGain = company.getFavorGain();
@ -230,7 +219,14 @@ export function CompanyLocation(props: IProps): React.ReactElement {
<br />
<Button onClick={work}>Work</Button>
&nbsp;&nbsp;&nbsp;&nbsp;
<Button onClick={quit}>Quit</Button>
<Button onClick={() => setQuitOpen(true)}>Quit</Button>
<QuitJobModal
locName={props.locName}
company={company}
onQuit={rerender}
open={quitOpen}
onClose={() => setQuitOpen(false)}
/>
</div>
)}
{company.hasAgentPositions() && (

@ -31,10 +31,12 @@ export function CoresButton(props: IProps): React.ReactElement {
return (
<Tooltip title={<MathComponent tex={String.raw`\large{cost = 10^9 \times 7.5 ^{\text{cores}}}`} />}>
<Button disabled={!props.p.canAfford(cost)} onClick={buy}>
Upgrade 'home' cores ({homeComputer.cpuCores} -&gt; {homeComputer.cpuCores + 1}) -&nbsp;
<Money money={cost} player={props.p} />
</Button>
<span>
<Button disabled={!props.p.canAfford(cost)} onClick={buy}>
Upgrade 'home' cores ({homeComputer.cpuCores} -&gt; {homeComputer.cpuCores + 1}) -&nbsp;
<Money money={cost} player={props.p} />
</Button>
</span>
</Tooltip>
);
}

@ -64,7 +64,7 @@ export function GenericLocation({ loc }: IProps): React.ReactElement {
}
if (loc.types.includes(LocationType.TechVendor)) {
content.push(<TechVendorLocation key={"techvendorlocation"} loc={loc} p={player} />);
content.push(<TechVendorLocation key={"techvendorlocation"} loc={loc} />);
}
if (loc.types.includes(LocationType.TravelAgency)) {

@ -0,0 +1,67 @@
/**
* React Component for the popup used to purchase a new server.
*/
import React, { useState } from "react";
import { purchaseServer } from "../../Server/ServerPurchases";
import { numeralWrapper } from "../../ui/numeralFormat";
import { Money } from "../../ui/React/Money";
import { Modal } from "../../ui/React/Modal";
import { StdButton } from "../../ui/React/StdButton";
import { use } from "../../ui/Context";
import Typography from "@mui/material/Typography";
import TextField from "@mui/material/TextField";
import Button from "@mui/material/Button";
interface IProps {
open: boolean;
onClose: () => void;
ram: number;
cost: number;
rerender: () => void;
}
export function PurchaseServerModal(props: IProps): React.ReactElement {
const player = use.Player();
const [hostname, setHostname] = useState("");
function tryToPurchaseServer(): void {
purchaseServer(hostname, props.ram, props.cost, player);
props.onClose();
}
function onKeyUp(event: React.KeyboardEvent<HTMLInputElement>): void {
if (event.keyCode === 13) tryToPurchaseServer();
}
function onChange(event: React.ChangeEvent<HTMLInputElement>): void {
setHostname(event.target.value);
}
return (
<Modal open={props.open} onClose={props.onClose}>
<Typography>
Would you like to purchase a new server with {numeralWrapper.formatRAM(props.ram)} of RAM for{" "}
<Money money={props.cost} player={player} />?
</Typography>
<br />
<br />
<Typography> Please enter the server hostname below:</Typography>
<br />
<TextField
autoFocus
onKeyUp={onKeyUp}
onChange={onChange}
type="text"
placeholder="Unique Hostname"
InputProps={{
endAdornment: (
<Button onClick={tryToPurchaseServer} disabled={!player.canAfford(props.cost) || hostname === ""}>
Buy
</Button>
),
}}
/>
</Modal>
);
}

@ -1,58 +0,0 @@
/**
* React Component for the popup used to purchase a new server.
*/
import React, { useState } from "react";
import { removePopup } from "../../ui/React/createPopup";
import { purchaseServer } from "../../Server/ServerPurchases";
import { numeralWrapper } from "../../ui/numeralFormat";
import { Money } from "../../ui/React/Money";
import { IPlayer } from "../../PersonObjects/IPlayer";
import { StdButton } from "../../ui/React/StdButton";
interface IPurchaseServerPopupProps {
ram: number;
cost: number;
p: IPlayer;
popupId: string;
rerender: () => void;
}
export function PurchaseServerPopup(props: IPurchaseServerPopupProps): React.ReactElement {
const [hostname, setHostname] = useState("");
function tryToPurchaseServer(): void {
purchaseServer(hostname, props.ram, props.cost, props.p);
removePopup(props.popupId);
}
function onKeyUp(event: React.KeyboardEvent<HTMLInputElement>): void {
if (event.keyCode === 13) tryToPurchaseServer();
}
function onChange(event: React.ChangeEvent<HTMLInputElement>): void {
setHostname(event.target.value);
}
return (
<>
Would you like to purchase a new server with {numeralWrapper.formatRAM(props.ram)} of RAM for{" "}
<Money money={props.cost} player={props.p} />?
<br />
<br />
Please enter the server hostname below:
<br />
<div className="popup-box-input-div">
<input
autoFocus
onKeyUp={onKeyUp}
onChange={onChange}
className="text-input noselect"
type="text"
placeholder="Unique Hostname"
/>
<StdButton onClick={tryToPurchaseServer} text="Purchase Server" disabled={!props.p.canAfford(props.cost)} />
</div>
</>
);
}

@ -29,10 +29,12 @@ export function RamButton(props: IProps): React.ReactElement {
return (
<Tooltip title={<MathComponent tex={String.raw`\large{cost = 3.2 \times 10^3 \times 1.58^{log_2{(ram)}}}`} />}>
<Button disabled={!props.p.canAfford(cost)} onClick={buy}>
Upgrade 'home' RAM ({homeComputer.maxRam}GB -&gt;&nbsp;{homeComputer.maxRam * 2}GB) -&nbsp;
<Money money={cost} player={props.p} />
</Button>
<span>
<Button disabled={!props.p.canAfford(cost)} onClick={buy}>
Upgrade 'home' RAM ({homeComputer.maxRam}GB -&gt;&nbsp;{homeComputer.maxRam * 2}GB) -&nbsp;
<Money money={cost} player={props.p} />
</Button>
</span>
</Tooltip>
);
}

@ -12,36 +12,50 @@ import { RamButton } from "./RamButton";
import { TorButton } from "./TorButton";
import { CoresButton } from "./CoresButton";
import { IPlayer } from "../../PersonObjects/IPlayer";
import { getPurchaseServerCost } from "../../Server/ServerPurchases";
import { StdButton } from "../../ui/React/StdButton";
import { Money } from "../../ui/React/Money";
import { createPopup } from "../../ui/React/createPopup";
import { PurchaseServerPopup } from "./PurchaseServerPopup";
import { use } from "../../ui/Context";
import { PurchaseServerModal } from "./PurchaseServerModal";
interface IServerProps {
ram: number;
rerender: () => void;
}
function ServerButton(props: IServerProps): React.ReactElement {
const [open, setOpen] = useState(false);
const player = use.Player();
const cost = getPurchaseServerCost(props.ram);
return (
<>
<Button onClick={() => setOpen(true)} disabled={!player.canAfford(cost)}>
Purchase {props.ram}GB Server&nbsp;-&nbsp;
<Money money={cost} player={player} />
</Button>
<PurchaseServerModal
open={open}
onClose={() => setOpen(false)}
ram={props.ram}
cost={cost}
rerender={props.rerender}
/>
<br />
</>
);
}
type IProps = {
loc: Location;
p: IPlayer;
};
export function TechVendorLocation(props: IProps): React.ReactElement {
const player = use.Player();
const setRerender = useState(false)[1];
function rerender(): void {
setRerender((old) => !old);
}
function openPurchaseServer(ram: number, cost: number, p: IPlayer): void {
const popupId = "purchase-server-popup";
createPopup(popupId, PurchaseServerPopup, {
ram: ram,
cost: cost,
p: p,
popupId: popupId,
rerender: rerender,
});
}
useEffect(() => {
const id = setInterval(rerender, 1000);
return () => clearInterval(id);
@ -49,16 +63,7 @@ export function TechVendorLocation(props: IProps): React.ReactElement {
const purchaseServerButtons: React.ReactNode[] = [];
for (let i = props.loc.techVendorMinRam; i <= props.loc.techVendorMaxRam; i *= 2) {
const cost = getPurchaseServerCost(i);
purchaseServerButtons.push(
<>
<Button key={i} onClick={() => openPurchaseServer(i, cost, props.p)} disabled={!props.p.canAfford(cost)}>
Purchase {i}GB Server&nbsp;-&nbsp;
<Money money={cost} player={props.p} />
</Button>
<br />
</>,
);
purchaseServerButtons.push(<ServerButton key={i} ram={i} rerender={rerender} />);
}
return (
@ -69,11 +74,11 @@ export function TechVendorLocation(props: IProps): React.ReactElement {
<i>"You can order bigger servers via scripts. We don't take custom order in person."</i>
</Typography>
<br />
<TorButton p={props.p} rerender={rerender} />
<TorButton p={player} rerender={rerender} />
<br />
<RamButton p={props.p} rerender={rerender} />
<RamButton p={player} rerender={rerender} />
<br />
<CoresButton p={props.p} rerender={rerender} />
<CoresButton p={player} rerender={rerender} />
</div>
);
}

@ -25,7 +25,8 @@ export function TorButton(props: IProps): React.ReactElement {
return (
<Button disabled={!props.p.canAfford(CONSTANTS.TorRouterCost)} onClick={buy}>
Purchase TOR router - <Money money={CONSTANTS.TorRouterCost} player={props.p} />
Purchase TOR router -&nbsp;
<Money money={CONSTANTS.TorRouterCost} player={props.p} />
</Button>
);
}