diff --git a/client/web/src/components/app.tsx b/client/web/src/components/app.tsx
index b90f993b7..03fe4cd95 100644
--- a/client/web/src/components/app.tsx
+++ b/client/web/src/components/app.tsx
@@ -3,7 +3,7 @@ import React, { useEffect } from "react"
import LoginToggle from "src/components/login-toggle"
import DeviceDetailsView from "src/components/views/device-details-view"
import HomeView from "src/components/views/home-view"
-import LoginClientView from "src/components/views/login-client-view"
+import LoginView from "src/components/views/login-view"
import SSHView from "src/components/views/ssh-view"
import { UpdatingView } from "src/components/views/updating-view"
import useAuth, { AuthResponse } from "src/hooks/auth"
@@ -39,12 +39,11 @@ function WebClient({
return !data ? (
Loading...
- ) : data.Status === "NeedsLogin" || data.Status === "NoState" ? (
+ ) : data.Status === "NeedsLogin" ||
+ data.Status === "NoState" ||
+ data.Status === "Stopped" ? (
// Client not on a tailnet, render login.
- updateNode({ Reauthenticate: true })}
- />
+
) : (
// Otherwise render the new web client.
<>
diff --git a/client/web/src/components/views/login-client-view.tsx b/client/web/src/components/views/login-view.tsx
similarity index 53%
rename from client/web/src/components/views/login-client-view.tsx
rename to client/web/src/components/views/login-view.tsx
index 9133a6715..62a188691 100644
--- a/client/web/src/components/views/login-client-view.tsx
+++ b/client/web/src/components/views/login-view.tsx
@@ -1,22 +1,45 @@
-import React from "react"
+import React, { useCallback } from "react"
+import { apiFetch } from "src/api"
import { NodeData } from "src/hooks/node-data"
import { ReactComponent as TailscaleIcon } from "src/icons/tailscale-icon.svg"
/**
- * LoginClientView is rendered when the client is not authenticated
+ * LoginView is rendered when the client is not authenticated
* to a tailnet.
*/
-export default function LoginClientView({
+export default function LoginView({
data,
- onLoginClick,
+ refreshData,
}: {
data: NodeData
- onLoginClick: () => void
+ refreshData: () => void
}) {
+ const login = useCallback(
+ (opt: TailscaleUpOptions) => {
+ tailscaleUp(opt).then(refreshData)
+ },
+ [refreshData]
+ )
+
return (
- {data.IP ? (
+ {data.Status == "Stopped" ? (
+ <>
+
+
Connect
+
+ Your device is disconnected from Tailscale.
+
+
+
+ >
+ ) : data.IP ? (
<>
@@ -33,7 +56,7 @@ export default function LoginClientView({