mirror of
https://github.com/Unkn0wnCat/matrix-veles.git
synced 2025-07-31 15:18:44 +02:00
webui: Add basic panel layout
This commit is contained in:
parent
45ca353b3f
commit
ac5faca859
5 changed files with 136 additions and 11 deletions
|
@ -1,5 +1,5 @@
|
|||
import React, {useState} from 'react';
|
||||
import { Routes, Route, Link } from "react-router-dom";
|
||||
import React from 'react';
|
||||
import { Routes, Route } from "react-router-dom";
|
||||
import AuthLayout from "./layouts/AuthLayout";
|
||||
import LoginView from "./components/auth/LoginView";
|
||||
import RegisterView from "./components/auth/RegisterView";
|
||||
|
@ -7,6 +7,7 @@ import RequireAuth from "./features/auth/RequireAuth";
|
|||
import {useAppDispatch} from "./app/hooks";
|
||||
import broadcastChannel from "./app/broadcastChannel";
|
||||
import {logOut, receiveAuthUpdate} from "./features/auth/authSlice";
|
||||
import PanelLayout from "./layouts/PanelLayout";
|
||||
|
||||
function App() {
|
||||
const dispatch = useAppDispatch()
|
||||
|
@ -23,10 +24,14 @@ function App() {
|
|||
<Route path={"login"} element={<LoginView/>} />
|
||||
<Route path={"register"} element={<RegisterView/>} />
|
||||
</Route>
|
||||
<Route path={"/"} element={<RequireAuth><h1>hi</h1> <button onClick={() => {
|
||||
dispatch(logOut())
|
||||
}
|
||||
}>Log out</button></RequireAuth>}/>
|
||||
<Route path={"/"} element={<PanelLayout/>}>
|
||||
<Route path={""} element={<RequireAuth><h1>hi</h1> <button onClick={() => {
|
||||
dispatch(logOut())
|
||||
}
|
||||
}>Log out</button></RequireAuth>} />
|
||||
<Route path={"hashing/lists"} element={<RequireAuth><h1>lists</h1></RequireAuth>} />
|
||||
<Route path={"hashing/entries"} element={<RequireAuth><h1>entries</h1></RequireAuth>} />
|
||||
</Route>
|
||||
</Routes>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import {createAsyncThunk, createSlice, PayloadAction} from '@reduxjs/toolkit';
|
||||
import {RootState, AppThunk} from '../../app/store';
|
||||
import broadcastChannel, { BroadcastMessage, sendMessage } from "../../app/broadcastChannel";
|
||||
import {createSlice, PayloadAction} from '@reduxjs/toolkit';
|
||||
import {RootState} from '../../app/store';
|
||||
import { BroadcastMessage, sendMessage } from "../../app/broadcastChannel";
|
||||
|
||||
export interface AuthState {
|
||||
jwt: string|null;
|
||||
|
|
|
@ -5,7 +5,7 @@ import {Link, useLocation, useNavigate, useOutlet} from "react-router-dom";
|
|||
import {UserPlus, User} from "lucide-react";
|
||||
|
||||
import {ReactComponent as Logo} from "../logo.svg";
|
||||
import {useAppDispatch, useAppSelector} from "../app/hooks";
|
||||
import {useAppSelector} from "../app/hooks";
|
||||
import {selectAuth} from "../features/auth/authSlice";
|
||||
|
||||
export type AuthLocationState = {
|
||||
|
@ -18,7 +18,6 @@ const AuthLayout = () => {
|
|||
|
||||
const locationState = location.state as AuthLocationState
|
||||
|
||||
const dispatch = useAppDispatch()
|
||||
const authState = useAppSelector(selectAuth)
|
||||
const navigate = useNavigate()
|
||||
|
||||
|
|
88
webui/src/layouts/PanelLayout.module.scss
Normal file
88
webui/src/layouts/PanelLayout.module.scss
Normal file
|
@ -0,0 +1,88 @@
|
|||
@import "../globals";
|
||||
|
||||
.skipToContent {
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
padding: var(--veles-layout-padding-slim);
|
||||
background-color: var(--veles-color-background);
|
||||
color: var(--veles-color-foreground);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
||||
&:focus {
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin panelTopBarLink {
|
||||
padding: var(--veles-layout-padding-slim) var(--veles-layout-padding);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
text-decoration: none;
|
||||
|
||||
transition: color .25s;
|
||||
|
||||
font-weight: 600;
|
||||
|
||||
&:hover, &.active, &:focus {
|
||||
color: var(--veles-color-accent);
|
||||
}
|
||||
|
||||
> svg {
|
||||
margin-right: var(--veles-layout-padding);
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
stroke-width: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.panel {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background-color: var(--veles-color-background);
|
||||
color: var(--veles-color-foreground);
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.topBar {
|
||||
display: flex;
|
||||
border-bottom: thin solid var(--veles-color-border);
|
||||
|
||||
a {
|
||||
@include panelTopBarLink;
|
||||
}
|
||||
|
||||
.logo {
|
||||
margin-right: auto;
|
||||
|
||||
> svg {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
flex-grow: 1;
|
||||
|
||||
> nav {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-right: thin solid var(--veles-color-border);
|
||||
|
||||
a {
|
||||
@include panelTopBarLink;
|
||||
padding: var(--veles-layout-padding);
|
||||
}
|
||||
}
|
||||
|
||||
> main {
|
||||
padding: var(--veles-layout-padding)
|
||||
}
|
||||
}
|
||||
}
|
33
webui/src/layouts/PanelLayout.tsx
Normal file
33
webui/src/layouts/PanelLayout.tsx
Normal file
|
@ -0,0 +1,33 @@
|
|||
import React from "react";
|
||||
|
||||
import {Link, NavLink, useOutlet} from "react-router-dom";
|
||||
import {Home, List, ClipboardList, ExternalLink} from "lucide-react";
|
||||
|
||||
import {ReactComponent as Logo} from "../logo.svg";
|
||||
|
||||
import styles from "./PanelLayout.module.scss";
|
||||
|
||||
const PanelLayout = () => {
|
||||
const outlet = useOutlet();
|
||||
|
||||
return <div className={styles.panel}>
|
||||
<a href={"#main"} className={styles.skipToContent}>Jump to Content</a>
|
||||
<a href={"#navigation"} className={styles.skipToContent}>Jump to Navigation</a>
|
||||
<div className={styles.topBar}>
|
||||
<Link to={"/"} className={styles.logo}><Logo/> <span>Matrix-Veles</span></Link>
|
||||
<a href={"https://veles.1in1.net/docs/intro"} target={"_blank"} rel={"noreferrer"}><ExternalLink/> <span>Documentation</span></a>
|
||||
</div>
|
||||
<div className={styles.content}>
|
||||
<nav id={"navigation"}>
|
||||
<NavLink to={"/"}><Home/><span>Dashboard</span></NavLink>
|
||||
<NavLink to={"/hashing/lists"}><List/><span>Lists</span></NavLink>
|
||||
<NavLink to={"/hashing/entries"}><ClipboardList/><span>Entries</span></NavLink>
|
||||
</nav>
|
||||
<main id={"main"}>
|
||||
{outlet}
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
export default PanelLayout
|
Loading…
Add table
Add a link
Reference in a new issue