mirror of
https://github.com/netbirdio/netbird.git
synced 2026-10-27 06:49:07 +01:00
update profile ui
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
import { useState } from "react";
|
||||
import { Outlet } from "react-router-dom";
|
||||
import { Header } from "@/layouts/Header.tsx";
|
||||
import { ClientVersionProvider } from "@/modules/auto-update/ClientVersionContext.tsx";
|
||||
@@ -6,22 +5,15 @@ import { StatusProvider } from "@/modules/daemon-status/StatusContext.tsx";
|
||||
import { DebugBundleProvider } from "@/modules/debug-bundle/DebugBundleContext.tsx";
|
||||
import { ProfileProvider } from "@/modules/profile/ProfileContext.tsx";
|
||||
|
||||
// The wide-panel toggle lives in plain React state here so every launch
|
||||
// starts in the small layout — no localStorage, no cross-machine drift.
|
||||
// Header drives the toggle; Main reads it via Outlet context to decide
|
||||
// whether to mount the right-side panel.
|
||||
export type MainOutletContext = { expanded: boolean };
|
||||
|
||||
export const AppLayout = () => {
|
||||
const [expanded, setExpanded] = useState(false);
|
||||
return (
|
||||
<div className={"relative flex h-full flex-col"}>
|
||||
<StatusProvider>
|
||||
<ProfileProvider>
|
||||
<DebugBundleProvider>
|
||||
<ClientVersionProvider>
|
||||
<Header expanded={expanded} setExpanded={setExpanded} />
|
||||
<Outlet context={{ expanded } satisfies MainOutletContext} />
|
||||
<Header />
|
||||
<Outlet />
|
||||
</ClientVersionProvider>
|
||||
</DebugBundleProvider>
|
||||
</ProfileProvider>
|
||||
|
||||
@@ -1,54 +1,10 @@
|
||||
import { useEffect, useRef } from "react";
|
||||
import { PanelRightCloseIcon, PanelRightOpenIcon, SettingsIcon } from "lucide-react";
|
||||
import { Window } from "@wailsio/runtime";
|
||||
import { SettingsIcon } from "lucide-react";
|
||||
import { WindowManager } from "@bindings/services";
|
||||
import { ProfileSelector } from "@/components/ProfileSelector.tsx";
|
||||
import { IconButton } from "@/components/IconButton.tsx";
|
||||
import { IconButton } from "@/components/IconButton";
|
||||
import { ProfileDropdown } from "@/components/ProfileDropdown";
|
||||
import { cn } from "@/lib/cn";
|
||||
|
||||
const WINDOW_SMALL_WIDTH = 380;
|
||||
const WINDOW_BIG_WIDTH = 925;
|
||||
const WINDOW_HEIGHT = 615;
|
||||
const EXPANDED_THRESHOLD = 500;
|
||||
|
||||
type HeaderProps = {
|
||||
expanded: boolean;
|
||||
setExpanded: (next: boolean) => void;
|
||||
};
|
||||
|
||||
export const Header = ({ expanded, setExpanded }: HeaderProps) => {
|
||||
const didInitialResize = useRef(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (didInitialResize.current) return;
|
||||
didInitialResize.current = true;
|
||||
const w = expanded ? WINDOW_BIG_WIDTH : WINDOW_SMALL_WIDTH;
|
||||
void Window.SetSize(w, WINDOW_HEIGHT).catch(() => {});
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!didInitialResize.current) return;
|
||||
const w = expanded ? WINDOW_BIG_WIDTH : WINDOW_SMALL_WIDTH;
|
||||
void Window.SetSize(w, WINDOW_HEIGHT).catch(() => {});
|
||||
}, [expanded]);
|
||||
|
||||
useEffect(() => {
|
||||
const onResize = () => {
|
||||
const isWide = window.innerWidth >= EXPANDED_THRESHOLD;
|
||||
if (isWide !== expanded) setExpanded(isWide);
|
||||
};
|
||||
window.addEventListener("resize", onResize);
|
||||
return () => window.removeEventListener("resize", onResize);
|
||||
}, [expanded, setExpanded]);
|
||||
|
||||
const togglePanel = () => {
|
||||
const next = !expanded;
|
||||
setExpanded(next);
|
||||
const w = next ? WINDOW_BIG_WIDTH : WINDOW_SMALL_WIDTH;
|
||||
void Window.SetSize(w, WINDOW_HEIGHT).catch(() => {});
|
||||
};
|
||||
|
||||
export const Header = () => {
|
||||
const openSettings = () => {
|
||||
void WindowManager.OpenSettings().catch(() => {});
|
||||
};
|
||||
@@ -56,19 +12,23 @@ export const Header = ({ expanded, setExpanded }: HeaderProps) => {
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"shrink-0 cursor-default wails-draggable flex items-center justify-end px-4 gap-3 bg-gradient-to-b from-nb-gray-800/15",
|
||||
"pt-4",
|
||||
"shrink-0 cursor-default wails-draggable grid grid-cols-3 items-center",
|
||||
//"bg-gradient-to-b from-nb-gray-850/30",
|
||||
//"bg-nb-gray-935 border border-b border-nb-gray-850",
|
||||
"py-3 px-3",
|
||||
)}
|
||||
>
|
||||
<div className={"ml-20"}>
|
||||
<ProfileSelector />
|
||||
<div />
|
||||
<div className={"flex justify-center ml-3"}>
|
||||
<ProfileDropdown />
|
||||
</div>
|
||||
<div className={"flex justify-end"}>
|
||||
<IconButton
|
||||
icon={SettingsIcon}
|
||||
iconClassName={"text-nb-gray-200"}
|
||||
onClick={openSettings}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<IconButton
|
||||
icon={expanded ? PanelRightOpenIcon : PanelRightCloseIcon}
|
||||
onClick={togglePanel}
|
||||
/>
|
||||
<IconButton icon={SettingsIcon} onClick={openSettings} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,29 +1,11 @@
|
||||
import { useOutletContext } from "react-router-dom";
|
||||
import { ConnectionStatusSwitch } from "@/layouts/ConnectionStatusSwitch.tsx";
|
||||
import { MainRightSide } from "@/layouts/MainRightSide.tsx";
|
||||
import { Navigation } from "@/layouts/Navigation.tsx";
|
||||
import { Peers } from "@/modules/peers/Peers.tsx";
|
||||
import type { MainOutletContext } from "@/layouts/AppLayout.tsx";
|
||||
import { cn } from "@/lib/cn";
|
||||
|
||||
export const Main = () => {
|
||||
const { expanded } = useOutletContext<MainOutletContext>();
|
||||
return (
|
||||
<div className={"wails-draggable flex flex-1 min-h-0 p-4 gap-4"}>
|
||||
<div
|
||||
className={cn(
|
||||
"flex flex-col w-full shrink-0 items-center",
|
||||
expanded && "max-w-xs",
|
||||
)}
|
||||
>
|
||||
<div className={"flex flex-col w-full shrink-0 items-center"}>
|
||||
<ConnectionStatusSwitch />
|
||||
<Navigation peersActive />
|
||||
</div>
|
||||
{expanded && (
|
||||
<MainRightSide>
|
||||
<Peers />
|
||||
</MainRightSide>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user