Merge pull request #2751 from nickofolas/improvement/ui-pass

UI Improvements Pass
This commit is contained in:
hydroflame
2022-01-26 00:44:20 -05:00
committed by GitHub
18 changed files with 581 additions and 445 deletions

View File

@ -26,6 +26,7 @@ import Table from "@mui/material/Table";
import TableBody from "@mui/material/TableBody"; import TableBody from "@mui/material/TableBody";
import TableRow from "@mui/material/TableRow"; import TableRow from "@mui/material/TableRow";
import { TableCell } from "../../ui/React/Table"; import { TableCell } from "../../ui/React/Table";
import { Box } from "@mui/material";
interface IProps { interface IProps {
office: OfficeSpace; office: OfficeSpace;
@ -430,20 +431,17 @@ export function IndustryOffice(props: IProps): React.ReactElement {
<Typography> <Typography>
Size: {props.office.employees.length} / {props.office.size} employees Size: {props.office.employees.length} / {props.office.size} employees
</Typography> </Typography>
<Box sx={{ display: 'grid', gridTemplateColumns: '1fr', width: 'fit-content' }}>
<Box sx={{ gridTemplateColumns: 'repeat(3, 1fr)' }}>
<Tooltip title={<Typography>Automatically hires an employee and gives him/her a random name</Typography>}> <Tooltip title={<Typography>Automatically hires an employee and gives him/her a random name</Typography>}>
<span>
<Button disabled={props.office.atCapacity()} onClick={autohireEmployeeButtonOnClick}> <Button disabled={props.office.atCapacity()} onClick={autohireEmployeeButtonOnClick}>
Hire Employee Hire Employee
</Button> </Button>
</span>
</Tooltip> </Tooltip>
<br />
<Tooltip title={<Typography>Upgrade the office's size so that it can hold more employees!</Typography>}> <Tooltip title={<Typography>Upgrade the office's size so that it can hold more employees!</Typography>}>
<span>
<Button disabled={corp.funds < 0} onClick={() => setUpgradeOfficeSizeOpen(true)}> <Button disabled={corp.funds < 0} onClick={() => setUpgradeOfficeSizeOpen(true)}>
Upgrade size Upgrade size
</Button> </Button>
</span>
</Tooltip> </Tooltip>
<UpgradeOfficeSizeModal <UpgradeOfficeSizeModal
rerender={props.rerender} rerender={props.rerender}
@ -457,11 +455,9 @@ export function IndustryOffice(props: IProps): React.ReactElement {
<Tooltip <Tooltip
title={<Typography>Throw an office party to increase your employee's morale and happiness</Typography>} title={<Typography>Throw an office party to increase your employee's morale and happiness</Typography>}
> >
<span>
<Button disabled={corp.funds < 0} onClick={() => setThrowPartyOpen(true)}> <Button disabled={corp.funds < 0} onClick={() => setThrowPartyOpen(true)}>
Throw Party Throw Party
</Button> </Button>
</span>
</Tooltip> </Tooltip>
<ThrowPartyModal <ThrowPartyModal
rerender={props.rerender} rerender={props.rerender}
@ -472,9 +468,9 @@ export function IndustryOffice(props: IProps): React.ReactElement {
</> </>
)} )}
<br /> </Box>
<SwitchButton manualMode={employeeManualAssignMode} switchMode={setEmployeeManualAssignMode} /> <SwitchButton manualMode={employeeManualAssignMode} switchMode={setEmployeeManualAssignMode} />
</Box>
{employeeManualAssignMode ? ( {employeeManualAssignMode ? (
<ManualManagement rerender={props.rerender} office={props.office} /> <ManualManagement rerender={props.rerender} office={props.office} />
) : ( ) : (

View File

@ -139,12 +139,12 @@ function WarehouseRoot(props: IProps): React.ReactElement {
{numeralWrapper.formatBigNumber(props.warehouse.size)} {numeralWrapper.formatBigNumber(props.warehouse.size)}
</Typography> </Typography>
</Tooltip> </Tooltip>
</Box>
<Button disabled={!canAffordUpgrade} onClick={upgradeWarehouseOnClick}> <Button disabled={!canAffordUpgrade} onClick={upgradeWarehouseOnClick}>
Upgrade Warehouse Size -&nbsp; Upgrade Warehouse Size -&nbsp;
<MoneyCost money={sizeUpgradeCost} corp={corp} /> <MoneyCost money={sizeUpgradeCost} corp={corp} />
</Button> </Button>
</Box>
<Typography>This industry uses the following equation for its production: </Typography> <Typography>This industry uses the following equation for its production: </Typography>
<br /> <br />

View File

@ -112,7 +112,7 @@ export function MaterialElem(props: IMaterialProps): React.ReactElement {
return ( return (
<Paper> <Paper>
<Box display="flex"> <Box sx={{ display: 'grid', gridTemplateColumns: '2fr 1fr', m: '5px' }}>
<Box> <Box>
<Tooltip <Tooltip
title={ title={
@ -149,11 +149,10 @@ export function MaterialElem(props: IMaterialProps): React.ReactElement {
</Tooltip> </Tooltip>
</Box> </Box>
<Box> <Box sx={{ "& button": { width: '100%' } }}>
<Tooltip <Tooltip
title={tutorial ? <Typography>Purchase your required materials to get production started!</Typography> : ""} title={tutorial ? <Typography>Purchase your required materials to get production started!</Typography> : ""}
> >
<span>
<Button <Button
color={tutorial ? "error" : "primary"} color={tutorial ? "error" : "primary"}
onClick={() => setPurchaseMaterialOpen(true)} onClick={() => setPurchaseMaterialOpen(true)}
@ -161,7 +160,6 @@ export function MaterialElem(props: IMaterialProps): React.ReactElement {
> >
{purchaseButtonText} {purchaseButtonText}
</Button> </Button>
</span>
</Tooltip> </Tooltip>
<PurchaseMaterialModal <PurchaseMaterialModal
mat={mat} mat={mat}
@ -177,7 +175,6 @@ export function MaterialElem(props: IMaterialProps): React.ReactElement {
<ExportModal mat={mat} open={exportOpen} onClose={() => setExportOpen(false)} /> <ExportModal mat={mat} open={exportOpen} onClose={() => setExportOpen(false)} />
</> </>
)} )}
<br />
<Button <Button
color={division.prodMats.includes(props.mat.name) && !mat.sllman[0] ? "error" : "primary"} color={division.prodMats.includes(props.mat.name) && !mat.sllman[0] ? "error" : "primary"}

View File

@ -89,6 +89,7 @@ export function Overview({ rerender }: IProps): React.ReactElement {
<StatsTable rows={multRows} /> <StatsTable rows={multRows} />
<br /> <br />
<BonusTime /> <BonusTime />
<Box sx={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', width: 'fit-content' }}>
<Tooltip <Tooltip
title={ title={
<Typography> <Typography>
@ -102,6 +103,7 @@ export function Overview({ rerender }: IProps): React.ReactElement {
</Tooltip> </Tooltip>
{corp.public ? <PublicButtons rerender={rerender} /> : <PrivateButtons rerender={rerender} />} {corp.public ? <PublicButtons rerender={rerender} /> : <PrivateButtons rerender={rerender} />}
<BribeButton /> <BribeButton />
</Box>
<br /> <br />
<Upgrades rerender={rerender} /> <Upgrades rerender={rerender} />
</> </>
@ -125,11 +127,9 @@ function PrivateButtons({ rerender }: IPrivateButtonsProps): React.ReactElement
return ( return (
<> <>
<Tooltip title={<Typography>{findInvestorsTooltip}</Typography>}> <Tooltip title={<Typography>{findInvestorsTooltip}</Typography>}>
<span>
<Button disabled={!fundingAvailable} onClick={() => setFindInvestorsopen(true)}> <Button disabled={!fundingAvailable} onClick={() => setFindInvestorsopen(true)}>
Find Investors Find Investors
</Button> </Button>
</span>
</Tooltip> </Tooltip>
<Tooltip <Tooltip
title={ title={
@ -143,7 +143,6 @@ function PrivateButtons({ rerender }: IPrivateButtonsProps): React.ReactElement
</Tooltip> </Tooltip>
<FindInvestorsModal open={findInvestorsopen} onClose={() => setFindInvestorsopen(false)} rerender={rerender} /> <FindInvestorsModal open={findInvestorsopen} onClose={() => setFindInvestorsopen(false)} rerender={rerender} />
<GoPublicModal open={goPublicopen} onClose={() => setGoPublicopen(false)} rerender={rerender} /> <GoPublicModal open={goPublicopen} onClose={() => setGoPublicopen(false)} rerender={rerender} />
<br />
</> </>
); );
} }
@ -212,28 +211,21 @@ function PublicButtons({ rerender }: IPublicButtonsProps): React.ReactElement {
return ( return (
<> <>
<Tooltip title={<Typography>{sellSharesTooltip}</Typography>}> <Tooltip title={<Typography>{sellSharesTooltip}</Typography>}>
<span>
<Button disabled={sellSharesOnCd} onClick={() => setSellSharesOpen(true)}> <Button disabled={sellSharesOnCd} onClick={() => setSellSharesOpen(true)}>
Sell Shares Sell Shares
</Button> </Button>
</span>
</Tooltip> </Tooltip>
<SellSharesModal open={sellSharesOpen} onClose={() => setSellSharesOpen(false)} rerender={rerender} /> <SellSharesModal open={sellSharesOpen} onClose={() => setSellSharesOpen(false)} rerender={rerender} />
<Tooltip title={<Typography>Buy back shares you that previously issued or sold at market price.</Typography>}> <Tooltip title={<Typography>Buy back shares you that previously issued or sold at market price.</Typography>}>
<span>
<Button disabled={corp.issuedShares < 1} onClick={() => setBuybackSharesOpen(true)}> <Button disabled={corp.issuedShares < 1} onClick={() => setBuybackSharesOpen(true)}>
Buyback shares Buyback shares
</Button> </Button>
</span>
</Tooltip> </Tooltip>
<BuybackSharesModal open={buybackSharesOpen} onClose={() => setBuybackSharesOpen(false)} rerender={rerender} /> <BuybackSharesModal open={buybackSharesOpen} onClose={() => setBuybackSharesOpen(false)} rerender={rerender} />
<br />
<Tooltip title={<Typography>{issueNewSharesTooltip}</Typography>}> <Tooltip title={<Typography>{issueNewSharesTooltip}</Typography>}>
<span>
<Button disabled={issueNewSharesOnCd} onClick={() => setIssueNewSharesOpen(true)}> <Button disabled={issueNewSharesOnCd} onClick={() => setIssueNewSharesOpen(true)}>
Issue New Shares Issue New Shares
</Button> </Button>
</span>
</Tooltip> </Tooltip>
<IssueNewSharesModal open={issueNewSharesOpen} onClose={() => setIssueNewSharesOpen(false)} /> <IssueNewSharesModal open={issueNewSharesOpen} onClose={() => setIssueNewSharesOpen(false)} />
<Tooltip <Tooltip
@ -242,7 +234,6 @@ function PublicButtons({ rerender }: IPublicButtonsProps): React.ReactElement {
<Button onClick={() => setIssueDividendsOpen(true)}>Issue Dividends</Button> <Button onClick={() => setIssueDividendsOpen(true)}>Issue Dividends</Button>
</Tooltip> </Tooltip>
<IssueDividendsModal open={issueDividendsOpen} onClose={() => setIssueDividendsOpen(false)} /> <IssueDividendsModal open={issueDividendsOpen} onClose={() => setIssueDividendsOpen(false)} />
<br />
</> </>
); );
} }
@ -269,11 +260,9 @@ function BribeButton(): React.ReactElement {
: "Your Corporation is not powerful enough to bribe Faction leaders" : "Your Corporation is not powerful enough to bribe Faction leaders"
} }
> >
<span>
<Button disabled={!canBribe} onClick={openBribe}> <Button disabled={!canBribe} onClick={openBribe}>
Bribe Factions Bribe Factions
</Button> </Button>
</span>
</Tooltip> </Tooltip>
<BribeFactionModal open={open} onClose={() => setOpen(false)} /> <BribeFactionModal open={open} onClose={() => setOpen(false)} />
</> </>

View File

@ -6,17 +6,18 @@ import { IIndustry } from "../IIndustry";
import { Research } from "../Actions"; import { Research } from "../Actions";
import { Node } from "../ResearchTree"; import { Node } from "../ResearchTree";
import { ResearchMap } from "../ResearchMap"; import { ResearchMap } from "../ResearchMap";
import { Settings } from "../../Settings/Settings";
import { dialogBoxCreate } from "../../ui/React/DialogBox"; import { dialogBoxCreate } from "../../ui/React/DialogBox";
import Typography from "@mui/material/Typography"; import Typography from "@mui/material/Typography";
import Tooltip from "@mui/material/Tooltip"; import Tooltip from "@mui/material/Tooltip";
import Button from "@mui/material/Button"; import Button from "@mui/material/Button";
import Box from "@mui/material/Box"; import Box from "@mui/material/Box";
import ListItemButton from "@mui/material/ListItemButton";
import ListItemText from "@mui/material/ListItemText";
import Collapse from "@mui/material/Collapse"; import Collapse from "@mui/material/Collapse";
import ExpandMore from "@mui/icons-material/ExpandMore"; import ExpandMore from "@mui/icons-material/ExpandMore";
import ExpandLess from "@mui/icons-material/ExpandLess"; import ExpandLess from "@mui/icons-material/ExpandLess";
import CheckIcon from '@mui/icons-material/Check';
interface INodeProps { interface INodeProps {
n: Node | null; n: Node | null;
division: IIndustry; division: IIndustry;
@ -52,8 +53,8 @@ function Upgrade({ n, division }: INodeProps): React.ReactElement {
color = "info"; color = "info";
} }
const but = ( const wrapInTooltip = (ele: React.ReactElement): React.ReactElement => {
<Box> return (
<Tooltip <Tooltip
title={ title={
<Typography> <Typography>
@ -63,12 +64,22 @@ function Upgrade({ n, division }: INodeProps): React.ReactElement {
</Typography> </Typography>
} }
> >
{ele}
</Tooltip>
)
}
const but = (
<Box>
{wrapInTooltip(
<span> <span>
<Button color={color} disabled={disabled && !n.researched} onClick={research}> <Button color={color} disabled={disabled && !n.researched} onClick={research}
{n.text} style={{ width: '100%', textAlign: 'left', justifyContent: 'unset' }}
>
{n.researched && (<CheckIcon sx={{ mr: 1 }} />)}{n.text}
</Button> </Button>
</span> </span>
</Tooltip> )}
</Box> </Box>
); );
@ -76,15 +87,25 @@ function Upgrade({ n, division }: INodeProps): React.ReactElement {
return ( return (
<Box> <Box>
<Box display="flex"> <Box display="flex" sx={{ border: '1px solid ' + Settings.theme.well }}>
{but} {wrapInTooltip(
<ListItemButton onClick={() => setOpen((old) => !old)}> <span style={{ width: '100%' }}>
<ListItemText /> <Button color={color} disabled={disabled && !n.researched} onClick={research} sx={{
width: '100%',
textAlign: 'left',
justifyContent: 'unset',
borderColor: Settings.theme.button
}}>
{n.researched && (<CheckIcon sx={{ mr: 1 }} />)}{n.text}
</Button>
</span>
)}
<Button onClick={() => setOpen((old) => !old)} sx={{ borderColor: Settings.theme.button, minWidth: 'fit-content' }}>
{open ? <ExpandLess color="primary" /> : <ExpandMore color="primary" />} {open ? <ExpandLess color="primary" /> : <ExpandMore color="primary" />}
</ListItemButton> </Button>
</Box> </Box>
<Collapse in={open} unmountOnExit> <Collapse in={open} unmountOnExit>
<Box m={4}> <Box m={1}>
{n.children.map((m) => ( {n.children.map((m) => (
<Upgrade key={m.text} division={division} n={m} /> <Upgrade key={m.text} division={division} n={m} />
))} ))}
@ -108,7 +129,7 @@ export function ResearchModal(props: IProps): React.ReactElement {
return ( return (
<Modal open={props.open} onClose={props.onClose}> <Modal open={props.open} onClose={props.onClose}>
<Upgrade division={props.industry} n={researchTree.root} /> <Upgrade division={props.industry} n={researchTree.root} />
<Typography> <Typography sx={{ mt: 1 }}>
Research points: {props.industry.sciResearch.qty.toFixed(3)} Research points: {props.industry.sciResearch.qty.toFixed(3)}
<br /> <br />
Multipliers from research: Multipliers from research:

View File

@ -77,7 +77,7 @@ export function DonateOption(props: IProps): React.ReactElement {
} }
return ( return (
<Paper sx={{ my: 1, p: 1, width: "100%" }}> <Paper sx={{ my: 1, p: 1 }}>
<Status /> <Status />
{props.disabled ? ( {props.disabled ? (
<Typography> <Typography>

View File

@ -19,7 +19,7 @@ type IProps = {
export function Option(props: IProps): React.ReactElement { export function Option(props: IProps): React.ReactElement {
return ( return (
<Box> <Box>
<Paper sx={{ my: 1, p: 1, width: "100%" }}> <Paper sx={{ my: 1, p: 1 }}>
<Button onClick={props.onClick}>{props.buttonText}</Button> <Button onClick={props.onClick}>{props.buttonText}</Button>
<Typography>{props.infoText}</Typography> <Typography>{props.infoText}</Typography>
</Paper> </Paper>

View File

@ -31,7 +31,7 @@ export function AscensionModal(props: IProps): React.ReactElement {
props.onAscend(); props.onAscend();
const res = gang.ascendMember(props.member); const res = gang.ascendMember(props.member);
dialogBoxCreate( dialogBoxCreate(
<Typography> <>
You ascended {props.member.name}!<br /> You ascended {props.member.name}!<br />
<br /> <br />
Your gang lost {numeralWrapper.formatRespect(res.respect)} respect. Your gang lost {numeralWrapper.formatRespect(res.respect)} respect.
@ -51,7 +51,7 @@ export function AscensionModal(props: IProps): React.ReactElement {
<br /> <br />
Charisma: x{numeralWrapper.format(res.cha, "0.000")} Charisma: x{numeralWrapper.format(res.cha, "0.000")}
<br /> <br />
</Typography>, </>
); );
props.onClose(); props.onClose();
} }

View File

@ -2,20 +2,27 @@
* React Component for the popup that manages gang members upgrades * React Component for the popup that manages gang members upgrades
*/ */
import React, { useState } from "react"; import React, { useState } from "react";
import { formatNumber } from "../../utils/StringHelperFunctions";
import { numeralWrapper } from "../../ui/numeralFormat";
import { GangMemberUpgrades } from "../GangMemberUpgrades";
import { GangMemberUpgrade } from "../GangMemberUpgrade";
import { Money } from "../../ui/React/Money";
import { useGang } from "./Context"; import { useGang } from "./Context";
import { GangMember } from "../GangMember"; import { generateTableRow } from "./GangMemberStats";
import { UpgradeType } from "../data/upgrades";
import { use } from "../../ui/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 Tooltip from "@mui/material/Tooltip"; import Tooltip from "@mui/material/Tooltip";
import Box from "@mui/material/Box"; import Box from "@mui/material/Box";
import Paper from "@mui/material/Paper"; import Paper from "@mui/material/Paper";
import Select, { SelectChangeEvent } from "@mui/material/Select";
import { MenuItem, Table, TableBody, TextField } from "@mui/material";
import SearchIcon from "@mui/icons-material/Search";
import { numeralWrapper } from "../../ui/numeralFormat";
import { GangMemberUpgrades } from "../GangMemberUpgrades";
import { GangMemberUpgrade } from "../GangMemberUpgrade";
import { Money } from "../../ui/React/Money";
import { GangMember } from "../GangMember";
import { UpgradeType } from "../data/upgrades";
import { use } from "../../ui/Context";
import { Settings } from "../../Settings/Settings";
import { characterOverviewStyles as useStyles } from "../../ui/React/CharacterOverview";
interface INextRevealProps { interface INextRevealProps {
upgrades: string[]; upgrades: string[];
@ -46,12 +53,10 @@ function NextReveal(props: INextRevealProps): React.ReactElement {
function PurchasedUpgrade({ upgName }: { upgName: string }): React.ReactElement { function PurchasedUpgrade({ upgName }: { upgName: string }): React.ReactElement {
const upg = GangMemberUpgrades[upgName]; const upg = GangMemberUpgrades[upgName];
return ( return (
<Paper sx={{ mx: 1, p: 1 }}> <Paper sx={{ p: 1 }}>
<Box display="flex">
<Tooltip title={<Typography dangerouslySetInnerHTML={{ __html: upg.desc }} />}> <Tooltip title={<Typography dangerouslySetInnerHTML={{ __html: upg.desc }} />}>
<Typography>{upg.name}</Typography> <Typography>{upg.name}</Typography>
</Tooltip> </Tooltip>
</Box>
</Paper> </Paper>
); );
} }
@ -72,8 +77,8 @@ function UpgradeButton(props: IUpgradeButtonProps): React.ReactElement {
return ( return (
<Tooltip title={<Typography dangerouslySetInnerHTML={{ __html: props.upg.desc }} />}> <Tooltip title={<Typography dangerouslySetInnerHTML={{ __html: props.upg.desc }} />}>
<span> <span>
<Typography>{props.upg.name}</Typography> <Button onClick={onClick} sx={{ display: 'flex', flexDirection: 'column', width: '100%', height: '100%' }}>
<Button onClick={onClick}> <Typography sx={{ display: 'block' }}>{props.upg.name}</Typography>
<Money money={gang.getUpgradeCost(props.upg)} /> <Money money={gang.getUpgradeCost(props.upg)} />
</Button> </Button>
</span> </span>
@ -86,12 +91,16 @@ interface IPanelProps {
} }
function GangMemberUpgradePanel(props: IPanelProps): React.ReactElement { function GangMemberUpgradePanel(props: IPanelProps): React.ReactElement {
const classes = useStyles();
const gang = useGang(); const gang = useGang();
const player = use.Player(); const player = use.Player();
const setRerender = useState(false)[1]; const setRerender = useState(false)[1];
const [currentCategory, setCurrentCategory] = useState("Weapons");
function rerender(): void { function rerender(): void {
setRerender((old) => !old); setRerender((old) => !old);
} }
function filterUpgrades(list: string[], type: UpgradeType): GangMemberUpgrade[] { function filterUpgrades(list: string[], type: UpgradeType): GangMemberUpgrade[] {
return Object.keys(GangMemberUpgrades) return Object.keys(GangMemberUpgrades)
.filter((upgName: string) => { .filter((upgName: string) => {
@ -103,12 +112,26 @@ function GangMemberUpgradePanel(props: IPanelProps): React.ReactElement {
}) })
.map((upgName: string) => GangMemberUpgrades[upgName]); .map((upgName: string) => GangMemberUpgrades[upgName]);
} }
const onChange = (event: SelectChangeEvent<string>): void => {
setCurrentCategory(event.target.value);
rerender()
}
const weaponUpgrades = filterUpgrades(props.member.upgrades, UpgradeType.Weapon); const weaponUpgrades = filterUpgrades(props.member.upgrades, UpgradeType.Weapon);
const armorUpgrades = filterUpgrades(props.member.upgrades, UpgradeType.Armor); const armorUpgrades = filterUpgrades(props.member.upgrades, UpgradeType.Armor);
const vehicleUpgrades = filterUpgrades(props.member.upgrades, UpgradeType.Vehicle); const vehicleUpgrades = filterUpgrades(props.member.upgrades, UpgradeType.Vehicle);
const rootkitUpgrades = filterUpgrades(props.member.upgrades, UpgradeType.Rootkit); const rootkitUpgrades = filterUpgrades(props.member.upgrades, UpgradeType.Rootkit);
const augUpgrades = filterUpgrades(props.member.augmentations, UpgradeType.Augmentation); const augUpgrades = filterUpgrades(props.member.augmentations, UpgradeType.Augmentation);
const categories: { [key: string]: (GangMemberUpgrade[] | UpgradeType)[] } = {
'Weapons': [weaponUpgrades, UpgradeType.Weapon],
'Armor': [armorUpgrades, UpgradeType.Armor],
'Vehicles': [vehicleUpgrades, UpgradeType.Vehicle],
'Rootkits': [rootkitUpgrades, UpgradeType.Rootkit],
'Augmentations': [augUpgrades, UpgradeType.Augmentation]
};
const asc = { const asc = {
hack: props.member.calculateAscensionMult(props.member.hack_asc_points), hack: props.member.calculateAscensionMult(props.member.hack_asc_points),
str: props.member.calculateAscensionMult(props.member.str_asc_points), str: props.member.calculateAscensionMult(props.member.str_asc_points),
@ -119,26 +142,89 @@ function GangMemberUpgradePanel(props: IPanelProps): React.ReactElement {
}; };
return ( return (
<Paper> <Paper>
<Box display="grid" sx={{ gridTemplateColumns: '1fr 1fr', m: 1, gap: 1 }}>
<span>
<Typography variant="h5" color="primary"> <Typography variant="h5" color="primary">
{props.member.name} ({props.member.task}) {props.member.name} ({props.member.task})
</Typography> </Typography>
<Tooltip
title={
<Typography> <Typography>
Hack: {props.member.hack} (x Hk: x{numeralWrapper.formatMultiplier(props.member.hack_mult * asc.hack)}(x
{formatNumber(props.member.hack_mult * asc.hack, 2)})<br /> {numeralWrapper.formatMultiplier(props.member.hack_mult)} Eq, x{numeralWrapper.formatMultiplier(asc.hack)}{" "}
Str: {props.member.str} (x Asc)
{formatNumber(props.member.str_mult * asc.str, 2)})<br />
Def: {props.member.def} (x
{formatNumber(props.member.def_mult * asc.def, 2)})<br />
Dex: {props.member.dex} (x
{formatNumber(props.member.dex_mult * asc.dex, 2)})<br />
Agi: {props.member.agi} (x
{formatNumber(props.member.agi_mult * asc.agi, 2)})<br />
Cha: {props.member.cha} (x
{formatNumber(props.member.cha_mult * asc.cha, 2)})
</Typography>
<Box display="flex" flexWrap="wrap">
<Typography>Purchased Upgrades: </Typography>
<br /> <br />
St: x{numeralWrapper.formatMultiplier(props.member.str_mult * asc.str)}
(x{numeralWrapper.formatMultiplier(props.member.str_mult)} Eq, x{numeralWrapper.formatMultiplier(asc.str)}{" "}
Asc)
<br />
Df: x{numeralWrapper.formatMultiplier(props.member.def_mult * asc.def)}
(x{numeralWrapper.formatMultiplier(props.member.def_mult)} Eq, x{numeralWrapper.formatMultiplier(asc.def)}{" "}
Asc)
<br />
Dx: x{numeralWrapper.formatMultiplier(props.member.dex_mult * asc.dex)}
(x{numeralWrapper.formatMultiplier(props.member.dex_mult)} Eq, x{numeralWrapper.formatMultiplier(asc.dex)}{" "}
Asc)
<br />
Ag: x{numeralWrapper.formatMultiplier(props.member.agi_mult * asc.agi)}
(x{numeralWrapper.formatMultiplier(props.member.agi_mult)} Eq, x{numeralWrapper.formatMultiplier(asc.agi)}{" "}
Asc)
<br />
Ch: x{numeralWrapper.formatMultiplier(props.member.cha_mult * asc.cha)}
(x{numeralWrapper.formatMultiplier(props.member.cha_mult)} Eq, x{numeralWrapper.formatMultiplier(asc.cha)}{" "}
Asc)
</Typography>
}
>
<Table>
<TableBody>
{generateTableRow("Hacking", props.member.hack, props.member.hack_exp, Settings.theme.hack, classes)}
{generateTableRow("Strength", props.member.str, props.member.str_exp, Settings.theme.combat, classes)}
{generateTableRow("Defense", props.member.def, props.member.def_exp, Settings.theme.combat, classes)}
{generateTableRow("Dexterity", props.member.dex, props.member.dex_exp, Settings.theme.combat, classes)}
{generateTableRow("Agility", props.member.agi, props.member.agi_exp, Settings.theme.combat, classes)}
{generateTableRow("Charisma", props.member.cha, props.member.cha_exp, Settings.theme.cha, classes)}
</TableBody>
</Table>
</Tooltip>
</span>
<span>
<Select onChange={onChange} value={currentCategory} sx={{ width: '100%', mb: 1 }}>
{Object.keys(categories).map((k, i) => (
<MenuItem key={i + 1} value={k}>
<Typography variant="h6">{k}</Typography>
</MenuItem>
))}
</Select>
<Box sx={{ width: '100%' }}>
{(categories[currentCategory][0] as GangMemberUpgrade[]).length === 0 && (
<Typography>
All upgrades owned!
</Typography>
)}
<Box display="grid" sx={{ gridTemplateColumns: '1fr 1fr' }}>
{(categories[currentCategory][0] as GangMemberUpgrade[]).map((upg) => (
<UpgradeButton
key={upg.name}
rerender={rerender}
member={props.member}
upg={upg}
/>
))}
</Box>
<NextReveal
type={categories[currentCategory][1] as UpgradeType}
upgrades={props.member.upgrades}
/>
</Box>
</span>
</Box>
<Typography sx={{ mx: 1 }}>Purchased Upgrades: </Typography>
<Box display="grid" sx={{ gridTemplateColumns: 'repeat(4, 1fr)', m: 1 }}>
{props.member.upgrades.map((upg: string) => ( {props.member.upgrades.map((upg: string) => (
<PurchasedUpgrade key={upg} upgName={upg} /> <PurchasedUpgrade key={upg} upgName={upg} />
))} ))}
@ -146,59 +232,22 @@ function GangMemberUpgradePanel(props: IPanelProps): React.ReactElement {
<PurchasedUpgrade key={upg} upgName={upg} /> <PurchasedUpgrade key={upg} upgName={upg} />
))} ))}
</Box> </Box>
<Box display="flex" justifyContent="space-around"> </Paper >
<Box>
<Typography variant="h6" color="primary">
Weapons
</Typography>
{weaponUpgrades.map((upg) => (
<UpgradeButton key={upg.name} rerender={rerender} member={props.member} upg={upg} />
))}
<NextReveal type={UpgradeType.Weapon} upgrades={props.member.upgrades} />
</Box>
<Box>
<Typography variant="h6" color="primary">
Armor
</Typography>
{armorUpgrades.map((upg) => (
<UpgradeButton key={upg.name} rerender={rerender} member={props.member} upg={upg} />
))}
<NextReveal type={UpgradeType.Armor} upgrades={props.member.upgrades} />
</Box>
<Box>
<Typography variant="h6" color="primary">
Vehicles
</Typography>
{vehicleUpgrades.map((upg) => (
<UpgradeButton key={upg.name} rerender={rerender} member={props.member} upg={upg} />
))}
<NextReveal type={UpgradeType.Vehicle} upgrades={props.member.upgrades} />
</Box>
<Box>
<Typography variant="h6" color="primary">
Rootkits
</Typography>
{rootkitUpgrades.map((upg) => (
<UpgradeButton key={upg.name} rerender={rerender} member={props.member} upg={upg} />
))}
<NextReveal type={UpgradeType.Rootkit} upgrades={props.member.upgrades} />
</Box>
<Box>
<Typography variant="h6" color="primary">
Augmentations
</Typography>
{augUpgrades.map((upg) => (
<UpgradeButton key={upg.name} rerender={rerender} member={props.member} upg={upg} />
))}
<NextReveal type={UpgradeType.Augmentation} upgrades={props.member.upgrades} />
</Box>
</Box>
</Paper>
); );
} }
export function EquipmentsSubpage(): React.ReactElement { export function EquipmentsSubpage(): React.ReactElement {
const gang = useGang(); const gang = useGang();
const [filter, setFilter] = useState("");
const handleFilterChange = (event: React.ChangeEvent<HTMLInputElement>): void => {
setFilter(event.target.value.toLowerCase());
}
const members = gang.members
.filter((member) => member && member.name.toLowerCase().includes(filter));
return ( return (
<> <>
<Tooltip <Tooltip
@ -209,11 +258,26 @@ export function EquipmentsSubpage(): React.ReactElement {
</Typography> </Typography>
} }
> >
<Typography>Discount: -{numeralWrapper.formatPercentage(1 - 1 / gang.getDiscount())}</Typography> <Typography sx={{ m: 1 }}>Discount: -{numeralWrapper.formatPercentage(1 - 1 / gang.getDiscount())}</Typography>
</Tooltip> </Tooltip>
{gang.members.map((member: GangMember) => (
<TextField
value={filter}
onChange={handleFilterChange}
autoFocus
InputProps={{
startAdornment: <SearchIcon />,
spellCheck: false
}}
placeholder="Filter by member name"
sx={{ m: 1, width: '15%' }}
/>
<Box display="grid" sx={{ gridTemplateColumns: '1fr 1fr', width: 'fit-content' }}>
{members.map((member: GangMember) => (
<GangMemberUpgradePanel key={member.name} member={member} /> <GangMemberUpgradePanel key={member.name} member={member} />
))} ))}
</Box>
</> </>
); );
} }

View File

@ -1,36 +0,0 @@
/**
* React Component for a gang member on the management subpage.
*/
import React, { useState } from "react";
import { GangMember } from "../GangMember";
import { GangMemberAccordionContent } from "./GangMemberAccordionContent";
import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";
import ListItemButton from "@mui/material/ListItemButton";
import ListItemText from "@mui/material/ListItemText";
import Paper from "@mui/material/Paper";
import Collapse from "@mui/material/Collapse";
import ExpandMore from "@mui/icons-material/ExpandMore";
import ExpandLess from "@mui/icons-material/ExpandLess";
interface IProps {
member: GangMember;
}
export function GangMemberAccordion(props: IProps): React.ReactElement {
const [open, setOpen] = useState(true);
return (
<Box component={Paper}>
<ListItemButton onClick={() => setOpen((old) => !old)}>
<ListItemText primary={<Typography>{props.member.name}</Typography>} />
{open ? <ExpandLess color="primary" /> : <ExpandMore color="primary" />}
</ListItemButton>
<Collapse in={open} unmountOnExit>
<Box sx={{ mx: 4 }}>
<GangMemberAccordionContent member={props.member} />
</Box>
</Collapse>
</Box>
);
}

View File

@ -1,31 +0,0 @@
/**
* React Component for the content of the accordion of gang members on the
* management subpage.
*/
import React, { useState } from "react";
import { GangMemberStats } from "./GangMemberStats";
import { TaskSelector } from "./TaskSelector";
import { TaskDescription } from "./TaskDescription";
import { GangMember } from "../GangMember";
import Grid from "@mui/material/Grid";
interface IProps {
member: GangMember;
}
export function GangMemberAccordionContent(props: IProps): React.ReactElement {
const setRerender = useState(false)[1];
return (
<Grid container>
<Grid item xs={4}>
<GangMemberStats onAscend={() => setRerender((old) => !old)} member={props.member} />
</Grid>
<Grid item xs={4}>
<TaskSelector onTaskChange={() => setRerender((old) => !old)} member={props.member} />
</Grid>
<Grid item xs={4}>
<TaskDescription member={props.member} />
</Grid>
</Grid>
);
}

View File

@ -0,0 +1,26 @@
/**
* React Component for a gang member on the management subpage.
*/
import React from "react";
import { GangMember } from "../GangMember";
import { GangMemberCardContent } from "./GangMemberCardContent";
import Box from "@mui/material/Box";
import ListItemText from "@mui/material/ListItemText";
import Paper from "@mui/material/Paper";
interface IProps {
member: GangMember;
}
export function GangMemberCard(props: IProps): React.ReactElement {
return (
<Box component={Paper} sx={{ width: 'auto' }}>
<Box sx={{ m: 1 }}>
<ListItemText primary={<b>{props.member.name}</b>} />
<GangMemberCardContent member={props.member} />
</Box>
</Box>
);
}

View File

@ -0,0 +1,62 @@
/**
* React Component for the content of the accordion of gang members on the
* management subpage.
*/
import React, { useState } from "react";
import { GangMemberStats } from "./GangMemberStats";
import { TaskSelector } from "./TaskSelector";
import { AscensionModal } from "./AscensionModal";
import { Box } from "@mui/system";
import { Button, Typography } from "@mui/material";
import HelpIcon from "@mui/icons-material/Help";
import { GangMember } from "../GangMember";
import { StaticModal } from "../../ui/React/StaticModal";
interface IProps {
member: GangMember;
}
export function GangMemberCardContent(props: IProps): React.ReactElement {
const setRerender = useState(false)[1];
const [helpOpen, setHelpOpen] = useState(false);
const [ascendOpen, setAscendOpen] = useState(false);
return (
<>
{props.member.canAscend() && (
<Box sx={{ display: 'flex', justifyContent: 'space-between', my: 1 }}>
<Button onClick={() => setAscendOpen(true)} style={{ flexGrow: 1, borderRightWidth: 0 }}>Ascend</Button>
<AscensionModal
open={ascendOpen}
onClose={() => setAscendOpen(false)}
member={props.member}
onAscend={() => setRerender((old) => !old)}
/>
<Button onClick={() => setHelpOpen(true)} style={{ width: 'fit-content', borderLeftWidth: 0 }}>
<HelpIcon />
</Button>
<StaticModal open={helpOpen} onClose={() => setHelpOpen(false)}>
<Typography>
Ascending a Gang Member resets the member's progress and stats in exchange for a permanent boost to their
stat multipliers.
<br />
<br />
The additional stat multiplier that the Gang Member gains upon ascension is based on the amount of exp
they have.
<br />
<br />
Upon ascension, the member will lose all of its non-Augmentation Equipment and your gang will lose respect
equal to the total respect earned by the member.
</Typography>
</StaticModal>
</Box>
)}
<Box display="grid" sx={{ gridTemplateColumns: '1fr 1fr', width: '100%', gap: 1 }}>
<GangMemberStats member={props.member} />
<TaskSelector onTaskChange={() => setRerender((old) => !old)} member={props.member} />
</Box>
</>
);
}

View File

@ -2,23 +2,63 @@
* React Component for the list of gang members on the management subpage. * React Component for the list of gang members on the management subpage.
*/ */
import React, { useState } from "react"; import React, { useState } from "react";
import { GangMemberAccordion } from "./GangMemberAccordion"; import { GangMemberCard } from "./GangMemberCard";
import { GangMember } from "../GangMember";
import { RecruitButton } from "./RecruitButton"; import { RecruitButton } from "./RecruitButton";
import { useGang } from "./Context"; import { useGang } from "./Context";
import { Box, TextField } from "@mui/material";
import SearchIcon from "@mui/icons-material/Search";
import { GangMember } from "../GangMember";
import { OptionSwitch } from "../../ui/React/OptionSwitch";
export function GangMemberList(): React.ReactElement { export function GangMemberList(): React.ReactElement {
const gang = useGang(); const gang = useGang();
const setRerender = useState(false)[1]; const setRerender = useState(false)[1];
const [filter, setFilter] = useState("");
const [ascendOnly, setAscendOnly] = useState(false);
const handleFilterChange = (event: React.ChangeEvent<HTMLInputElement>): void => {
setFilter(event.target.value.toLowerCase());
}
const members = gang.members
.filter((member) => member && member.name.toLowerCase().includes(filter))
.filter((member) => {
if (ascendOnly) return member.canAscend();
return true;
});
return ( return (
<> <>
<RecruitButton onRecruit={() => setRerender((old) => !old)} /> <RecruitButton onRecruit={() => setRerender((old) => !old)} />
<ul> <TextField
{gang.members.map((member: GangMember) => ( value={filter}
<GangMemberAccordion key={member.name} member={member} /> onChange={handleFilterChange}
autoFocus
InputProps={{
startAdornment: <SearchIcon />,
spellCheck: false
}}
placeholder="Filter by member name"
sx={{ m: 1, width: '15%' }}
/>
<OptionSwitch
checked={ascendOnly}
onChange={(newValue) => (setAscendOnly(newValue))}
text="Show only ascendable"
tooltip={
<>
Filter the members list by whether or not the member
can be ascended.
</>
}
/>
<Box display="grid" sx={{ gridTemplateColumns: 'repeat(2, 1fr)' }}>
{members.map((member: GangMember) => (
<GangMemberCard key={member.name} member={member} />
))} ))}
</ul> </Box>
</> </>
); );
} }

View File

@ -2,26 +2,53 @@
* React Component for the first part of a gang member details. * React Component for the first part of a gang member details.
* Contains skills and exp. * Contains skills and exp.
*/ */
import React, { useState } from "react"; import React from "react";
import { formatNumber } from "../../utils/StringHelperFunctions"; import { useGang } from "./Context";
import { numeralWrapper } from "../../ui/numeralFormat";
import { GangMember } from "../GangMember";
import { AscensionModal } from "./AscensionModal";
import Typography from "@mui/material/Typography"; import Typography from "@mui/material/Typography";
import Tooltip from "@mui/material/Tooltip"; import Tooltip from "@mui/material/Tooltip";
import Button from "@mui/material/Button"; import {
import { StaticModal } from "../../ui/React/StaticModal"; Table,
import IconButton from "@mui/material/IconButton"; TableBody,
import HelpIcon from "@mui/icons-material/Help"; TableCell,
TableRow,
} from "@mui/material";
import { numeralWrapper } from "../../ui/numeralFormat";
import { GangMember } from "../GangMember";
import { Settings } from "../../Settings/Settings";
import { formatNumber } from "../../utils/StringHelperFunctions";
import { MoneyRate } from "../../ui/React/MoneyRate";
import { characterOverviewStyles as useStyles } from "../../ui/React/CharacterOverview";
interface IProps { interface IProps {
member: GangMember; member: GangMember;
onAscend: () => void; }
export const generateTableRow = (
name: string,
level: number,
exp: number,
color: string,
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
classes: any
): React.ReactElement => {
return (
<TableRow>
<TableCell classes={{ root: classes.cellNone }}>
<Typography style={{ color: color }}>{name}</Typography>
</TableCell>
<TableCell align="right" classes={{ root: classes.cellNone }}>
<Typography style={{ color: color }}>
{formatNumber(level, 0)} ({numeralWrapper.formatExp(exp)} exp)
</Typography>
</TableCell>
</TableRow>
)
} }
export function GangMemberStats(props: IProps): React.ReactElement { export function GangMemberStats(props: IProps): React.ReactElement {
const [helpOpen, setHelpOpen] = useState(false); const classes = useStyles();
const [ascendOpen, setAscendOpen] = useState(false);
const asc = { const asc = {
hack: props.member.calculateAscensionMult(props.member.hack_asc_points), hack: props.member.calculateAscensionMult(props.member.hack_asc_points),
@ -32,6 +59,16 @@ export function GangMemberStats(props: IProps): React.ReactElement {
cha: props.member.calculateAscensionMult(props.member.cha_asc_points), cha: props.member.calculateAscensionMult(props.member.cha_asc_points),
}; };
const gang = useGang();
const data = [
[`Money:`, <MoneyRate money={5 * props.member.calculateMoneyGain(gang)} />],
[`Respect:`, `${numeralWrapper.formatRespect(5 * props.member.calculateRespectGain(gang))} / sec`],
[`Wanted Level:`, `${numeralWrapper.formatWanted(5 * props.member.calculateWantedLevelGain(gang))} / sec`],
[`Total Respect:`, `${numeralWrapper.formatRespect(props.member.earnedRespect)}`],
];
return ( return (
<> <>
<Tooltip <Tooltip
@ -63,50 +100,32 @@ export function GangMemberStats(props: IProps): React.ReactElement {
</Typography> </Typography>
} }
> >
<Typography> <Table sx={{ display: 'table', mb: 1, width: '100%' }}>
Hacking: {formatNumber(props.member.hack, 0)} ({numeralWrapper.formatExp(props.member.hack_exp)} exp) <TableBody>
{generateTableRow("Hacking", props.member.hack, props.member.hack_exp, Settings.theme.hack, classes)}
{generateTableRow("Strength", props.member.str, props.member.str_exp, Settings.theme.combat, classes)}
{generateTableRow("Defense", props.member.def, props.member.def_exp, Settings.theme.combat, classes)}
{generateTableRow("Dexterity", props.member.dex, props.member.dex_exp, Settings.theme.combat, classes)}
{generateTableRow("Agility", props.member.agi, props.member.agi_exp, Settings.theme.combat, classes)}
{generateTableRow("Charisma", props.member.cha, props.member.cha_exp, Settings.theme.cha, classes)}
<TableRow>
<TableCell classes={{ root: classes.cellNone }}>
<br /> <br />
Strength: {formatNumber(props.member.str, 0)} ({numeralWrapper.formatExp(props.member.str_exp)} exp) </TableCell>
<br /> </TableRow>
Defense: {formatNumber(props.member.def, 0)} ({numeralWrapper.formatExp(props.member.def_exp)} exp) {data.map(([a, b]) => (
<br /> <TableRow key={a.toString() + b.toString()}>
Dexterity: {formatNumber(props.member.dex, 0)} ({numeralWrapper.formatExp(props.member.dex_exp)} exp) <TableCell classes={{ root: classes.cellNone }}>
<br /> <Typography>{a}</Typography>
Agility: {formatNumber(props.member.agi, 0)} ({numeralWrapper.formatExp(props.member.agi_exp)} exp) </TableCell>
<br /> <TableCell align="right" classes={{ root: classes.cellNone }}>
Charisma: {formatNumber(props.member.cha, 0)} ({numeralWrapper.formatExp(props.member.cha_exp)} exp) <Typography>{b}</Typography>
<br /> </TableCell>
</Typography> </TableRow>
))}
</TableBody>
</Table>
</Tooltip> </Tooltip>
<br />
{props.member.canAscend() && (
<>
<Button onClick={() => setAscendOpen(true)}>Ascend</Button>
<AscensionModal
open={ascendOpen}
onClose={() => setAscendOpen(false)}
member={props.member}
onAscend={props.onAscend}
/>
<IconButton onClick={() => setHelpOpen(true)}>
<HelpIcon />
</IconButton>
<StaticModal open={helpOpen} onClose={() => setHelpOpen(false)}>
<Typography>
Ascending a Gang Member resets the member's progress and stats in exchange for a permanent boost to their
stat multipliers.
<br />
<br />
The additional stat multiplier that the Gang Member gains upon ascension is based on the amount of exp
they have.
<br />
<br />
Upon ascension, the member will lose all of its non-Augmentation Equipment and your gang will lose respect
equal to the total respect earned by the member.
</Typography>
</StaticModal>
</>
)}
</> </>
); );
} }

View File

@ -24,18 +24,20 @@ export function RecruitButton(props: IProps): React.ReactElement {
if (!gang.canRecruitMember()) { if (!gang.canRecruitMember()) {
const respect = gang.getRespectNeededToRecruitMember(); const respect = gang.getRespectNeededToRecruitMember();
return ( return (
<Box display="flex" alignItems="center"> <Box display="flex" alignItems="center" sx={{ mx: 1 }}>
<Button sx={{ mx: 1 }} disabled> <Button disabled>
Recruit Gang Member Recruit Gang Member
</Button> </Button>
<Typography>{numeralWrapper.formatRespect(respect)} respect needed to recruit next member</Typography> <Typography sx={{ ml: 1 }}>{numeralWrapper.formatRespect(respect)} respect needed to recruit next member</Typography>
</Box> </Box>
); );
} }
return ( return (
<> <>
<Box sx={{ mx: 1 }}>
<Button onClick={() => setOpen(true)}>Recruit Gang Member</Button> <Button onClick={() => setOpen(true)}>Recruit Gang Member</Button>
</Box>
<RecruitModal open={open} onClose={() => setOpen(false)} onRecruit={props.onRecruit} /> <RecruitModal open={open} onClose={() => setOpen(false)} onRecruit={props.onRecruit} />
</> </>
); );

View File

@ -3,14 +3,15 @@
* the task selector as well as some stats. * the task selector as well as some stats.
*/ */
import React, { useState } from "react"; import React, { useState } from "react";
import { numeralWrapper } from "../../ui/numeralFormat";
import { StatsTable } from "../../ui/React/StatsTable";
import { MoneyRate } from "../../ui/React/MoneyRate";
import { useGang } from "./Context"; import { useGang } from "./Context";
import { GangMember } from "../GangMember"; import { TaskDescription } from "./TaskDescription";
import { Box } from "@mui/material";
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 { GangMember } from "../GangMember";
interface IProps { interface IProps {
member: GangMember; member: GangMember;
onTaskChange: () => void; onTaskChange: () => void;
@ -29,16 +30,9 @@ export function TaskSelector(props: IProps): React.ReactElement {
const tasks = gang.getAllTaskNames(); const tasks = gang.getAllTaskNames();
const data = [
[`Money:`, <MoneyRate money={5 * props.member.calculateMoneyGain(gang)} />],
[`Respect:`, `${numeralWrapper.formatRespect(5 * props.member.calculateRespectGain(gang))} / sec`],
[`Wanted Level:`, `${numeralWrapper.formatWanted(5 * props.member.calculateWantedLevelGain(gang))} / sec`],
[`Total Respect:`, `${numeralWrapper.formatRespect(props.member.earnedRespect)}`],
];
return ( return (
<> <Box>
<Select onChange={onChange} value={currentTask}> <Select onChange={onChange} value={currentTask} sx={{ width: '100%' }}>
<MenuItem key={0} value={"Unassigned"}> <MenuItem key={0} value={"Unassigned"}>
Unassigned Unassigned
</MenuItem> </MenuItem>
@ -48,8 +42,7 @@ export function TaskSelector(props: IProps): React.ReactElement {
</MenuItem> </MenuItem>
))} ))}
</Select> </Select>
<TaskDescription member={props.member} />
<StatsTable rows={data} /> </Box>
</>
); );
} }

View File

@ -205,6 +205,7 @@ export function GameOptionsRoot(props: IProps): React.ReactElement {
<Grid item xs={12} sm={6}> <Grid item xs={12} sm={6}>
<List> <List>
<ListItem> <ListItem>
<Box display="grid" sx={{ width: 'fit-content', gridTemplateColumns: '1fr 3.5fr', gap: 1 }}>
<Tooltip <Tooltip
title={ title={
<Typography> <Typography>
@ -223,8 +224,6 @@ export function GameOptionsRoot(props: IProps): React.ReactElement {
max={100} max={100}
valueLabelDisplay="auto" valueLabelDisplay="auto"
/> />
</ListItem>
<ListItem>
<Tooltip <Tooltip
title={ title={
<Typography> <Typography>
@ -243,8 +242,6 @@ export function GameOptionsRoot(props: IProps): React.ReactElement {
max={500} max={500}
valueLabelDisplay="auto" valueLabelDisplay="auto"
/> />
</ListItem>
<ListItem>
<Tooltip <Tooltip
title={ title={
<Typography> <Typography>
@ -263,8 +260,6 @@ export function GameOptionsRoot(props: IProps): React.ReactElement {
max={100} max={100}
valueLabelDisplay="auto" valueLabelDisplay="auto"
/> />
</ListItem>
<ListItem>
<Tooltip <Tooltip
title={ title={
<Typography> <Typography>
@ -284,8 +279,6 @@ export function GameOptionsRoot(props: IProps): React.ReactElement {
valueLabelDisplay="auto" valueLabelDisplay="auto"
marks marks
/> />
</ListItem>
<ListItem>
<Tooltip <Tooltip
title={ title={
<Typography>The time (in seconds) between each autosave. Set to 0 to disable autosave.</Typography> <Typography>The time (in seconds) between each autosave. Set to 0 to disable autosave.</Typography>
@ -302,6 +295,7 @@ export function GameOptionsRoot(props: IProps): React.ReactElement {
valueLabelDisplay="auto" valueLabelDisplay="auto"
marks marks
/> />
</Box>
</ListItem> </ListItem>
<ListItem> <ListItem>
<OptionSwitch <OptionSwitch