diff --git a/webui/src/App.tsx b/webui/src/App.tsx index 0b52622..b5939f4 100644 --- a/webui/src/App.tsx +++ b/webui/src/App.tsx @@ -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() { } /> } /> -

hi

}/> + }> +

hi

} /> +

lists

} /> +

entries

} /> +
); } diff --git a/webui/src/features/auth/authSlice.ts b/webui/src/features/auth/authSlice.ts index 52cbd02..71a3a69 100644 --- a/webui/src/features/auth/authSlice.ts +++ b/webui/src/features/auth/authSlice.ts @@ -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; diff --git a/webui/src/layouts/AuthLayout.tsx b/webui/src/layouts/AuthLayout.tsx index de953ec..b8f400e 100644 --- a/webui/src/layouts/AuthLayout.tsx +++ b/webui/src/layouts/AuthLayout.tsx @@ -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() diff --git a/webui/src/layouts/PanelLayout.module.scss b/webui/src/layouts/PanelLayout.module.scss new file mode 100644 index 0000000..8b0476a --- /dev/null +++ b/webui/src/layouts/PanelLayout.module.scss @@ -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) + } + } +} \ No newline at end of file diff --git a/webui/src/layouts/PanelLayout.tsx b/webui/src/layouts/PanelLayout.tsx new file mode 100644 index 0000000..3403f9b --- /dev/null +++ b/webui/src/layouts/PanelLayout.tsx @@ -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
+ Jump to Content + Jump to Navigation +
+ Matrix-Veles + Documentation +
+
+ +
+ {outlet} +
+
+
+} + +export default PanelLayout \ No newline at end of file