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

162 lines
7.4 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";
2021-06-19 22:37:12 +01:00
import { Servers } from "revolt.js/dist/api/objects";
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";
2021-07-29 15:11:21 +01:00
import { useData } from "../../../mobx/State";
import { useClient } from "../../../context/revoltjs/RevoltClient";
2021-06-19 22:37:12 +01:00
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-05 11:25:20 +01:00
server: Servers.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>();
2021-07-05 11:25:20 +01:00
const [members, setMembers] = useState<Servers.Member[] | undefined>(
undefined,
);
2021-07-01 17:36:34 +01:00
2021-07-29 15:11:21 +01:00
const store = useData();
const client = useClient();
const users = members?.map((member) => store.users.get(member._id.user));
2021-06-19 22:37:12 +01:00
2021-07-05 11:25:20 +01:00
useEffect(() => {
2021-07-29 15:11:21 +01:00
client.members
2021-07-05 11:25:20 +01:00
.fetchMembers(server._id)
.then((members) => setMembers(members));
}, []);
2021-06-19 22:37:12 +01:00
const [roles, setRoles] = useState<string[]>([]);
useEffect(() => {
if (selected) {
setRoles(
members!.find((x) => x._id.user === selected)?.roles ?? [],
);
}
}, [selected]);
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}>
{members?.length ?? 0} Members
</div>
{members &&
members.length > 0 &&
members
2021-07-29 15:11:21 +01:00
.map((member, index) => {
return {
2021-07-29 15:11:21 +01:00
member,
user: users![index],
};
})
.map(({ member, user }) => (
<>
<div
key={member._id.user}
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 && (
<div
key={"drop_" + member._id.user}
className={styles.memberView}>
<Overline type="subtle">Roles</Overline>
{Object.keys(server.roles ?? {}).map(
(key) => {
let role = server.roles![key];
return (
<Checkbox
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={async () => {
2021-07-29 15:11:21 +01:00
await client.members.editMember(
server._id,
member._id.user,
{
roles,
},
);
setMembers(
members.map((x) =>
x._id.user ===
member._id.user
? {
...x,
roles,
}
: x,
),
);
}}>
<Text id="app.special.modals.actions.save" />
</Button>
</div>
)}
</>
))}
2021-07-05 11:25:20 +01:00
</div>
);
2021-07-29 15:11:21 +01:00
});