mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-26 17:43:48 +01:00
convert some corp to mui
This commit is contained in:
parent
510fcedf90
commit
86ddc940aa
@ -1,29 +1,27 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { removePopup } from "../../ui/React/createPopup";
|
|
||||||
import { ICorporation } from "../ICorporation";
|
|
||||||
import { Product } from "../Product";
|
import { Product } from "../Product";
|
||||||
import { IIndustry } from "../IIndustry";
|
import { Modal } from "../../ui/React/Modal";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { useDivision } from "./Context";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
|
open: boolean;
|
||||||
|
onClose: () => void;
|
||||||
product: Product;
|
product: Product;
|
||||||
industry: IIndustry;
|
|
||||||
corp: ICorporation;
|
|
||||||
popupId: string;
|
|
||||||
player: IPlayer;
|
|
||||||
rerender: () => void;
|
rerender: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a popup that lets the player discontinue a product
|
// 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 {
|
function discontinue(): void {
|
||||||
props.industry.discontinueProduct(props.product);
|
division.discontinueProduct(props.product);
|
||||||
removePopup(props.popupId);
|
props.onClose();
|
||||||
props.rerender();
|
props.rerender();
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<Modal open={props.open} onClose={props.onClose}>
|
||||||
<p>
|
<p>
|
||||||
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
|
||||||
@ -31,6 +29,6 @@ export function DiscontinueProductPopup(props: IProps): React.ReactElement {
|
|||||||
<button className="popup-box-button" onClick={discontinue}>
|
<button className="popup-box-button" onClick={discontinue}>
|
||||||
Discontinue
|
Discontinue
|
||||||
</button>
|
</button>
|
||||||
</>
|
</Modal>
|
||||||
);
|
);
|
||||||
}
|
}
|
@ -7,15 +7,12 @@ import { OfficeSpace } from "../OfficeSpace";
|
|||||||
import { Material } from "../Material";
|
import { Material } from "../Material";
|
||||||
import { Product } from "../Product";
|
import { Product } from "../Product";
|
||||||
import { Warehouse } from "../Warehouse";
|
import { Warehouse } from "../Warehouse";
|
||||||
import { DiscontinueProductPopup } from "./DiscontinueProductPopup";
|
|
||||||
import { ExportPopup } from "./ExportPopup";
|
import { ExportPopup } from "./ExportPopup";
|
||||||
import { LimitProductProductionPopup } from "./LimitProductProductionPopup";
|
|
||||||
import { MaterialMarketTaPopup } from "./MaterialMarketTaPopup";
|
import { MaterialMarketTaPopup } from "./MaterialMarketTaPopup";
|
||||||
import { SellMaterialPopup } from "./SellMaterialPopup";
|
import { SellMaterialPopup } from "./SellMaterialPopup";
|
||||||
import { SellProductPopup } from "./SellProductPopup";
|
|
||||||
import { PurchaseMaterialPopup } from "./PurchaseMaterialPopup";
|
import { PurchaseMaterialPopup } from "./PurchaseMaterialPopup";
|
||||||
import { ProductMarketTaPopup } from "./ProductMarketTaPopup";
|
|
||||||
import { SmartSupplyModal } from "./SmartSupplyModal";
|
import { SmartSupplyModal } from "./SmartSupplyModal";
|
||||||
|
import { ProductElem } from "./ProductElem";
|
||||||
import { MaterialSizes } from "../MaterialSizes";
|
import { MaterialSizes } from "../MaterialSizes";
|
||||||
|
|
||||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||||
@ -38,203 +35,6 @@ import Paper from "@mui/material/Paper";
|
|||||||
import Button from "@mui/material/Button";
|
import Button from "@mui/material/Button";
|
||||||
import Box from "@mui/material/Box";
|
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 {
|
interface IMaterialProps {
|
||||||
warehouse: Warehouse;
|
warehouse: Warehouse;
|
||||||
city: string;
|
city: string;
|
||||||
@ -506,15 +306,7 @@ function WarehouseRoot(props: IProps): React.ReactElement {
|
|||||||
const product = division.products[productName];
|
const product = division.products[productName];
|
||||||
if (!(product instanceof Product)) continue;
|
if (!(product instanceof Product)) continue;
|
||||||
products.push(
|
products.push(
|
||||||
<ProductComponent
|
<ProductElem rerender={props.rerender} city={props.currentCity} key={productName} product={product} />,
|
||||||
rerender={props.rerender}
|
|
||||||
player={props.player}
|
|
||||||
city={props.currentCity}
|
|
||||||
corp={corp}
|
|
||||||
division={division}
|
|
||||||
key={productName}
|
|
||||||
product={product}
|
|
||||||
/>,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,23 +1,24 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { removePopup } from "../../ui/React/createPopup";
|
|
||||||
import { Product } from "../Product";
|
import { Product } from "../Product";
|
||||||
import { LimitProductProduction } from "../Actions";
|
import { LimitProductProduction } from "../Actions";
|
||||||
|
import { Modal } from "../../ui/React/Modal";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
|
open: boolean;
|
||||||
|
onClose: () => void;
|
||||||
product: Product;
|
product: Product;
|
||||||
city: string;
|
city: string;
|
||||||
popupId: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a popup that lets the player limit the production of a product
|
// 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);
|
const [limit, setLimit] = useState<number | null>(null);
|
||||||
|
|
||||||
function limitProductProduction(): void {
|
function limitProductProduction(): void {
|
||||||
let qty = limit;
|
let qty = limit;
|
||||||
if (qty === null) qty = -1;
|
if (qty === null) qty = -1;
|
||||||
LimitProductProduction(props.product, props.city, qty);
|
LimitProductProduction(props.product, props.city, qty);
|
||||||
removePopup(props.popupId);
|
props.onClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
function onKeyDown(event: React.KeyboardEvent<HTMLInputElement>): void {
|
function onKeyDown(event: React.KeyboardEvent<HTMLInputElement>): void {
|
||||||
@ -30,7 +31,7 @@ export function LimitProductProductionPopup(props: IProps): React.ReactElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<Modal open={props.open} onClose={props.onClose}>
|
||||||
<p>
|
<p>
|
||||||
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.
|
||||||
@ -51,6 +52,6 @@ export function LimitProductProductionPopup(props: IProps): React.ReactElement {
|
|||||||
>
|
>
|
||||||
Limit production
|
Limit production
|
||||||
</button>
|
</button>
|
||||||
</>
|
</Modal>
|
||||||
);
|
);
|
||||||
}
|
}
|
207
src/Corporation/ui/ProductElem.tsx
Normal file
207
src/Corporation/ui/ProductElem.tsx
Normal file
@ -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 React, { useState } from "react";
|
||||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||||
import { IIndustry } from "../IIndustry";
|
|
||||||
import { Product } from "../Product";
|
import { Product } from "../Product";
|
||||||
|
import { Modal } from "../../ui/React/Modal";
|
||||||
|
import { useDivision } from "./Context";
|
||||||
|
|
||||||
interface IProps {
|
interface ITa2Props {
|
||||||
product: Product;
|
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 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];
|
||||||
@ -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
|
// 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 markupLimit = props.product.rat / props.product.mku;
|
||||||
const setRerender = useState(false)[1];
|
const setRerender = useState(false)[1];
|
||||||
function rerender(): void {
|
function rerender(): void {
|
||||||
@ -86,36 +92,36 @@ export function ProductMarketTaPopup(props: IProps): React.ReactElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<Modal open={props.open} onClose={props.onClose}>
|
||||||
<p>
|
<>
|
||||||
<u>
|
<p>
|
||||||
<strong>Market-TA.I</strong>
|
<u>
|
||||||
</u>
|
<strong>Market-TA.I</strong>
|
||||||
<br />
|
</u>
|
||||||
The maximum sale price you can mark this up to is{" "}
|
<br />
|
||||||
{numeralWrapper.formatMoney(props.product.pCost + markupLimit)}. This means that if you set the sale price
|
The maximum sale price you can mark this up to is{" "}
|
||||||
higher than this, you will begin to experience a loss in number of sales.
|
{numeralWrapper.formatMoney(props.product.pCost + markupLimit)}. This means that if you set the sale price
|
||||||
</p>
|
higher than this, you will begin to experience a loss in number of sales.
|
||||||
<div style={{ display: "block" }}>
|
</p>
|
||||||
<label className="tooltip" htmlFor="cmpy-mgmt-marketa1-checkbox" style={{ color: "white" }}>
|
<div style={{ display: "block" }}>
|
||||||
Use Market-TA.I for Auto-Sale Price
|
<label className="tooltip" htmlFor="cmpy-mgmt-marketa1-checkbox" style={{ color: "white" }}>
|
||||||
<span className="tooltiptext">
|
Use Market-TA.I for Auto-Sale Price
|
||||||
If this is enabled, then this Product will automatically be sold at the price identified by Market-TA.I
|
<span className="tooltiptext">
|
||||||
(i.e. the price shown above).
|
If this is enabled, then this Product will automatically be sold at the price identified by Market-TA.I
|
||||||
</span>
|
(i.e. the price shown above).
|
||||||
</label>
|
</span>
|
||||||
<input
|
</label>
|
||||||
onChange={onChange}
|
<input
|
||||||
className="text-input"
|
onChange={onChange}
|
||||||
id="cmpy-mgmt-marketa1-checkbox"
|
className="text-input"
|
||||||
style={{ margin: "3px" }}
|
id="cmpy-mgmt-marketa1-checkbox"
|
||||||
type="checkbox"
|
style={{ margin: "3px" }}
|
||||||
checked={props.product.marketTa1}
|
type="checkbox"
|
||||||
/>
|
checked={props.product.marketTa1}
|
||||||
</div>
|
/>
|
||||||
{props.industry.hasResearch("Market-TA.II") && (
|
</div>
|
||||||
<MarketTA2 product={props.product} industry={props.industry} popupId={props.popupId} />
|
{division.hasResearch("Market-TA.II") && <MarketTA2 product={props.product} />}
|
||||||
)}
|
</>
|
||||||
</>
|
</Modal>
|
||||||
);
|
);
|
||||||
}
|
}
|
@ -1,8 +1,14 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { dialogBoxCreate } from "../../ui/React/DialogBox";
|
import { dialogBoxCreate } from "../../ui/React/DialogBox";
|
||||||
import { removePopup } from "../../ui/React/createPopup";
|
|
||||||
import { Product } from "../Product";
|
import { Product } from "../Product";
|
||||||
import { SellProduct } from "../Actions";
|
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 {
|
function initialPrice(product: Product): string {
|
||||||
let val = product.sCost ? product.sCost + "" : "";
|
let val = product.sCost ? product.sCost + "" : "";
|
||||||
@ -15,13 +21,14 @@ function initialPrice(product: Product): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
|
open: boolean;
|
||||||
|
onClose: () => void;
|
||||||
product: Product;
|
product: Product;
|
||||||
city: string;
|
city: string;
|
||||||
popupId: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a popup that let the player manage sales of a material
|
// 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 [checked, setChecked] = useState(true);
|
||||||
const [iQty, setQty] = useState<string>(
|
const [iQty, setQty] = useState<string>(
|
||||||
props.product.sllman[props.city][1] ? props.product.sllman[props.city][1] : "",
|
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 + "");
|
dialogBoxCreate(err + "");
|
||||||
}
|
}
|
||||||
|
|
||||||
removePopup(props.popupId);
|
props.onClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
function onAmtChange(event: React.ChangeEvent<HTMLInputElement>): void {
|
function onAmtChange(event: React.ChangeEvent<HTMLInputElement>): void {
|
||||||
@ -55,8 +62,8 @@ export function SellProductPopup(props: IProps): React.ReactElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<Modal open={props.open} onClose={props.onClose}>
|
||||||
<p>
|
<Typography>
|
||||||
Enter the maximum amount of {props.product.name} you would like to sell per second, as well as the price at
|
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.
|
which you would like to sell it at.
|
||||||
<br />
|
<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
|
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
|
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.
|
times the estimated market price.
|
||||||
</p>
|
</Typography>
|
||||||
<br />
|
<br />
|
||||||
<input
|
<TextField
|
||||||
className="text-input"
|
|
||||||
value={iQty}
|
value={iQty}
|
||||||
autoFocus={true}
|
autoFocus={true}
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Sell amount"
|
placeholder="Sell amount"
|
||||||
style={{ marginTop: "4px" }}
|
|
||||||
onChange={onAmtChange}
|
onChange={onAmtChange}
|
||||||
onKeyDown={onKeyDown}
|
onKeyDown={onKeyDown}
|
||||||
/>
|
/>
|
||||||
<input
|
<TextField value={px} type="text" placeholder="Sell price" onChange={onPriceChange} onKeyDown={onKeyDown} />
|
||||||
className="text-input"
|
<Button onClick={sellProduct}>Confirm</Button>
|
||||||
value={px}
|
<FormControlLabel
|
||||||
type="text"
|
control={<Switch checked={checked} onChange={onCheckedChange} />}
|
||||||
placeholder="Sell price"
|
label={<Typography>Use same 'Sell Amount' for all cities</Typography>}
|
||||||
style={{ marginTop: "4px" }}
|
|
||||||
onChange={onPriceChange}
|
|
||||||
onKeyDown={onKeyDown}
|
|
||||||
/>
|
/>
|
||||||
<button className="std-button" onClick={sellProduct}>
|
</Modal>
|
||||||
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>
|
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user