mirror of
https://github.com/dec0dOS/zero-ui.git
synced 2025-07-06 04:51:44 -07:00
feat: keyboard shortcuts
This commit is contained in:
parent
213c9499f2
commit
94f1a8b00b
48 changed files with 398 additions and 90 deletions
|
@ -1,6 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "frontend",
|
"name": "frontend",
|
||||||
"private": true,
|
"private": true,
|
||||||
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fontsource/roboto": "^4.5.8",
|
"@fontsource/roboto": "^4.5.8",
|
||||||
"@material-ui/core": "^4.12.4",
|
"@material-ui/core": "^4.12.4",
|
||||||
|
@ -13,6 +14,7 @@
|
||||||
"history": "^5.3.0",
|
"history": "^5.3.0",
|
||||||
"ipaddr.js": "^2.0.1",
|
"ipaddr.js": "^2.0.1",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
|
"ninja-keys": "^1.2.2",
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
"react-data-table-component": "^6.11.8",
|
"react-data-table-component": "^6.11.8",
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "^17.0.2",
|
||||||
|
|
|
@ -2,12 +2,13 @@ import "@fontsource/roboto";
|
||||||
|
|
||||||
import { BrowserRouter, Route, Redirect, Switch } from "react-router-dom";
|
import { BrowserRouter, Route, Redirect, Switch } from "react-router-dom";
|
||||||
|
|
||||||
import Theme from "./components/Theme";
|
import Theme from "./components/Theme/Theme.jsx";
|
||||||
import Bar from "./components/Bar";
|
import Bar from "./components/Bar/Bar.jsx";
|
||||||
|
|
||||||
import Home from "./routes/Home";
|
import Home from "./routes/Home/Home.jsx";
|
||||||
import NotFound from "./routes/NotFound";
|
import NotFound from "./routes/NotFound/NotFound.jsx";
|
||||||
import Network from "./routes/Network/Network";
|
import Network from "./routes/Network/Network.jsx";
|
||||||
|
import Settings from "./routes/Settings/Settings.jsx";
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import logo from "./assets/logo.png";
|
import logo from "./assets/logo.png";
|
||||||
|
|
||||||
import { useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
import { Link as RouterLink, useHistory } from "react-router-dom";
|
import { Redirect, Link as RouterLink, useHistory } from "react-router-dom";
|
||||||
import { useLocalStorage } from "react-use";
|
import { useLocalStorage, useWindowScroll } from "react-use";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
AppBar,
|
AppBar,
|
||||||
|
@ -15,16 +15,56 @@ import {
|
||||||
MenuItem,
|
MenuItem,
|
||||||
Link,
|
Link,
|
||||||
} from "@material-ui/core";
|
} from "@material-ui/core";
|
||||||
import MenuIcon from "@material-ui/icons/Menu";
|
import MenuIcon from "@material-ui/icons/Menu.js";
|
||||||
|
|
||||||
import LogIn from "components/LogIn";
|
import LogIn from "components/LogIn/LogIn.jsx";
|
||||||
|
import "ninja-keys";
|
||||||
|
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import API from "utils/API.js";
|
||||||
|
import { generateNetworkConfig } from "utils/NetworkConfig.js";
|
||||||
|
|
||||||
function Bar() {
|
function Bar() {
|
||||||
|
const ninjaKeys = useRef(null);
|
||||||
|
const history = useHistory();
|
||||||
|
const { t, i18n } = useTranslation();
|
||||||
|
|
||||||
|
const [hotkeys, setHotkeys] = useState([
|
||||||
|
{
|
||||||
|
id: "Settings",
|
||||||
|
title: t("settings"),
|
||||||
|
hotkey: "cmd+shift+s",
|
||||||
|
handler: () => {
|
||||||
|
history.push("/settings");
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "createNet",
|
||||||
|
title: t("createNetwork"),
|
||||||
|
hotkey: "cmd+shift+n",
|
||||||
|
handler: () => {
|
||||||
|
createNetwork();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "LogOut",
|
||||||
|
title: t("logOut"),
|
||||||
|
hotkey: "cmd+shift+g",
|
||||||
|
handler: () => {
|
||||||
|
onLogOutClick();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
const [loggedIn, setLoggedIn] = useLocalStorage("loggedIn", false);
|
const [loggedIn, setLoggedIn] = useLocalStorage("loggedIn", false);
|
||||||
const [disabledAuth] = useLocalStorage("disableAuth", false);
|
const [disabledAuth] = useLocalStorage("disableAuth", false);
|
||||||
const [anchorEl, setAnchorEl] = useState(null);
|
const [anchorEl, setAnchorEl] = useState(null);
|
||||||
|
|
||||||
const history = useHistory();
|
const createNetwork = async () => {
|
||||||
|
const network = await API.post("network", generateNetworkConfig());
|
||||||
|
console.log(network);
|
||||||
|
history.push("/network/" + network.data["config"]["id"]);
|
||||||
|
};
|
||||||
|
|
||||||
const openMenu = (event) => {
|
const openMenu = (event) => {
|
||||||
setAnchorEl(event.currentTarget);
|
setAnchorEl(event.currentTarget);
|
||||||
|
@ -41,6 +81,12 @@ function Bar() {
|
||||||
history.go(0);
|
history.go(0);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (ninjaKeys.current) {
|
||||||
|
ninjaKeys.current.data = hotkeys;
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
const menuItems = [
|
const menuItems = [
|
||||||
// TODO: add settings page
|
// TODO: add settings page
|
||||||
// {
|
// {
|
||||||
|
@ -64,6 +110,11 @@ function Bar() {
|
||||||
style={{ background: "#000000" }}
|
style={{ background: "#000000" }}
|
||||||
position="static"
|
position="static"
|
||||||
>
|
>
|
||||||
|
{loggedIn && (
|
||||||
|
<>
|
||||||
|
<ninja-keys ref={ninjaKeys}></ninja-keys>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
<Toolbar>
|
<Toolbar>
|
||||||
<Box display="flex" flexGrow={1}>
|
<Box display="flex" flexGrow={1}>
|
||||||
<Typography color="inherit" variant="h6">
|
<Typography color="inherit" variant="h6">
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
export { default } from "./Bar";
|
export { default } from "./Bar.jsx";
|
||||||
|
|
|
@ -2,12 +2,12 @@ import { useState, useEffect } from "react";
|
||||||
import { useHistory } from "react-router-dom";
|
import { useHistory } from "react-router-dom";
|
||||||
|
|
||||||
import { Divider, Button, Grid, Typography, Box } from "@material-ui/core";
|
import { Divider, Button, Grid, Typography, Box } from "@material-ui/core";
|
||||||
import useStyles from "./HomeLoggedIn.styles";
|
import useStyles from "./HomeLoggedIn.styles.jsx";
|
||||||
|
|
||||||
import NetworkButton from "./components/NetworkButton";
|
import NetworkButton from "./components/NetworkButton/NetworkButton.jsx";
|
||||||
|
|
||||||
import API from "utils/API";
|
import API from "utils/API.js";
|
||||||
import { generateNetworkConfig } from "utils/NetworkConfig";
|
import { generateNetworkConfig } from "utils/NetworkConfig.js";
|
||||||
|
|
||||||
function HomeLoggedIn() {
|
function HomeLoggedIn() {
|
||||||
const [networks, setNetworks] = useState([]);
|
const [networks, setNetworks] = useState([]);
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
export { default } from "./HomeLoggedIn";
|
export { default } from "./HomeLoggedIn.jsx";
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
export { default } from "./HomeLoggedOut";
|
export { default } from "./HomeLoggedOut.jsx";
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { Divider } from "@material-ui/core";
|
import { Divider } from "@material-ui/core";
|
||||||
|
|
||||||
import LogInUser from "./components/LogInUser";
|
import LogInUser from "./components/LogInUser/LogInUser.jsx";
|
||||||
import LogInToken from "./components/LogInToken";
|
import LogInToken from "./components/LogInToken/LogInToken.jsx";
|
||||||
|
|
||||||
function LogIn() {
|
function LogIn() {
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
export { default } from "./LogInToken";
|
export { default } from "./LogInToken.jsx";
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
export { default } from "./LogInUser";
|
export { default } from "./LogInUser.jsx";
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
export { default } from "./LogIn";
|
export { default } from "./LogIn.jsx";
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
export { default } from "./NetworkHeader";
|
export { default } from "./NetworkHeader.jsx";
|
||||||
|
|
|
@ -13,10 +13,10 @@ import {
|
||||||
DialogActions,
|
DialogActions,
|
||||||
Typography,
|
Typography,
|
||||||
} from "@material-ui/core";
|
} from "@material-ui/core";
|
||||||
import ExpandMoreIcon from "@material-ui/icons/ExpandMore";
|
import ExpandMoreIcon from "@material-ui/icons/ExpandMore.js";
|
||||||
import DeleteIcon from "@material-ui/icons/Delete";
|
import DeleteIcon from "@material-ui/icons/Delete.js";
|
||||||
|
|
||||||
import API from "utils/API";
|
import API from "utils/API.js";
|
||||||
|
|
||||||
function NetworkManagement() {
|
function NetworkManagement() {
|
||||||
const { nwid } = useParams();
|
const { nwid } = useParams();
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
export { default } from "./NetworkManagement";
|
export { default } from "./NetworkManagement.jsx";
|
||||||
|
|
|
@ -7,19 +7,19 @@ import {
|
||||||
IconButton,
|
IconButton,
|
||||||
Typography,
|
Typography,
|
||||||
} from "@material-ui/core";
|
} from "@material-ui/core";
|
||||||
import ExpandMoreIcon from "@material-ui/icons/ExpandMore";
|
import ExpandMoreIcon from "@material-ui/icons/ExpandMore.js";
|
||||||
import RefreshIcon from "@material-ui/icons/Refresh";
|
import RefreshIcon from "@material-ui/icons/Refresh.js";
|
||||||
import { useCallback, useEffect, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
import DataTable from "react-data-table-component";
|
import DataTable from "react-data-table-component";
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
import API from "utils/API";
|
import API from "utils/API.js";
|
||||||
import { parseValue, replaceValue, setValue } from "utils/ChangeHelper";
|
import { parseValue, replaceValue, setValue } from "utils/ChangeHelper.js";
|
||||||
import { formatDistance } from "date-fns";
|
import { formatDistance } from "date-fns";
|
||||||
import AddMember from "./components/AddMember";
|
import AddMember from "./components/AddMember/AddMember.jsx";
|
||||||
import DeleteMember from "./components/DeleteMember";
|
import DeleteMember from "./components/DeleteMember/DeleteMember.jsx";
|
||||||
import ManagedIP from "./components/ManagedIP";
|
import ManagedIP from "./components/ManagedIP/ManagedIP.jsx";
|
||||||
import MemberName from "./components/MemberName";
|
import MemberName from "./components/MemberName/MemberName.jsx";
|
||||||
import MemberSettings from "./components/MemberSettings";
|
import MemberSettings from "./components/MemberSettings/MemberSettings.jsx";
|
||||||
|
|
||||||
function NetworkMembers({ network }) {
|
function NetworkMembers({ network }) {
|
||||||
const { nwid } = useParams();
|
const { nwid } = useParams();
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
|
||||||
import { List, Typography, IconButton, TextField } from "@material-ui/core";
|
import { List, Typography, IconButton, TextField } from "@material-ui/core";
|
||||||
import AddIcon from "@material-ui/icons/Add";
|
import AddIcon from "@material-ui/icons/Add.js";
|
||||||
|
|
||||||
import API from "utils/API";
|
import API from "utils/API.js";
|
||||||
|
|
||||||
function AddMember({ nwid, callback }) {
|
function AddMember({ nwid, callback }) {
|
||||||
const [member, setMember] = useState("");
|
const [member, setMember] = useState("");
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
export { default } from "./AddMember";
|
export { default } from "./AddMember.jsx";
|
||||||
|
|
|
@ -9,9 +9,10 @@ import {
|
||||||
DialogActions,
|
DialogActions,
|
||||||
IconButton,
|
IconButton,
|
||||||
} from "@material-ui/core";
|
} from "@material-ui/core";
|
||||||
import DeleteOutlineIcon from "@material-ui/icons/DeleteOutline";
|
import DeleteOutlineIcon from "@material-ui/icons/DeleteOutline.js";
|
||||||
|
|
||||||
import API from "utils/API";
|
import API from "utils/API.js";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
function DeleteMember({ nwid, mid, callback }) {
|
function DeleteMember({ nwid, mid, callback }) {
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
export { default } from "./DeleteMember";
|
export { default } from "./DeleteMember.jsx";
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
|
||||||
import { Grid, List, TextField, IconButton } from "@material-ui/core";
|
import { Grid, List, TextField, IconButton } from "@material-ui/core";
|
||||||
import AddIcon from "@material-ui/icons/Add";
|
import AddIcon from "@material-ui/icons/Add.js";
|
||||||
import DeleteOutlineIcon from "@material-ui/icons/DeleteOutline";
|
import DeleteOutlineIcon from "@material-ui/icons/DeleteOutline.js";
|
||||||
|
|
||||||
import { validateIP, normilizeIP } from "utils/IP";
|
import { validateIP, normilizeIP } from "utils/IP.js";
|
||||||
|
|
||||||
function ManagedIP({ member, handleChange }) {
|
function ManagedIP({ member, handleChange }) {
|
||||||
const [ipInput, setIpInput] = useState();
|
const [ipInput, setIpInput] = useState();
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
export { default } from "./ManagedIP";
|
export { default } from "./ManagedIP.jsx";
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
export { default } from "./MemberName";
|
export { default } from "./MemberName.jsx";
|
||||||
|
|
|
@ -9,9 +9,9 @@ import {
|
||||||
Paper,
|
Paper,
|
||||||
Typography,
|
Typography,
|
||||||
} from "@material-ui/core";
|
} from "@material-ui/core";
|
||||||
import BuildIcon from "@material-ui/icons/Build";
|
import BuildIcon from "@material-ui/icons/Build.js";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import Tag from "./components/Tag";
|
import Tag from "./components/Tag/Tag.jsx";
|
||||||
|
|
||||||
function MemberSettings({ member, network, handleChange }) {
|
function MemberSettings({ member, network, handleChange }) {
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
|
|
|
@ -8,7 +8,7 @@ import {
|
||||||
Select,
|
Select,
|
||||||
Typography,
|
Typography,
|
||||||
} from "@material-ui/core";
|
} from "@material-ui/core";
|
||||||
import DeleteIcon from "@material-ui/icons/Delete";
|
import DeleteIcon from "@material-ui/icons/Delete.js";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { useDebounce } from "react-use";
|
import { useDebounce } from "react-use";
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
export { default } from "./Tag";
|
export { default } from "./Tag.jsx";
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
export { default } from "./MemberSettings";
|
export { default } from "./MemberSettings.jsx";
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
export { default } from "./NetworkMembers";
|
export { default } from "./NetworkMembers.jsx";
|
||||||
|
|
|
@ -9,13 +9,13 @@ import {
|
||||||
Snackbar,
|
Snackbar,
|
||||||
Typography,
|
Typography,
|
||||||
} from "@material-ui/core";
|
} from "@material-ui/core";
|
||||||
import ExpandMoreIcon from "@material-ui/icons/ExpandMore";
|
import ExpandMoreIcon from "@material-ui/icons/ExpandMore.js";
|
||||||
import CodeMirror from "@uiw/react-codemirror";
|
import CodeMirror from "@uiw/react-codemirror";
|
||||||
import "codemirror/theme/3024-day.css";
|
import "codemirror/theme/3024-day.css";
|
||||||
import { compile } from "external/RuleCompiler";
|
import { compile } from "external/RuleCompiler.js";
|
||||||
import debounce from "lodash/debounce";
|
import debounce from "lodash/debounce.js";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import API from "utils/API";
|
import API from "utils/API.js";
|
||||||
|
|
||||||
function NetworkRules({ network, callback }) {
|
function NetworkRules({ network, callback }) {
|
||||||
const [editor, setEditor] = useState(null);
|
const [editor, setEditor] = useState(null);
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
export { default } from "./NetworkRules";
|
export { default } from "./NetworkRules.jsx";
|
||||||
|
|
|
@ -9,13 +9,13 @@ import {
|
||||||
TextField,
|
TextField,
|
||||||
Select,
|
Select,
|
||||||
} from "@material-ui/core";
|
} from "@material-ui/core";
|
||||||
import ExpandMoreIcon from "@material-ui/icons/ExpandMore";
|
import ExpandMoreIcon from "@material-ui/icons/ExpandMore.js";
|
||||||
|
|
||||||
import ManagedRoutes from "./components/ManagedRoutes";
|
import ManagedRoutes from "./components/ManagedRoutes/ManagedRoutes.jsx";
|
||||||
import IPv4AutoAssign from "./components/IPv4AutoAssign";
|
import IPv4AutoAssign from "./components/IPv4AutoAssign/IPv4AutoAssign.jsx";
|
||||||
|
|
||||||
import API from "utils/API";
|
import API from "utils/API.js";
|
||||||
import { parseValue, replaceValue, setValue } from "utils/ChangeHelper";
|
import { parseValue, replaceValue, setValue } from "utils/ChangeHelper.js";
|
||||||
|
|
||||||
function NetworkSettings({ network, setNetwork }) {
|
function NetworkSettings({ network, setNetwork }) {
|
||||||
const sendReq = async (data) => {
|
const sendReq = async (data) => {
|
||||||
|
|
|
@ -10,13 +10,13 @@ import {
|
||||||
TextField,
|
TextField,
|
||||||
IconButton,
|
IconButton,
|
||||||
} from "@material-ui/core";
|
} from "@material-ui/core";
|
||||||
import AddIcon from "@material-ui/icons/Add";
|
import AddIcon from "@material-ui/icons/Add.js";
|
||||||
import DeleteOutlineIcon from "@material-ui/icons/DeleteOutline";
|
import DeleteOutlineIcon from "@material-ui/icons/DeleteOutline.js";
|
||||||
|
|
||||||
import DataTable from "react-data-table-component";
|
import DataTable from "react-data-table-component";
|
||||||
|
|
||||||
import { addressPool } from "utils/NetworkConfig";
|
import { addressPool } from "utils/NetworkConfig.js";
|
||||||
import { getCIDRAddress, validateIP, normilizeIP } from "utils/IP";
|
import { getCIDRAddress, validateIP, normilizeIP } from "utils/IP.js";
|
||||||
|
|
||||||
function IPv4AutoAssign({ ipAssignmentPools, handleChange }) {
|
function IPv4AutoAssign({ ipAssignmentPools, handleChange }) {
|
||||||
const [start, setStart] = useState("");
|
const [start, setStart] = useState("");
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
export { default } from "./IPv4AutoAssign";
|
export { default } from "./IPv4AutoAssign.jsx";
|
||||||
|
|
|
@ -9,12 +9,12 @@ import {
|
||||||
TextField,
|
TextField,
|
||||||
IconButton,
|
IconButton,
|
||||||
} from "@material-ui/core";
|
} from "@material-ui/core";
|
||||||
import AddIcon from "@material-ui/icons/Add";
|
import AddIcon from "@material-ui/icons/Add.js";
|
||||||
import DeleteOutlineIcon from "@material-ui/icons/DeleteOutline";
|
import DeleteOutlineIcon from "@material-ui/icons/DeleteOutline.js";
|
||||||
|
|
||||||
import DataTable from "react-data-table-component";
|
import DataTable from "react-data-table-component";
|
||||||
|
|
||||||
import { validateIP, normilizeIP, validateCIDR } from "utils/IP";
|
import { validateIP, normilizeIP, validateCIDR } from "utils/IP.js";
|
||||||
|
|
||||||
function ManagedRoutes({ routes, handleChange }) {
|
function ManagedRoutes({ routes, handleChange }) {
|
||||||
const [destination, setDestination] = useState("");
|
const [destination, setDestination] = useState("");
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
export { default } from "./ManagedRoutes";
|
export { default } from "./ManagedRoutes.jsx";
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
export { default } from "./NetworkSettings";
|
export { default } from "./NetworkSettings.jsx";
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
import {
|
||||||
|
Accordion,
|
||||||
|
AccordionSummary,
|
||||||
|
AccordionDetails,
|
||||||
|
Checkbox,
|
||||||
|
Divider,
|
||||||
|
Grid,
|
||||||
|
Typography,
|
||||||
|
TextField,
|
||||||
|
Select,
|
||||||
|
} from "@material-ui/core";
|
||||||
|
import ExpandMoreIcon from "@material-ui/icons/ExpandMore.js";
|
||||||
|
|
||||||
|
import API from "utils/API.js";
|
||||||
|
import { parseValue, replaceValue, setValue } from "utils/ChangeHelper.js";
|
||||||
|
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
|
function SettingsComponent() {
|
||||||
|
const { t, i18n } = useTranslation();
|
||||||
|
|
||||||
|
const handleChange = () => (event) => {
|
||||||
|
i18n.changeLanguage(event.target.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Accordion>
|
||||||
|
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
|
||||||
|
<Typography>{t("language")}</Typography>
|
||||||
|
</AccordionSummary>
|
||||||
|
<AccordionDetails>
|
||||||
|
<Grid item>
|
||||||
|
<Select native value={i18n.language} onChange={handleChange()}>
|
||||||
|
<option value={"en"}>English</option>
|
||||||
|
<option value={"es-ES"}>Español</option>
|
||||||
|
</Select>
|
||||||
|
</Grid>
|
||||||
|
</AccordionDetails>
|
||||||
|
</Accordion>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SettingsComponent;
|
1
frontend/src/components/SettingsComponent/index.jsx
Normal file
1
frontend/src/components/SettingsComponent/index.jsx
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export { default } from "./SettingsComponent.jsx";
|
|
@ -1 +1 @@
|
||||||
export { default } from "./Theme";
|
export { default } from "./Theme.jsx";
|
||||||
|
|
34
frontend/src/i18n.js
Normal file
34
frontend/src/i18n.js
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
import i18n from "i18next";
|
||||||
|
import languageDetector from "i18next-browser-languagedetector";
|
||||||
|
import { initReactI18next } from "react-i18next";
|
||||||
|
import Backend from "i18next-http-backend";
|
||||||
|
|
||||||
|
i18n
|
||||||
|
.use(languageDetector)
|
||||||
|
.use(initReactI18next)
|
||||||
|
.use(Backend)
|
||||||
|
.init({
|
||||||
|
compatibilityJSON: "v4",
|
||||||
|
//lng: "en",
|
||||||
|
fallbackLng: "en",
|
||||||
|
detection: {
|
||||||
|
order: ["path", "cookie", "localStorage", "htmlTag"],
|
||||||
|
caches: ["localStorage", "cookie"], // cache user language on
|
||||||
|
},
|
||||||
|
debug: true,
|
||||||
|
//keySeparator: false, // we use content as keys
|
||||||
|
interpolation: {
|
||||||
|
escapeValue: true,
|
||||||
|
},
|
||||||
|
react: {
|
||||||
|
useSuspense: true,
|
||||||
|
},
|
||||||
|
supportedLngs: ["en", "es-ES"],
|
||||||
|
backend: {
|
||||||
|
loadPath: "/locales/{{lng}}/{{ns}}.json",
|
||||||
|
},
|
||||||
|
ns: ["common"],
|
||||||
|
defaultNS: "common",
|
||||||
|
});
|
||||||
|
|
||||||
|
export default i18n;
|
|
@ -3,7 +3,7 @@ import "./index.css";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import ReactDOM from "react-dom";
|
import ReactDOM from "react-dom";
|
||||||
|
|
||||||
import App from "./App";
|
import App from "./App.jsx";
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { useLocalStorage } from "react-use";
|
import { useLocalStorage } from "react-use";
|
||||||
|
|
||||||
import HomeLoggedIn from "components/HomeLoggedIn";
|
import HomeLoggedIn from "components/HomeLoggedIn/HomeLoggedIn.jsx";
|
||||||
import HomeLoggedOut from "components/HomeLoggedOut";
|
import HomeLoggedOut from "components/HomeLoggedOut/HomeLoggedOut.jsx";
|
||||||
|
|
||||||
function Home() {
|
function Home() {
|
||||||
const [loggedIn] = useLocalStorage("loggedIn", false);
|
const [loggedIn] = useLocalStorage("loggedIn", false);
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
export { default } from "./Home";
|
export { default } from "./Home.jsx";
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
import { Grid, Link, Typography } from "@material-ui/core";
|
import { Grid, Link, Typography } from "@material-ui/core";
|
||||||
import ArrowBackIcon from "@material-ui/icons/ArrowBack";
|
import ArrowBackIcon from "@material-ui/icons/ArrowBack.js";
|
||||||
import NetworkHeader from "components/NetworkHeader";
|
import NetworkHeader from "components/NetworkHeader/NetworkHeader.jsx";
|
||||||
import NetworkManagement from "components/NetworkManagement";
|
import NetworkManagement from "components/NetworkManagement/NetworkManagement.jsx";
|
||||||
import NetworkMembers from "components/NetworkMembers";
|
import NetworkMembers from "components/NetworkMembers/NetworkMembers.jsx";
|
||||||
import NetworkRules from "components/NetworkRules";
|
import NetworkRules from "components/NetworkRules/NetworkRules.jsx";
|
||||||
import NetworkSettings from "components/NetworkSettings";
|
import NetworkSettings from "components/NetworkSettings/NetworkSettings.jsx";
|
||||||
import { useCallback, useEffect, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
import { Link as RouterLink, useHistory, useParams } from "react-router-dom";
|
import { Link as RouterLink, useHistory, useParams } from "react-router-dom";
|
||||||
import { useLocalStorage } from "react-use";
|
import { useLocalStorage } from "react-use";
|
||||||
import API from "utils/API";
|
import API from "utils/API.js";
|
||||||
import useStyles from "./Network.styles";
|
import useStyles from "./Network.styles.jsx";
|
||||||
|
|
||||||
function Network() {
|
function Network() {
|
||||||
const { nwid } = useParams();
|
const { nwid } = useParams();
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
export { default } from "./Network";
|
export { default } from "./Network.jsx";
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
export { default } from "./NotFound";
|
export { default } from "./NotFound.jsx";
|
||||||
|
|
57
frontend/src/routes/Settings/Settings.jsx
Normal file
57
frontend/src/routes/Settings/Settings.jsx
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
import { Grid, Link, Typography } from "@material-ui/core";
|
||||||
|
import ArrowBackIcon from "@material-ui/icons/ArrowBack.js";
|
||||||
|
import SettingsComponent from "components/SettingsComponent/SettingsComponent.jsx";
|
||||||
|
|
||||||
|
import { useCallback, useEffect, useState } from "react";
|
||||||
|
import { Link as RouterLink, useHistory, useParams } from "react-router-dom";
|
||||||
|
import { useLocalStorage } from "react-use";
|
||||||
|
import API from "utils/API";
|
||||||
|
import useStyles from "./Settings.styles.jsx";
|
||||||
|
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
|
function Settings() {
|
||||||
|
const { t, i18n } = useTranslation();
|
||||||
|
const [loggedIn] = useLocalStorage("loggedIn", false);
|
||||||
|
const [network, setNetwork] = useState({});
|
||||||
|
|
||||||
|
const classes = useStyles();
|
||||||
|
const history = useHistory();
|
||||||
|
|
||||||
|
if (loggedIn) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className={classes.breadcrumbs}>
|
||||||
|
<Link color="inherit" component={RouterLink} to="/" underline="none">
|
||||||
|
<ArrowBackIcon className={classes.backIcon}></ArrowBackIcon>
|
||||||
|
{t("settings")}
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
<div className={classes.container}>
|
||||||
|
<SettingsComponent />
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<Grid
|
||||||
|
container
|
||||||
|
spacing={0}
|
||||||
|
direction="column"
|
||||||
|
alignItems="center"
|
||||||
|
justify="center"
|
||||||
|
style={{
|
||||||
|
minHeight: "50vh",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Grid item xs={10}>
|
||||||
|
<Typography variant="h5">
|
||||||
|
You are not authorized. Please Log In
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Settings;
|
1
frontend/src/routes/Settings/index.jsx
Normal file
1
frontend/src/routes/Settings/index.jsx
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export { default } from "./Settings.jsx";
|
119
yarn.lock
119
yarn.lock
|
@ -860,6 +860,22 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@lit-labs/ssr-dom-shim@npm:^1.0.0, @lit-labs/ssr-dom-shim@npm:^1.1.0":
|
||||||
|
version: 1.1.2
|
||||||
|
resolution: "@lit-labs/ssr-dom-shim@npm:1.1.2"
|
||||||
|
checksum: a930f7de57b952dc21317a5754aa0411e000bb4991053cde771c111b7792c4a4cdc896922f0353c832215bed71400431c5ab5a6252c8f4f70bb9ce0b37fe4752
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@lit/reactive-element@npm:^1.3.0, @lit/reactive-element@npm:^1.6.0":
|
||||||
|
version: 1.6.3
|
||||||
|
resolution: "@lit/reactive-element@npm:1.6.3"
|
||||||
|
dependencies:
|
||||||
|
"@lit-labs/ssr-dom-shim": "npm:^1.0.0"
|
||||||
|
checksum: 664c899bb0b144590dc4faf83b358b1504810eac107778c3aeb384affc65a7ef4eda754944bcc34a57237db03dff145332406345ac24da19ca37cf4b3cb343d3
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@material-ui/core@npm:^4.12.4":
|
"@material-ui/core@npm:^4.12.4":
|
||||||
version: 4.12.4
|
version: 4.12.4
|
||||||
resolution: "@material-ui/core@npm:4.12.4"
|
resolution: "@material-ui/core@npm:4.12.4"
|
||||||
|
@ -980,6 +996,16 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@material/mwc-icon@npm:0.25.3":
|
||||||
|
version: 0.25.3
|
||||||
|
resolution: "@material/mwc-icon@npm:0.25.3"
|
||||||
|
dependencies:
|
||||||
|
lit: "npm:^2.0.0"
|
||||||
|
tslib: "npm:^2.0.1"
|
||||||
|
checksum: ee4eb4c746795666b576395046238f72714e7f3985e33a2edec8e11d3f9a2e11087edae70c6ba5b1804ff5348fe85a19a752281af97dff3c9ebad1b20f5969ea
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@nodelib/fs.scandir@npm:2.1.5":
|
"@nodelib/fs.scandir@npm:2.1.5":
|
||||||
version: 2.1.5
|
version: 2.1.5
|
||||||
resolution: "@nodelib/fs.scandir@npm:2.1.5"
|
resolution: "@nodelib/fs.scandir@npm:2.1.5"
|
||||||
|
@ -1432,6 +1458,13 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@types/trusted-types@npm:^2.0.2":
|
||||||
|
version: 2.0.4
|
||||||
|
resolution: "@types/trusted-types@npm:2.0.4"
|
||||||
|
checksum: 5256c4576cd1c90d33ddd9cc9cbd4f202b39c98cbe8b7f74963298f9eb2159c285ea5c25a6181b4c594d8d75641765bff85d72c2d251ad076e6529ce0eeedd1c
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@typescript-eslint/eslint-plugin@npm:^6.7.4":
|
"@typescript-eslint/eslint-plugin@npm:^6.7.4":
|
||||||
version: 6.7.4
|
version: 6.7.4
|
||||||
resolution: "@typescript-eslint/eslint-plugin@npm:6.7.4"
|
resolution: "@typescript-eslint/eslint-plugin@npm:6.7.4"
|
||||||
|
@ -4346,6 +4379,7 @@ __metadata:
|
||||||
history: "npm:^5.3.0"
|
history: "npm:^5.3.0"
|
||||||
ipaddr.js: "npm:^2.0.1"
|
ipaddr.js: "npm:^2.0.1"
|
||||||
lodash: "npm:^4.17.21"
|
lodash: "npm:^4.17.21"
|
||||||
|
ninja-keys: "npm:^1.2.2"
|
||||||
react: "npm:^17.0.2"
|
react: "npm:^17.0.2"
|
||||||
react-data-table-component: "npm:^6.11.8"
|
react-data-table-component: "npm:^6.11.8"
|
||||||
react-dom: "npm:^17.0.2"
|
react-dom: "npm:^17.0.2"
|
||||||
|
@ -4888,6 +4922,22 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"hotkeys-js@npm:3.8.7":
|
||||||
|
version: 3.8.7
|
||||||
|
resolution: "hotkeys-js@npm:3.8.7"
|
||||||
|
checksum: a70b797ae26ea89e9f0bef49711a48622422b641362ee0c2ac4a1f70794e85066623fefdf200866fce1f75fc520e530e35ebd0334f61cbf500da882a6b795faf
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"html-parse-stringify@npm:^3.0.1":
|
||||||
|
version: 3.0.1
|
||||||
|
resolution: "html-parse-stringify@npm:3.0.1"
|
||||||
|
dependencies:
|
||||||
|
void-elements: "npm:3.1.0"
|
||||||
|
checksum: 8743b76cc50e46d1956c1ad879d18eb9613b0d2d81e24686d633f9f69bb26b84676f64a926973de793cca479997017a63219278476d617b6c42d68246d7c07fe
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"http-cache-semantics@npm:^4.1.1":
|
"http-cache-semantics@npm:^4.1.1":
|
||||||
version: 4.1.1
|
version: 4.1.1
|
||||||
resolution: "http-cache-semantics@npm:4.1.1"
|
resolution: "http-cache-semantics@npm:4.1.1"
|
||||||
|
@ -5870,6 +5920,48 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"lit-element@npm:^3.2.0, lit-element@npm:^3.3.0":
|
||||||
|
version: 3.3.3
|
||||||
|
resolution: "lit-element@npm:3.3.3"
|
||||||
|
dependencies:
|
||||||
|
"@lit-labs/ssr-dom-shim": "npm:^1.1.0"
|
||||||
|
"@lit/reactive-element": "npm:^1.3.0"
|
||||||
|
lit-html: "npm:^2.8.0"
|
||||||
|
checksum: 7968e7f3ce3994911f27c4c54acc956488c91d8af81677cce3d6f0c2eaea45cceb79b064077159392238d6e43d46015a950269db9914fea8913566aacb17eaa1
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"lit-html@npm:^2.2.0, lit-html@npm:^2.8.0":
|
||||||
|
version: 2.8.0
|
||||||
|
resolution: "lit-html@npm:2.8.0"
|
||||||
|
dependencies:
|
||||||
|
"@types/trusted-types": "npm:^2.0.2"
|
||||||
|
checksum: 3503e55e2927c2ff94773cf041fc4128f92291869c9192f36eacb7f95132d11f6b329e5b910ab60a4456349cd2e6d23b33d83291b24d557bcd6b904d6314ac1a
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"lit@npm:2.2.6":
|
||||||
|
version: 2.2.6
|
||||||
|
resolution: "lit@npm:2.2.6"
|
||||||
|
dependencies:
|
||||||
|
"@lit/reactive-element": "npm:^1.3.0"
|
||||||
|
lit-element: "npm:^3.2.0"
|
||||||
|
lit-html: "npm:^2.2.0"
|
||||||
|
checksum: 160363c6d271559f629404301f4df324f97f0d7f48c69c784f277fdeabc5f975ab98cb792198136c87175f185b28699ff25c105dc91f08eb4e96e46143a6c162
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"lit@npm:^2.0.0":
|
||||||
|
version: 2.8.0
|
||||||
|
resolution: "lit@npm:2.8.0"
|
||||||
|
dependencies:
|
||||||
|
"@lit/reactive-element": "npm:^1.6.0"
|
||||||
|
lit-element: "npm:^3.3.0"
|
||||||
|
lit-html: "npm:^2.8.0"
|
||||||
|
checksum: aa64c1136b855ba328d41157dba67657d480345aeec3c1dd829abeb67719d759c9ff2ade9903f9cfb4f9d012b16087034aaa5b33f1182e70c615765562e3251b
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"load-json-file@npm:^4.0.0":
|
"load-json-file@npm:^4.0.0":
|
||||||
version: 4.0.0
|
version: 4.0.0
|
||||||
resolution: "load-json-file@npm:4.0.0"
|
resolution: "load-json-file@npm:4.0.0"
|
||||||
|
@ -6532,6 +6624,31 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"ninja-keys@npm:^1.2.2":
|
||||||
|
version: 1.2.2
|
||||||
|
resolution: "ninja-keys@npm:1.2.2"
|
||||||
|
dependencies:
|
||||||
|
"@material/mwc-icon": "npm:0.25.3"
|
||||||
|
hotkeys-js: "npm:3.8.7"
|
||||||
|
lit: "npm:2.2.6"
|
||||||
|
checksum: 5f573fd547c54f926d13f30877f8e54245ec22097f0a539f9b89532aa4c21582572f7df4dc1db407f128fb44867fc9ef23e8c9065a36c5870652057b7149db73
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"node-fetch@npm:^2.6.11":
|
||||||
|
version: 2.7.0
|
||||||
|
resolution: "node-fetch@npm:2.7.0"
|
||||||
|
dependencies:
|
||||||
|
whatwg-url: "npm:^5.0.0"
|
||||||
|
peerDependencies:
|
||||||
|
encoding: ^0.1.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
encoding:
|
||||||
|
optional: true
|
||||||
|
checksum: b24f8a3dc937f388192e59bcf9d0857d7b6940a2496f328381641cb616efccc9866e89ec43f2ec956bbd6c3d3ee05524ce77fe7b29ccd34692b3a16f237d6676
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"node-gyp@npm:latest":
|
"node-gyp@npm:latest":
|
||||||
version: 9.4.0
|
version: 9.4.0
|
||||||
resolution: "node-gyp@npm:9.4.0"
|
resolution: "node-gyp@npm:9.4.0"
|
||||||
|
@ -8736,7 +8853,7 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"tslib@npm:^2.1.0":
|
"tslib@npm:^2.0.1, tslib@npm:^2.1.0":
|
||||||
version: 2.6.2
|
version: 2.6.2
|
||||||
resolution: "tslib@npm:2.6.2"
|
resolution: "tslib@npm:2.6.2"
|
||||||
checksum: bd26c22d36736513980091a1e356378e8b662ded04204453d353a7f34a4c21ed0afc59b5f90719d4ba756e581a162ecbf93118dc9c6be5acf70aa309188166ca
|
checksum: bd26c22d36736513980091a1e356378e8b662ded04204453d353a7f34a4c21ed0afc59b5f90719d4ba756e581a162ecbf93118dc9c6be5acf70aa309188166ca
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue