First pass on bot management page
This commit is contained in:
33
ui/src/api/guilds.ts
Normal file
33
ui/src/api/guilds.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { getRequest, postRequest } from '.';
|
||||
import { GuildChannel, GuildInfo } from './guilds.types';
|
||||
|
||||
export async function getGuilds(): Promise<GuildInfo[]> {
|
||||
const response = await getRequest('guilds', {});
|
||||
return response?.data || { data: [] };
|
||||
}
|
||||
|
||||
export async function getTextChannels(guildId: number): Promise<GuildChannel[]> {
|
||||
const response = await getRequest(`guilds/${guildId}/text`, {});
|
||||
return response?.data || { data: [] };
|
||||
}
|
||||
|
||||
export async function getVoiceChannels(guildId: number): Promise<GuildChannel[]> {
|
||||
const response = await getRequest(`guilds/${guildId}/voice`, {});
|
||||
return response?.data || { data: [] };
|
||||
}
|
||||
|
||||
export async function playTrack(guildId: number, channelId: number, track: string): Promise<void> {
|
||||
await postRequest(`guilds/${guildId}/voice/${channelId}/play`, { track_url: track });
|
||||
}
|
||||
|
||||
export async function stopTrack(guildId: number, channelId: number): Promise<void> {
|
||||
await postRequest(`guilds/${guildId}/voice/${channelId}/stop`, {});
|
||||
}
|
||||
|
||||
export async function pauseTrack(guildId: number, channelId: number): Promise<void> {
|
||||
await postRequest(`guilds/${guildId}/voice/${channelId}/pause`, {});
|
||||
}
|
||||
|
||||
export async function resumeTrack(guildId: number, channelId: number): Promise<void> {
|
||||
await postRequest(`guilds/${guildId}/voice/${channelId}/resume`, {});
|
||||
}
|
||||
13
ui/src/api/guilds.types.ts
Normal file
13
ui/src/api/guilds.types.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
export interface GuildInfo {
|
||||
id: number;
|
||||
icon?: string;
|
||||
name: string;
|
||||
owner: boolean;
|
||||
}
|
||||
|
||||
export interface GuildChannel {
|
||||
id: number;
|
||||
name: string;
|
||||
type: string;
|
||||
guild_id: number;
|
||||
}
|
||||
@@ -12,7 +12,7 @@ export async function getRequest(endpoint: string, params: any): Promise<AxiosRe
|
||||
|
||||
export async function postRequest(endpoint: string, body: any): Promise<AxiosResponse<any, any> | undefined> {
|
||||
const response = await axios
|
||||
.post(`${serviceHost}:${servicePort}/${endpoint}`, { body })
|
||||
.post(`${serviceHost}:${servicePort}/${endpoint}`, body || {})
|
||||
.catch((error) => console.error(error));
|
||||
return response || undefined;
|
||||
}
|
||||
|
||||
106
ui/src/app/management/page.tsx
Normal file
106
ui/src/app/management/page.tsx
Normal file
@@ -0,0 +1,106 @@
|
||||
'use client';
|
||||
|
||||
import {
|
||||
getGuilds,
|
||||
getTextChannels,
|
||||
getVoiceChannels,
|
||||
pauseTrack,
|
||||
playTrack,
|
||||
resumeTrack,
|
||||
stopTrack
|
||||
} from '@/api/guilds';
|
||||
import { GuildChannel, GuildInfo } from '@/api/guilds.types';
|
||||
import { Button, Slider, Tabs, TextInput } from '@mantine/core';
|
||||
import { useForm } from '@mantine/form';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
|
||||
export default function Page() {
|
||||
const [guilds, setGuilds] = useState<GuildInfo[]>([]);
|
||||
const [activeGuild, setActiveGuild] = useState<GuildInfo | null>(null);
|
||||
const [textChannels, setTextChannels] = useState<GuildChannel[]>([]);
|
||||
const [voiceChannels, setVoiceChannels] = useState<GuildChannel[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
getGuilds().then((g) => {
|
||||
setGuilds(g);
|
||||
if (g.length > 0) {
|
||||
setActiveGuild(g[0]);
|
||||
}
|
||||
});
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (activeGuild) {
|
||||
getTextChannels(activeGuild.id).then((c) => setTextChannels(c));
|
||||
getVoiceChannels(activeGuild.id).then((c) => setVoiceChannels(c));
|
||||
}
|
||||
}, [activeGuild]);
|
||||
|
||||
const playForm = useForm({
|
||||
initialValues: {
|
||||
trackUrl: ''
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<Tabs orientation='vertical' defaultValue={activeGuild?.name}>
|
||||
<Tabs.List>
|
||||
{guilds.map((guild) => (
|
||||
<Tabs.Tab key={guild.id} value={guild.name} onClick={() => setActiveGuild(guild)}>
|
||||
{guild.name}
|
||||
</Tabs.Tab>
|
||||
))}
|
||||
</Tabs.List>
|
||||
{guilds.map((guild) => (
|
||||
<Tabs.Panel key={guild.id} value={guild.name}>
|
||||
<h1>{guild.name}</h1>
|
||||
<h2>Text Channels</h2>
|
||||
<Tabs orientation='horizontal' defaultValue={textChannels[0]?.name}>
|
||||
<Tabs.List>
|
||||
{textChannels.map((channel) => (
|
||||
<Tabs.Tab key={channel.id} value={channel.name}>
|
||||
{channel.name}
|
||||
</Tabs.Tab>
|
||||
))}
|
||||
</Tabs.List>
|
||||
{textChannels.map((channel) => (
|
||||
<Tabs.Panel key={channel.id} value={channel.name}>
|
||||
{channel.name}
|
||||
</Tabs.Panel>
|
||||
))}
|
||||
</Tabs>
|
||||
<h2>Voice Channels</h2>
|
||||
<Tabs orientation='horizontal' defaultValue={voiceChannels[0]?.name}>
|
||||
<Tabs.List>
|
||||
{voiceChannels.map((channel) => (
|
||||
<Tabs.Tab key={channel.id} value={channel.name}>
|
||||
{channel.name}
|
||||
</Tabs.Tab>
|
||||
))}
|
||||
</Tabs.List>
|
||||
{voiceChannels.map((channel) => (
|
||||
<Tabs.Panel key={channel.id} value={channel.name}>
|
||||
{channel.name}
|
||||
<form
|
||||
style={{ display: 'flex' }}
|
||||
onSubmit={playForm.onSubmit((values) => {
|
||||
playTrack(activeGuild!.id, channel.id, values.trackUrl);
|
||||
})}
|
||||
>
|
||||
<TextInput placeholder='Youtube URL...' {...playForm.getInputProps('trackUrl')} />
|
||||
<Button type='submit'>Play Track</Button>
|
||||
</form>
|
||||
<Button onClick={() => stopTrack(activeGuild!.id, channel.id)}>Stop</Button>
|
||||
<Button onClick={() => pauseTrack(activeGuild!.id, channel.id)}>Pause</Button>
|
||||
<Button onClick={() => resumeTrack(activeGuild!.id, channel.id)}>Resume</Button>
|
||||
<div>
|
||||
<Slider label='Volume' style={{ width: '20%' }} defaultValue={50} onChange={(v) => {}} />
|
||||
</div>
|
||||
</Tabs.Panel>
|
||||
))}
|
||||
</Tabs>
|
||||
</Tabs.Panel>
|
||||
))}
|
||||
</Tabs>
|
||||
);
|
||||
}
|
||||
@@ -32,6 +32,10 @@ const headerItems = [
|
||||
{
|
||||
name: 'Spells',
|
||||
link: '/spells'
|
||||
},
|
||||
{
|
||||
name: 'Management',
|
||||
link: '/management'
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user