convert some corp to mui

This commit is contained in:
Olivier Gagnon 2021-09-30 15:12:06 -04:00
parent 510fcedf90
commit 86ddc940aa
6 changed files with 291 additions and 298 deletions

@ -1,29 +1,27 @@
import React from "react";
import { removePopup } from "../../ui/React/createPopup";
import { ICorporation } from "../ICorporation";
import { Product } from "../Product";
import { IIndustry } from "../IIndustry";
import { IPlayer } from "../../PersonObjects/IPlayer";
import { Modal } from "../../ui/React/Modal";
import { useDivision } from "./Context";
interface IProps {
open: boolean;
onClose: () => void;
product: Product;
industry: IIndustry;
corp: ICorporation;
popupId: string;
player: IPlayer;
rerender: () => void;
}
// Create a popup that lets the player discontinue a product
export function DiscontinueProductPopup(props: IProps): React.ReactElement {
export function DiscontinueProductModal(props: IProps): React.ReactElement {
const division = useDivision();
function discontinue(): void {
props.industry.discontinueProduct(props.product);
removePopup(props.popupId);
division.discontinueProduct(props.product);
props.onClose();
props.rerender();
}
return (
<>
<Modal open={props.open} onClose={props.onClose}>
<p>
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
@ -31,6 +29,6 @@ export function DiscontinueProductPopup(props: IProps): React.ReactElement {
<button className="popup-box-button" onClick={discontinue}>
Discontinue
</button>
</>
</Modal>
);
}

@ -7,15 +7,12 @@ import { OfficeSpace } from "../OfficeSpace";
import { Material } from "../Material";
import { Product } from "../Product";
import { Warehouse } from "../Warehouse";
import { DiscontinueProductPopup } from "./DiscontinueProductPopup";
import { ExportPopup } from "./ExportPopup";
import { LimitProductProductionPopup } from "./LimitProductProductionPopup";
import { MaterialMarketTaPopup } from "./MaterialMarketTaPopup";
import { SellMaterialPopup } from "./SellMaterialPopup";
import { SellProductPopup } from "./SellProductPopup";
import { PurchaseMaterialPopup } from "./PurchaseMaterialPopup";
import { ProductMarketTaPopup } from "./ProductMarketTaPopup";
import { SmartSupplyModal } from "./SmartSupplyModal";
import { ProductElem } from "./ProductElem";
import { MaterialSizes } from "../MaterialSizes";
import { numeralWrapper } from "../../ui/numeralFormat";
@ -38,203 +35,6 @@ import Paper from "@mui/material/Paper";
import Button from "@mui/material/Button";
import Box from "@mui/material/Box";
interface IProductProps {
corp: ICorporation;
division: IIndustry;
city: string;
product: Product;
player: IPlayer;
rerender: () => void;
}
// Creates the UI for a single Product type
function ProductComponent(props: IProductProps): React.ReactElement {
const corp = useCorporation();
const division = useDivision();
const city = props.city;
const product = props.product;
// Numeraljs formatters
const nf = "0.000";
const nfB = "0.000a"; // For numbers that might be big
const hasUpgradeDashboard = division.hasResearch("uPgrade: Dashboard");
// Total product gain = production - sale
const totalGain = product.data[city][1] - product.data[city][2];
// Sell button
let sellButtonText: JSX.Element;
if (product.sllman[city][0]) {
if (isString(product.sllman[city][1])) {
sellButtonText = (
<>
Sell ({numeralWrapper.format(product.data[city][2], nfB)}/{product.sllman[city][1]})
</>
);
} else {
sellButtonText = (
<>
Sell ({numeralWrapper.format(product.data[city][2], nfB)}/
{numeralWrapper.format(product.sllman[city][1], nfB)})
</>
);
}
} else {
sellButtonText = <>Sell (0.000/0.000)</>;
}
if (product.marketTa2) {
sellButtonText = (
<>
{sellButtonText} @ <Money money={product.marketTa2Price[city]} />
</>
);
} else if (product.marketTa1) {
const markupLimit = product.rat / product.mku;
sellButtonText = (
<>
{sellButtonText} @ <Money money={product.pCost + markupLimit} />
</>
);
} else if (product.sCost) {
if (isString(product.sCost)) {
const sCost = (product.sCost as string).replace(/MP/g, product.pCost + "");
sellButtonText = (
<>
{sellButtonText} @ <Money money={eval(sCost)} />
</>
);
} else {
sellButtonText = (
<>
{sellButtonText} @ <Money money={product.sCost} />
</>
);
}
}
function openSellProductPopup(): void {
const popupId = "cmpy-mgmt-limit-product-production-popup";
createPopup(popupId, SellProductPopup, {
product: product,
city: city,
popupId: popupId,
});
}
// Limit Production button
let limitProductionButtonText = "Limit Production";
if (product.prdman[city][0]) {
limitProductionButtonText += " (" + numeralWrapper.format(product.prdman[city][1], nf) + ")";
}
function openLimitProductProdutionPopup(): void {
const popupId = "cmpy-mgmt-limit-product-production-popup";
createPopup(popupId, LimitProductProductionPopup, {
product: product,
city: city,
popupId: popupId,
});
}
function openDiscontinueProductPopup(): void {
const popupId = "cmpy-mgmt-discontinue-product-popup";
createPopup(popupId, DiscontinueProductPopup, {
rerender: props.rerender,
product: product,
industry: division,
corp: corp,
popupId: popupId,
player: props.player,
});
}
function openProductMarketTaPopup(): void {
const popupId = "cmpy-mgmt-marketta-popup";
createPopup(popupId, ProductMarketTaPopup, {
product: product,
industry: division,
popupId: popupId,
});
}
// Unfinished Product
if (!product.fin) {
return (
<div className={"cmpy-mgmt-warehouse-product-div"}>
<p>
Designing {product.name} (req. Operations/Engineers in {product.createCity})...
</p>
<br />
<p>{numeralWrapper.format(product.prog, "0.00")}% complete</p>
<br />
{hasUpgradeDashboard && (
<div>
<Button onClick={openSellProductPopup}>{sellButtonText}</Button>
<br />
<Button onClick={openLimitProductProdutionPopup}>{limitProductionButtonText}</Button>
<Button onClick={openDiscontinueProductPopup}>Discontinue</Button>
{division.hasResearch("Market-TA.I") && <Button onClick={openProductMarketTaPopup}>Market-TA</Button>}
</div>
)}
</div>
);
}
return (
<div className={"cmpy-mgmt-warehouse-product-div"}>
<p className={"tooltip"}>
{product.name}: {numeralWrapper.format(product.data[city][0], nfB)} ({numeralWrapper.format(totalGain, nfB)}/s)
<span className={"tooltiptext"}>
Prod: {numeralWrapper.format(product.data[city][1], nfB)}/s
<br />
Sell: {numeralWrapper.format(product.data[city][2], nfB)} /s
</span>
</p>
<br />
<p className={"tooltip"}>
Rating: {numeralWrapper.format(product.rat, nf)}
<span className={"tooltiptext"}>
Quality: {numeralWrapper.format(product.qlt, nf)} <br />
Performance: {numeralWrapper.format(product.per, nf)} <br />
Durability: {numeralWrapper.format(product.dur, nf)} <br />
Reliability: {numeralWrapper.format(product.rel, nf)} <br />
Aesthetics: {numeralWrapper.format(product.aes, nf)} <br />
Features: {numeralWrapper.format(product.fea, nf)}
{corp.unlockUpgrades[2] === 1 && <br />}
{corp.unlockUpgrades[2] === 1 && "Demand: " + numeralWrapper.format(product.dmd, nf)}
{corp.unlockUpgrades[3] === 1 && <br />}
{corp.unlockUpgrades[3] === 1 && "Competition: " + numeralWrapper.format(product.cmp, nf)}
</span>
</p>
<br />
<p className={"tooltip"}>
Est. Production Cost:{" "}
{numeralWrapper.formatMoney(product.pCost / CorporationConstants.ProductProductionCostRatio)}
<span className={"tooltiptext"}>An estimate of the material cost it takes to create this Product.</span>
</p>
<br />
<p className={"tooltip"}>
Est. Market Price: {numeralWrapper.formatMoney(product.pCost)}
<span className={"tooltiptext"}>
An estimate of how much consumers are willing to pay for this product. Setting the sale price above this may
result in less sales. Setting the sale price below this may result in more sales.
</span>
</p>
<div>
<Button onClick={openSellProductPopup}>{sellButtonText}</Button>
<br />
<Button onClick={openLimitProductProdutionPopup}>{limitProductionButtonText}</Button>
<Button onClick={openDiscontinueProductPopup}>Discontinue</Button>
{division.hasResearch("Market-TA.I") && <Button onClick={openProductMarketTaPopup}>Market-TA</Button>}
</div>
</div>
);
}
interface IMaterialProps {
warehouse: Warehouse;
city: string;
@ -506,15 +306,7 @@ function WarehouseRoot(props: IProps): React.ReactElement {
const product = division.products[productName];
if (!(product instanceof Product)) continue;
products.push(
<ProductComponent
rerender={props.rerender}
player={props.player}
city={props.currentCity}
corp={corp}
division={division}
key={productName}
product={product}
/>,
<ProductElem rerender={props.rerender} city={props.currentCity} key={productName} product={product} />,
);
}
}

@ -1,23 +1,24 @@
import React, { useState } from "react";
import { removePopup } from "../../ui/React/createPopup";
import { Product } from "../Product";
import { LimitProductProduction } from "../Actions";
import { Modal } from "../../ui/React/Modal";
interface IProps {
open: boolean;
onClose: () => void;
product: Product;
city: string;
popupId: string;
}
// Create a popup that lets the player limit the production of a product
export function LimitProductProductionPopup(props: IProps): React.ReactElement {
export function LimitProductProductionModal(props: IProps): React.ReactElement {
const [limit, setLimit] = useState<number | null>(null);
function limitProductProduction(): void {
let qty = limit;
if (qty === null) qty = -1;
LimitProductProduction(props.product, props.city, qty);
removePopup(props.popupId);
props.onClose();
}
function onKeyDown(event: React.KeyboardEvent<HTMLInputElement>): void {
@ -30,7 +31,7 @@ export function LimitProductProductionPopup(props: IProps): React.ReactElement {
}
return (
<>
<Modal open={props.open} onClose={props.onClose}>
<p>
Enter a limit to the amount of this product you would like to product per second. Leave the box empty to set no
limit.
@ -51,6 +52,6 @@ export function LimitProductProductionPopup(props: IProps): React.ReactElement {
>
Limit production
</button>
</>
</Modal>
);
}

@ -0,0 +1,207 @@
import React, { useState } from "react";
import { CorporationConstants } from "../data/Constants";
import { Product } from "../Product";
import { DiscontinueProductModal } from "./DiscontinueProductModal";
import { LimitProductProductionModal } from "./LimitProductProductionModal";
import { SellProductModal } from "./SellProductModal";
import { ProductMarketTaModal } from "./ProductMarketTaModal";
import { numeralWrapper } from "../../ui/numeralFormat";
import { isString } from "../../utils/helpers/isString";
import { Money } from "../../ui/React/Money";
import { useCorporation, useDivision } from "./Context";
import Typography from "@mui/material/Typography";
import Tooltip from "@mui/material/Tooltip";
import Paper from "@mui/material/Paper";
import Button from "@mui/material/Button";
import Box from "@mui/material/Box";
interface IProductProps {
city: string;
product: Product;
rerender: () => void;
}
// Creates the UI for a single Product type
export function ProductElem(props: IProductProps): React.ReactElement {
const corp = useCorporation();
const division = useDivision();
const [sellOpen, setSellOpen] = useState(false);
const [limitOpen, setLimitOpen] = useState(false);
const [discontinueOpen, setDiscontinueOpen] = useState(false);
const [marketTaOpen, setMarketTaOpen] = useState(false);
const city = props.city;
const product = props.product;
// Numeraljs formatters
const nf = "0.000";
const nfB = "0.000a"; // For numbers that might be big
const hasUpgradeDashboard = division.hasResearch("uPgrade: Dashboard");
// Total product gain = production - sale
const totalGain = product.data[city][1] - product.data[city][2];
// Sell button
let sellButtonText: JSX.Element;
if (product.sllman[city][0]) {
if (isString(product.sllman[city][1])) {
sellButtonText = (
<>
Sell ({numeralWrapper.format(product.data[city][2], nfB)}/{product.sllman[city][1]})
</>
);
} else {
sellButtonText = (
<>
Sell ({numeralWrapper.format(product.data[city][2], nfB)}/
{numeralWrapper.format(product.sllman[city][1], nfB)})
</>
);
}
} else {
sellButtonText = <>Sell (0.000/0.000)</>;
}
if (product.marketTa2) {
sellButtonText = (
<>
{sellButtonText} @ <Money money={product.marketTa2Price[city]} />
</>
);
} else if (product.marketTa1) {
const markupLimit = product.rat / product.mku;
sellButtonText = (
<>
{sellButtonText} @ <Money money={product.pCost + markupLimit} />
</>
);
} else if (product.sCost) {
if (isString(product.sCost)) {
const sCost = (product.sCost as string).replace(/MP/g, product.pCost + "");
sellButtonText = (
<>
{sellButtonText} @ <Money money={eval(sCost)} />
</>
);
} else {
sellButtonText = (
<>
{sellButtonText} @ <Money money={product.sCost} />
</>
);
}
}
// Limit Production button
let limitProductionButtonText = "Limit Production";
if (product.prdman[city][0]) {
limitProductionButtonText += " (" + numeralWrapper.format(product.prdman[city][1], nf) + ")";
}
return (
<Paper>
{!product.fin ? (
<>
<Typography>
Designing {product.name} (req. Operations/Engineers in {product.createCity})...
</Typography>
<br />
<Typography>{numeralWrapper.format(product.prog, "0.00")}% complete</Typography>
</>
) : (
<>
<Box display="flex">
<Tooltip
title={
<Typography>
Prod: {numeralWrapper.format(product.data[city][1], nfB)}/s
<br />
Sell: {numeralWrapper.format(product.data[city][2], nfB)} /s
</Typography>
}
>
<Typography>
{product.name}: {numeralWrapper.format(product.data[city][0], nfB)} (
{numeralWrapper.format(totalGain, nfB)}
/s)
</Typography>
</Tooltip>
</Box>
<Box display="flex">
<Tooltip
title={
<Typography>
Quality: {numeralWrapper.format(product.qlt, nf)} <br />
Performance: {numeralWrapper.format(product.per, nf)} <br />
Durability: {numeralWrapper.format(product.dur, nf)} <br />
Reliability: {numeralWrapper.format(product.rel, nf)} <br />
Aesthetics: {numeralWrapper.format(product.aes, nf)} <br />
Features: {numeralWrapper.format(product.fea, nf)}
{corp.unlockUpgrades[2] === 1 && <br />}
{corp.unlockUpgrades[2] === 1 && "Demand: " + numeralWrapper.format(product.dmd, nf)}
{corp.unlockUpgrades[3] === 1 && <br />}
{corp.unlockUpgrades[3] === 1 && "Competition: " + numeralWrapper.format(product.cmp, nf)}
</Typography>
}
>
<Typography>Rating: {numeralWrapper.format(product.rat, nf)}</Typography>
</Tooltip>
</Box>
<Box display="flex">
<Tooltip title={<Typography>An estimate of the material cost it takes to create this Product.</Typography>}>
<Typography>
Est. Production Cost:{" "}
{numeralWrapper.formatMoney(product.pCost / CorporationConstants.ProductProductionCostRatio)}
</Typography>
</Tooltip>
</Box>
<Box display="flex">
<Tooltip
title={
<Typography>
An estimate of how much consumers are willing to pay for this product. Setting the sale price above
this may result in less sales. Setting the sale price below this may result in more sales.
</Typography>
}
>
<Typography>Est. Market Price: {numeralWrapper.formatMoney(product.pCost)}</Typography>
</Tooltip>
</Box>
</>
)}
{(hasUpgradeDashboard || product.fin) && (
<>
<Button onClick={() => setSellOpen(true)}>{sellButtonText}</Button>
<SellProductModal product={product} city={city} open={sellOpen} onClose={() => setSellOpen(false)} />
<br />
<Button onClick={() => setLimitOpen(true)}>{limitProductionButtonText}</Button>
<LimitProductProductionModal
product={product}
city={city}
open={limitOpen}
onClose={() => setLimitOpen(false)}
/>
<Button onClick={() => setDiscontinueOpen(true)}>Discontinue</Button>
<DiscontinueProductModal
product={product}
rerender={props.rerender}
open={discontinueOpen}
onClose={() => setDiscontinueOpen(false)}
/>
{division.hasResearch("Market-TA.I") && (
<>
<Button onClick={() => setMarketTaOpen(true)}>Market-TA</Button>
<ProductMarketTaModal product={product} open={marketTaOpen} onClose={() => setMarketTaOpen(false)} />
</>
)}
</>
)}
</Paper>
);
}

@ -1,15 +1,14 @@
import React, { useState } from "react";
import { numeralWrapper } from "../../ui/numeralFormat";
import { IIndustry } from "../IIndustry";
import { Product } from "../Product";
import { Modal } from "../../ui/React/Modal";
import { useDivision } from "./Context";
interface IProps {
interface ITa2Props {
product: Product;
industry: IIndustry;
popupId: string;
}
function MarketTA2(props: IProps): React.ReactElement {
function MarketTA2(props: ITa2Props): React.ReactElement {
const markupLimit = props.product.rat / props.product.mku;
const [value, setValue] = useState(props.product.pCost);
const setRerender = useState(false)[1];
@ -72,8 +71,15 @@ function MarketTA2(props: IProps): React.ReactElement {
);
}
interface IProps {
open: boolean;
onClose: () => void;
product: Product;
}
// Create a popup that lets the player use the Market TA research for Products
export function ProductMarketTaPopup(props: IProps): React.ReactElement {
export function ProductMarketTaModal(props: IProps): React.ReactElement {
const division = useDivision();
const markupLimit = props.product.rat / props.product.mku;
const setRerender = useState(false)[1];
function rerender(): void {
@ -86,36 +92,36 @@ export function ProductMarketTaPopup(props: IProps): React.ReactElement {
}
return (
<>
<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>
{props.industry.hasResearch("Market-TA.II") && (
<MarketTA2 product={props.product} industry={props.industry} popupId={props.popupId} />
)}
</>
<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} />}
</>
</Modal>
);
}

@ -1,8 +1,14 @@
import React, { useState } from "react";
import { dialogBoxCreate } from "../../ui/React/DialogBox";
import { removePopup } from "../../ui/React/createPopup";
import { Product } from "../Product";
import { SellProduct } from "../Actions";
import { Modal } from "../../ui/React/Modal";
import Typography from "@mui/material/Typography";
import TextField from "@mui/material/TextField";
import Button from "@mui/material/Button";
import FormControlLabel from "@mui/material/FormControlLabel";
import Switch from "@mui/material/Switch";
function initialPrice(product: Product): string {
let val = product.sCost ? product.sCost + "" : "";
@ -15,13 +21,14 @@ function initialPrice(product: Product): string {
}
interface IProps {
open: boolean;
onClose: () => void;
product: Product;
city: string;
popupId: string;
}
// Create a popup that let the player manage sales of a material
export function SellProductPopup(props: IProps): React.ReactElement {
export function SellProductModal(props: IProps): React.ReactElement {
const [checked, setChecked] = useState(true);
const [iQty, setQty] = useState<string>(
props.product.sllman[props.city][1] ? props.product.sllman[props.city][1] : "",
@ -39,7 +46,7 @@ export function SellProductPopup(props: IProps): React.ReactElement {
dialogBoxCreate(err + "");
}
removePopup(props.popupId);
props.onClose();
}
function onAmtChange(event: React.ChangeEvent<HTMLInputElement>): void {
@ -55,8 +62,8 @@ export function SellProductPopup(props: IProps): React.ReactElement {
}
return (
<>
<p>
<Modal open={props.open} onClose={props.onClose}>
<Typography>
Enter the maximum amount of {props.product.name} you would like to sell per second, as well as the price at
which you would like to sell it at.
<br />
@ -76,40 +83,22 @@ export function SellProductPopup(props: IProps): React.ReactElement {
When setting the sell price, you can use the 'MP' variable to set a dynamically changing price that depends on
the Product's estimated market price. For example, if you set it to 'MP*5' then it will always be sold at five
times the estimated market price.
</p>
</Typography>
<br />
<input
className="text-input"
<TextField
value={iQty}
autoFocus={true}
type="text"
placeholder="Sell amount"
style={{ marginTop: "4px" }}
onChange={onAmtChange}
onKeyDown={onKeyDown}
/>
<input
className="text-input"
value={px}
type="text"
placeholder="Sell price"
style={{ marginTop: "4px" }}
onChange={onPriceChange}
onKeyDown={onKeyDown}
<TextField value={px} type="text" placeholder="Sell price" onChange={onPriceChange} onKeyDown={onKeyDown} />
<Button onClick={sellProduct}>Confirm</Button>
<FormControlLabel
control={<Switch checked={checked} onChange={onCheckedChange} />}
label={<Typography>Use same 'Sell Amount' for all cities</Typography>}
/>
<button className="std-button" onClick={sellProduct}>
Confirm
</button>
<div style={{ border: "1px solid white", display: "inline-block" }}>
<label htmlFor={props.popupId + "-checkbox"}>Use same 'Sell Amount' for all cities</label>
<input
checked={checked}
onChange={onCheckedChange}
id={props.popupId + "-checkbox"}
style={{ margin: "2px" }}
type="checkbox"
/>
</div>
</>
</Modal>
);
}