mirror of
https://github.com/openziti/zrok.git
synced 2025-01-23 06:19:04 +01:00
parent
ceb96b3e4f
commit
40783cdcda
@ -2,10 +2,17 @@ import {useEffect, useState} from "react";
|
||||
import {Configuration, MetadataApi} from "./api";
|
||||
import buildVisualizerGraph from "./model/visualizer.ts";
|
||||
import {GraphCanvas} from "reagraph";
|
||||
import {Box} from "@mui/material";
|
||||
import {Box, Button} from "@mui/material";
|
||||
import NavBar from "./NavBar.tsx";
|
||||
import {reagraphTheme} from "./model/theme.ts";
|
||||
import {User} from "./model/user.ts";
|
||||
|
||||
const ApiConsole = () => {
|
||||
interface ApiConsoleProps {
|
||||
user: User;
|
||||
logout: () => void;
|
||||
}
|
||||
|
||||
const ApiConsole = ({ user, logout }: ApiConsoleProps) => {
|
||||
const [version, setVersion] = useState("no version set");
|
||||
const [nodes, setNodes] = useState([]);
|
||||
const [edges, setEdges] = useState([]);
|
||||
@ -26,7 +33,7 @@ const ApiConsole = () => {
|
||||
let cfg = new Configuration({
|
||||
headers: {
|
||||
// ignorable token, local development environment
|
||||
"X-TOKEN": "8TPUmoBHMdA8"
|
||||
"X-TOKEN": user.token
|
||||
}
|
||||
});
|
||||
let api = new MetadataApi(cfg);
|
||||
@ -52,8 +59,9 @@ const ApiConsole = () => {
|
||||
<NavBar version={version} />
|
||||
<Box>
|
||||
<div style={{position: "relative", width: "100%", height: "500px"}}>
|
||||
<GraphCanvas nodes={nodes} edges={edges}/>
|
||||
<GraphCanvas nodes={nodes} edges={edges} theme={reagraphTheme} labelFontUrl={"https://fonts.googleapis.com/css?family=Poppins"}/>
|
||||
</div>
|
||||
<Button onClick={logout}>Log Out</Button>
|
||||
</Box>
|
||||
</div>
|
||||
);
|
||||
|
42
ui100/src/App.tsx
Normal file
42
ui100/src/App.tsx
Normal file
@ -0,0 +1,42 @@
|
||||
import {BrowserRouter, Route, Routes} from "react-router";
|
||||
import ApiConsole from "./ApiConsole.tsx";
|
||||
import Login from "./Login.tsx";
|
||||
import {useEffect, useState} from "react";
|
||||
import {User} from "./model/user.ts";
|
||||
|
||||
const App = () => {
|
||||
const [user, setUser] = useState(null as User);
|
||||
|
||||
useEffect(() => {
|
||||
const checkUser = () => {
|
||||
const user = localStorage.getItem("user");
|
||||
if(user) {
|
||||
console.log(user);
|
||||
setUser(JSON.parse(user));
|
||||
console.log("reloaded user", user);
|
||||
}
|
||||
}
|
||||
checkUser();
|
||||
}, []);
|
||||
|
||||
const login = (user: User) => {
|
||||
setUser(user);
|
||||
}
|
||||
|
||||
const logout = () => {
|
||||
setUser(null);
|
||||
localStorage.clear();
|
||||
}
|
||||
|
||||
const consoleRoot = user ? <ApiConsole user={user} logout={logout} /> : <Login onLogin={login} />
|
||||
|
||||
return (
|
||||
<BrowserRouter>
|
||||
<Routes>
|
||||
<Route index element={consoleRoot} />
|
||||
</Routes>
|
||||
</BrowserRouter>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
@ -1,12 +1,37 @@
|
||||
import {Box, Button, Container, TextField, Typography} from "@mui/material";
|
||||
import {User} from "./model/user.ts";
|
||||
import {useState} from "react";
|
||||
import {AccountApi} from "./api";
|
||||
|
||||
interface LoginProps {
|
||||
onLogin: (user: User) => void;
|
||||
}
|
||||
|
||||
const Login = ({ onLogin }: LoginProps) => {
|
||||
const [email, setEmail] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
const [message, setMessage] = useState("");
|
||||
|
||||
const login = async e => {
|
||||
e.preventDefault();
|
||||
console.log(email, password);
|
||||
|
||||
let api = new AccountApi();
|
||||
api.login({body: {"email": email, "password": password}})
|
||||
.then(d => {
|
||||
onLogin({email: email, token: d.toString()});
|
||||
})
|
||||
.catch(e => {
|
||||
setMessage("login failed: " + e.toString());
|
||||
});
|
||||
}
|
||||
|
||||
const Login = () => {
|
||||
return (
|
||||
<Typography>
|
||||
<Container maxWidth="xs">
|
||||
<Box sx={{ marginTop: 8, display: "flex", flexDirection: "column", alignItems: "center"}}>
|
||||
<h2>welcome to zrok...</h2>
|
||||
<Box component="form" noValidate>
|
||||
<Box component="form" noValidate onSubmit={login}>
|
||||
<TextField
|
||||
margin="normal"
|
||||
required
|
||||
@ -16,6 +41,8 @@ const Login = () => {
|
||||
name="email"
|
||||
autoComplete="email"
|
||||
autoFocus
|
||||
value={email}
|
||||
onChange={v => { setMessage(""); setEmail(v.target.value) }}
|
||||
/>
|
||||
<TextField
|
||||
margin="normal"
|
||||
@ -26,10 +53,13 @@ const Login = () => {
|
||||
type="password"
|
||||
id="password"
|
||||
autoComplete="current-password"
|
||||
value={password}
|
||||
onChange={v => { setMessage(""); setPassword(v.target.value) }}
|
||||
/>
|
||||
<Button type="submit" fullWidth variant="contained" sx={{ mt: 3, mb: 2 }}>
|
||||
Log In
|
||||
</Button>
|
||||
<Box component="h3">{message}</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
</Container>
|
||||
|
@ -1,21 +1,14 @@
|
||||
import "./index.css";
|
||||
import {StrictMode} from "react";
|
||||
import {createRoot} from "react-dom/client";
|
||||
import ApiConsole from "./ApiConsole.tsx";
|
||||
import {ThemeProvider} from "@mui/material";
|
||||
import {theme} from "./model/theme.ts";
|
||||
import {BrowserRouter, Route, Routes} from "react-router";
|
||||
import Login from "./Login.tsx";
|
||||
import App from "./App.tsx";
|
||||
|
||||
createRoot(document.getElementById('root')!).render(
|
||||
<StrictMode>
|
||||
<ThemeProvider theme={theme}>
|
||||
<BrowserRouter>
|
||||
<Routes>
|
||||
<Route index element={<ApiConsole />} />
|
||||
<Route path="login" element={<Login />} />
|
||||
</Routes>
|
||||
</BrowserRouter>
|
||||
<App />
|
||||
</ThemeProvider>
|
||||
</StrictMode>
|
||||
);
|
@ -1,4 +1,5 @@
|
||||
import {createTheme} from "@mui/material";
|
||||
import {Theme} from "reagraph";
|
||||
|
||||
const componentOptions = {
|
||||
MuiCard: {
|
||||
@ -45,3 +46,61 @@ export const modalStyle = {
|
||||
boxShadow: 24,
|
||||
p: 4,
|
||||
};
|
||||
|
||||
export const reagraphTheme: Theme = {
|
||||
canvas: {
|
||||
background: '#fff',
|
||||
fog: '#fff'
|
||||
},
|
||||
node: {
|
||||
fill: '#241775',
|
||||
activeFill: '#9bf316',
|
||||
opacity: 1,
|
||||
selectedOpacity: 1,
|
||||
inactiveOpacity: 0.2,
|
||||
label: {
|
||||
color: '#241775',
|
||||
stroke: '#fff',
|
||||
activeColor: '#9bf316'
|
||||
},
|
||||
subLabel: {
|
||||
color: '#241775',
|
||||
stroke: '#eee',
|
||||
activeColor: '#9bf316'
|
||||
}
|
||||
},
|
||||
lasso: {
|
||||
border: '1px solid #55aaff',
|
||||
background: 'rgba(75, 160, 255, 0.1)'
|
||||
},
|
||||
ring: {
|
||||
fill: '#D8E6EA',
|
||||
activeFill: '#1DE9AC'
|
||||
},
|
||||
edge: {
|
||||
fill: '#D8E6EA',
|
||||
activeFill: '#1DE9AC',
|
||||
opacity: 1,
|
||||
selectedOpacity: 1,
|
||||
inactiveOpacity: 0.1,
|
||||
label: {
|
||||
stroke: '#fff',
|
||||
color: '#2A6475',
|
||||
activeColor: '#1DE9AC'
|
||||
}
|
||||
},
|
||||
arrow: {
|
||||
fill: '#D8E6EA',
|
||||
activeFill: '#1DE9AC'
|
||||
},
|
||||
cluster: {
|
||||
stroke: '#D8E6EA',
|
||||
opacity: 1,
|
||||
selectedOpacity: 1,
|
||||
inactiveOpacity: 0.1,
|
||||
label: {
|
||||
stroke: '#fff',
|
||||
color: '#2A6475'
|
||||
}
|
||||
}
|
||||
};
|
4
ui100/src/model/user.ts
Normal file
4
ui100/src/model/user.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export interface User {
|
||||
email: string;
|
||||
token: string;
|
||||
}
|
Loading…
Reference in New Issue
Block a user