Merge pull request #3779 from borisflagell/CorpoNumeral

CORPORATION: Add big number format support in some Corporation's modal
This commit is contained in:
hydroflame 2022-07-21 01:42:35 -04:00 committed by GitHub
commit 2772511525
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 35 additions and 92 deletions

@ -9,7 +9,7 @@ import { useCorporation } from "../Context";
import Typography from "@mui/material/Typography"; import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button"; import Button from "@mui/material/Button";
import MenuItem from "@mui/material/MenuItem"; import MenuItem from "@mui/material/MenuItem";
import TextField from "@mui/material/TextField"; import { NumberInput } from "../../../ui/React/NumberInput";
import Box from "@mui/material/Box"; import Box from "@mui/material/Box";
import Select, { SelectChangeEvent } from "@mui/material/Select"; import Select, { SelectChangeEvent } from "@mui/material/Select";
@ -27,12 +27,10 @@ export function BribeFactionModal(props: IProps): React.ReactElement {
return true; return true;
}); });
const corp = useCorporation(); const corp = useCorporation();
const [money, setMoney] = useState<number | null>(0); const [money, setMoney] = useState<number>(NaN);
const [stock, setStock] = useState<number | null>(0); const [stock, setStock] = useState<number>(NaN);
const [selectedFaction, setSelectedFaction] = useState(factions.length > 0 ? factions[0] : ""); const [selectedFaction, setSelectedFaction] = useState(factions.length > 0 ? factions[0] : "");
const disabled = const disabled =
money === null ||
stock === null ||
(money === 0 && stock === 0) || (money === 0 && stock === 0) ||
isNaN(money) || isNaN(money) ||
isNaN(stock) || isNaN(stock) ||
@ -41,14 +39,6 @@ export function BribeFactionModal(props: IProps): React.ReactElement {
corp.funds < money || corp.funds < money ||
stock > corp.numShares; stock > corp.numShares;
function onMoneyChange(event: React.ChangeEvent<HTMLInputElement>): void {
setMoney(parseFloat(event.target.value));
}
function onStockChange(event: React.ChangeEvent<HTMLInputElement>): void {
setStock(parseFloat(event.target.value));
}
function changeFaction(event: SelectChangeEvent<string>): void { function changeFaction(event: SelectChangeEvent<string>): void {
setSelectedFaction(event.target.value); setSelectedFaction(event.target.value);
} }
@ -110,8 +100,8 @@ export function BribeFactionModal(props: IProps): React.ReactElement {
</Select> </Select>
</Box> </Box>
<Typography>{getRepText(money ? money : 0, stock ? stock : 0)}</Typography> <Typography>{getRepText(money ? money : 0, stock ? stock : 0)}</Typography>
<TextField onChange={onMoneyChange} placeholder="Corporation funds" /> <NumberInput onChange={setMoney} placeholder="Corporation funds" />
<TextField sx={{ mx: 1 }} onChange={onStockChange} placeholder="Stock Shares" /> <NumberInput sx={{ mx: 1 }} onChange={setStock} placeholder="Stock Shares" />
<Button disabled={disabled} sx={{ mx: 1 }} onClick={() => bribe(money ? money : 0, stock ? stock : 0)}> <Button disabled={disabled} sx={{ mx: 1 }} onClick={() => bribe(money ? money : 0, stock ? stock : 0)}>
Bribe Bribe
</Button> </Button>

@ -5,7 +5,7 @@ import { use } from "../../../ui/Context";
import { useCorporation } from "../Context"; import { useCorporation } from "../Context";
import Typography from "@mui/material/Typography"; 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 { NumberInput } from "../../../ui/React/NumberInput";
import { BuyBackShares } from "../../Actions"; import { BuyBackShares } from "../../Actions";
import { dialogBoxCreate } from "../../../ui/React/DialogBox"; import { dialogBoxCreate } from "../../../ui/React/DialogBox";
import { KEY } from "../../../utils/helpers/keyCodes"; import { KEY } from "../../../utils/helpers/keyCodes";
@ -21,12 +21,7 @@ interface IProps {
export function BuybackSharesModal(props: IProps): React.ReactElement { export function BuybackSharesModal(props: IProps): React.ReactElement {
const player = use.Player(); const player = use.Player();
const corp = useCorporation(); const corp = useCorporation();
const [shares, setShares] = useState<number | null>(null); const [shares, setShares] = useState<number>(NaN);
function changeShares(event: React.ChangeEvent<HTMLInputElement>): void {
if (event.target.value === "") setShares(null);
else setShares(Math.round(parseFloat(event.target.value)));
}
const currentStockPrice = corp.sharePrice; const currentStockPrice = corp.sharePrice;
const buybackPrice = currentStockPrice * 1.1; const buybackPrice = currentStockPrice * 1.1;
@ -87,11 +82,10 @@ export function BuybackSharesModal(props: IProps): React.ReactElement {
</Typography> </Typography>
<CostIndicator /> <CostIndicator />
<br /> <br />
<TextField <NumberInput
autoFocus={true} autoFocus={true}
type="number"
placeholder="Shares to buyback" placeholder="Shares to buyback"
onChange={changeShares} onChange={setShares}
onKeyDown={onKeyDown} onKeyDown={onKeyDown}
/> />
<Button disabled={disabled} onClick={buy}> <Button disabled={disabled} onClick={buy}>

@ -5,7 +5,7 @@ import { numeralWrapper } from "../../../ui/numeralFormat";
import { useCorporation } from "../Context"; import { useCorporation } from "../Context";
import Typography from "@mui/material/Typography"; 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 { NumberInput } from "../../../ui/React/NumberInput";
import Box from "@mui/material/Box"; import Box from "@mui/material/Box";
import { KEY } from "../../../utils/helpers/keyCodes"; import { KEY } from "../../../utils/helpers/keyCodes";
@ -18,29 +18,28 @@ interface IProps {
// Create a popup that lets the player manage exports // Create a popup that lets the player manage exports
export function GoPublicModal(props: IProps): React.ReactElement { export function GoPublicModal(props: IProps): React.ReactElement {
const corp = useCorporation(); const corp = useCorporation();
const [shares, setShares] = useState(""); const [shares, setShares] = useState<number>(NaN);
const initialSharePrice = corp.determineValuation() / corp.totalShares; const initialSharePrice = corp.determineValuation() / corp.totalShares;
function goPublic(): void { function goPublic(): void {
const numShares = parseFloat(shares);
const initialSharePrice = corp.determineValuation() / corp.totalShares; const initialSharePrice = corp.determineValuation() / corp.totalShares;
if (isNaN(numShares)) { if (isNaN(shares)) {
dialogBoxCreate("Invalid value for number of issued shares"); dialogBoxCreate("Invalid value for number of issued shares");
return; return;
} }
if (numShares > corp.numShares) { if (shares > corp.numShares) {
dialogBoxCreate("Error: You don't have that many shares to issue!"); dialogBoxCreate("Error: You don't have that many shares to issue!");
return; return;
} }
corp.public = true; corp.public = true;
corp.sharePrice = initialSharePrice; corp.sharePrice = initialSharePrice;
corp.issuedShares = numShares; corp.issuedShares = shares;
corp.numShares -= numShares; corp.numShares -= shares;
corp.addFunds(numShares * initialSharePrice); corp.addFunds(shares * initialSharePrice);
props.rerender(); props.rerender();
dialogBoxCreate( dialogBoxCreate(
`You took your ${corp.name} public and earned ` + `You took your ${corp.name} public and earned ` +
`${numeralWrapper.formatMoney(numShares * initialSharePrice)} in your IPO`, `${numeralWrapper.formatMoney(shares * initialSharePrice)} in your IPO`,
); );
props.onClose(); props.onClose();
} }
@ -49,10 +48,6 @@ export function GoPublicModal(props: IProps): React.ReactElement {
if (event.key === KEY.ENTER) goPublic(); if (event.key === KEY.ENTER) goPublic();
} }
function onChange(event: React.ChangeEvent<HTMLInputElement>): void {
setShares(event.target.value);
}
return ( return (
<Modal open={props.open} onClose={props.onClose}> <Modal open={props.open} onClose={props.onClose}>
<Typography> <Typography>
@ -64,19 +59,8 @@ export function GoPublicModal(props: IProps): React.ReactElement {
You have a total of {numeralWrapper.format(corp.numShares, "0.000a")} of shares that you can issue. You have a total of {numeralWrapper.format(corp.numShares, "0.000a")} of shares that you can issue.
</Typography> </Typography>
<Box display="flex" alignItems="center"> <Box display="flex" alignItems="center">
<TextField <NumberInput onChange={setShares} autoFocus placeholder="Shares to issue" onKeyDown={onKeyDown} />
value={shares} <Button disabled={shares < 0 || shares > corp.numShares} sx={{ mx: 1 }} onClick={goPublic}>
onChange={onChange}
autoFocus
type="number"
placeholder="Shares to issue"
onKeyDown={onKeyDown}
/>
<Button
disabled={parseFloat(shares) < 0 || parseFloat(shares) > corp.numShares}
sx={{ mx: 1 }}
onClick={goPublic}
>
Go Public Go Public
</Button> </Button>
</Box> </Box>

@ -6,7 +6,7 @@ import { getRandomInt } from "../../../utils/helpers/getRandomInt";
import { CorporationConstants } from "../../data/Constants"; import { CorporationConstants } from "../../data/Constants";
import { useCorporation } from "../Context"; import { useCorporation } from "../Context";
import Typography from "@mui/material/Typography"; import Typography from "@mui/material/Typography";
import TextField from "@mui/material/TextField"; import { NumberInput } from "../../../ui/React/NumberInput";
import Button from "@mui/material/Button"; import Button from "@mui/material/Button";
import { KEY } from "../../../utils/helpers/keyCodes"; import { KEY } from "../../../utils/helpers/keyCodes";
@ -54,15 +54,15 @@ interface IProps {
// This is created when the player clicks the "Issue New Shares" buttons in the overview panel // This is created when the player clicks the "Issue New Shares" buttons in the overview panel
export function IssueNewSharesModal(props: IProps): React.ReactElement { export function IssueNewSharesModal(props: IProps): React.ReactElement {
const corp = useCorporation(); const corp = useCorporation();
const [shares, setShares] = useState<number | null>(null); const [shares, setShares] = useState<number>(NaN);
const maxNewSharesUnrounded = Math.round(corp.totalShares * 0.2); const maxNewSharesUnrounded = Math.round(corp.totalShares * 0.2);
const maxNewShares = maxNewSharesUnrounded - (maxNewSharesUnrounded % 1e6); const maxNewShares = maxNewSharesUnrounded - (maxNewSharesUnrounded % 1e6);
const newShares = Math.round((shares || 0) / 10e6) * 10e6; const newShares = Math.round((shares || 0) / 10e6) * 10e6;
const disabled = shares === null || isNaN(newShares) || newShares < 10e6 || newShares > maxNewShares; const disabled = isNaN(shares) || isNaN(newShares) || newShares < 10e6 || newShares > maxNewShares;
function issueNewShares(): void { function issueNewShares(): void {
if (shares === null) return; if (isNaN(shares)) return;
if (disabled) return; if (disabled) return;
const newSharePrice = Math.round(corp.sharePrice * 0.9); const newSharePrice = Math.round(corp.sharePrice * 0.9);
@ -97,11 +97,6 @@ export function IssueNewSharesModal(props: IProps): React.ReactElement {
if (event.key === KEY.ENTER) issueNewShares(); if (event.key === KEY.ENTER) issueNewShares();
} }
function onChange(event: React.ChangeEvent<HTMLInputElement>): void {
if (event.target.value === "") setShares(null);
else setShares(parseFloat(event.target.value));
}
return ( return (
<Modal open={props.open} onClose={props.onClose}> <Modal open={props.open} onClose={props.onClose}>
<Typography> <Typography>
@ -124,7 +119,7 @@ export function IssueNewSharesModal(props: IProps): React.ReactElement {
you cannot buy them back. you cannot buy them back.
</Typography> </Typography>
<EffectText shares={shares} /> <EffectText shares={shares} />
<TextField autoFocus placeholder="# New Shares" onChange={onChange} onKeyDown={onKeyDown} /> <NumberInput autoFocus placeholder="# New Shares" onChange={setShares} onKeyDown={onKeyDown} />
<Button disabled={disabled} onClick={issueNewShares} sx={{ mx: 1 }}> <Button disabled={disabled} onClick={issueNewShares} sx={{ mx: 1 }}>
Issue New Shares Issue New Shares
</Button> </Button>

@ -10,6 +10,7 @@ import Button from "@mui/material/Button";
import MenuItem from "@mui/material/MenuItem"; import MenuItem from "@mui/material/MenuItem";
import Select, { SelectChangeEvent } from "@mui/material/Select"; import Select, { SelectChangeEvent } from "@mui/material/Select";
import { KEY } from "../../../utils/helpers/keyCodes"; import { KEY } from "../../../utils/helpers/keyCodes";
import { NumberInput } from "../../../ui/React/NumberInput";
interface IProps { interface IProps {
open: boolean; open: boolean;
@ -34,8 +35,8 @@ export function MakeProductModal(props: IProps): React.ReactElement {
const allCities = Object.keys(division.offices).filter((cityName: string) => division.offices[cityName] !== 0); const allCities = Object.keys(division.offices).filter((cityName: string) => division.offices[cityName] !== 0);
const [city, setCity] = useState(allCities.length > 0 ? allCities[0] : ""); const [city, setCity] = useState(allCities.length > 0 ? allCities[0] : "");
const [name, setName] = useState(""); const [name, setName] = useState("");
const [design, setDesign] = useState<number | null>(null); const [design, setDesign] = useState<number>(NaN);
const [marketing, setMarketing] = useState<number | null>(null); const [marketing, setMarketing] = useState<number>(NaN);
if (division.hasMaximumNumberProducts()) return <></>; if (division.hasMaximumNumberProducts()) return <></>;
let createProductPopupText = <></>; let createProductPopupText = <></>;
@ -138,7 +139,7 @@ export function MakeProductModal(props: IProps): React.ReactElement {
); );
function makeProduct(): void { function makeProduct(): void {
if (design === null || marketing === null) return; if (isNaN(design) || isNaN(marketing)) return;
try { try {
MakeProduct(corp, division, city, name, design, marketing); MakeProduct(corp, division, city, name, design, marketing);
} catch (err) { } catch (err) {
@ -155,16 +156,6 @@ export function MakeProductModal(props: IProps): React.ReactElement {
setName(event.target.value); setName(event.target.value);
} }
function onDesignChange(event: React.ChangeEvent<HTMLInputElement>): void {
if (event.target.value === "") setDesign(null);
else setDesign(parseFloat(event.target.value));
}
function onMarketingChange(event: React.ChangeEvent<HTMLInputElement>): void {
if (event.target.value === "") setMarketing(null);
else setMarketing(parseFloat(event.target.value));
}
function onKeyDown(event: React.KeyboardEvent<HTMLInputElement>): void { function onKeyDown(event: React.KeyboardEvent<HTMLInputElement>): void {
if (event.key === KEY.ENTER) makeProduct(); if (event.key === KEY.ENTER) makeProduct();
} }
@ -181,13 +172,8 @@ export function MakeProductModal(props: IProps): React.ReactElement {
</Select> </Select>
<TextField onChange={onProductNameChange} placeholder={productPlaceholder(division.type)} /> <TextField onChange={onProductNameChange} placeholder={productPlaceholder(division.type)} />
<br /> <br />
<TextField onChange={onDesignChange} autoFocus={true} type="number" placeholder={"Design investment"} /> <NumberInput onChange={setDesign} autoFocus={true} placeholder={"Design investment"} />
<TextField <NumberInput onChange={setMarketing} onKeyDown={onKeyDown} placeholder={"Marketing investment"} />
onChange={onMarketingChange}
onKeyDown={onKeyDown}
type="number"
placeholder={"Marketing investment"}
/>
<Button onClick={makeProduct}>Develop Product</Button> <Button onClick={makeProduct}>Develop Product</Button>
</Modal> </Modal>
); );

@ -6,11 +6,11 @@ import { use } from "../../../ui/Context";
import { useCorporation } from "../Context"; import { useCorporation } from "../Context";
import { ICorporation } from "../../ICorporation"; import { ICorporation } from "../../ICorporation";
import Typography from "@mui/material/Typography"; import Typography from "@mui/material/Typography";
import TextField from "@mui/material/TextField";
import Button from "@mui/material/Button"; import Button from "@mui/material/Button";
import { Money } from "../../../ui/React/Money"; import { Money } from "../../../ui/React/Money";
import { SellShares } from "../../Actions"; import { SellShares } from "../../Actions";
import { KEY } from "../../../utils/helpers/keyCodes"; import { KEY } from "../../../utils/helpers/keyCodes";
import { NumberInput } from "../../../ui/React/NumberInput";
interface IProps { interface IProps {
open: boolean; open: boolean;
onClose: () => void; onClose: () => void;
@ -22,14 +22,9 @@ interface IProps {
export function SellSharesModal(props: IProps): React.ReactElement { export function SellSharesModal(props: IProps): React.ReactElement {
const player = use.Player(); const player = use.Player();
const corp = useCorporation(); const corp = useCorporation();
const [shares, setShares] = useState<number | null>(null); const [shares, setShares] = useState<number>(NaN);
const disabled = shares === null || isNaN(shares) || shares <= 0 || shares > corp.numShares; const disabled = isNaN(shares) || shares <= 0 || shares > corp.numShares;
function changeShares(event: React.ChangeEvent<HTMLInputElement>): void {
if (event.target.value === "") setShares(null);
else setShares(Math.round(parseFloat(event.target.value)));
}
function ProfitIndicator(props: { shares: number | null; corp: ICorporation }): React.ReactElement { function ProfitIndicator(props: { shares: number | null; corp: ICorporation }): React.ReactElement {
if (props.shares === null) return <></>; if (props.shares === null) return <></>;
@ -88,12 +83,11 @@ export function SellSharesModal(props: IProps): React.ReactElement {
The current price of your company's stock is {numeralWrapper.formatMoney(corp.sharePrice)} The current price of your company's stock is {numeralWrapper.formatMoney(corp.sharePrice)}
</Typography> </Typography>
<br /> <br />
<TextField <NumberInput
variant="standard" variant="standard"
autoFocus autoFocus
type="number"
placeholder="Shares to sell" placeholder="Shares to sell"
onChange={changeShares} onChange={setShares}
onKeyDown={onKeyDown} onKeyDown={onKeyDown}
/> />
<Button disabled={disabled} onClick={sell} sx={{ mx: 1 }}> <Button disabled={disabled} onClick={sell} sx={{ mx: 1 }}>