From c6ddba9f5f3b07871409d00c625ac24c057d11f9 Mon Sep 17 00:00:00 2001 From: nickofolas Date: Fri, 21 Jan 2022 20:02:29 -0600 Subject: [PATCH] Redesign Gang management page --- src/Gang/ui/GangMemberAccordion.tsx | 36 ------- src/Gang/ui/GangMemberAccordionContent.tsx | 31 ------ src/Gang/ui/GangMemberCard.tsx | 26 +++++ src/Gang/ui/GangMemberCardContent.tsx | 62 +++++++++++ src/Gang/ui/GangMemberList.tsx | 52 +++++++-- src/Gang/ui/GangMemberStats.tsx | 116 +++++++++++---------- src/Gang/ui/RecruitButton.tsx | 10 +- src/Gang/ui/TaskSelector.tsx | 25 ++--- 8 files changed, 210 insertions(+), 148 deletions(-) delete mode 100644 src/Gang/ui/GangMemberAccordion.tsx delete mode 100644 src/Gang/ui/GangMemberAccordionContent.tsx create mode 100644 src/Gang/ui/GangMemberCard.tsx create mode 100644 src/Gang/ui/GangMemberCardContent.tsx diff --git a/src/Gang/ui/GangMemberAccordion.tsx b/src/Gang/ui/GangMemberAccordion.tsx deleted file mode 100644 index 0f9cefcef..000000000 --- a/src/Gang/ui/GangMemberAccordion.tsx +++ /dev/null @@ -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 ( - - setOpen((old) => !old)}> - {props.member.name}} /> - {open ? : } - - - - - - - - ); -} diff --git a/src/Gang/ui/GangMemberAccordionContent.tsx b/src/Gang/ui/GangMemberAccordionContent.tsx deleted file mode 100644 index a79592b36..000000000 --- a/src/Gang/ui/GangMemberAccordionContent.tsx +++ /dev/null @@ -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 ( - - - setRerender((old) => !old)} member={props.member} /> - - - setRerender((old) => !old)} member={props.member} /> - - - - - - ); -} diff --git a/src/Gang/ui/GangMemberCard.tsx b/src/Gang/ui/GangMemberCard.tsx new file mode 100644 index 000000000..f8ed9dd06 --- /dev/null +++ b/src/Gang/ui/GangMemberCard.tsx @@ -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 ( + + + {props.member.name}} /> + + + + ); +} diff --git a/src/Gang/ui/GangMemberCardContent.tsx b/src/Gang/ui/GangMemberCardContent.tsx new file mode 100644 index 000000000..ca3cb9de5 --- /dev/null +++ b/src/Gang/ui/GangMemberCardContent.tsx @@ -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() && ( + + + setAscendOpen(false)} + member={props.member} + onAscend={() => setRerender((old) => !old)} + /> + + setHelpOpen(false)}> + + Ascending a Gang Member resets the member's progress and stats in exchange for a permanent boost to their + stat multipliers. +
+
+ The additional stat multiplier that the Gang Member gains upon ascension is based on the amount of exp + they have. +
+
+ 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. +
+
+
+ )} + + + setRerender((old) => !old)} member={props.member} /> + + + ); +} diff --git a/src/Gang/ui/GangMemberList.tsx b/src/Gang/ui/GangMemberList.tsx index 104e218b8..fcd8a6b6f 100644 --- a/src/Gang/ui/GangMemberList.tsx +++ b/src/Gang/ui/GangMemberList.tsx @@ -2,23 +2,63 @@ * React Component for the list of gang members on the management subpage. */ import React, { useState } from "react"; -import { GangMemberAccordion } from "./GangMemberAccordion"; -import { GangMember } from "../GangMember"; +import { GangMemberCard } from "./GangMemberCard"; import { RecruitButton } from "./RecruitButton"; 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 { const gang = useGang(); const setRerender = useState(false)[1]; + const [filter, setFilter] = useState(""); + const [ascendOnly, setAscendOnly] = useState(false); + + const handleFilterChange = (event: React.ChangeEvent): 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 ( <> setRerender((old) => !old)} /> -
    - {gang.members.map((member: GangMember) => ( - + , + spellCheck: false + }} + placeholder="Filter by member name" + sx={{ m: 1, width: '15%' }} + /> + (setAscendOnly(newValue))} + text="Show only ascendable" + tooltip={ + <> + Filter the members list by whether or not the member + can be ascended. + + } + /> + + {members.map((member: GangMember) => ( + ))} -
+ ); } diff --git a/src/Gang/ui/GangMemberStats.tsx b/src/Gang/ui/GangMemberStats.tsx index c81161a7e..03198f01d 100644 --- a/src/Gang/ui/GangMemberStats.tsx +++ b/src/Gang/ui/GangMemberStats.tsx @@ -2,26 +2,31 @@ * React Component for the first part of a gang member details. * Contains skills and exp. */ -import React, { useState } from "react"; -import { formatNumber } from "../../utils/StringHelperFunctions"; -import { numeralWrapper } from "../../ui/numeralFormat"; -import { GangMember } from "../GangMember"; -import { AscensionModal } from "./AscensionModal"; +import React from "react"; +import { useGang } from "./Context"; + import Typography from "@mui/material/Typography"; import Tooltip from "@mui/material/Tooltip"; -import Button from "@mui/material/Button"; -import { StaticModal } from "../../ui/React/StaticModal"; -import IconButton from "@mui/material/IconButton"; -import HelpIcon from "@mui/icons-material/Help"; +import { + Table, + TableBody, + 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 { member: GangMember; - onAscend: () => void; } export function GangMemberStats(props: IProps): React.ReactElement { - const [helpOpen, setHelpOpen] = useState(false); - const [ascendOpen, setAscendOpen] = useState(false); + const classes = useStyles(); const asc = { hack: props.member.calculateAscensionMult(props.member.hack_asc_points), @@ -32,6 +37,29 @@ export function GangMemberStats(props: IProps): React.ReactElement { cha: props.member.calculateAscensionMult(props.member.cha_asc_points), }; + const generateTableRow = (name: string, level: number, exp: number, color: string): React.ReactElement => { + return ( + + + {name} + + + + {formatNumber(level, 0)} ({numeralWrapper.formatExp(exp)} exp) + + + + ) + } + + const gang = useGang(); + const data = [ + [`Money:`, ], + [`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 ( <> } > - - Hacking: {formatNumber(props.member.hack, 0)} ({numeralWrapper.formatExp(props.member.hack_exp)} exp) -
- Strength: {formatNumber(props.member.str, 0)} ({numeralWrapper.formatExp(props.member.str_exp)} exp) -
- Defense: {formatNumber(props.member.def, 0)} ({numeralWrapper.formatExp(props.member.def_exp)} exp) -
- Dexterity: {formatNumber(props.member.dex, 0)} ({numeralWrapper.formatExp(props.member.dex_exp)} exp) -
- Agility: {formatNumber(props.member.agi, 0)} ({numeralWrapper.formatExp(props.member.agi_exp)} exp) -
- Charisma: {formatNumber(props.member.cha, 0)} ({numeralWrapper.formatExp(props.member.cha_exp)} exp) -
-
+ + + {generateTableRow("Hacking", props.member.hack, props.member.hack_exp, Settings.theme.hack)} + {generateTableRow("Strength", props.member.str, props.member.str_exp, Settings.theme.combat)} + {generateTableRow("Defense", props.member.def, props.member.def_exp, Settings.theme.combat)} + {generateTableRow("Dexterity", props.member.dex, props.member.dex_exp, Settings.theme.combat)} + {generateTableRow("Agility", props.member.agi, props.member.agi_exp, Settings.theme.combat)} + {generateTableRow("Charisma", props.member.cha, props.member.cha_exp, Settings.theme.cha)} +
+ {data.map(([a, b]) => ( + + + {a} + + + {b} + + + ))} +
+
-
- {props.member.canAscend() && ( - <> - - setAscendOpen(false)} - member={props.member} - onAscend={props.onAscend} - /> - setHelpOpen(true)}> - - - setHelpOpen(false)}> - - Ascending a Gang Member resets the member's progress and stats in exchange for a permanent boost to their - stat multipliers. -
-
- The additional stat multiplier that the Gang Member gains upon ascension is based on the amount of exp - they have. -
-
- 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. -
-
- - )} ); } diff --git a/src/Gang/ui/RecruitButton.tsx b/src/Gang/ui/RecruitButton.tsx index 9897557d5..bea1f5e4f 100644 --- a/src/Gang/ui/RecruitButton.tsx +++ b/src/Gang/ui/RecruitButton.tsx @@ -24,18 +24,20 @@ export function RecruitButton(props: IProps): React.ReactElement { if (!gang.canRecruitMember()) { const respect = gang.getRespectNeededToRecruitMember(); return ( - - - {numeralWrapper.formatRespect(respect)} respect needed to recruit next member + {numeralWrapper.formatRespect(respect)} respect needed to recruit next member ); } return ( <> - + + + setOpen(false)} onRecruit={props.onRecruit} /> ); diff --git a/src/Gang/ui/TaskSelector.tsx b/src/Gang/ui/TaskSelector.tsx index 02e3e2013..ff19ff550 100644 --- a/src/Gang/ui/TaskSelector.tsx +++ b/src/Gang/ui/TaskSelector.tsx @@ -3,14 +3,15 @@ * the task selector as well as some stats. */ 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 { GangMember } from "../GangMember"; +import { TaskDescription } from "./TaskDescription"; + +import { Box } from "@mui/material"; import MenuItem from "@mui/material/MenuItem"; import Select, { SelectChangeEvent } from "@mui/material/Select"; +import { GangMember } from "../GangMember"; + interface IProps { member: GangMember; onTaskChange: () => void; @@ -29,16 +30,9 @@ export function TaskSelector(props: IProps): React.ReactElement { const tasks = gang.getAllTaskNames(); - const data = [ - [`Money:`, ], - [`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 ( - <> - Unassigned @@ -48,8 +42,7 @@ export function TaskSelector(props: IProps): React.ReactElement { ))} - - - + + ); }