mirror of
https://github.com/netbirdio/netbird.git
synced 2026-08-03 03:18:56 -04:00
update dialogs, hide main window on browser login, keep state as disconnected when needslogin
This commit is contained in:
@@ -4,14 +4,17 @@ import { useSearchParams } from "react-router-dom";
|
||||
import { Events } from "@wailsio/runtime";
|
||||
import { ClockIcon } from "lucide-react";
|
||||
import { Button } from "@/components/Button";
|
||||
import {
|
||||
Connection,
|
||||
Profiles as ProfilesSvc,
|
||||
WindowManager,
|
||||
} from "@bindings/services";
|
||||
import { ConfirmDialog } from "@/components/ConfirmDialog";
|
||||
import { DialogActions } from "@/components/DialogActions";
|
||||
import { DialogDescription } from "@/components/DialogDescription";
|
||||
import { DialogHeading } from "@/components/DialogHeading";
|
||||
import { SquareIcon } from "@/components/SquareIcon";
|
||||
import { Connection, Profiles as ProfilesSvc, WindowManager } from "@bindings/services";
|
||||
import { useAutoSizeWindow } from "@/lib/useAutoSizeWindow";
|
||||
|
||||
const EVENT_TRIGGER_LOGIN = "trigger-login";
|
||||
const DEFAULT_SECONDS = 360;
|
||||
const WINDOW_WIDTH = 360;
|
||||
|
||||
function formatMMSS(seconds: number): string {
|
||||
const s = Math.max(0, seconds | 0);
|
||||
@@ -20,8 +23,9 @@ function formatMMSS(seconds: number): string {
|
||||
return `${String(m).padStart(2, "0")}:${String(r).padStart(2, "0")}`;
|
||||
}
|
||||
|
||||
export default function SessionAboutToExpire() {
|
||||
export default function SessionAboutToExpireDialog() {
|
||||
const { t } = useTranslation();
|
||||
const contentRef = useAutoSizeWindow<HTMLDivElement>(WINDOW_WIDTH);
|
||||
const [params] = useSearchParams();
|
||||
const initialSeconds = useMemo(() => {
|
||||
const raw = params.get("seconds");
|
||||
@@ -66,53 +70,48 @@ export default function SessionAboutToExpire() {
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={
|
||||
"h-screen w-full flex flex-col items-center justify-center text-center px-6 py-8 bg-nb-gray-950"
|
||||
}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
"h-12 w-12 rounded-full flex items-center justify-center bg-nb-gray-900 text-netbird mb-4"
|
||||
}
|
||||
>
|
||||
<ClockIcon size={22} />
|
||||
<ConfirmDialog ref={contentRef}>
|
||||
<SquareIcon icon={ClockIcon} className={"mt-4"} />
|
||||
|
||||
<div className={"flex flex-col items-center gap-1"}>
|
||||
<DialogHeading>
|
||||
{expired
|
||||
? t("sessionAboutToExpire.expired")
|
||||
: t("sessionAboutToExpire.title")}
|
||||
</DialogHeading>
|
||||
<DialogDescription>
|
||||
{t("sessionAboutToExpire.description")}
|
||||
</DialogDescription>
|
||||
</div>
|
||||
<h1 className={"text-base font-semibold text-nb-gray-100"}>
|
||||
{expired
|
||||
? t("sessionAboutToExpire.expired")
|
||||
: t("sessionAboutToExpire.title")}
|
||||
</h1>
|
||||
<p className={"text-xs text-nb-gray-400 mt-1.5 max-w-[20rem] leading-snug"}>
|
||||
{t("sessionAboutToExpire.description")}
|
||||
</p>
|
||||
|
||||
<div
|
||||
className={
|
||||
"mt-5 font-mono text-3xl tabular-nums text-nb-gray-100 tracking-wider"
|
||||
"font-mono font-semibold text-2xl tabular-nums text-nb-gray-50 tracking-wider"
|
||||
}
|
||||
aria-live={"polite"}
|
||||
>
|
||||
{formatMMSS(remaining)}
|
||||
</div>
|
||||
<div className={"flex gap-2 mt-5 w-full max-w-[18rem]"}>
|
||||
<Button
|
||||
variant={"secondary"}
|
||||
size={"xs"}
|
||||
className={"flex-1"}
|
||||
onClick={logout}
|
||||
>
|
||||
{t("sessionAboutToExpire.logout")}
|
||||
</Button>
|
||||
|
||||
<DialogActions>
|
||||
<Button
|
||||
variant={"primary"}
|
||||
size={"xs"}
|
||||
className={"flex-1"}
|
||||
size={"md"}
|
||||
className={"w-full"}
|
||||
onClick={stay}
|
||||
disabled={expired}
|
||||
>
|
||||
{t("sessionAboutToExpire.stay")}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<Button
|
||||
variant={"secondary"}
|
||||
size={"md"}
|
||||
className={"w-full"}
|
||||
onClick={logout}
|
||||
>
|
||||
{t("sessionAboutToExpire.logout")}
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</ConfirmDialog>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
import { useCallback } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Events } from "@wailsio/runtime";
|
||||
import { AlertCircleIcon } from "lucide-react";
|
||||
import { Button } from "@/components/Button";
|
||||
import { ConfirmDialog } from "@/components/ConfirmDialog";
|
||||
import { DialogActions } from "@/components/DialogActions";
|
||||
import { DialogDescription } from "@/components/DialogDescription";
|
||||
import { DialogHeading } from "@/components/DialogHeading";
|
||||
import { SquareIcon } from "@/components/SquareIcon";
|
||||
import { WindowManager } from "@bindings/services";
|
||||
import { useAutoSizeWindow } from "@/lib/useAutoSizeWindow";
|
||||
|
||||
const EVENT_TRIGGER_LOGIN = "trigger-login";
|
||||
const WINDOW_WIDTH = 360;
|
||||
|
||||
export default function SessionExpiredDialog() {
|
||||
const { t } = useTranslation();
|
||||
const contentRef = useAutoSizeWindow<HTMLDivElement>(WINDOW_WIDTH);
|
||||
|
||||
const signIn = useCallback(() => {
|
||||
void Events.Emit(EVENT_TRIGGER_LOGIN);
|
||||
WindowManager.CloseSessionExpired().catch(console.error);
|
||||
}, []);
|
||||
|
||||
const later = useCallback(() => {
|
||||
WindowManager.CloseSessionExpired().catch(console.error);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<ConfirmDialog ref={contentRef}>
|
||||
<SquareIcon icon={AlertCircleIcon} className={"mt-4"} />
|
||||
|
||||
<div className={"flex flex-col items-center gap-1"}>
|
||||
<DialogHeading>{t("sessionExpired.title")}</DialogHeading>
|
||||
<DialogDescription>{t("sessionExpired.description")}</DialogDescription>
|
||||
</div>
|
||||
|
||||
<DialogActions>
|
||||
<Button variant={"primary"} size={"md"} className={"w-full"} onClick={signIn}>
|
||||
{t("sessionExpired.signIn")}
|
||||
</Button>
|
||||
<Button variant={"secondary"} size={"md"} className={"w-full"} onClick={later}>
|
||||
{t("sessionExpired.later")}
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</ConfirmDialog>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
import { useCallback } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useSearchParams } from "react-router-dom";
|
||||
import { Events } from "@wailsio/runtime";
|
||||
import { Loader2 } from "lucide-react";
|
||||
import { Connection } from "@bindings/services";
|
||||
import { Button } from "@/components/Button";
|
||||
import { ConfirmDialog } from "@/components/ConfirmDialog";
|
||||
import { DialogActions } from "@/components/DialogActions";
|
||||
import { DialogDescription } from "@/components/DialogDescription";
|
||||
import { DialogHeading } from "@/components/DialogHeading";
|
||||
import { SquareIcon } from "@/components/SquareIcon";
|
||||
import { useAutoSizeWindow } from "@/lib/useAutoSizeWindow";
|
||||
|
||||
const EVENT_CANCEL = "browser-login:cancel";
|
||||
const WINDOW_WIDTH = 360;
|
||||
|
||||
export default function WaitingForBrowserDialog() {
|
||||
const { t } = useTranslation();
|
||||
const [params] = useSearchParams();
|
||||
const uri = params.get("uri") ?? "";
|
||||
const contentRef = useAutoSizeWindow<HTMLDivElement>(WINDOW_WIDTH);
|
||||
|
||||
const tryAgain = useCallback(() => {
|
||||
if (!uri) return;
|
||||
Connection.OpenURL(uri).catch(console.error);
|
||||
}, [uri]);
|
||||
|
||||
const cancel = useCallback(() => {
|
||||
void Events.Emit(EVENT_CANCEL);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<ConfirmDialog ref={contentRef}>
|
||||
<SquareIcon
|
||||
icon={Loader2}
|
||||
className={"mt-4 [&_svg]:animate-spin"}
|
||||
/>
|
||||
|
||||
<div className={"flex flex-col items-center gap-2"}>
|
||||
<DialogHeading className={"text-balance"}>
|
||||
{t("browserLogin.title")}
|
||||
</DialogHeading>
|
||||
<DialogDescription>
|
||||
{t("browserLogin.notSeeing")}{" "}
|
||||
<button
|
||||
type={"button"}
|
||||
onClick={tryAgain}
|
||||
disabled={!uri}
|
||||
className={
|
||||
"wails-no-draggable text-netbird hover:underline disabled:opacity-40 disabled:cursor-not-allowed"
|
||||
}
|
||||
>
|
||||
{t("browserLogin.tryAgain")}
|
||||
</button>
|
||||
</DialogDescription>
|
||||
</div>
|
||||
|
||||
<DialogActions>
|
||||
<Button
|
||||
variant={"secondary"}
|
||||
size={"md"}
|
||||
className={"w-full"}
|
||||
onClick={cancel}
|
||||
>
|
||||
{t("common.cancel")}
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</ConfirmDialog>
|
||||
);
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
import { useCallback } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Events } from "@wailsio/runtime";
|
||||
import { ShieldAlertIcon } from "lucide-react";
|
||||
import { Button } from "@/components/Button";
|
||||
import { WindowManager } from "@bindings/services";
|
||||
|
||||
const EVENT_TRIGGER_LOGIN = "trigger-login";
|
||||
|
||||
export default function SessionExpired() {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const signIn = useCallback(() => {
|
||||
void Events.Emit(EVENT_TRIGGER_LOGIN);
|
||||
WindowManager.CloseSessionExpired().catch(console.error);
|
||||
}, []);
|
||||
|
||||
const later = useCallback(() => {
|
||||
WindowManager.CloseSessionExpired().catch(console.error);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={
|
||||
"h-screen w-full flex flex-col items-center justify-center text-center px-6 py-8 bg-nb-gray-950"
|
||||
}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
"h-12 w-12 rounded-full flex items-center justify-center bg-nb-gray-900 text-netbird mb-4"
|
||||
}
|
||||
>
|
||||
<ShieldAlertIcon size={22} />
|
||||
</div>
|
||||
<h1 className={"text-base font-semibold text-nb-gray-100"}>
|
||||
{t("sessionExpired.title")}
|
||||
</h1>
|
||||
<p className={"text-xs text-nb-gray-400 mt-1.5 max-w-[20rem] leading-snug"}>
|
||||
{t("sessionExpired.description")}
|
||||
</p>
|
||||
<div className={"flex gap-2 mt-5 w-full max-w-[18rem]"}>
|
||||
<Button
|
||||
variant={"secondary"}
|
||||
size={"xs"}
|
||||
className={"flex-1"}
|
||||
onClick={later}
|
||||
>
|
||||
{t("sessionExpired.later")}
|
||||
</Button>
|
||||
<Button
|
||||
variant={"primary"}
|
||||
size={"xs"}
|
||||
className={"flex-1"}
|
||||
onClick={signIn}
|
||||
>
|
||||
{t("sessionExpired.signIn")}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user