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(true)} style={{ flexGrow: 1, borderRightWidth: 0 }}>Ascend
+ setAscendOpen(false)}
+ member={props.member}
+ onAscend={() => setRerender((old) => !old)}
+ />
+ setHelpOpen(true)} style={{ width: 'fit-content', borderLeftWidth: 0 }}>
+
+
+ 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(true)}>Ascend
- 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 (
-
-
+
+
Recruit Gang Member
- {numeralWrapper.formatRespect(respect)} respect needed to recruit next member
+ {numeralWrapper.formatRespect(respect)} respect needed to recruit next member
);
}
return (
<>
- setOpen(true)}>Recruit Gang Member
+
+ setOpen(true)}>Recruit Gang Member
+
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 {
))}
-
-
- >
+
+
);
}