mirror of
https://github.com/netbirdio/netbird.git
synced 2026-05-17 06:09:55 +00:00
Merge branch 'ui-refactor' into ui-refactor-ui
This commit is contained in:
19
client/ui/frontend/src/layouts/AppLayout.tsx
Normal file
19
client/ui/frontend/src/layouts/AppLayout.tsx
Normal file
@@ -0,0 +1,19 @@
|
||||
import { Outlet } from "react-router-dom";
|
||||
import { Header } from "@/layouts/Header.tsx";
|
||||
import { UpdateAvailableBanner } from "@/modules/auto-update/UpdateAvailableBanner.tsx";
|
||||
import { DebugBundleProvider } from "@/modules/debug-bundle/DebugBundleContext.tsx";
|
||||
import { ProfileProvider } from "@/modules/profile/ProfileContext.tsx";
|
||||
|
||||
export const AppLayout = () => {
|
||||
return (
|
||||
<ProfileProvider>
|
||||
<DebugBundleProvider>
|
||||
<div className={"relative flex h-full flex-col"}>
|
||||
<Header />
|
||||
<Outlet />
|
||||
<UpdateAvailableBanner />
|
||||
</div>
|
||||
</DebugBundleProvider>
|
||||
</ProfileProvider>
|
||||
);
|
||||
};
|
||||
25
client/ui/frontend/src/layouts/ConnectionStatus.tsx
Normal file
25
client/ui/frontend/src/layouts/ConnectionStatus.tsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import {
|
||||
ConnectionState,
|
||||
NetBirdConnectToggle,
|
||||
} from "@/components/NetBirdConnectToggle.tsx";
|
||||
|
||||
export const ConnectionStatus = () => {
|
||||
return (
|
||||
<div className={"flex flex-col h-full items-center justify-center"}>
|
||||
<NetBirdConnectToggle state={ConnectionState.Connected} />
|
||||
<h1
|
||||
className={
|
||||
"text-base font-medium mt-8 text-nb-gray-200 tracking-wide"
|
||||
}
|
||||
>
|
||||
Connected
|
||||
</h1>
|
||||
<p className={"font-mono text-xs text-nb-gray-300 mt-1"}>
|
||||
peer-hostname.netbird.cloud
|
||||
</p>
|
||||
<p className={"font-mono text-xs text-nb-gray-300 mt-0.5"}>
|
||||
192.168.0.1
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
31
client/ui/frontend/src/layouts/Header.tsx
Normal file
31
client/ui/frontend/src/layouts/Header.tsx
Normal file
@@ -0,0 +1,31 @@
|
||||
import { useLocation, useNavigate } from "react-router-dom";
|
||||
import { SettingsIcon } from "lucide-react";
|
||||
import { ProfileSelector } from "@/components/ProfileSelector.tsx";
|
||||
import { IconButton } from "@/components/IconButton.tsx";
|
||||
import { cn } from "@/lib/cn";
|
||||
|
||||
export const Header = () => {
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
const isSettingsPage = location.pathname.startsWith("/settings");
|
||||
|
||||
return (
|
||||
<div
|
||||
className={
|
||||
"pt-4 shrink-0 cursor-default wails-draggable flex items-center justify-end px-4 gap-3 bg-gradient-to-b from-nb-gray-800/15"
|
||||
}
|
||||
>
|
||||
<div className={"ml-20"}>
|
||||
<ProfileSelector email={"eduard@netbird.io"} />
|
||||
</div>
|
||||
<IconButton
|
||||
icon={SettingsIcon}
|
||||
onClick={() => navigate(isSettingsPage ? "/" : "/settings")}
|
||||
className={cn(
|
||||
isSettingsPage &&
|
||||
"bg-nb-gray-910 hover:bg-nb-gray-910 text-nb-gray-200 hover:text-nb-gray-200",
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
22
client/ui/frontend/src/layouts/Main.tsx
Normal file
22
client/ui/frontend/src/layouts/Main.tsx
Normal file
@@ -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 (
|
||||
<div className={"wails-draggable flex flex-1 min-h-0 p-4 gap-4"}>
|
||||
<div
|
||||
className={
|
||||
"flex flex-col max-w-xs w-full shrink-0 items-center"
|
||||
}
|
||||
>
|
||||
<ConnectionStatus />
|
||||
<Navigation peersActive />
|
||||
</div>
|
||||
<MainRightSide>
|
||||
<Peers />
|
||||
</MainRightSide>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
20
client/ui/frontend/src/layouts/MainRightSide.tsx
Normal file
20
client/ui/frontend/src/layouts/MainRightSide.tsx
Normal file
@@ -0,0 +1,20 @@
|
||||
import { ReactNode } from "react";
|
||||
import { cn } from "@/lib/cn.ts";
|
||||
|
||||
type Props = {
|
||||
children: ReactNode;
|
||||
};
|
||||
|
||||
export const MainRightSide = ({ children }: Props) => {
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"wails-no-draggable",
|
||||
"bg-nb-gray-935 border border-nb-gray-910",
|
||||
"flex-1 min-h-0 min-w-0 flex flex-col rounded-xl rounded-br-2xl overflow-hidden",
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
37
client/ui/frontend/src/layouts/Navigation.tsx
Normal file
37
client/ui/frontend/src/layouts/Navigation.tsx
Normal file
@@ -0,0 +1,37 @@
|
||||
import { CardNavItem } from "@/components/CardNavItem.tsx";
|
||||
import {
|
||||
Layers3Icon,
|
||||
MonitorSmartphoneIcon,
|
||||
SquareArrowUpRight,
|
||||
} from "lucide-react";
|
||||
|
||||
type Props = {
|
||||
peersActive?: boolean;
|
||||
onPeersClick?: () => void;
|
||||
};
|
||||
|
||||
export const Navigation = ({ peersActive = false, onPeersClick }: Props) => {
|
||||
return (
|
||||
<nav className={"w-full flex flex-col gap-1 mt-auto"}>
|
||||
<CardNavItem
|
||||
icon={MonitorSmartphoneIcon}
|
||||
title={"Peers"}
|
||||
description={"13 of 16 Online"}
|
||||
active={peersActive}
|
||||
onClick={onPeersClick}
|
||||
/>
|
||||
<CardNavItem
|
||||
icon={Layers3Icon}
|
||||
title={"Resources"}
|
||||
description={"13 of 16 Active"}
|
||||
iconSize={14}
|
||||
/>
|
||||
<CardNavItem
|
||||
icon={SquareArrowUpRight}
|
||||
title={"Exit Node Berlin"}
|
||||
description={"192.168..."}
|
||||
iconSize={14}
|
||||
/>
|
||||
</nav>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user