// Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause import React from "react" import { ReactComponent as TailscaleIcon } from "src/assets/icons/tailscale-icon.svg" 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 LoginView from "src/components/views/login-view" import SSHView from "src/components/views/ssh-view" import SubnetRouterView from "src/components/views/subnet-router-view" import { UpdatingView } from "src/components/views/updating-view" import useAuth, { AuthResponse } from "src/hooks/auth" import { Feature, featureDescription, NodeData } from "src/types" import LoadingDots from "src/ui/loading-dots" import useSWR from "swr" import { Link, Route, Router, Switch, useLocation } from "wouter" export default function App() { const { data: auth, loading: loadingAuth, newSession } = useAuth() return (
{loadingAuth || !auth ? ( ) : ( )}
) } function WebClient({ auth, newSession, }: { auth: AuthResponse newSession: () => Promise }) { const { data: node } = useSWR("/data") return !node ? ( ) : node.Status === "NeedsLogin" || node.Status === "NoState" || node.Status === "Stopped" ? ( // Client not on a tailnet, render login. ) : ( // Otherwise render the new web client. <>
{/* TODO */}Share local content
Page not found
) } /** * FeatureRoute renders a Route component, * but only displays the child view if the specified feature is * available for use on this node's platform. If not available, * a not allowed view is rendered instead. */ function FeatureRoute({ path, node, feature, children, }: { path: string node: NodeData feature: Feature children: React.ReactNode }) { return ( {!node.Features[feature] ? (
{featureDescription(feature)} not available on this device.
) : ( children )}
) } function Header({ node, auth, newSession, }: { node: NodeData auth: AuthResponse newSession: () => Promise }) { const [loc] = useLocation() return ( <>
{node.DomainName}
{loc !== "/" && loc !== "/update" && ( ← Back to {node.DeviceName} )} ) } /** * LoadingView fills its container with small animated loading dots * in the center. */ export function LoadingView() { return ( ) }