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 { Product } from "../Product";
import { Modal } from "../../ui/React/Modal"; import { Modal } from "../../ui/React/Modal";
import { useDivision } from "./Context"; import { useDivision } from "./Context";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
interface IProps { interface IProps {
open: boolean; open: boolean;
@ -22,13 +24,11 @@ export function DiscontinueProductModal(props: IProps): React.ReactElement {
return ( return (
<Modal open={props.open} onClose={props.onClose}> <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 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 longer produce this product and all of its existing stock will be removed and left unsold
</p> </Typography>
<button className="popup-box-button" onClick={discontinue}> <Button onClick={discontinue}>Discontinue</Button>
Discontinue
</button>
</Modal> </Modal>
); );
} }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@ -23,7 +23,7 @@ import { Reputation } from "../../ui/React/Reputation";
import { Favor } from "../../ui/React/Favor"; import { Favor } from "../../ui/React/Favor";
import { createPopup } from "../../ui/React/createPopup"; import { createPopup } from "../../ui/React/createPopup";
import { use } from "../../ui/Context"; import { use } from "../../ui/Context";
import { QuitJobPopup } from "../../Company/ui/QuitJobPopup"; import { QuitJobModal } from "../../Company/ui/QuitJobModal";
type IProps = { type IProps = {
locName: LocationName; locName: LocationName;
@ -32,6 +32,7 @@ type IProps = {
export function CompanyLocation(props: IProps): React.ReactElement { export function CompanyLocation(props: IProps): React.ReactElement {
const p = use.Player(); const p = use.Player();
const router = use.Router(); const router = use.Router();
const [quitOpen, setQuitOpen] = useState(false);
const setRerender = useState(false)[1]; const setRerender = useState(false)[1];
function rerender(): void { function rerender(): void {
setRerender((old) => !old); 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 isEmployedHere = jobTitle != null;
const favorGain = company.getFavorGain(); const favorGain = company.getFavorGain();
@ -230,7 +219,14 @@ export function CompanyLocation(props: IProps): React.ReactElement {
<br /> <br />
<Button onClick={work}>Work</Button> <Button onClick={work}>Work</Button>
&nbsp;&nbsp;&nbsp;&nbsp; &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> </div>
)} )}
{company.hasAgentPositions() && ( {company.hasAgentPositions() && (

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

@ -64,7 +64,7 @@ export function GenericLocation({ loc }: IProps): React.ReactElement {
} }
if (loc.types.includes(LocationType.TechVendor)) { 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)) { 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 ( return (
<Tooltip title={<MathComponent tex={String.raw`\large{cost = 3.2 \times 10^3 \times 1.58^{log_2{(ram)}}}`} />}> <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}> <span>
Upgrade 'home' RAM ({homeComputer.maxRam}GB -&gt;&nbsp;{homeComputer.maxRam * 2}GB) -&nbsp; <Button disabled={!props.p.canAfford(cost)} onClick={buy}>
<Money money={cost} player={props.p} /> Upgrade 'home' RAM ({homeComputer.maxRam}GB -&gt;&nbsp;{homeComputer.maxRam * 2}GB) -&nbsp;
</Button> <Money money={cost} player={props.p} />
</Button>
</span>
</Tooltip> </Tooltip>
); );
} }

@ -12,36 +12,50 @@ import { RamButton } from "./RamButton";
import { TorButton } from "./TorButton"; import { TorButton } from "./TorButton";
import { CoresButton } from "./CoresButton"; import { CoresButton } from "./CoresButton";
import { IPlayer } from "../../PersonObjects/IPlayer";
import { getPurchaseServerCost } from "../../Server/ServerPurchases"; import { getPurchaseServerCost } from "../../Server/ServerPurchases";
import { StdButton } from "../../ui/React/StdButton";
import { Money } from "../../ui/React/Money"; import { Money } from "../../ui/React/Money";
import { createPopup } from "../../ui/React/createPopup"; import { use } from "../../ui/Context";
import { PurchaseServerPopup } from "./PurchaseServerPopup"; 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 = { type IProps = {
loc: Location; loc: Location;
p: IPlayer;
}; };
export function TechVendorLocation(props: IProps): React.ReactElement { export function TechVendorLocation(props: IProps): React.ReactElement {
const player = use.Player();
const setRerender = useState(false)[1]; const setRerender = useState(false)[1];
function rerender(): void { function rerender(): void {
setRerender((old) => !old); 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(() => { useEffect(() => {
const id = setInterval(rerender, 1000); const id = setInterval(rerender, 1000);
return () => clearInterval(id); return () => clearInterval(id);
@ -49,16 +63,7 @@ export function TechVendorLocation(props: IProps): React.ReactElement {
const purchaseServerButtons: React.ReactNode[] = []; const purchaseServerButtons: React.ReactNode[] = [];
for (let i = props.loc.techVendorMinRam; i <= props.loc.techVendorMaxRam; i *= 2) { for (let i = props.loc.techVendorMinRam; i <= props.loc.techVendorMaxRam; i *= 2) {
const cost = getPurchaseServerCost(i); purchaseServerButtons.push(<ServerButton key={i} ram={i} rerender={rerender} />);
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 />
</>,
);
} }
return ( 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> <i>"You can order bigger servers via scripts. We don't take custom order in person."</i>
</Typography> </Typography>
<br /> <br />
<TorButton p={props.p} rerender={rerender} /> <TorButton p={player} rerender={rerender} />
<br /> <br />
<RamButton p={props.p} rerender={rerender} /> <RamButton p={player} rerender={rerender} />
<br /> <br />
<CoresButton p={props.p} rerender={rerender} /> <CoresButton p={player} rerender={rerender} />
</div> </div>
); );
} }

@ -25,7 +25,8 @@ export function TorButton(props: IProps): React.ReactElement {
return ( return (
<Button disabled={!props.p.canAfford(CONSTANTS.TorRouterCost)} onClick={buy}> <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> </Button>
); );
} }