add/remove bot managers and mods from dashboard
This commit is contained in:
parent
4675ed8bdd
commit
0e4667a298
13 changed files with 432 additions and 20 deletions
|
@ -3,6 +3,7 @@ import { app, logger } from "..";
|
|||
|
||||
app.use('*', (req: Request, res: Response, next: () => void) => {
|
||||
res.header('Access-Control-Allow-Origin', '*');
|
||||
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, x-auth-user, x-auth-token");
|
||||
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, x-auth-user, x-auth-token');
|
||||
res.header('Access-Control-Allow-Methods', '*');
|
||||
next();
|
||||
});
|
||||
|
|
|
@ -1,16 +1,19 @@
|
|||
import { app } from '../..';
|
||||
import { app, db } from '../..';
|
||||
import { Request, Response } from 'express';
|
||||
import { badRequest, isAuthenticated, unauthorized } from '../../utils';
|
||||
import { badRequest, getPermissionLevel, isAuthenticated, unauthorized } from '../../utils';
|
||||
import { botReq } from '../internal/ws';
|
||||
|
||||
type User = { id: string, username?: string, avatarURL?: string }
|
||||
|
||||
type ServerDetails = {
|
||||
id: string,
|
||||
perms: 0|1|2,
|
||||
perms: 0|1|2|3,
|
||||
name: string,
|
||||
description?: string,
|
||||
iconURL?: string,
|
||||
bannerURL?: string,
|
||||
serverConfig: any,
|
||||
users: User[],
|
||||
}
|
||||
|
||||
app.get('/dash/server/:server', async (req: Request, res: Response) => {
|
||||
|
@ -30,3 +33,122 @@ app.get('/dash/server/:server', async (req: Request, res: Response) => {
|
|||
const s: ServerDetails = response.server;
|
||||
res.send({ server: s });
|
||||
});
|
||||
|
||||
app.put('/dash/server/:server/:option', async (req: Request, res: Response) => {
|
||||
try {
|
||||
const user = await isAuthenticated(req, res, true);
|
||||
if (!user) return unauthorized(res);
|
||||
|
||||
const { server } = req.params;
|
||||
const { item } = req.body;
|
||||
if (!server || typeof server != 'string' || !item || typeof item != 'string') return badRequest(res);
|
||||
|
||||
const permissionLevelRes = await getPermissionLevel(user, server);
|
||||
if (!permissionLevelRes.success)
|
||||
return res.status(permissionLevelRes.statusCode || 500).send({ error: permissionLevelRes.error });
|
||||
|
||||
const servers = db.get('servers');
|
||||
const permissionLevel: 0|1|2|3 = permissionLevelRes.level;
|
||||
const settings = await servers.findOne({ id: server });
|
||||
|
||||
switch(req.params.option) {
|
||||
case 'managers': {
|
||||
if (permissionLevel < 3) return res.status(403).send({ error: 'You are not allowed to add other bot managers.' });
|
||||
|
||||
const userRes = await botReq('getUser', { user: item });
|
||||
if (!userRes.success) {
|
||||
return res.status(404).send({ error: 'User could not be found' });
|
||||
}
|
||||
|
||||
if (settings.botManagers?.includes(userRes.user.id) === true) {
|
||||
return res.status(400).send({ error: 'This user is already manager' });
|
||||
}
|
||||
|
||||
const newManagers = [ ...(settings.botManagers ?? []), userRes.user.id ];
|
||||
await servers.update({ id: server }, { $set: { botManagers: newManagers } });
|
||||
res.send({
|
||||
success: true,
|
||||
managers: newManagers,
|
||||
users: [ userRes.user ],
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
case 'mods': {
|
||||
if (permissionLevel < 2) return res.status(403).send({ error: 'You are not allowed to add other moderators.' });
|
||||
|
||||
const userRes = await botReq('getUser', { user: item });
|
||||
if (!userRes.success) {
|
||||
return res.status(404).send({ error: 'User could not be found' });
|
||||
}
|
||||
|
||||
if (settings.moderators?.includes(userRes.user.id) === true) {
|
||||
return res.status(400).send({ error: 'This user is already moderator' });
|
||||
}
|
||||
|
||||
const newMods = [ ...(settings.moderators ?? []), userRes.user.id ];
|
||||
await servers.update({ id: server }, { $set: { moderators: newMods } });
|
||||
res.send({
|
||||
success: true,
|
||||
mods: newMods,
|
||||
users: [ userRes.user ],
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
default: return badRequest(res);
|
||||
}
|
||||
} catch(e: any) {
|
||||
res.status(500).send({ error: e });
|
||||
}
|
||||
});
|
||||
|
||||
app.delete('/dash/server/:server/:option/:target', async (req: Request, res: Response) => {
|
||||
const user = await isAuthenticated(req, res, true);
|
||||
if (!user) return unauthorized(res);
|
||||
|
||||
const { server, target, option } = req.params;
|
||||
if (!server || typeof server != 'string' || !target || typeof target != 'string') return badRequest(res);
|
||||
|
||||
const permissionLevelRes = await getPermissionLevel(user, server);
|
||||
if (!permissionLevelRes.success)
|
||||
return res.status(permissionLevelRes.statusCode || 500).send({ error: permissionLevelRes.error });
|
||||
|
||||
const servers = db.get('servers');
|
||||
const permissionLevel: 0|1|2|3 = permissionLevelRes.level;
|
||||
const settings = await servers.findOne({ id: server });
|
||||
|
||||
switch(option) {
|
||||
case 'managers': {
|
||||
if (permissionLevel < 3) return res.status(403).send({ error: 'You are not allowed to remove bot managers.' });
|
||||
|
||||
if (!settings.botManagers?.includes(target)) {
|
||||
return res.status(400).send({ error: 'This user is not manager' });
|
||||
}
|
||||
|
||||
const newManagers = (settings.botManagers ?? []).filter((i: string) => i != target);
|
||||
await servers.update({ id: server }, { $set: { botManagers: newManagers } });
|
||||
res.send({
|
||||
success: true,
|
||||
managers: newManagers,
|
||||
});
|
||||
return;
|
||||
}
|
||||
case 'mods': {
|
||||
if (permissionLevel < 2) return res.status(403).send({ error: 'You are not allowed to remove moderators.' });
|
||||
|
||||
if (!settings.moderators?.includes(target)) {
|
||||
return res.status(400).send({ error: 'This user is not moderator' });
|
||||
}
|
||||
|
||||
const newMods = (settings.moderators ?? []).filter((i: string) => i != target);
|
||||
await servers.update({ id: server }, { $set: { moderators: newMods } });
|
||||
res.send({
|
||||
success: true,
|
||||
mods: newMods,
|
||||
});
|
||||
return;
|
||||
}
|
||||
default: return badRequest(res);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -3,7 +3,7 @@ import { Request, Response } from 'express';
|
|||
import { isAuthenticated, unauthorized } from '../../utils';
|
||||
import { botReq } from '../internal/ws';
|
||||
|
||||
type Server = { id: string, perms: 0|1|2, name: string, iconURL?: string, bannerURL?: string }
|
||||
type Server = { id: string, perms: 0|1|2|3, name: string, iconURL?: string, bannerURL?: string }
|
||||
|
||||
app.get('/dash/servers', async (req: Request, res: Response) => {
|
||||
const user = await isAuthenticated(req, res, true);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { Request, Response } from "express";
|
||||
import { FindOneResult } from "monk";
|
||||
import { db } from ".";
|
||||
import { botReq } from "./routes/internal/ws";
|
||||
|
||||
class Session {
|
||||
user: string;
|
||||
|
@ -44,4 +45,8 @@ function unauthorized(res: Response) {
|
|||
res.status(401).send(JSON.stringify({ "error": "Unauthorized" }, null, 4));
|
||||
}
|
||||
|
||||
export { isAuthenticated, getSessionInfo, badRequest, unauthorized }
|
||||
async function getPermissionLevel(user: string, server: string) {
|
||||
return await botReq('getPermissionLevel', { user, server });
|
||||
}
|
||||
|
||||
export { isAuthenticated, getSessionInfo, badRequest, unauthorized, getPermissionLevel }
|
||||
|
|
|
@ -1,21 +1,22 @@
|
|||
import { Member } from "revolt.js/dist/maps/Members";
|
||||
import { User } from "revolt.js/dist/maps/Users";
|
||||
import { client } from "../../..";
|
||||
import AutomodSettings from "../../../struct/antispam/AutomodSettings";
|
||||
import ServerConfig from "../../../struct/ServerConfig";
|
||||
import { getPermissionLevel } from "../../util";
|
||||
import { wsEvents, WSResponse } from "../api_communication";
|
||||
|
||||
type ReqData = { user: string, server: string }
|
||||
type APIUser = { id: string, username?: string, avatarURL?: string }
|
||||
|
||||
type ServerDetails = {
|
||||
id: string,
|
||||
perms: 0|1|2,
|
||||
perms: 0|1|2|3,
|
||||
name: string,
|
||||
description?: string,
|
||||
iconURL?: string,
|
||||
bannerURL?: string,
|
||||
serverConfig?: ServerConfig,
|
||||
users: APIUser[],
|
||||
}
|
||||
|
||||
wsEvents.on('req:getUserServerDetails', async (data: ReqData, cb: (data: WSResponse) => void) => {
|
||||
|
@ -43,6 +44,20 @@ wsEvents.on('req:getUserServerDetails', async (data: ReqData, cb: (data: WSRespo
|
|||
|
||||
// todo: remove unwanted keys from server config
|
||||
|
||||
async function fetchUser(id: string) {
|
||||
try {
|
||||
return client.users.get(id) || await client.users.fetch(id);
|
||||
} catch(e) {
|
||||
throw id; // this is stupid but idc
|
||||
}
|
||||
}
|
||||
|
||||
const users = await Promise.allSettled([
|
||||
...(serverConfig.botManagers?.map(u => fetchUser(u)) ?? []),
|
||||
...(serverConfig.moderators?.map(u => fetchUser(u)) ?? []),
|
||||
fetchUser(user._id),
|
||||
]);
|
||||
|
||||
const response: ServerDetails = {
|
||||
id: server._id,
|
||||
name: server.name,
|
||||
|
@ -51,6 +66,11 @@ wsEvents.on('req:getUserServerDetails', async (data: ReqData, cb: (data: WSRespo
|
|||
bannerURL: server.generateBannerURL(),
|
||||
iconURL: server.generateIconURL(),
|
||||
serverConfig,
|
||||
users: users.map(
|
||||
u => u.status == 'fulfilled'
|
||||
? { id: u.value._id, avatarURL: u.value.generateAvatarURL(), username: u.value.username }
|
||||
: { id: u.reason }
|
||||
),
|
||||
}
|
||||
|
||||
cb({ success: true, server: response });
|
||||
|
@ -59,3 +79,5 @@ wsEvents.on('req:getUserServerDetails', async (data: ReqData, cb: (data: WSRespo
|
|||
cb({ success: false, error: `${e}` });
|
||||
}
|
||||
});
|
||||
|
||||
export { APIUser }
|
||||
|
|
|
@ -17,7 +17,7 @@ wsEvents.on('req:getUserServers', async (data: ReqData, cb: (data: WSResponse) =
|
|||
|
||||
const mutuals = await user.fetchMutual();
|
||||
|
||||
type ServerResponse = { id: string, perms: 0|1|2, name: string, iconURL?: string, bannerURL?: string }
|
||||
type ServerResponse = { id: string, perms: 0|1|2|3, name: string, iconURL?: string, bannerURL?: string }
|
||||
|
||||
const promises: Promise<ServerResponse>[] = [];
|
||||
|
||||
|
|
38
bot/src/bot/modules/api/users.ts
Normal file
38
bot/src/bot/modules/api/users.ts
Normal file
|
@ -0,0 +1,38 @@
|
|||
import { User } from "revolt.js/dist/maps/Users";
|
||||
import { client } from "../../..";
|
||||
import { getPermissionLevel, parseUser } from "../../util";
|
||||
import { wsEvents, WSResponse } from "../api_communication";
|
||||
import { APIUser } from "./server_details";
|
||||
|
||||
wsEvents.on('req:getPermissionLevel', async (data: { user: string, server: string }, cb: (data: WSResponse) => void) => {
|
||||
try {
|
||||
const server = client.servers.get(data.server);
|
||||
if (!server) return cb({ success: false, error: 'The requested server could not be found', statusCode: 404 });
|
||||
|
||||
let user: User;
|
||||
try {
|
||||
user = client.users.get(data.user) || await client.users.fetch(data.user);
|
||||
} catch(e) {
|
||||
cb({ success: false, error: 'The requested user could not be found', statusCode: 404 });
|
||||
return;
|
||||
}
|
||||
|
||||
return cb({ success: true, level: await getPermissionLevel(user, server) })
|
||||
} catch(e) {
|
||||
console.error(e);
|
||||
cb({ success: false, error: `${e}` });
|
||||
}
|
||||
});
|
||||
|
||||
wsEvents.on('req:getUser', async (data: { user: string }, cb: (data: WSResponse) => void) => {
|
||||
try {
|
||||
const user = await parseUser(data.user);
|
||||
if (!user)
|
||||
cb({ success: false, statusCode: 404, error: 'User could not be found' });
|
||||
else
|
||||
cb({ success: true, user: { id: user._id, username: user.username, avatarURL: user.generateAvatarURL() } as APIUser });
|
||||
} catch(e) {
|
||||
console.error(e);
|
||||
cb({ success: false, error: `${e}` });
|
||||
}
|
||||
});
|
|
@ -135,3 +135,4 @@ export { wsEvents, wsSend, WSResponse }
|
|||
|
||||
import('./api/servers');
|
||||
import('./api/server_details');
|
||||
import('./api/users');
|
||||
|
|
|
@ -99,13 +99,13 @@ async function checkSudoPermission(message: Message): Promise<boolean> {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
async function getPermissionLevel(user: User|Member, server: Server): Promise<0|1|2> {
|
||||
async function getPermissionLevel(user: User|Member, server: Server): Promise<0|1|2|3> {
|
||||
if (isSudo(user instanceof User ? user : (user.user || await client.users.fetch(user._id.user)))) return 2;
|
||||
|
||||
const member = user instanceof User ? await server.fetchMember(user) : user;
|
||||
if (user instanceof Member) user = user.user!;
|
||||
|
||||
if (hasPerm(member, 'ManageServer')) return 2;
|
||||
if (hasPerm(member, 'ManageServer')) return 3;
|
||||
if (hasPerm(member, 'KickMembers')) return 1;
|
||||
|
||||
const config = (await client.db.get('servers').findOne({ id: server._id }) || {}) as ServerConfig;
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@mdi/js": "^6.5.95",
|
||||
"@mdi/react": "^1.5.0",
|
||||
"@revoltchat/ui": "^1.0.24",
|
||||
"@types/axios": "^0.14.0",
|
||||
"@types/core-js": "^2.5.5",
|
||||
|
@ -14,6 +16,7 @@
|
|||
"axios": "^0.25.0",
|
||||
"core-js": "^3.20.3",
|
||||
"localforage": "^1.10.0",
|
||||
"prop-types": "^15.8.1",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-router-dom": "^6.2.1",
|
||||
|
|
|
@ -7,7 +7,7 @@ import { H2 } from '@revoltchat/ui/lib/components/atoms/heading/H2';
|
|||
import { API_URL } from "../App";
|
||||
import { getAuthHeaders } from "../utils";
|
||||
|
||||
type Server = { id: string, perms: 0|1|2, name: string, iconURL?: string, bannerURL?: string }
|
||||
type Server = { id: string, perms: 0|1|2|3, name: string, iconURL?: string, bannerURL?: string }
|
||||
|
||||
function permissionName(p: number) {
|
||||
switch(p) {
|
||||
|
|
|
@ -1,17 +1,30 @@
|
|||
import localforage from "localforage";
|
||||
import axios from 'axios';
|
||||
import { FunctionComponent, useCallback, useEffect, useState } from "react";
|
||||
import { Button } from '@revoltchat/ui/lib/components/atoms/inputs/Button';
|
||||
import { InputBox } from '@revoltchat/ui/lib/components/atoms/inputs/InputBox';
|
||||
import { Checkbox } from '@revoltchat/ui/lib/components/atoms/inputs/Checkbox';
|
||||
import { LineDivider } from '@revoltchat/ui/lib/components/atoms/layout/LineDivider';
|
||||
import { H1 } from '@revoltchat/ui/lib/components/atoms/heading/H1';
|
||||
import { H3 } from '@revoltchat/ui/lib/components/atoms/heading/H3';
|
||||
import { H4 } from '@revoltchat/ui/lib/components/atoms/heading/H4';
|
||||
import { Icon } from '@mdi/react';
|
||||
import { mdiCloseBox } from '@mdi/js';
|
||||
import { API_URL } from "../App";
|
||||
import { getAuthHeaders } from "../utils";
|
||||
import { useParams } from "react-router-dom";
|
||||
|
||||
type Server = { id?: string, perms?: 0|1|2, name?: string, description?: string, iconURL?: string, bannerURL?: string, serverConfig?: any }
|
||||
type User = { id: string, username?: string, avatarURL?: string }
|
||||
|
||||
type Server = {
|
||||
id?: string,
|
||||
perms?: 0|1|2|3,
|
||||
name?: string,
|
||||
description?: string,
|
||||
iconURL?: string,
|
||||
bannerURL?: string,
|
||||
serverConfig?: { [key: string]: any },
|
||||
users: User[],
|
||||
}
|
||||
|
||||
const ServerDashboard: FunctionComponent = () => {
|
||||
const [serverInfo, setServerInfo] = useState({} as Server);
|
||||
|
@ -19,6 +32,9 @@ const ServerDashboard: FunctionComponent = () => {
|
|||
|
||||
const [prefix, setPrefix] = useState('' as string|undefined);
|
||||
const [prefixAllowSpace, setPrefixAllowSpace] = useState(false);
|
||||
|
||||
const [botManagers, setBotManagers] = useState([] as string[]);
|
||||
const [moderators, setModerators] = useState([] as string[]);
|
||||
|
||||
const { serverid } = useParams();
|
||||
|
||||
|
@ -30,11 +46,15 @@ const ServerDashboard: FunctionComponent = () => {
|
|||
try {
|
||||
const res = await axios.get(`${API_URL}/dash/server/${serverid}`, { headers: await getAuthHeaders() });
|
||||
console.log(res.data);
|
||||
|
||||
const server: Server = res.data.server;
|
||||
setServerInfo(server);
|
||||
|
||||
setPrefix(server.serverConfig?.prefix || undefined);
|
||||
setPrefix(server.serverConfig?.prefix || '');
|
||||
setPrefixAllowSpace(!!server.serverConfig?.spaceAfterPrefix);
|
||||
|
||||
setBotManagers(server.serverConfig?.botManagers ?? []);
|
||||
setModerators(server.serverConfig?.moderators ?? []);
|
||||
} catch(e: any) {
|
||||
console.error(e);
|
||||
setStatus(`${e?.message ?? e}`);
|
||||
|
@ -50,7 +70,7 @@ const ServerDashboard: FunctionComponent = () => {
|
|||
<div hidden={Object.keys(serverInfo).length == 0}>
|
||||
<H4>{serverInfo.description ?? <i>No server description set</i>}</H4>
|
||||
<br/>
|
||||
<div style={{ paddingLeft: '10px' }}>
|
||||
<div style={{ paddingLeft: '10px', paddingRight: '10px' }}>
|
||||
<H3>Prefix</H3>
|
||||
<InputBox
|
||||
style={{ width: '150px', }}
|
||||
|
@ -61,7 +81,7 @@ const ServerDashboard: FunctionComponent = () => {
|
|||
}}
|
||||
/>
|
||||
<Checkbox
|
||||
style={{ width: '400px' }}
|
||||
style={{ maxWidth: '400px' }}
|
||||
value={prefixAllowSpace}
|
||||
onChange={() => {
|
||||
setPrefixAllowSpace(!prefixAllowSpace);
|
||||
|
@ -73,10 +93,191 @@ const ServerDashboard: FunctionComponent = () => {
|
|||
style={{ marginTop: "16px" }}
|
||||
onClick={saveConfig}
|
||||
>Save</Button>
|
||||
|
||||
<LineDivider />
|
||||
|
||||
<H3>Bot Managers</H3>
|
||||
<H4>
|
||||
Only users with "Manage Server" permission are allowed to add/remove other
|
||||
bot managers and are automatically considered bot manager.
|
||||
</H4>
|
||||
<UserListTypeContainer>
|
||||
<UserListContainer disabled={(serverInfo.perms ?? 0) < 3}>
|
||||
{botManagers.map((uid: string) => {
|
||||
const user = serverInfo.users.find(u => u.id == uid) || { id: uid }
|
||||
return (
|
||||
<UserListEntry type='MANAGER' user={user} key={uid} />
|
||||
)})}
|
||||
<UserListAddField type='MANAGER' />
|
||||
</UserListContainer>
|
||||
</UserListTypeContainer>
|
||||
|
||||
<H3>Moderators</H3>
|
||||
<H4>
|
||||
Only bot managers are allowed to add/remove moderators.
|
||||
All bot managers are also moderators.
|
||||
</H4>
|
||||
<UserListTypeContainer>
|
||||
<UserListContainer disabled={(serverInfo.perms ?? 0) < 2}>
|
||||
{moderators.map((uid: string) => {
|
||||
const user = serverInfo.users.find(u => u.id == uid) || { id: uid }
|
||||
return (
|
||||
<UserListEntry type='MOD' user={user} key={uid} />
|
||||
)})}
|
||||
<UserListAddField type='MOD' />
|
||||
</UserListContainer>
|
||||
</UserListTypeContainer>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function UserListEntry(props: { user: User, type: 'MANAGER'|'MOD' }) {
|
||||
return (
|
||||
<div
|
||||
key={props.user.id}
|
||||
style={{
|
||||
display: 'block',
|
||||
margin: '4px 6px',
|
||||
padding: '4px',
|
||||
backgroundColor: 'var(--tertiary-background)',
|
||||
borderRadius: '5px',
|
||||
}}
|
||||
>
|
||||
<img
|
||||
src={props.user.avatarURL ?? 'https://amogus.org/amogus.png'}
|
||||
width={28}
|
||||
height={28}
|
||||
style={{
|
||||
borderRadius: '50%',
|
||||
verticalAlign: 'middle',
|
||||
display: 'inline-block',
|
||||
}}
|
||||
/>
|
||||
<span
|
||||
style={{
|
||||
color: 'var(--foreground)',
|
||||
fontSize: '20px',
|
||||
paddingLeft: '6px',
|
||||
marginBottom: '2px',
|
||||
verticalAlign: 'middle',
|
||||
display: 'inline-block',
|
||||
}}
|
||||
>{props.user.username ?? 'Unknown'}</span>
|
||||
<div
|
||||
style={{
|
||||
marginLeft: '4px',
|
||||
verticalAlign: 'middle',
|
||||
display: 'inline-block',
|
||||
height: '30px',
|
||||
}}
|
||||
onClick={async () => {
|
||||
const res = await axios.delete(
|
||||
`${API_URL}/dash/server/${serverid}/${props.type == 'MANAGER' ? 'managers' : 'mods'}/${props.user.id}`,
|
||||
{ headers: await getAuthHeaders() }
|
||||
);
|
||||
|
||||
if (props.type == 'MANAGER') {
|
||||
setBotManagers(res.data.managers);
|
||||
}
|
||||
else if (props.type == 'MOD') {
|
||||
setModerators(res.data.mods);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Icon // todo: hover effect
|
||||
path={mdiCloseBox}
|
||||
color='var(--tertiary-foreground)'
|
||||
size='30px'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function UserListContainer(props: { disabled: boolean, children: any }) {
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexWrap: 'wrap',
|
||||
...(props.disabled ? {
|
||||
filter: 'grayscale(100%)',
|
||||
pointerEvents: 'none',
|
||||
} : {})
|
||||
}}
|
||||
>
|
||||
{props.children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function UserListTypeContainer(props: any) {
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
backgroundColor: 'var(--secondary-background)',
|
||||
borderRadius: '10px',
|
||||
marginTop: '15px',
|
||||
paddingTop: '5px',
|
||||
paddingBottom: '5px',
|
||||
}}
|
||||
>{props.children}</div>
|
||||
);
|
||||
}
|
||||
|
||||
function UserListAddField(props: { type: 'MANAGER'|'MOD' }) {
|
||||
const [content, setContent] = useState('');
|
||||
|
||||
const onConfirm = useCallback(async () => {
|
||||
if (content.length) {
|
||||
const res = await axios.put(
|
||||
`${API_URL}/dash/server/${serverid}/${props.type == 'MANAGER' ? 'managers' : 'mods'}`,
|
||||
{ item: content },
|
||||
{ headers: await getAuthHeaders() }
|
||||
);
|
||||
|
||||
if (res.data.users?.length) {
|
||||
res.data.users.forEach((user: User) => {
|
||||
if (!serverInfo.users.find(u => u.id == user.id)) serverInfo.users.push(user);
|
||||
});
|
||||
}
|
||||
|
||||
if (props.type == 'MANAGER') {
|
||||
setBotManagers(res.data.managers);
|
||||
}
|
||||
else if (props.type == 'MOD') {
|
||||
setModerators(res.data.mods);
|
||||
}
|
||||
}
|
||||
}, [content]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<InputBox
|
||||
placeholder={`Add a ${props.type == 'MANAGER' ? 'bot manager' : 'moderator'}...`}
|
||||
value={content}
|
||||
onChange={e => setContent(e.currentTarget.value)}
|
||||
style={{
|
||||
float: 'left',
|
||||
width: '180px',
|
||||
height: '38px',
|
||||
margin: '4px 8px',
|
||||
}}
|
||||
onKeyDown={e => e.key == 'Enter' && onConfirm()}
|
||||
/>
|
||||
<Button
|
||||
style={{
|
||||
float: 'left',
|
||||
width: '40px',
|
||||
height: '38px',
|
||||
margin: '4px 8px',
|
||||
}}
|
||||
onClick={onConfirm}
|
||||
>Ok</Button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
export default ServerDashboard;
|
||||
|
|
|
@ -265,6 +265,16 @@
|
|||
resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.5.tgz#77211291c1900a700b8a78cfafda3160d76949ed"
|
||||
integrity sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==
|
||||
|
||||
"@mdi/js@^6.5.95":
|
||||
version "6.5.95"
|
||||
resolved "https://registry.yarnpkg.com/@mdi/js/-/js-6.5.95.tgz#2d895b013408f213252b77c30e0fdaaba6dc8b4b"
|
||||
integrity sha512-x/bwEoAGP+Mo10Dfk5audNIPi7Yz8ZBrILcbXLW3ShOI/njpgodzpgpC2WYK3D2ZSC392peRRemIFb/JsyzzYQ==
|
||||
|
||||
"@mdi/react@^1.5.0":
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@mdi/react/-/react-1.5.0.tgz#461d2064ba12d509723bffc95e2f7169a6ac884a"
|
||||
integrity sha512-NztRgUxSYD+ImaKN94Tg66VVVqXj4SmlDGzZoz48H9riJ+Awha56sfXH2fegw819NWo7KI3oeS1Es0lNQqwr0w==
|
||||
|
||||
"@revoltchat/ui@^1.0.24":
|
||||
version "1.0.24"
|
||||
resolved "https://registry.yarnpkg.com/@revoltchat/ui/-/ui-1.0.24.tgz#ce55cc225ec92eb07dd5865b9255d1f160d06ce2"
|
||||
|
@ -719,7 +729,7 @@ lodash@^4.17.11:
|
|||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||
|
||||
loose-envify@^1.1.0:
|
||||
loose-envify@^1.1.0, loose-envify@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
|
||||
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
|
||||
|
@ -780,6 +790,15 @@ postcss@^8.4.5:
|
|||
picocolors "^1.0.0"
|
||||
source-map-js "^1.0.1"
|
||||
|
||||
prop-types@^15.8.1:
|
||||
version "15.8.1"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
|
||||
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
|
||||
dependencies:
|
||||
loose-envify "^1.4.0"
|
||||
object-assign "^4.1.1"
|
||||
react-is "^16.13.1"
|
||||
|
||||
react-dom@^17.0.2:
|
||||
version "17.0.2"
|
||||
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23"
|
||||
|
@ -789,7 +808,7 @@ react-dom@^17.0.2:
|
|||
object-assign "^4.1.1"
|
||||
scheduler "^0.20.2"
|
||||
|
||||
react-is@^16.7.0:
|
||||
react-is@^16.13.1, react-is@^16.7.0:
|
||||
version "16.13.1"
|
||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
|
||||
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
|
||||
|
|
Loading…
Reference in a new issue