revite/src/pages/settings/server/Members.tsx

140 lines
6.5 KiB
TypeScript
Raw Normal View History

import { ChevronDown } from "@styled-icons/boxicons-regular";
import { isEqual } from "lodash";
2021-07-29 15:11:21 +01:00
import { observer } from "mobx-react-lite";
import { Member } from "revolt.js/dist/maps/Members";
import { Server } from "revolt.js/dist/maps/Servers";
import { User } from "revolt.js/dist/maps/Users";
2021-07-05 11:23:23 +01:00
import styles from "./Panes.module.scss";
import { Text } from "preact-i18n";
2021-07-05 11:23:23 +01:00
import { useEffect, useState } from "preact/hooks";
import UserIcon from "../../../components/common/user/UserIcon";
import Button from "../../../components/ui/Button";
import Checkbox from "../../../components/ui/Checkbox";
import IconButton from "../../../components/ui/IconButton";
import Overline from "../../../components/ui/Overline";
2021-06-19 22:37:12 +01:00
interface Props {
2021-07-29 19:01:40 +01:00
server: Server;
2021-06-19 22:37:12 +01:00
}
2021-07-29 15:11:21 +01:00
export const Members = observer(({ server }: Props) => {
const [selected, setSelected] = useState<undefined | string>();
const [data, setData] = useState<
{ members: Member[]; users: User[] } | undefined
>(undefined);
2021-07-01 17:36:34 +01:00
2021-07-05 11:25:20 +01:00
useEffect(() => {
server.fetchMembers().then(setData);
2021-08-05 14:47:00 +01:00
}, [server, setData]);
2021-06-19 22:37:12 +01:00
const [roles, setRoles] = useState<string[]>([]);
useEffect(() => {
if (selected) {
setRoles(
data!.members.find((x) => x._id.user === selected)?.roles ?? [],
);
}
2021-08-05 14:47:00 +01:00
}, [setRoles, selected, data]);
2021-07-05 11:25:20 +01:00
return (
<div className={styles.userList}>
2021-07-05 11:25:20 +01:00
<div className={styles.subtitle}>
{data?.members.length ?? 0} Members
2021-07-05 11:25:20 +01:00
</div>
{data &&
data.members.length > 0 &&
data.members
.map((member) => {
return {
2021-07-29 15:11:21 +01:00
member,
user: data.users.find(
(x) => x._id === member._id.user,
),
};
})
.map(({ member, user }) => (
2021-08-05 14:47:00 +01:00
// @ts-expect-error brokey
// eslint-disable-next-line react/jsx-no-undef
<Fragment key={member._id.user}>
<div
className={styles.member}
data-open={selected === member._id.user}
onClick={() =>
setSelected(
selected === member._id.user
? undefined
: member._id.user,
)
}>
<span>
<UserIcon target={user} size={24} />{" "}
{user?.username ?? (
<Text id="app.main.channel.unknown_user" />
)}
</span>
<IconButton className={styles.chevron}>
<ChevronDown size={24} />
</IconButton>
2021-07-05 11:25:20 +01:00
</div>
{selected === member._id.user && (
2021-08-13 22:31:28 +01:00
<div className={styles.memberView}>
<Overline type="subtle">Roles</Overline>
{Object.keys(server.roles ?? {}).map(
(key) => {
2021-08-05 14:47:00 +01:00
const role = server.roles![key];
return (
<Checkbox
2021-08-05 14:47:00 +01:00
key={key}
checked={
roles.includes(key) ??
false
}
onChange={(v) => {
if (v) {
setRoles([
...roles,
key,
]);
} else {
setRoles(
roles.filter(
(x) =>
x !==
key,
),
);
}
}}>
<span
style={{
color: role.colour,
}}>
{role.name}
</span>
</Checkbox>
);
},
)}
<Button
compact
disabled={isEqual(
member.roles ?? [],
roles,
)}
onClick={() =>
member.edit({
roles,
})
}>
<Text id="app.special.modals.actions.save" />
</Button>
</div>
)}
2021-08-05 14:47:00 +01:00
</Fragment>
))}
2021-07-05 11:25:20 +01:00
</div>
);
2021-07-29 15:11:21 +01:00
});