import { ExclamationTriangleIcon, QuestionMarkCircleIcon } from '@heroicons/react/24/outline' import type { LinksFunction, MetaFunction } from '@remix-run/node' import { isRouteErrorResponse, Links, Meta, Outlet, Scripts, ScrollRestoration, useRouteError } from '@remix-run/react' import clsx from 'clsx' import Toaster from '~/components/Toaster' import stylesheet from '~/tailwind.css?url' export const meta: MetaFunction = () => [ { title: 'Headplane' }, { name: 'description', content: 'A frontend for the headscale coordination server' } ] export const links: LinksFunction = () => [ { rel: 'stylesheet', href: stylesheet } ] export function loader() { if (!process.env.HEADSCALE_URL) { throw new Error('The HEADSCALE_URL environment variable is required') } if (!process.env.COOKIE_SECRET) { throw new Error('The COOKIE_SECRET environment variable is required') } if (!process.env.API_KEY) { throw new Error('The API_KEY environment variable is required') } // eslint-disable-next-line unicorn/no-null return null } export function Layout({ children }: { readonly children: React.ReactNode }) { return ( {children} ) } export function ErrorBoundary() { const error = useRouteError() const routing = isRouteErrorResponse(error) const message = (error instanceof Error ? error.message : 'An unexpected error occurred') return (
{routing ? ( <>

{error.status}

{error.statusText}

) : ( <>

Error

{message}

If you are the administrator of this site, please check your logs for information.

)}
) } export default function App() { return }