ui updates and bot updates. new commands and command handler
This commit is contained in:
@@ -6,6 +6,10 @@ import { CssBaseline } from '@mui/material';
|
||||
import Login from './components/Login';
|
||||
import Dashboard from './components/Dashboard';
|
||||
import ServerSettings from './components/ServerSettings';
|
||||
import NavBar from './components/NavBar';
|
||||
import HelpPage from './components/HelpPage';
|
||||
import ContactPage from './components/ContactPage';
|
||||
import DiscordPage from './components/DiscordPage';
|
||||
|
||||
function App() {
|
||||
return (
|
||||
@@ -13,10 +17,14 @@ function App() {
|
||||
<ThemeProvider>
|
||||
<CssBaseline />
|
||||
<Router>
|
||||
<NavBar />
|
||||
<Routes>
|
||||
<Route path="/" element={<Login />} />
|
||||
<Route path="/dashboard" element={<Dashboard />} />
|
||||
<Route path="/server/:guildId" element={<ServerSettings />} />
|
||||
<Route path="/server/:guildId/help" element={<HelpPage />} />
|
||||
<Route path="/contact" element={<ContactPage />} />
|
||||
<Route path="/discord" element={<DiscordPage />} />
|
||||
</Routes>
|
||||
</Router>
|
||||
</ThemeProvider>
|
||||
|
||||
11
frontend/src/components/ContactPage.js
Normal file
11
frontend/src/components/ContactPage.js
Normal file
@@ -0,0 +1,11 @@
|
||||
import React from 'react';
|
||||
import { Box, Typography } from '@mui/material';
|
||||
|
||||
const ContactPage = () => (
|
||||
<Box sx={{ padding: 2 }}>
|
||||
<Typography variant="h5">Contact</Typography>
|
||||
<Typography sx={{ mt: 1 }}>For support, contact support@example.com</Typography>
|
||||
</Box>
|
||||
);
|
||||
|
||||
export default ContactPage;
|
||||
11
frontend/src/components/DiscordPage.js
Normal file
11
frontend/src/components/DiscordPage.js
Normal file
@@ -0,0 +1,11 @@
|
||||
import React from 'react';
|
||||
import { Box, Typography } from '@mui/material';
|
||||
|
||||
const DiscordPage = () => (
|
||||
<Box sx={{ padding: 2 }}>
|
||||
<Typography variant="h5">Discord!</Typography>
|
||||
<Typography sx={{ mt: 1 }}>Open the Discord invite or community links here.</Typography>
|
||||
</Box>
|
||||
);
|
||||
|
||||
export default DiscordPage;
|
||||
46
frontend/src/components/HelpPage.js
Normal file
46
frontend/src/components/HelpPage.js
Normal file
@@ -0,0 +1,46 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useParams, useNavigate, useLocation } from 'react-router-dom';
|
||||
import axios from 'axios';
|
||||
import { Box, IconButton, Typography } from '@mui/material';
|
||||
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
|
||||
|
||||
const HelpPage = () => {
|
||||
const { guildId } = useParams();
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
const [commands, setCommands] = useState([]);
|
||||
|
||||
useEffect(() => {
|
||||
axios.get(`http://localhost:3002/api/servers/${guildId}/commands`)
|
||||
.then(res => setCommands(res.data || []))
|
||||
.catch(() => setCommands([]));
|
||||
}, [guildId]);
|
||||
|
||||
const handleBack = () => {
|
||||
// Navigate back to server settings and instruct it to open Commands accordion
|
||||
navigate(`/server/${guildId}`, { state: { openCommands: true } });
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={{ padding: 20 }}>
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 2 }}>
|
||||
<IconButton onClick={handleBack}><ArrowBackIcon /></IconButton>
|
||||
<Typography variant="h5">Help - Commands for this Server</Typography>
|
||||
</Box>
|
||||
<Box sx={{ marginTop: 2 }}>
|
||||
{commands.length === 0 && <Typography>No commands available.</Typography>}
|
||||
{commands.map(cmd => (
|
||||
<Box key={cmd.name} sx={{ border: '1px solid #eee', borderRadius: 1, padding: 1, marginTop: 1 }}>
|
||||
<Box sx={{ display: 'flex', justifyContent: 'space-between' }}>
|
||||
<Typography sx={{ fontWeight: 'bold' }}>/{cmd.name}</Typography>
|
||||
<Typography sx={{ color: cmd.locked ? 'primary.main' : (cmd.enabled ? 'success.main' : 'text.secondary') }}>{cmd.locked ? 'Locked' : (cmd.enabled ? 'Enabled' : 'Disabled')}</Typography>
|
||||
</Box>
|
||||
<Typography sx={{ mt: 0.5 }}>{cmd.description}</Typography>
|
||||
</Box>
|
||||
))}
|
||||
</Box>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default HelpPage;
|
||||
21
frontend/src/components/NameBar.js
Normal file
21
frontend/src/components/NameBar.js
Normal file
@@ -0,0 +1,21 @@
|
||||
import React from 'react';
|
||||
import { AppBar, Toolbar, Button, Box } from '@mui/material';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
const NameBar = () => {
|
||||
const navigate = useNavigate();
|
||||
|
||||
return (
|
||||
<AppBar position="static" color="transparent" elevation={0} sx={{ mb: 2 }}>
|
||||
<Toolbar>
|
||||
<Box sx={{ flexGrow: 1 }}>
|
||||
<Button onClick={() => navigate('/dashboard')} color="inherit">Dashboard</Button>
|
||||
<Button onClick={() => navigate('/discord')} color="inherit">Discord!</Button>
|
||||
<Button onClick={() => navigate('/contact')} color="inherit">Contact</Button>
|
||||
</Box>
|
||||
</Toolbar>
|
||||
</AppBar>
|
||||
);
|
||||
};
|
||||
|
||||
export default NameBar;
|
||||
34
frontend/src/components/NavBar.js
Normal file
34
frontend/src/components/NavBar.js
Normal file
@@ -0,0 +1,34 @@
|
||||
import React, { useState } from 'react';
|
||||
import { AppBar, Toolbar, Button, Box, IconButton, Collapse } from '@mui/material';
|
||||
import MenuIcon from '@mui/icons-material/Menu';
|
||||
import HelpOutlineIcon from '@mui/icons-material/HelpOutline';
|
||||
import { useNavigate, useLocation, useParams } from 'react-router-dom';
|
||||
|
||||
const NavBar = () => {
|
||||
const [open, setOpen] = useState(true);
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
// Pull guildId from URL if present
|
||||
const guildIdMatch = location.pathname.match(/\/server\/(\d+)/);
|
||||
const guildId = guildIdMatch ? guildIdMatch[1] : null;
|
||||
|
||||
return (
|
||||
<AppBar position="static" color="transparent" elevation={0} sx={{ mb: 2 }}>
|
||||
<Toolbar>
|
||||
<IconButton onClick={() => setOpen(prev => !prev)} aria-label="toggle menu"><MenuIcon /></IconButton>
|
||||
<Collapse in={open} orientation="horizontal">
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
||||
<Button onClick={() => navigate('/dashboard')} color="inherit">Dashboard</Button>
|
||||
<Button onClick={() => navigate('/discord')} color="inherit">Discord!</Button>
|
||||
<Button onClick={() => navigate('/contact')} color="inherit">Contact</Button>
|
||||
{guildId && (
|
||||
<Button startIcon={<HelpOutlineIcon />} onClick={() => navigate(`/server/${guildId}/help`)} color="inherit">Help</Button>
|
||||
)}
|
||||
</Box>
|
||||
</Collapse>
|
||||
</Toolbar>
|
||||
</AppBar>
|
||||
);
|
||||
};
|
||||
|
||||
export default NavBar;
|
||||
@@ -17,6 +17,13 @@ const ServerSettings = () => {
|
||||
const [server, setServer] = useState(null);
|
||||
const [dialogOpen, setDialogOpen] = useState(false);
|
||||
const [channels, setChannels] = useState([]);
|
||||
const [roles, setRoles] = useState([]);
|
||||
const [autoroleSettings, setAutoroleSettings] = useState({
|
||||
enabled: false,
|
||||
roleId: '',
|
||||
});
|
||||
const [commandsList, setCommandsList] = useState([]);
|
||||
const [commandsExpanded, setCommandsExpanded] = useState(false);
|
||||
const [welcomeLeaveSettings, setWelcomeLeaveSettings] = useState({
|
||||
welcome: {
|
||||
enabled: false,
|
||||
@@ -79,8 +86,53 @@ const ServerSettings = () => {
|
||||
}
|
||||
});
|
||||
|
||||
// Fetch roles
|
||||
axios.get(`http://localhost:3002/api/servers/${guildId}/roles`)
|
||||
.then(response => {
|
||||
setRoles(response.data);
|
||||
});
|
||||
|
||||
// Fetch autorole settings
|
||||
axios.get(`http://localhost:3002/api/servers/${guildId}/autorole-settings`)
|
||||
.then(response => {
|
||||
if (response.data) {
|
||||
setAutoroleSettings(response.data);
|
||||
}
|
||||
});
|
||||
|
||||
// Fetch commands/help list
|
||||
axios.get(`http://localhost:3002/api/servers/${guildId}/commands`)
|
||||
.then(response => {
|
||||
setCommandsList(response.data || []);
|
||||
})
|
||||
.catch(() => setCommandsList([]));
|
||||
|
||||
// Open commands accordion if navigated from Help back button
|
||||
if (location.state && location.state.openCommands) {
|
||||
setCommandsExpanded(true);
|
||||
}
|
||||
|
||||
}, [guildId, location.state]);
|
||||
|
||||
const handleAutoroleSettingUpdate = (newSettings) => {
|
||||
axios.post(`http://localhost:3002/api/servers/${guildId}/autorole-settings`, newSettings)
|
||||
.then(response => {
|
||||
if (response.data.success) {
|
||||
setAutoroleSettings(newSettings);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const handleAutoroleToggleChange = (event) => {
|
||||
const newSettings = { ...autoroleSettings, enabled: event.target.checked };
|
||||
handleAutoroleSettingUpdate(newSettings);
|
||||
};
|
||||
|
||||
const handleAutoroleRoleChange = (event) => {
|
||||
const newSettings = { ...autoroleSettings, roleId: event.target.value };
|
||||
handleAutoroleSettingUpdate(newSettings);
|
||||
};
|
||||
|
||||
const handleSettingUpdate = (newSettings) => {
|
||||
axios.post(`http://localhost:3002/api/servers/${guildId}/welcome-leave-settings`, newSettings)
|
||||
.then(response => {
|
||||
@@ -193,7 +245,7 @@ const ServerSettings = () => {
|
||||
</Box>
|
||||
<UserSettings />
|
||||
</Box>
|
||||
<Accordion sx={{ marginTop: '20px', opacity: isBotInServer ? 1 : 0.5 }}>
|
||||
<Accordion sx={{ marginTop: '20px', opacity: isBotInServer ? 1 : 0.5 }} expanded={commandsExpanded} onChange={() => setCommandsExpanded(prev => !prev)}>
|
||||
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
|
||||
<Typography variant="h6">Commands</Typography>
|
||||
</AccordionSummary>
|
||||
@@ -201,12 +253,18 @@ const ServerSettings = () => {
|
||||
{!isBotInServer && <Typography>Invite the bot to enable commands.</Typography>}
|
||||
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginTop: '10px' }}>
|
||||
<Typography>Ping Command</Typography>
|
||||
<Button variant="contained" onClick={togglePingCommand} disabled={!isBotInServer}>
|
||||
{settings.pingCommand ? 'Disable' : 'Enable'}
|
||||
</Button>
|
||||
<Box>
|
||||
<Button variant="contained" onClick={togglePingCommand} disabled={!isBotInServer}>
|
||||
{settings.pingCommand ? 'Disable' : 'Enable'}
|
||||
</Button>
|
||||
<Button sx={{ ml: 1 }} variant="outlined" onClick={() => navigate(`/server/${guildId}/help`)}>
|
||||
Open Help Page
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
</AccordionDetails>
|
||||
</Accordion>
|
||||
{/* Help moved to dedicated Help page */}
|
||||
<Accordion sx={{ marginTop: '20px', opacity: isBotInServer ? 1 : 0.5 }}>
|
||||
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
|
||||
<Typography variant="h6">Welcome/Leave</Typography>
|
||||
@@ -297,6 +355,32 @@ const ServerSettings = () => {
|
||||
</Box>
|
||||
</AccordionDetails>
|
||||
</Accordion>
|
||||
<Accordion sx={{ marginTop: '20px', opacity: isBotInServer ? 1 : 0.5 }}>
|
||||
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
|
||||
<Typography variant="h6">Autorole</Typography>
|
||||
</AccordionSummary>
|
||||
<AccordionDetails>
|
||||
{!isBotInServer && <Typography>Invite the bot to enable this feature.</Typography>}
|
||||
<Box sx={{ marginTop: '10px' }}>
|
||||
<FormControlLabel
|
||||
control={<Switch checked={autoroleSettings.enabled} onChange={handleAutoroleToggleChange} disabled={!isBotInServer} />}
|
||||
label="Enable Autorole"
|
||||
/>
|
||||
<FormControl fullWidth sx={{ marginTop: '10px' }} disabled={!isBotInServer || !autoroleSettings.enabled}>
|
||||
<Select
|
||||
value={autoroleSettings.roleId}
|
||||
onChange={handleAutoroleRoleChange}
|
||||
displayEmpty
|
||||
>
|
||||
<MenuItem value="" disabled>Select a role</MenuItem>
|
||||
{roles.map(role => (
|
||||
<MenuItem key={role.id} value={role.id}><span style={{ color: role.color }}>{role.name}</span></MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
</FormControl>
|
||||
</Box>
|
||||
</AccordionDetails>
|
||||
</Accordion>
|
||||
<Accordion sx={{ marginTop: '20px', opacity: isBotInServer ? 1 : 0.5 }}>
|
||||
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
|
||||
<Typography variant="h6">Admin Commands</Typography>
|
||||
|
||||
Reference in New Issue
Block a user