Skip to content

Commit 57e71a3

Browse files
committed
Add option to install netbird after creating a setup key
1 parent 2b7b587 commit 57e71a3

File tree

6 files changed

+191
-72
lines changed

6 files changed

+191
-72
lines changed

src/modules/setup-keys/SetupKeyModal.tsx

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import { cn } from "@utils/helpers";
2323
import { trim } from "lodash";
2424
import {
2525
AlarmClock,
26-
CopyIcon,
26+
DownloadIcon,
2727
ExternalLinkIcon,
2828
MonitorSmartphoneIcon,
2929
PlusCircle,
@@ -35,6 +35,7 @@ import SetupKeysIcon from "@/assets/icons/SetupKeysIcon";
3535
import useCopyToClipboard from "@/hooks/useCopyToClipboard";
3636
import { SetupKey } from "@/interfaces/SetupKey";
3737
import useGroupHelper from "@/modules/groups/useGroupHelper";
38+
import SetupModal from "@/modules/setup-netbird-modal/SetupModal";
3839

3940
type Props = {
4041
children?: React.ReactNode;
@@ -49,6 +50,7 @@ export default function SetupKeyModal({
4950
}: Readonly<Props>) {
5051
const [successModal, setSuccessModal] = useState(false);
5152
const [setupKey, setSetupKey] = useState<SetupKey>();
53+
const [installModal, setInstallModal] = useState(false);
5254
const [, copy] = useCopyToClipboard(setupKey?.key);
5355

5456
const handleSuccess = (setupKey: SetupKey) => {
@@ -62,6 +64,15 @@ export default function SetupKeyModal({
6264
{children && <ModalTrigger asChild>{children}</ModalTrigger>}
6365
<SetupKeyModalContent onSuccess={handleSuccess} />
6466
</Modal>
67+
68+
<Modal
69+
open={installModal}
70+
onOpenChange={setInstallModal}
71+
key={installModal ? 1 : 0}
72+
>
73+
<SetupModal showClose={true} setupKey={setupKey?.key} />
74+
</Modal>
75+
6576
<Modal
6677
open={successModal}
6778
onOpenChange={(open) => {
@@ -118,10 +129,10 @@ export default function SetupKeyModal({
118129
variant={"primary"}
119130
className={"w-full"}
120131
data-cy={"setup-key-copy"}
121-
onClick={() => copy(copyMessage)}
132+
onClick={() => setInstallModal(true)}
122133
>
123-
<CopyIcon size={14} />
124-
Copy to clipboard
134+
<DownloadIcon size={14} />
135+
Install NetBird
125136
</Button>
126137
</div>
127138
</ModalFooter>

src/modules/setup-netbird-modal/DockerTab.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@ import Link from "next/link";
1010
import React from "react";
1111
import { OperatingSystem } from "@/interfaces/OperatingSystem";
1212

13-
export default function DockerTab() {
13+
type Props = {
14+
setupKey?: string;
15+
};
16+
17+
export default function DockerTab({ setupKey }: Readonly<Props>) {
1418
return (
1519
<TabsContent value={String(OperatingSystem.DOCKER)}>
1620
<TabsContentPadding>
@@ -42,7 +46,10 @@ export default function DockerTab() {
4246
<Code.Line>
4347
{" "}
4448
-e NB_SETUP_KEY=
45-
<span className={"text-netbird"}>SETUP_KEY</span> \
49+
<span className={"text-netbird"}>
50+
{setupKey ?? "SETUP_KEY"}
51+
</span>{" "}
52+
\
4653
</Code.Line>
4754
<Code.Line> -v netbird-client:/etc/netbird \</Code.Line>
4855
{GRPC_API_ORIGIN && (

src/modules/setup-netbird-modal/LinuxTab.tsx

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,13 @@ import { getNetBirdUpCommand } from "@utils/netbird";
1313
import { TerminalSquareIcon } from "lucide-react";
1414
import React from "react";
1515
import { OperatingSystem } from "@/interfaces/OperatingSystem";
16+
import { SetupKeyParameter } from "@/modules/setup-netbird-modal/SetupModal";
1617

17-
export default function LinuxTab() {
18+
type Props = {
19+
setupKey?: string;
20+
};
21+
22+
export default function LinuxTab({ setupKey }: Readonly<Props>) {
1823
return (
1924
<TabsContent value={String(OperatingSystem.LINUX)}>
2025
<TabsContentPadding>
@@ -27,9 +32,12 @@ export default function LinuxTab() {
2732
<Code>curl -fsSL https://pkgs.netbird.io/install.sh | sh</Code>
2833
</Steps.Step>
2934
<Steps.Step step={2} line={false}>
30-
<p>Run NetBird and log in the browser</p>
35+
<p>Run NetBird {!setupKey && "and log in the browser"}</p>
3136
<Code>
32-
<Code.Line>{getNetBirdUpCommand()}</Code.Line>
37+
<Code.Line>
38+
{getNetBirdUpCommand()}
39+
<SetupKeyParameter setupKey={setupKey} />
40+
</Code.Line>
3341
</Code>
3442
</Steps.Step>
3543
</Steps>
@@ -78,9 +86,12 @@ export default function LinuxTab() {
7886
</Code>
7987
</Steps.Step>
8088
<Steps.Step step={3} line={false}>
81-
<p>Run NetBird and log in the browser</p>
89+
<p>Run NetBird {!setupKey && "and log in the browser"}</p>
8290
<Code>
83-
<Code.Line>{getNetBirdUpCommand()}</Code.Line>
91+
<Code.Line>
92+
{getNetBirdUpCommand()}
93+
<SetupKeyParameter setupKey={setupKey} />
94+
</Code.Line>
8495
</Code>
8596
</Steps.Step>
8697
</Steps>

src/modules/setup-netbird-modal/MacOSTab.tsx

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,12 @@ import {
2323
import Link from "next/link";
2424
import React from "react";
2525
import { OperatingSystem } from "@/interfaces/OperatingSystem";
26+
import { SetupKeyParameter } from "@/modules/setup-netbird-modal/SetupModal";
2627

27-
export default function MacOSTab() {
28+
type Props = {
29+
setupKey?: string;
30+
};
31+
export default function MacOSTab({ setupKey }: Readonly<Props>) {
2832
return (
2933
<TabsContent value={String(OperatingSystem.APPLE)}>
3034
<TabsContentPadding>
@@ -98,15 +102,29 @@ export default function MacOSTab() {
98102
</Steps.Step>
99103
)}
100104

101-
<Steps.Step step={GRPC_API_ORIGIN ? 3 : 2}>
102-
<p>
103-
{/* eslint-disable-next-line react/no-unescaped-entities */}
104-
Click on "Connect" from the NetBird icon in your system tray
105-
</p>
106-
</Steps.Step>
107-
<Steps.Step step={GRPC_API_ORIGIN ? 4 : 3} line={false}>
108-
<p>Sign up using your email address</p>
109-
</Steps.Step>
105+
{setupKey ? (
106+
<Steps.Step step={GRPC_API_ORIGIN ? 3 : 2} line={false}>
107+
<p>Open Terminal and run NetBird</p>
108+
<Code>
109+
<Code.Line>
110+
{getNetBirdUpCommand()}
111+
<SetupKeyParameter setupKey={setupKey} />
112+
</Code.Line>
113+
</Code>
114+
</Steps.Step>
115+
) : (
116+
<>
117+
<Steps.Step step={GRPC_API_ORIGIN ? 3 : 2}>
118+
<p>
119+
{/* eslint-disable-next-line react/no-unescaped-entities */}
120+
Click on "Connect" from the NetBird icon in your system tray
121+
</p>
122+
</Steps.Step>
123+
<Steps.Step step={GRPC_API_ORIGIN ? 4 : 3} line={false}>
124+
<p>Sign up using your email address</p>
125+
</Steps.Step>
126+
</>
127+
)}
110128
</Steps>
111129
</TabsContentPadding>
112130
<Separator />
@@ -125,9 +143,12 @@ export default function MacOSTab() {
125143
</Code>
126144
</Steps.Step>
127145
<Steps.Step step={2} line={false}>
128-
<p>Run NetBird and log in the browser</p>
146+
<p>Run NetBird {!setupKey && "and log in the browser"}</p>
129147
<Code>
130-
<Code.Line>{getNetBirdUpCommand()}</Code.Line>
148+
<Code.Line>
149+
{getNetBirdUpCommand()}
150+
<SetupKeyParameter setupKey={setupKey} />
151+
</Code.Line>
131152
</Code>
132153
</Steps.Step>
133154
</Steps>
@@ -179,9 +200,12 @@ export default function MacOSTab() {
179200
</Code>
180201
</Steps.Step>
181202
<Steps.Step step={4} line={false}>
182-
<p>Run NetBird and log in the browser</p>
203+
<p>Run NetBird {!setupKey && "and log in the browser"}</p>
183204
<Code>
184-
<Code.Line>{getNetBirdUpCommand()}</Code.Line>
205+
<Code.Line>
206+
{getNetBirdUpCommand()}
207+
<SetupKeyParameter setupKey={setupKey} />
208+
</Code.Line>
185209
</Code>
186210
</Steps.Step>
187211
</Steps>

src/modules/setup-netbird-modal/SetupModal.tsx

Lines changed: 83 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { ModalContent, ModalFooter } from "@components/modal/Modal";
55
import Paragraph from "@components/Paragraph";
66
import SmallParagraph from "@components/SmallParagraph";
77
import { Tabs, TabsList, TabsTrigger } from "@components/Tabs";
8+
import { cn } from "@utils/helpers";
89
import { ExternalLinkIcon } from "lucide-react";
910
import { usePathname } from "next/navigation";
1011
import React from "react";
@@ -31,27 +32,36 @@ type OidcUserInfo = {
3132
type Props = {
3233
showClose?: boolean;
3334
user?: OidcUserInfo;
35+
setupKey?: string;
3436
};
3537

36-
export default function SetupModal({ showClose = true, user }: Props) {
38+
export default function SetupModal({
39+
showClose = true,
40+
user,
41+
setupKey,
42+
}: Readonly<Props>) {
3743
return (
3844
<ModalContent showClose={showClose}>
39-
<SetupModalContent user={user} />
45+
<SetupModalContent user={user} setupKey={setupKey} />
4046
</ModalContent>
4147
);
4248
}
4349

50+
type SetupModalContentProps = {
51+
user?: OidcUserInfo;
52+
header?: boolean;
53+
footer?: boolean;
54+
tabAlignment?: "center" | "start" | "end";
55+
setupKey?: string;
56+
};
57+
4458
export function SetupModalContent({
4559
user,
4660
header = true,
4761
footer = true,
4862
tabAlignment = "center",
49-
}: {
50-
user?: OidcUserInfo;
51-
header?: boolean;
52-
footer?: boolean;
53-
tabAlignment?: "center" | "start" | "end";
54-
}) {
63+
setupKey,
64+
}: Readonly<SetupModalContentProps>) {
5565
const os = useOperatingSystem();
5666
const [isFirstRun] = useLocalStorage<boolean>("netbird-first-run", true);
5767
const pathname = usePathname();
@@ -60,24 +70,33 @@ export function SetupModalContent({
6070
return (
6171
<>
6272
{header && (
63-
<div className={"text-center pb-8 pt-4 px-8"}>
64-
<h2 className={"text-3xl max-w-lg mx-auto"}>
73+
<div className={"text-center pb-5 pt-4 px-8"}>
74+
<h2
75+
className={cn(
76+
"max-w-lg mx-auto",
77+
setupKey ? "text-2xl" : "text-3xl",
78+
)}
79+
>
6580
{isFirstRun && !isInstallPage ? (
6681
<>
6782
Hello {user?.given_name || "there"}! 👋 <br />
6883
{`It's time to add your first device.`}
6984
</>
7085
) : (
71-
<>Install NetBird</>
86+
<>Install NetBird with Setup Key</>
7287
)}
7388
</h2>
74-
<Paragraph className={"max-w-xs mx-auto mt-3"}>
75-
To get started, install NetBird and log in with your email account.
89+
<Paragraph
90+
className={cn("mx-auto mt-3", setupKey ? "max-w-sm" : "max-w-xs")}
91+
>
92+
{setupKey
93+
? "To get started, install and run NetBird with your recently created setup key as a parameter."
94+
: "To get started, install NetBird and log in with your email account."}
7695
</Paragraph>
7796
</div>
7897
)}
7998

80-
<Tabs defaultValue={String(os)}>
99+
<Tabs defaultValue={String(setupKey ? OperatingSystem.LINUX : os)}>
81100
<TabsList justify={tabAlignment} className={"pt-2 px-3"}>
82101
<TabsTrigger value={String(OperatingSystem.LINUX)}>
83102
<ShellIcon
@@ -103,22 +122,28 @@ export function SetupModalContent({
103122
/>
104123
macOS
105124
</TabsTrigger>
106-
<TabsTrigger value={String(OperatingSystem.IOS)}>
107-
<IOSIcon
108-
className={
109-
"fill-nb-gray-500 group-data-[state=active]/trigger:fill-netbird transition-all"
110-
}
111-
/>
112-
iOS
113-
</TabsTrigger>
114-
<TabsTrigger value={String(OperatingSystem.ANDROID)}>
115-
<AndroidIcon
116-
className={
117-
"fill-nb-gray-500 group-data-[state=active]/trigger:fill-netbird transition-all"
118-
}
119-
/>
120-
Android
121-
</TabsTrigger>
125+
126+
{!setupKey && (
127+
<>
128+
<TabsTrigger value={String(OperatingSystem.IOS)}>
129+
<IOSIcon
130+
className={
131+
"fill-nb-gray-500 group-data-[state=active]/trigger:fill-netbird transition-all"
132+
}
133+
/>
134+
iOS
135+
</TabsTrigger>
136+
<TabsTrigger value={String(OperatingSystem.ANDROID)}>
137+
<AndroidIcon
138+
className={
139+
"fill-nb-gray-500 group-data-[state=active]/trigger:fill-netbird transition-all"
140+
}
141+
/>
142+
Android
143+
</TabsTrigger>
144+
</>
145+
)}
146+
122147
<TabsTrigger value={String(OperatingSystem.DOCKER)}>
123148
<DockerIcon
124149
className={
@@ -128,12 +153,19 @@ export function SetupModalContent({
128153
Docker
129154
</TabsTrigger>
130155
</TabsList>
131-
<LinuxTab />
132-
<WindowsTab />
133-
<MacOSTab />
134-
<AndroidTab />
135-
<IOSTab />
136-
<DockerTab />
156+
157+
<LinuxTab setupKey={setupKey} />
158+
<WindowsTab setupKey={setupKey} />
159+
<MacOSTab setupKey={setupKey} />
160+
161+
{!setupKey && (
162+
<>
163+
<AndroidTab />
164+
<IOSTab />
165+
</>
166+
)}
167+
168+
<DockerTab setupKey={setupKey} />
137169
</Tabs>
138170
{footer && (
139171
<ModalFooter variant={"setup"}>
@@ -158,3 +190,18 @@ export function SetupModalContent({
158190
</>
159191
);
160192
}
193+
194+
type SetupKeyParameterProps = {
195+
setupKey?: string;
196+
};
197+
198+
export const SetupKeyParameter = ({ setupKey }: SetupKeyParameterProps) => {
199+
return (
200+
setupKey && (
201+
<>
202+
{" "}
203+
--setup-key <span className={"text-netbird"}>{setupKey}</span>{" "}
204+
</>
205+
)
206+
);
207+
};

0 commit comments

Comments
 (0)