import { type LoaderFunctionArgs } from '@remix-run/node' import { Link, useLoaderData } from '@remix-run/react' import Attribute from '~/components/Attribute' import Card from '~/components/Card' import StatusCircle from '~/components/StatusCircle' import { type Machine, Route } from '~/types' import { cn } from '~/utils/cn' import { loadContext } from '~/utils/config/headplane' import { loadConfig } from '~/utils/config/headscale' import { pull } from '~/utils/headscale' import { getSession } from '~/utils/sessions' import { useLiveData } from '~/utils/useLiveData' import MenuOptions from './_data.machines._index/menu' export async function loader({ request, params }: LoaderFunctionArgs) { const session = await getSession(request.headers.get('Cookie')) if (!params.id) { throw new Error('No machine ID provided') } const context = await loadContext() let magic: string | undefined if (context.config.read) { const config = await loadConfig() if (config.dns_config.magic_dns) { magic = config.dns_config.base_domain } } const [machine, routes] = await Promise.all([ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion pull<{ node: Machine }>(`v1/node/${params.id}`, session.get('hsApiKey')!), // eslint-disable-next-line @typescript-eslint/no-non-null-assertion pull<{ routes: Route[] }>('v1/routes', session.get('hsApiKey')!), ]) return { machine: machine.node, routes: routes.routes.filter(route => route.node.id === params.id), magic, } } export default function Page() { const { machine, magic, routes } = useLoaderData() useLiveData({ interval: 1000 }) const expired = machine.expiry === '0001-01-01 00:00:00' || machine.expiry === '0001-01-01T00:00:00Z' ? false : new Date(machine.expiry).getTime() < Date.now() const tags = [ ...machine.forcedTags, ...machine.validTags, ] if (expired) { tags.unshift('Expired') } return (

All Machines / {machine.givenName}

{machine.givenName}

{tags.map(tag => ( {tag} ))}

Machine Details

Machine Routes

{routes.length === 0 ? (

No routes are advertised on this machine.

) : routes.map((route, i) => (

{route.prefix}

{' '} (Created: {' '} {new Date(route.createdAt).toLocaleString()} )

{route.enabled ? 'Enabled' : 'Disabled'}

{route.isPrimary ? 'Primary' : 'Secondary'}

))}
) }