mirror of
https://github.com/netbirdio/netbird.git
synced 2026-05-17 22:29:54 +00:00
add setting
This commit is contained in:
@@ -1,8 +1,7 @@
|
||||
export default function PlaceholderHeader() {
|
||||
return (
|
||||
<div
|
||||
className="h-[36px] shrink-0 cursor-default"
|
||||
style={{ "--wails-draggable": "drag" } as React.CSSProperties}
|
||||
className="h-[36px] shrink-0 cursor-default wails-draggable"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ export const ProfileSelector = ({ email = "" }: Props) => {
|
||||
<button
|
||||
type="button"
|
||||
className={
|
||||
"h-11 rounded-md text-nb-gray-300 flex items-center gap-1 text-xs hover:bg-nb-gray-930 data-[state=open]:bg-nb-gray-930 px-2 -mx-2 outline-none cursor-default transition-colors duration-150"
|
||||
"h-11 rounded-md text-nb-gray-300 flex items-center gap-1 text-xs hover:bg-nb-gray-930 data-[state=open]:bg-nb-gray-930 px-2 -mx-1 outline-none cursor-default transition-colors duration-150"
|
||||
}
|
||||
>
|
||||
<div
|
||||
|
||||
@@ -19,3 +19,11 @@ body,
|
||||
body {
|
||||
@apply bg-nb-gray font-sans text-nb-gray-200 antialiased;
|
||||
}
|
||||
|
||||
.wails-draggable {
|
||||
--wails-draggable: drag;
|
||||
}
|
||||
|
||||
.wails-no-draggable {
|
||||
--wails-draggable: no-drag;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,25 @@
|
||||
import { ProfileSelector } from "@/components/ProfileSelector.tsx";
|
||||
import { IconButton } from "@/components/IconButton.tsx";
|
||||
import { SettingsIcon } from "lucide-react";
|
||||
import { cn } from "@/lib/cn";
|
||||
|
||||
export const Header = () => {
|
||||
type Props = {
|
||||
settingsActive?: boolean;
|
||||
onSettingsClick?: () => void;
|
||||
};
|
||||
|
||||
export const Header = ({ settingsActive = false, onSettingsClick }: Props) => {
|
||||
return (
|
||||
<div className={"w-full justify-between flex mb-12"}>
|
||||
<ProfileSelector />
|
||||
<IconButton icon={SettingsIcon} />
|
||||
<ProfileSelector email={"eduard@netbird.io"} />
|
||||
<IconButton
|
||||
icon={SettingsIcon}
|
||||
onClick={onSettingsClick}
|
||||
className={cn(
|
||||
settingsActive &&
|
||||
"bg-nb-gray-930 text-nb-gray-200 hover:text-nb-gray-200",
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
32
client/ui-wails/frontend/src/layouts/MainLeftSide.tsx
Normal file
32
client/ui-wails/frontend/src/layouts/MainLeftSide.tsx
Normal file
@@ -0,0 +1,32 @@
|
||||
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 (
|
||||
<div
|
||||
className={"flex flex-col max-w-xs w-full shrink-0 items-center"}
|
||||
>
|
||||
<Header
|
||||
settingsActive={active === "settings"}
|
||||
onSettingsClick={() =>
|
||||
onChange(active === "settings" ? "peers" : "settings")
|
||||
}
|
||||
/>
|
||||
<ConnectionStatus />
|
||||
<Navigation
|
||||
peersActive={active === "peers"}
|
||||
onPeersClick={() => {
|
||||
if (active !== "peers") onChange("peers");
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
15
client/ui-wails/frontend/src/layouts/MainRightSide.tsx
Normal file
15
client/ui-wails/frontend/src/layouts/MainRightSide.tsx
Normal file
@@ -0,0 +1,15 @@
|
||||
import { ReactNode } from "react";
|
||||
|
||||
type Props = {
|
||||
children: ReactNode;
|
||||
};
|
||||
|
||||
export const MainRightSide = ({ children }: Props) => {
|
||||
return (
|
||||
<div
|
||||
className={"wails-no-draggable flex-1 min-h-0 min-w-0 flex flex-col bg-nb-gray-935 rounded-xl rounded-br-2xl border border-nb-gray-900"}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -5,14 +5,20 @@ import {
|
||||
SquareArrowUpRight,
|
||||
} from "lucide-react";
|
||||
|
||||
export const Navigation = () => {
|
||||
type Props = {
|
||||
peersActive?: boolean;
|
||||
onPeersClick?: () => void;
|
||||
};
|
||||
|
||||
export const Navigation = ({ peersActive = false, onPeersClick }: Props) => {
|
||||
return (
|
||||
<nav className={"w-full flex flex-col gap-1 mt-8"}>
|
||||
<NavItem
|
||||
icon={MonitorSmartphoneIcon}
|
||||
title={"Peers"}
|
||||
description={"13 of 16 Online"}
|
||||
active
|
||||
active={peersActive}
|
||||
onClick={onPeersClick}
|
||||
/>
|
||||
<NavItem
|
||||
icon={Layers3Icon}
|
||||
|
||||
@@ -8,7 +8,7 @@ import { PeersList } from "./PeersList";
|
||||
|
||||
const isOnline = (status: string) => status === "connected";
|
||||
|
||||
export const PeersModule = () => {
|
||||
export const Peers = () => {
|
||||
const [search, setSearch] = useState("");
|
||||
const [statusFilter, setStatusFilter] = useState<StatusFilter>("all");
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
export const Settings = () => {
|
||||
return (
|
||||
<div className={"flex flex-col w-full h-full min-h-0 pt-4 px-4"}>
|
||||
<h2 className={"text-sm font-medium text-nb-gray-200"}>Settings</h2>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1,23 +1,22 @@
|
||||
import { ConnectionStatus } from "@/layouts/ConnectionStatus.tsx";
|
||||
import { Header } from "@/layouts/Header.tsx";
|
||||
import { Navigation } from "@/layouts/Navigation.tsx";
|
||||
import { PeersModule } from "@/modules/peers/PeersModule.tsx";
|
||||
import { useState } from "react";
|
||||
import { MainLeftSide, MainModule } from "@/layouts/MainLeftSide.tsx";
|
||||
import { MainRightSide } from "@/layouts/MainRightSide.tsx";
|
||||
import { Peers } from "@/modules/peers/Peers.tsx";
|
||||
import { Settings } from "@/modules/settings/Settings.tsx";
|
||||
|
||||
type Props = {
|
||||
|
||||
};
|
||||
export const Main = ({}: Props) => {
|
||||
return (
|
||||
<div className={"flex h-full p-4 gap-4 min-h-0"}>
|
||||
<div className={"flex flex-col max-w-xs w-full shrink-0 items-center"}>
|
||||
<Header />
|
||||
<ConnectionStatus />
|
||||
<Navigation />
|
||||
</div>
|
||||
const [active, setActive] = useState<MainModule>("peers");
|
||||
|
||||
<div className={"flex-1 min-h-0 min-w-0 flex flex-col bg-nb-gray-935 rounded-xl border border-nb-gray-900"}>
|
||||
<PeersModule />
|
||||
</div>
|
||||
return (
|
||||
<div className={"wails-draggable flex h-full p-4 gap-4 min-h-0"}>
|
||||
<MainLeftSide active={active} onChange={setActive} />
|
||||
|
||||
<MainRightSide>
|
||||
{active === "peers" ? <Peers /> : <Settings />}
|
||||
</MainRightSide>
|
||||
</div>
|
||||
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user