From debb558aa3904200ceafbdaad7d206964a0699cc Mon Sep 17 00:00:00 2001 From: Eduard Gert Date: Thu, 7 May 2026 09:57:14 +0200 Subject: [PATCH] wip --- client/ui-wails/frontend/package.json | 1 + client/ui-wails/frontend/pnpm-lock.yaml | 42 +++ client/ui-wails/frontend/settings.md | 158 +++++++--- client/ui-wails/frontend/src/app.tsx | 49 ++- .../src/components/FancyToggleSwitch.tsx | 79 +++++ .../frontend/src/components/NavItem.tsx | 32 +- .../src/components/PlaceholderHeader.tsx | 7 - .../src/components/ProfileSelector.tsx | 7 +- .../frontend/src/components/ToggleSwitch.tsx | 71 +++++ client/ui-wails/frontend/src/layout.tsx | 15 - .../frontend/src/layouts/AppLayout.tsx | 11 + .../frontend/src/layouts/ConnectionStatus.tsx | 2 +- .../ui-wails/frontend/src/layouts/Header.tsx | 24 +- client/ui-wails/frontend/src/layouts/Main.tsx | 22 ++ .../frontend/src/layouts/MainLeftSide.tsx | 32 -- .../frontend/src/layouts/Navigation.tsx | 2 +- .../frontend/src/lib/MainModuleContext.tsx | 27 ++ .../src/modules/settings/Settings.tsx | 16 +- .../modules/settings/SettingsNavigation.tsx | 53 ++++ client/ui-wails/frontend/src/screens/Main.tsx | 23 -- client/ui-wails/frontend/wails-go-api (1).md | 278 ++++++++++++++++++ client/ui-wails/main.go | 1 + 22 files changed, 774 insertions(+), 178 deletions(-) create mode 100644 client/ui-wails/frontend/src/components/FancyToggleSwitch.tsx delete mode 100644 client/ui-wails/frontend/src/components/PlaceholderHeader.tsx create mode 100644 client/ui-wails/frontend/src/components/ToggleSwitch.tsx delete mode 100644 client/ui-wails/frontend/src/layout.tsx create mode 100644 client/ui-wails/frontend/src/layouts/AppLayout.tsx create mode 100644 client/ui-wails/frontend/src/layouts/Main.tsx delete mode 100644 client/ui-wails/frontend/src/layouts/MainLeftSide.tsx create mode 100644 client/ui-wails/frontend/src/lib/MainModuleContext.tsx create mode 100644 client/ui-wails/frontend/src/modules/settings/SettingsNavigation.tsx delete mode 100644 client/ui-wails/frontend/src/screens/Main.tsx create mode 100644 client/ui-wails/frontend/wails-go-api (1).md diff --git a/client/ui-wails/frontend/package.json b/client/ui-wails/frontend/package.json index 18c8616b2..8e66a4d00 100644 --- a/client/ui-wails/frontend/package.json +++ b/client/ui-wails/frontend/package.json @@ -16,6 +16,7 @@ "@radix-ui/react-label": "^2.1.8", "@radix-ui/react-popover": "^1.1.15", "@radix-ui/react-scroll-area": "^1.2.10", + "@radix-ui/react-switch": "^1.2.6", "@radix-ui/react-visually-hidden": "^1.2.4", "@wailsio/runtime": "latest", "chroma-js": "^3.2.0", diff --git a/client/ui-wails/frontend/pnpm-lock.yaml b/client/ui-wails/frontend/pnpm-lock.yaml index 05f06e597..d7383249f 100644 --- a/client/ui-wails/frontend/pnpm-lock.yaml +++ b/client/ui-wails/frontend/pnpm-lock.yaml @@ -20,6 +20,9 @@ dependencies: '@radix-ui/react-scroll-area': specifier: ^1.2.10 version: 1.2.10(@types/react-dom@18.3.7)(@types/react@18.3.28)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-switch': + specifier: ^1.2.6 + version: 1.2.6(@types/react-dom@18.3.7)(@types/react@18.3.28)(react-dom@18.3.1)(react@18.3.1) '@radix-ui/react-visually-hidden': specifier: ^1.2.4 version: 1.2.4(@types/react-dom@18.3.7)(@types/react@18.3.28)(react-dom@18.3.1)(react@18.3.1) @@ -1102,6 +1105,32 @@ packages: react: 18.3.1 dev: false + /@radix-ui/react-switch@1.2.6(@types/react-dom@18.3.7)(@types/react@18.3.28)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7)(@types/react@18.3.28)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.1(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.1(@types/react@18.3.28)(react@18.3.1) + '@types/react': 18.3.28 + '@types/react-dom': 18.3.7(@types/react@18.3.28) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + /@radix-ui/react-use-callback-ref@1.1.1(@types/react@18.3.28)(react@18.3.1): resolution: {integrity: sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==} peerDependencies: @@ -1171,6 +1200,19 @@ packages: react: 18.3.1 dev: false + /@radix-ui/react-use-previous@1.1.1(@types/react@18.3.28)(react@18.3.1): + resolution: {integrity: sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.3.28 + react: 18.3.1 + dev: false + /@radix-ui/react-use-rect@1.1.1(@types/react@18.3.28)(react@18.3.1): resolution: {integrity: sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==} peerDependencies: diff --git a/client/ui-wails/frontend/settings.md b/client/ui-wails/frontend/settings.md index 071863e21..6ee885d13 100644 --- a/client/ui-wails/frontend/settings.md +++ b/client/ui-wails/frontend/settings.md @@ -1,69 +1,129 @@ -1. General +# Settings — Tabs & Controls -The "old tray" toggles + notifications. This is what 90% of users come to Settings for. +Each row has a title and short description. Booleans default to **toggle switch**; pick another control only when noted. -- Connect on startup — disableAutoConnect (inverted) -- Allow SSH — serverSshAllowed (master switch; the SSH tab is the detail) -- Quantum-resistance — rosenpassEnabled - - Nested when on: Permissive mode — rosenpassPermissive -- Lazy connections — lazyConnectionEnabled -- Block inbound — blockInbound -- Show notifications — disableNotifications (inverted) +Tab order: **General · Network · SSH · Troubleshooting · About**. -▎ Note: blockInbound is technically a firewall behavior, but Stage 1 explicitly groups it with the tray-replacement toggles. Keep it here. +--- -2. Connection +## 1. General -Identity + how the wire is established. The "what server am I talking to and how" tab. +App behavior + how the client connects. -- Management URL — managementUrl -- Pre-shared key — preSharedKey (password input, toggle reveal) -- Advanced (collapsed by default) - - Admin URL — adminUrl - - Interface name — interfaceName - - WireGuard port — wireguardPort - - MTU — mtu +### Startup -3. Network +- **Connect on startup** — `disableAutoConnect` (inverted) · *toggle switch* + - Automatically connect to NetBird when the app launches. +- **Show notifications** — `disableNotifications` (inverted) · *toggle switch* + - Show desktop notifications for connection events and updates. -Routing / DNS / LAN behavior — i.e. what the daemon does to the host network. +### Connection -- Network monitor — networkMonitor -- Disable DNS — disableDns -- Disable client routes — disableClientRoutes -- Disable server routes — disableServerRoutes -- Block LAN access — blockLanAccess +- **Management URL** — `managementUrl` · *text input* + - The NetBird management server this client connects to. +- **Admin URL** — `adminUrl` · *text input* + - Web dashboard URL used by "Open Admin Panel". +- **Pre-shared key** — `preSharedKey` · *password input with reveal toggle* + - Optional WireGuard pre-shared key for an extra layer of symmetric encryption. -4. SSH +### Interface -Detailed SSH server config. Greyed out with an inline notice ("Enable Allow SSH in General to configure") when serverSshAllowed is off. +- **Interface name** — `interfaceName` · *text input* + - Name of the WireGuard network interface created on this host. +- **WireGuard port** — `wireguardPort` · *number input* + - Local UDP port the WireGuard interface listens on. +- **MTU** — `mtu` · *number input* + - Maximum transmission unit for the WireGuard interface. -- SSH root login — enableSshRoot -- SFTP — enableSshSftp -- Local port forwarding — enableSshLocalPortForwarding -- Remote port forwarding — enableSshRemotePortForwarding -- Advanced (collapsed) - - Disable SSH auth — disableSshAuth - - JWT cache TTL — sshJwtCacheTtl +--- -5. Diagnostics +## 2. Network -Everything you reach for when something is wrong. Mixes config (log level) with actions (bundle creation) deliberately — they're used together. +Routing, DNS, firewall, and encryption — everything the daemon does on the wire and to the host network. -- Log level — Debug / Info / Warn / Error (dropdown) -- Log file path — read-only, with Copy + Reveal in Finder/Explorer buttons (configFile / logFile from daemon) -- Config file path — same pattern -- Debug bundle (own section) - - Anonymize toggle - - Include system info toggle - - Upload on create toggle → reveals URL field when on - - Create Bundle button → progress indicator → resulting path or upload URL displayed below +### Routing & DNS -6. About +- **Lazy connections** — `lazyConnectionEnabled` · *toggle switch* + - Only establish peer tunnels on first traffic instead of eagerly at startup. +- **Network monitor** — `networkMonitor` · *toggle switch* + - Reconnect automatically when the host network changes (Wi-Fi switch, VPN, sleep/wake). +- **Enable DNS** — `disableDns` (inverted) · *toggle switch* + - Apply NetBird-managed DNS settings to the host resolver. +- **Enable client routes** — `disableClientRoutes` (inverted) · *toggle switch* + - Accept routes advertised by other peers so this client can reach their networks. +- **Enable server routes** — `disableServerRoutes` (inverted) · *toggle switch* + - Advertise this host's local routes to other peers. -Version + update flow + identity reference. +### Firewall + +- **Block inbound traffic** — `blockInbound` · *toggle switch* + - Drop all unsolicited inbound traffic on the NetBird interface. +- **Block LAN access** — `blockLanAccess` · *toggle switch* + - Prevent peers from reaching this host's local network. + +### Encryption + +- **Quantum-resistant encryption** — `rosenpassEnabled` · *toggle switch* + - Add a post-quantum key exchange (Rosenpass) on top of WireGuard. + - **Permissive mode** — `rosenpassPermissive` · *toggle switch* (nested, only when above is on) + - Allow connections to peers without quantum-resistance support. + +--- + +## 3. SSH + +NetBird SSH server config. Master switch at the top; sub-toggles greyed out with an inline notice ("Enable Allow SSH to configure") when the master is off. + +### Server + +- **Allow SSH** — `serverSshAllowed` · *toggle switch* (master) + - Run the NetBird SSH server on this host so other peers can connect to it. +- **Allow root login** — `enableSshRoot` · *toggle switch* + - Permit incoming SSH sessions to authenticate as `root`. +- **Enable SFTP** — `enableSshSftp` · *toggle switch* + - Allow file transfers over the NetBird SSH server. +- **Local port forwarding** — `enableSshLocalPortForwarding` · *toggle switch* + - Allow clients to forward local ports through this host. +- **Remote port forwarding** — `enableSshRemotePortForwarding` · *toggle switch* + - Allow clients to expose remote ports back through this host. + +### Authentication + +- **Disable SSH auth** — `disableSshAuth` · *toggle switch* + - Skip JWT authentication for incoming SSH sessions. **Insecure — diagnostics only.** +- **JWT cache TTL** — `sshJwtCacheTtl` · *number input (seconds)* + - How long verified JWTs are cached before re-validation. + +--- + +## 4. Troubleshooting + +Everything you reach for when something is wrong. Config + actions deliberately mixed — they're used together. + +### Logging + +- **Log level** — *dropdown: Debug / Info / Warn / Error* + - Verbosity of the daemon log. Raise to Debug when reproducing an issue. +- **Log file path** — *read-only text + Copy + Reveal in Finder/Explorer* +- **Config file path** — *read-only text + Copy + Reveal in Finder/Explorer* + +### Debug bundle + +- **Anonymize** — *toggle switch* + - Strip IPs, hostnames, and peer names from the bundle before saving. +- **Include system info** — *toggle switch* + - Add OS, kernel, and network interface details to the bundle. +- **Upload on create** — *toggle switch* + - When on, reveals an upload URL field and uploads the bundle after creation. +- **Create Bundle** — *button* → progress indicator → resulting path or upload URL. + +--- + +## 5. About + +Version, update flow, and identity reference. - App version, daemon version -- Check for Updates button → drives the auto-update flow (15-min timeout, success/error states) -- Local peer info quick-reference (FQDN, IP) — same data the connection-state view shows +- **Check for Updates** — *button* (drives auto-update flow; 15-min timeout, success/error states) +- Local peer info quick-reference (FQDN, IP) — same data shown in the connection-state view - Links: docs, GitHub repo, license diff --git a/client/ui-wails/frontend/src/app.tsx b/client/ui-wails/frontend/src/app.tsx index c861a3a4b..b5e7bef82 100644 --- a/client/ui-wails/frontend/src/app.tsx +++ b/client/ui-wails/frontend/src/app.tsx @@ -5,35 +5,30 @@ import { HashRouter, Navigate, Route, Routes } from "react-router-dom"; import QuickActions from "@/screens/QuickActions.tsx"; import LoginUrl from "@/screens/LoginUrl.tsx"; import Update from "@/screens/Update.tsx"; -import Layout from "@/layout.tsx"; -import Peers from "@/screens/Peers.tsx"; -import Networks from "@/screens/Networks.tsx"; -import Profiles from "@/screens/Profiles.tsx"; -import Settings from "@/screens/Settings.tsx"; -import Debug from "@/screens/Debug.tsx"; -import {Main} from "@/screens/Main.tsx"; +import { AppLayout } from "@/layouts/AppLayout.tsx"; +import { Main } from "@/layouts/Main.tsx"; +import { Settings } from "@/modules/settings/Settings.tsx"; import { SkeletonTheme } from "react-loading-skeleton"; import "react-loading-skeleton/dist/skeleton.css"; ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render( - - - - - } /> - } /> - } /> - }> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - - - - - , + + + + + } /> + } /> + } /> + }> + } /> + } /> + } + /> + + + + + , ); diff --git a/client/ui-wails/frontend/src/components/FancyToggleSwitch.tsx b/client/ui-wails/frontend/src/components/FancyToggleSwitch.tsx new file mode 100644 index 000000000..a3440a06a --- /dev/null +++ b/client/ui-wails/frontend/src/components/FancyToggleSwitch.tsx @@ -0,0 +1,79 @@ +import React from "react"; +import { HelpText } from "@/components/HelpText"; +import { Label } from "@/components/Label"; +import { ToggleSwitch } from "@/components/ToggleSwitch"; +import { cn } from "@/lib/cn"; + +interface Props { + value: boolean; + onChange: (value: boolean) => void; + helpText?: React.ReactNode; + label?: React.ReactNode; + children?: React.ReactNode; + disabled?: boolean; + dataCy?: string; + className?: string; + labelClassName?: string; + textWrapperClassName?: string; +} + +export default function FancyToggleSwitch({ + value, + onChange, + helpText, + label, + children, + disabled = false, + dataCy, + className, + labelClassName, + textWrapperClassName = "max-w-sm", +}: Readonly) { + const handleToggle = () => { + if (disabled) return; + onChange(!value); + }; + + const handleKeyDown = (event: React.KeyboardEvent) => { + if (disabled) return; + if (event.key === "Enter" || event.key === " ") { + event.preventDefault(); + handleToggle(); + } + }; + + return ( +
+
+
+ + {helpText} +
+
+ +
+
+ {children && value ? ( +
e.stopPropagation()}> + {children} +
+ ) : null} +
+ ); +} diff --git a/client/ui-wails/frontend/src/components/NavItem.tsx b/client/ui-wails/frontend/src/components/NavItem.tsx index 276f2e888..e00030fcb 100644 --- a/client/ui-wails/frontend/src/components/NavItem.tsx +++ b/client/ui-wails/frontend/src/components/NavItem.tsx @@ -9,6 +9,7 @@ type Props = HTMLMotionProps<"button"> & { description?: string; active?: boolean; iconSize?: number; + iconBackground?: boolean; }; export const NavItem = forwardRef( @@ -19,6 +20,7 @@ export const NavItem = forwardRef( description, active = false, iconSize = 15, + iconBackground = true, className, type = "button", ...props @@ -40,21 +42,33 @@ export const NavItem = forwardRef( )} {...props} > -
+ {iconBackground ? ( +
+ +
+ ) : ( -
+ )}

- ); -} diff --git a/client/ui-wails/frontend/src/components/ProfileSelector.tsx b/client/ui-wails/frontend/src/components/ProfileSelector.tsx index f05e8a6ce..db59f383d 100644 --- a/client/ui-wails/frontend/src/components/ProfileSelector.tsx +++ b/client/ui-wails/frontend/src/components/ProfileSelector.tsx @@ -124,9 +124,10 @@ export const ProfileSelector = ({ email = "" }: Props) => { } >
{initial} diff --git a/client/ui-wails/frontend/src/components/ToggleSwitch.tsx b/client/ui-wails/frontend/src/components/ToggleSwitch.tsx new file mode 100644 index 000000000..b8b709c1a --- /dev/null +++ b/client/ui-wails/frontend/src/components/ToggleSwitch.tsx @@ -0,0 +1,71 @@ +"use client"; + +import * as SwitchPrimitives from "@radix-ui/react-switch"; +import { cva, VariantProps } from "class-variance-authority"; +import * as React from "react"; +import { cn } from "@/lib/cn"; + +type SwitchVariants = VariantProps; + +const switchVariants = cva("", { + variants: { + size: { + default: "h-[24px] w-[44px]", + small: "h-[18px] w-[36px]", + }, + variant: { + default: [ + "dark:data-[state=checked]:bg-netbird dark:data-[state=unchecked]:bg-nb-gray-700", + "data-[state=checked]:bg-neutral-900 data-[state=unchecked]:bg-neutral-200", + ], + "red-green": [ + "dark:data-[state=checked]:bg-red-600 dark:data-[state=unchecked]:bg-nb-gray-700", + "data-[state=checked]:bg-red-500 data-[state=unchecked]:bg-red-200", + ], + red: [ + "dark:data-[state=checked]:bg-red-600 dark:data-[state=unchecked]:bg-nb-gray-700", + "data-[state=checked]:bg-red-500 data-[state=unchecked]:bg-red-200", + ], + }, + "thumb-size": { + default: "h-5 w-5 data-[state=checked]:translate-x-5", + small: "h-[14px] w-[14px] data-[state=checked]:translate-x-[17px]", + }, + }, +}); + +const ToggleSwitch = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & + SwitchVariants & { dataCy?: string } +>( + ( + { className, size = "default", variant = "default", dataCy, ...props }, + ref, + ) => ( + { + e.stopPropagation(); + props.onClick?.(e); + }} + ref={ref} + > + + + ), +); +ToggleSwitch.displayName = SwitchPrimitives.Root.displayName; + +export { ToggleSwitch }; diff --git a/client/ui-wails/frontend/src/layout.tsx b/client/ui-wails/frontend/src/layout.tsx deleted file mode 100644 index c0f5a67d1..000000000 --- a/client/ui-wails/frontend/src/layout.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { Outlet } from "react-router-dom"; -import PlaceholderHeader from "@/components/PlaceholderHeader"; - -export default function Layout() { - return ( -
- -
-
- -
-
-
- ); -} diff --git a/client/ui-wails/frontend/src/layouts/AppLayout.tsx b/client/ui-wails/frontend/src/layouts/AppLayout.tsx new file mode 100644 index 000000000..4a6ebf07e --- /dev/null +++ b/client/ui-wails/frontend/src/layouts/AppLayout.tsx @@ -0,0 +1,11 @@ +import { Outlet } from "react-router-dom"; +import { Header } from "@/layouts/Header.tsx"; + +export const AppLayout = () => { + return ( +
+
+ +
+ ); +}; diff --git a/client/ui-wails/frontend/src/layouts/ConnectionStatus.tsx b/client/ui-wails/frontend/src/layouts/ConnectionStatus.tsx index d431020f2..b22d8c1b8 100644 --- a/client/ui-wails/frontend/src/layouts/ConnectionStatus.tsx +++ b/client/ui-wails/frontend/src/layouts/ConnectionStatus.tsx @@ -5,7 +5,7 @@ import { export const ConnectionStatus = () => { return ( -
+

void; -}; +export const Header = () => { + const navigate = useNavigate(); + const location = useLocation(); + const settingsActive = location.pathname.startsWith("/settings"); -export const Header = ({ settingsActive = false, onSettingsClick }: Props) => { return ( -
- +
+
+ +
navigate(settingsActive ? "/" : "/settings")} className={cn( settingsActive && "bg-nb-gray-930 text-nb-gray-200 hover:text-nb-gray-200", diff --git a/client/ui-wails/frontend/src/layouts/Main.tsx b/client/ui-wails/frontend/src/layouts/Main.tsx new file mode 100644 index 000000000..b80168154 --- /dev/null +++ b/client/ui-wails/frontend/src/layouts/Main.tsx @@ -0,0 +1,22 @@ +import { ConnectionStatus } from "@/layouts/ConnectionStatus.tsx"; +import { MainRightSide } from "@/layouts/MainRightSide.tsx"; +import { Navigation } from "@/layouts/Navigation.tsx"; +import { Peers } from "@/modules/peers/Peers.tsx"; + +export const Main = () => { + return ( +
+
+ + +
+ + + +
+ ); +}; diff --git a/client/ui-wails/frontend/src/layouts/MainLeftSide.tsx b/client/ui-wails/frontend/src/layouts/MainLeftSide.tsx deleted file mode 100644 index a0d74e4d2..000000000 --- a/client/ui-wails/frontend/src/layouts/MainLeftSide.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import { ConnectionStatus } from "@/layouts/ConnectionStatus.tsx"; -import { Header } from "@/layouts/Header.tsx"; -import { Navigation } from "@/layouts/Navigation.tsx"; - -export type MainModule = "peers" | "settings"; - -type Props = { - active: MainModule; - onChange: (module: MainModule) => void; -}; - -export const MainLeftSide = ({ active, onChange }: Props) => { - return ( -
-
- onChange(active === "settings" ? "peers" : "settings") - } - /> - - { - if (active !== "peers") onChange("peers"); - }} - /> -
- ); -}; diff --git a/client/ui-wails/frontend/src/layouts/Navigation.tsx b/client/ui-wails/frontend/src/layouts/Navigation.tsx index ce9fedad6..3dbad6617 100644 --- a/client/ui-wails/frontend/src/layouts/Navigation.tsx +++ b/client/ui-wails/frontend/src/layouts/Navigation.tsx @@ -12,7 +12,7 @@ type Props = { export const Navigation = ({ peersActive = false, onPeersClick }: Props) => { return ( -