updated navbar and ui

This commit is contained in:
2025-10-04 08:08:45 -04:00
parent f63fca3f1b
commit 0b1a6cdea4
7 changed files with 118 additions and 40 deletions

View File

@@ -8,7 +8,6 @@ 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() {
@@ -23,7 +22,6 @@ function App() {
<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>

View File

@@ -2,7 +2,6 @@ import React, { useState, useEffect, useLayoutEffect, useContext } from 'react';
import { useNavigate } from 'react-router-dom';
import { Grid, Card, CardContent, Typography, Box, CardMedia, IconButton, Snackbar, Alert } from '@mui/material';
import { UserContext } from '../contexts/UserContext';
import UserSettings from './UserSettings';
import PersonAddIcon from '@mui/icons-material/PersonAdd';
import RemoveCircleOutlineIcon from '@mui/icons-material/RemoveCircleOutline';
import axios from 'axios';
@@ -119,9 +118,7 @@ const Dashboard = () => {
return (
<div style={{ padding: '20px' }}>
<Box sx={{ display: 'flex', justifyContent: 'flex-end' }}>
<UserSettings />
</Box>
{/* UserSettings moved to NavBar */}
<Typography variant="h4" gutterBottom>
Dashboard
</Typography>

View File

@@ -24,8 +24,8 @@ const HelpPage = () => {
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>
<IconButton onClick={handleBack}><ArrowBackIcon /></IconButton>
<Typography variant="h5">Commands List</Typography>
</Box>
<Box sx={{ marginTop: 2 }}>
{commands.length === 0 && <Typography>No commands available.</Typography>}

View File

@@ -1,31 +1,58 @@
import React, { useState } from 'react';
import { AppBar, Toolbar, Button, Box, IconButton, Collapse } from '@mui/material';
import { AppBar, Toolbar, IconButton, Typography, Box, Menu, MenuItem } from '@mui/material';
import UserSettings from './UserSettings';
import MenuIcon from '@mui/icons-material/Menu';
import HelpOutlineIcon from '@mui/icons-material/HelpOutline';
import { useNavigate, useLocation, useParams } from 'react-router-dom';
import CloseIcon from '@mui/icons-material/Close';
import { useNavigate, useLocation } from 'react-router-dom';
const NavBar = () => {
const [open, setOpen] = useState(true);
const navigate = useNavigate();
const location = useLocation();
// Pull guildId from URL if present
const [open, setOpen] = useState(false);
const [anchorEl, setAnchorEl] = useState(null);
const guildIdMatch = location.pathname.match(/\/server\/(\d+)/);
const guildId = guildIdMatch ? guildIdMatch[1] : null;
const toggleOpen = (e) => {
if (!open) {
setAnchorEl(e.currentTarget);
setOpen(true);
} else {
setAnchorEl(null);
setOpen(false);
}
};
const closeMenu = () => { setAnchorEl(null); setOpen(false); };
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>
<AppBar position="static" color="transparent" elevation={0} sx={{ mb: 2, borderBottom: '1px solid rgba(0,0,0,0.06)' }}>
<Toolbar sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', px: { xs: 2, sm: 4 } }}>
<Box>
<IconButton onClick={toggleOpen} aria-label="menu" size="large" sx={{ bgcolor: open ? 'primary.main' : 'transparent', color: open ? 'white' : 'text.primary' }}>
{open ? <CloseIcon /> : <MenuIcon />}
</IconButton>
</Box>
<Typography variant="h6" component="div" sx={{ fontWeight: 800 }} onClick={() => { navigate('/dashboard'); closeMenu(); }}>
ECS - EHDCHADSWORTH
</Typography>
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
<UserSettings />
</Box>
<Menu
anchorEl={anchorEl}
open={open}
onClose={closeMenu}
anchorOrigin={{ vertical: 'bottom', horizontal: 'left' }}
transformOrigin={{ vertical: 'top', horizontal: 'left' }}
PaperProps={{ sx: { width: { xs: 'calc(100% - 32px)', sm: 300 }, left: { xs: 16, sm: 'auto' } } }}
>
<MenuItem onClick={() => { navigate('/dashboard'); closeMenu(); }}>Dashboard</MenuItem>
<MenuItem onClick={() => { window.open('https://discord.gg/EAqNqWjJMQ', '_blank'); closeMenu(); }}>Join The Discord!</MenuItem>
{guildId && <MenuItem onClick={() => { navigate(`/server/${guildId}/help`); closeMenu(); }}>Commands List</MenuItem>}
</Menu>
</Toolbar>
</AppBar>
);

View File

@@ -4,7 +4,7 @@ import axios from 'axios';
import { Button, Typography, Box, IconButton, Switch, Select, MenuItem, FormControl, FormControlLabel, Radio, RadioGroup, TextField, Accordion, AccordionSummary, AccordionDetails } from '@mui/material';
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import UserSettings from './UserSettings';
// UserSettings moved to NavBar
import ConfirmDialog from './ConfirmDialog';
const ServerSettings = () => {
@@ -243,24 +243,48 @@ const ServerSettings = () => {
</Button>
)}
</Box>
<UserSettings />
{/* UserSettings moved to NavBar */}
</Box>
<Accordion sx={{ marginTop: '20px', opacity: isBotInServer ? 1 : 0.5 }} expanded={commandsExpanded} onChange={() => setCommandsExpanded(prev => !prev)}>
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
<Typography variant="h6">Commands</Typography>
</AccordionSummary>
<Box sx={{ display: 'flex', justifyContent: 'flex-end', padding: 1 }}>
<Button variant="text" onClick={() => navigate(`/server/${guildId}/help`)} disabled={!isBotInServer}>Commands List</Button>
</Box>
<AccordionDetails>
{!isBotInServer && <Typography>Invite the bot to enable commands.</Typography>}
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginTop: '10px' }}>
<Typography>Ping Command</Typography>
<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 sx={{ display: 'flex', flexDirection: 'column', gap: 2, marginTop: '10px' }}>
{commandsList.map(cmd => (
<Box key={cmd.name} sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: 1, border: '1px solid #eee', borderRadius: 1 }}>
<Box>
<Typography sx={{ fontWeight: 'bold' }}>{cmd.name}</Typography>
<Typography variant="body2">{cmd.description}</Typography>
</Box>
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
{['help', 'manage-commands'].includes(cmd.name) ? (
<FormControlLabel
control={<Switch checked={true} disabled />}
label="Locked"
/>
) : (
<FormControlLabel
control={<Switch checked={cmd.enabled} onChange={async (e) => {
const newVal = e.target.checked;
// optimistic update
setCommandsList(prev => prev.map(c => c.name === cmd.name ? { ...c, enabled: newVal } : c));
try {
await axios.post(`http://localhost:3002/api/servers/${guildId}/commands/${cmd.name}/toggle`, { enabled: newVal });
} catch (err) {
// revert on error
setCommandsList(prev => prev.map(c => c.name === cmd.name ? { ...c, enabled: cmd.enabled } : c));
}
}} disabled={!isBotInServer} label={cmd.enabled ? 'Enabled' : 'Disabled'} />}
/>
)}
</Box>
</Box>
))}
</Box>
</AccordionDetails>
</Accordion>