[FEATURE] Autocomplete & theming

This commit is contained in:
dunemask 2023-10-09 13:42:11 -06:00
parent ef00eef464
commit 5a9212a814
18 changed files with 114 additions and 35 deletions

View file

@ -1,4 +1,6 @@
// Imports
import { ThemeProvider } from "@mui/material/styles";
import mclTheme from "./util/theme.js";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { SettingsProvider } from "@mcl/settings";
import Viewport from "./nav/Viewport.jsx";
@ -11,9 +13,11 @@ export default function MCL() {
<div className="minecluster">
<QueryClientProvider client={queryClient}>
<SettingsProvider>
<BrowserRouter>
<Viewport />
</BrowserRouter>
<ThemeProvider theme={mclTheme}>
<BrowserRouter>
<Viewport />
</BrowserRouter>
</ThemeProvider>
</SettingsProvider>
</QueryClientProvider>
</div>

View file

@ -13,7 +13,7 @@ import IconButton from "@mui/material/IconButton";
import Typography from "@mui/material/Typography";
import MenuIcon from "@mui/icons-material/Menu";
import Drawer from "@mui/material/Drawer";
import ListItemIcon from "@mui/material/ListItemIcon";
import HomeIcon from "@mui/icons-material/Home";
import ListItemText from "@mui/material/ListItemText";
import List from "@mui/material/List";
import ListItemButton from "@mui/material/ListItemButton";
@ -36,11 +36,27 @@ export default function MCLMenu() {
theme.zIndex.modal + 2 - (isDrawer ? 1 : 0);
return (
<AppBar position="fixed" sx={{ bgcolor: "black", zIndex: drawerIndex() }}>
<AppBar
position="fixed"
color="primary"
sx={{ zIndex: drawerIndex(), bgcolor: "black" }}
enableColorOnDark={false}
>
<Box sx={{ flexGrow: 1, margin: "0 20px" }}>
<Toolbar disableGutters>
<Typography variant="h6" noWrap component="div" sx={{ flexGrow: 1 }}>
{navHeader()}
<Typography
variant="h6"
noWrap
component="div"
sx={{ flexGrow: 1, display: "flex" }}
color="white"
>
<IconButton component={Link} to="/" color="inherit">
<HomeIcon />
</IconButton>
<span style={{ margin: "auto 0", color: "inherit" }}>
{navHeader()}{" "}
</span>
</Typography>
</Toolbar>
</Box>

View file

@ -1,6 +1,8 @@
import Box from "@mui/material/Box";
import Toolbar from "@mui/material/Toolbar";
import MCLPortal from "./MCLPortal.jsx";
import Button from "@mui/material/Button";
import SpeedDialIcon from "@mui/material/SpeedDialIcon";
// Import Navbar
/*import Navbar from "./Navbar.jsx";*/
import MCLMenu from "./MCLMenu.jsx";

View file

@ -1,13 +1,12 @@
import Box from "@mui/material/Box";
import CreateOptions from "./CreateOptions.jsx";
export default function Create(){
return (
<Box className="create">
{/*<CreateMenu />*/}
{/*<CreateOptions />*/}
</Box>
);
export default function Create() {
return (
<Box className="create">
{/*<CreateMenu />*/}
<Box className="create-wrapper" sx={{ display: "flex" }}>
<CreateOptions />
</Box>
</Box>
);
}

View file

@ -1,4 +1,5 @@
import { useState, useEffect } from "react";
import Autocomplete from "@mui/material/Autocomplete";
import TextField from "@mui/material/TextField";
import Box from "@mui/material/Box";
import Button from "@mui/material/Button";
@ -20,6 +21,8 @@ const defaultServer = {
};
export default function Create() {
const [wl, setWl] = useState([]);
const [spec, setSpec] = useState(defaultServer);
const versionList = useVersionList();
const [versions, setVersions] = useState(["latest"]);
@ -42,6 +45,9 @@ export default function Create() {
const coreUpdate = (attr) => (e) => updateSpec(attr, e.target.value);
const whitelistUpdate = (e) => alert("Whitelist not Implimented");
const opUpdate = (e) => alert("Op not implimented");
function upsertSpec() {
if (validateSpec() !== "validated") return;
createServer(spec);
@ -60,23 +66,31 @@ export default function Create() {
}
return (
<Box className="create">
<Box className="create-options" sx={{maxWidth:"400px"}}>
<FormControl fullWidth>
<Box
className="create-options"
sx={{ width: "100%", maxWidth: "600px", margin: "auto" }}
>
<FormControl fullWidth sx={{ mt: "2rem", display: "flex", gap: ".5rem" }}>
<TextField
label="Name"
onChange={coreUpdate("name")}
defaultValue={spec.name}
required
/>
<TextField label="URL" onChange={coreUpdate("url")} required />
<TextField
label="Host"
onChange={coreUpdate("url")}
helperText="Example: host.mc.example.com"
FormHelperTextProps={{ sx: { ml: 0 } }}
required
/>
<TextField
label="Version"
onChange={coreUpdate("version")}
value={spec.version}
select
required
SelectProps={{ MenuProps: { sx: { maxHeight: "12rem" } } }}
SelectProps={{ MenuProps: { sx: { maxHeight: "20rem" } } }}
>
{versions.map((v, k) => (
<MenuItem value={v} key={k}>
@ -109,9 +123,16 @@ export default function Create() {
<MenuItem value={"hard"}>Hard</MenuItem>
</TextField>
<TextField label="Whitelist" onChange={coreUpdate("whitelist")} />
<Autocomplete
multiple
id="whitelist-autocomplete"
options={[]}
onChange={whitelistUpdate}
freeSolo
renderInput={(p) => <TextField {...p} label="Whitelist" />}
/>
<TextField label="Ops" onChange={coreUpdate("ops")} />
<TextField label="Icon" onChange={coreUpdate("icon")} required />
{/*<TextField label="Icon" onChange={coreUpdate("icon")} required />*/}
<TextField
label="Max Players"
onChange={coreUpdate("maxPlayers")}
@ -131,7 +152,7 @@ export default function Create() {
<MenuItem value={"spectator"}>Spectator</MenuItem>
</TextField>
<TextField label="Seed" onChange={coreUpdate("seed")} />
<TextField label="Modpack" onChange={coreUpdate("modpack")} />
{/*<TextField label="Modpack" onChange={coreUpdate("modpack")} />*/}
<TextField
label="Memory"
onChange={coreUpdate("memory")}
@ -148,7 +169,6 @@ export default function Create() {
Create
</Button>
</FormControl>
</Box>
</Box>
);
}

View file

@ -1,9 +1,14 @@
import { Link } from "react-router-dom";
import { useState, useEffect } from "react";
import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";
import ServerCard from "../servers/ServerCard.jsx";
import RconDialog, { useRconDialog } from "../servers/RconDialog.jsx";
import Overview from "../overview/Overview.jsx";
import ServerCard from "@mcl/components/servers/ServerCard.jsx";
import RconDialog, {
useRconDialog,
} from "@mcl/components/servers/RconDialog.jsx";
import Overview from "@mcl/components/overview/Overview.jsx";
import Button from "@mui/material/Button";
import SpeedDialIcon from "@mui/material/SpeedDialIcon";
import "@mcl/css/server-card.css";
import "@mcl/css/overview.css";
import { useServerInstances } from "@mcl/queries";
@ -53,7 +58,23 @@ export default function Home() {
dialogToggle={rconToggle}
serverName={server}
/>
<Button
component={Link}
to="/mcl/create"
color="primary"
variant="contained"
sx={{
position: "absolute",
bottom: 16,
right: 16,
padding: "1rem",
borderRadius: "100%",
height: "4rem",
width: "4rem",
}}
>
<SpeedDialIcon />
</Button>
</Box>
);
}

View file

@ -14,13 +14,13 @@ const fetchApiPost = (subPath, json) => async () =>
export const useServerStatus = (server) =>
useQuery(
[`server-status-${server}`],
fetchApiPost("/server/status", { name: server })
fetchApiPost("/server/status", { name: server }),
);
export const useServerMetrics = (server) =>
useQuery(
[`server-metrics-${server}`],
fetchApiPost("/server/metrics", { name: server }),
{ refetchInterval: 10000 }
{ refetchInterval: 10000 },
);
export const useStartServer = (server) =>
postJsonApi("/server/start", { name: server }, "server-instances");
@ -41,8 +41,8 @@ export const useSystemAvailable = () =>
export const useVersionList = () =>
useQuery(["minecraft-versions"], () =>
fetch("https://piston-meta.mojang.com/mc/game/version_manifest.json").then(
(r) => r.json()
)
(r) => r.json(),
),
);
const postJsonApi = (subPath, body, invalidate, method = "POST") => {

16
src/util/theme.js Normal file
View file

@ -0,0 +1,16 @@
// Generated using https://zenoo.github.io/mui-theme-creator/
import { createTheme } from "@mui/material/styles";
const themeOptions = {
palette: {
mode: "light",
primary: {
main: "rgba(109,216,144,255)",
},
secondary: {
main: "#f50057",
},
},
};
export default createTheme(themeOptions);

View file

@ -26,10 +26,11 @@ export default () => {
base: "/mcl/",
resolve: {
alias: {
"@mcl/css": path.resolve("./public/css"),
"@mcl/css": path.resolve("./src/css"),
"@mcl/settings": path.resolve("./src/ctx/SettingsContext.jsx"),
"@mcl/pages": path.resolve("./src/pages"),
"@mcl/queries": path.resolve("./src/util/queries.js"),
"@mcl/components": path.resolve("./src/components"),
"@mcl": path.resolve("./src"),
},
},