<html lang="en">
<head></head>
<body>

<form id="mainForm" method="post" action="https://stackblitz.com/run" target="_self">
<input type="hidden" name="project[files][.gitignore]" value="node_modules
.DS_Store
dist
dist-ssr
*.local
">
<input type="hidden" name="project[files][README.md]" value="# TanStack Router - Kitchen Sink File-Based Example

A comprehensive file-based routing example demonstrating many TanStack Router features.

- [TanStack Router Docs](https://tanstack.com/router)

## Start a new project based on this example

To start a new project based on this example, run:

```sh
npx gitpick TanStack/router/tree/main/examples/react/kitchen-sink-file-based kitchen-sink-file-based
```

## Getting Started

Install dependencies:

```sh
pnpm install
```

Start the development server:

```sh
pnpm dev
```

## Build

Build for production:

```sh
pnpm build
```

## About This Example

This &quot;kitchen sink&quot; example with file-based routing demonstrates:

- File-based route generation
- Advanced routing patterns
- Nested routes
- Route parameters and search params
- Data loading
- Error handling
- Route guards
- Type-safe file-based routes
">
<input type="hidden" name="project[files][index.html]" value="&lt;!doctype html&gt;
&lt;html lang=&quot;en&quot;&gt;
  &lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot; /&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;
    &lt;title&gt;Vite App&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div id=&quot;app&quot;&gt;&lt;/div&gt;
    &lt;script type=&quot;module&quot; src=&quot;/src/main.tsx&quot;&gt;&lt;/script&gt;
  &lt;/body&gt;
&lt;/html&gt;
">
<input type="hidden" name="project[files][package.json]" value="{&quot;name&quot;:&quot;tanstack-router-react-example-kitchen-sink-file-based&quot;,&quot;private&quot;:true,&quot;type&quot;:&quot;module&quot;,&quot;scripts&quot;:{&quot;dev&quot;:&quot;vite --port 3000&quot;,&quot;build&quot;:&quot;vite build &amp;&amp; tsc --noEmit&quot;,&quot;preview&quot;:&quot;vite preview&quot;,&quot;start&quot;:&quot;vite&quot;},&quot;dependencies&quot;:{&quot;@tailwindcss/vite&quot;:&quot;^4.1.18&quot;,&quot;@tanstack/react-router&quot;:&quot;https://pkg.pr.new/TanStack/router/@tanstack/react-router@d7ab9056820e6849f34d639f3039559e1427038c&quot;,&quot;@tanstack/react-router-devtools&quot;:&quot;https://pkg.pr.new/TanStack/router/@tanstack/react-router-devtools@d7ab9056820e6849f34d639f3039559e1427038c&quot;,&quot;@tanstack/router-plugin&quot;:&quot;https://pkg.pr.new/TanStack/router/@tanstack/router-plugin@d7ab9056820e6849f34d639f3039559e1427038c&quot;,&quot;immer&quot;:&quot;^10.1.1&quot;,&quot;react&quot;:&quot;^19.0.0&quot;,&quot;react-dom&quot;:&quot;^19.0.0&quot;,&quot;redaxios&quot;:&quot;^0.5.1&quot;,&quot;tailwindcss&quot;:&quot;^4.1.18&quot;,&quot;zod&quot;:&quot;^3.24.2&quot;},&quot;devDependencies&quot;:{&quot;@types/react&quot;:&quot;^19.0.8&quot;,&quot;@types/react-dom&quot;:&quot;^19.0.3&quot;,&quot;@vitejs/plugin-react&quot;:&quot;^4.3.4&quot;,&quot;typescript&quot;:&quot;^5.7.2&quot;,&quot;vite&quot;:&quot;^7.3.1&quot;}}">
<input type="hidden" name="project[files][tsconfig.json]" value="{
  &quot;compilerOptions&quot;: {
    &quot;strict&quot;: true,
    &quot;esModuleInterop&quot;: true,
    &quot;jsx&quot;: &quot;react-jsx&quot;,
    &quot;target&quot;: &quot;ESNext&quot;,
    &quot;moduleResolution&quot;: &quot;Bundler&quot;,
    &quot;module&quot;: &quot;ESNext&quot;,
    &quot;lib&quot;: [&quot;DOM&quot;, &quot;DOM.Iterable&quot;, &quot;ES2022&quot;],
    &quot;skipLibCheck&quot;: true
  }
}
">
<input type="hidden" name="project[files][vite.config.js]" value="import { defineConfig } from &#39;vite&#39;
import react from &#39;@vitejs/plugin-react&#39;
import { tanstackRouter } from &#39;@tanstack/router-plugin/vite&#39;
import tailwindcss from &#39;@tailwindcss/vite&#39;

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    tailwindcss(),
    tanstackRouter({ target: &#39;react&#39;, autoCodeSplitting: true }),
    react(),
  ],
})
">
<input type="hidden" name="project[files][.vscode/settings.json]" value="{
  &quot;files.watcherExclude&quot;: {
    &quot;**/routeTree.gen.ts&quot;: true
  },
  &quot;search.exclude&quot;: {
    &quot;**/routeTree.gen.ts&quot;: true
  },
  &quot;files.readonlyInclude&quot;: {
    &quot;**/routeTree.gen.ts&quot;: true
  }
}
">
<input type="hidden" name="project[files][src/main.tsx]" value="import * as React from &#39;react&#39;
import ReactDOM from &#39;react-dom/client&#39;
import {
  ErrorComponent,
  RouterProvider,
  createRouter,
} from &#39;@tanstack/react-router&#39;
import { auth } from &#39;./utils/auth&#39;
import { Spinner } from &#39;./components/Spinner&#39;
import { routeTree } from &#39;./routeTree.gen&#39;
import { useSessionStorage } from &#39;./hooks/useSessionStorage&#39;
import &#39;./styles.css&#39;

//

const router = createRouter({
  routeTree,
  defaultPendingComponent: () =&gt; (
    &lt;div className={`p-2 text-2xl`}&gt;
      &lt;Spinner /&gt;
    &lt;/div&gt;
  ),
  defaultErrorComponent: ({ error }) =&gt; &lt;ErrorComponent error={error} /&gt;,
  context: {
    auth: undefined!, // We&#39;ll inject this when we render
  },
  defaultPreload: &#39;intent&#39;,
  scrollRestoration: true,
})

declare module &#39;@tanstack/react-router&#39; {
  interface Register {
    router: typeof router
  }
}

function App() {
  // This stuff is just to tweak our sandbox setup in real-time
  const [loaderDelay, setLoaderDelay] = useSessionStorage(&#39;loaderDelay&#39;, 500)
  const [pendingMs, setPendingMs] = useSessionStorage(&#39;pendingMs&#39;, 1000)
  const [pendingMinMs, setPendingMinMs] = useSessionStorage(&#39;pendingMinMs&#39;, 500)

  return (
    &lt;&gt;
      &lt;div className=&quot;text-xs fixed w-52 shadow-md shadow-black/20 rounded-sm bottom-2 left-2 bg-white dark:bg-gray-800 bg-opacity-75 border-b flex flex-col gap-1 flex-wrap items-left divide-y&quot;&gt;
        &lt;div className=&quot;p-2 space-y-2&quot;&gt;
          &lt;div className=&quot;flex gap-2&quot;&gt;
            &lt;button
              className=&quot;bg-blue-500 text-white rounded-sm p-1 px-2&quot;
              onClick={() =&gt; {
                setLoaderDelay(150)
              }}
            &gt;
              Fast
            &lt;/button&gt;
            &lt;button
              className=&quot;bg-blue-500 text-white rounded-sm p-1 px-2&quot;
              onClick={() =&gt; {
                setLoaderDelay(500)
              }}
            &gt;
              Fast 3G
            &lt;/button&gt;
            &lt;button
              className=&quot;bg-blue-500 text-white rounded-sm p-1 px-2&quot;
              onClick={() =&gt; {
                setLoaderDelay(2000)
              }}
            &gt;
              Slow 3G
            &lt;/button&gt;
          &lt;/div&gt;
          &lt;div&gt;
            &lt;div&gt;Loader Delay: {loaderDelay}ms&lt;/div&gt;
            &lt;input
              type=&quot;range&quot;
              min=&quot;0&quot;
              max=&quot;5000&quot;
              step=&quot;100&quot;
              value={loaderDelay}
              onChange={(e) =&gt; setLoaderDelay(e.target.valueAsNumber)}
              className=&quot;w-full&quot;
            /&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div className=&quot;p-2 space-y-2&quot;&gt;
          &lt;div className=&quot;flex gap-2&quot;&gt;
            &lt;button
              className=&quot;bg-blue-500 text-white rounded-sm p-1 px-2&quot;
              onClick={() =&gt; {
                setPendingMs(1000)
                setPendingMinMs(500)
              }}
            &gt;
              Reset to Default
            &lt;/button&gt;
          &lt;/div&gt;
          &lt;div&gt;
            &lt;div&gt;defaultPendingMs: {pendingMs}ms&lt;/div&gt;
            &lt;input
              type=&quot;range&quot;
              min=&quot;0&quot;
              max=&quot;5000&quot;
              step=&quot;100&quot;
              value={pendingMs}
              onChange={(e) =&gt; setPendingMs(e.target.valueAsNumber)}
              className=&quot;w-full&quot;
            /&gt;
          &lt;/div&gt;
          &lt;div&gt;
            &lt;div&gt;defaultPendingMinMs: {pendingMinMs}ms&lt;/div&gt;
            &lt;input
              type=&quot;range&quot;
              min=&quot;0&quot;
              max=&quot;5000&quot;
              step=&quot;100&quot;
              value={pendingMinMs}
              onChange={(e) =&gt; setPendingMinMs(e.target.valueAsNumber)}
              className=&quot;w-full&quot;
            /&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      &lt;RouterProvider
        router={router}
        defaultPreload=&quot;intent&quot;
        defaultPendingMs={pendingMs}
        defaultPendingMinMs={pendingMinMs}
        context={{
          auth,
        }}
      /&gt;
    &lt;/&gt;
  )
}

const rootElement = document.getElementById(&#39;app&#39;)!
if (!rootElement.innerHTML) {
  const root = ReactDOM.createRoot(rootElement)
  root.render(
    &lt;React.StrictMode&gt;
      &lt;App /&gt;
    &lt;/React.StrictMode&gt;,
  )
}
">
<input type="hidden" name="project[files][src/routeTree.gen.ts]" value="/* eslint-disable */

// @ts-nocheck

// noinspection JSUnusedGlobalSymbols

// This file was automatically generated by TanStack Router.
// You should NOT make any changes in this file as it will be overwritten.
// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.

// Import Routes

import { Route as rootRoute } from &#39;./routes/__root&#39;
import { Route as LoginRouteImport } from &#39;./routes/login&#39;
import { Route as PathlessLayoutRouteImport } from &#39;./routes/_pathlessLayout&#39;
import { Route as AuthRouteImport } from &#39;./routes/_auth&#39;
import { Route as DashboardRouteRouteImport } from &#39;./routes/dashboard.route&#39;
import { Route as IndexRouteImport } from &#39;./routes/index&#39;
import { Route as ExpensiveIndexRouteImport } from &#39;./routes/expensive/index&#39;
import { Route as DashboardIndexRouteImport } from &#39;./routes/dashboard.index&#39;
import { Route as PathlessLayoutRouteBRouteImport } from &#39;./routes/_pathlessLayout.route-b&#39;
import { Route as PathlessLayoutRouteARouteImport } from &#39;./routes/_pathlessLayout.route-a&#39;
import { Route as AuthProfileRouteImport } from &#39;./routes/_auth.profile&#39;
import { Route as thisFolderIsNotInTheUrlRouteGroupRouteImport } from &#39;./routes/(this-folder-is-not-in-the-url)/route-group&#39;
import { Route as DashboardUsersRouteRouteImport } from &#39;./routes/dashboard.users.route&#39;
import { Route as DashboardInvoicesRouteRouteImport } from &#39;./routes/dashboard.invoices.route&#39;
import { Route as DashboardUsersIndexRouteImport } from &#39;./routes/dashboard.users.index&#39;
import { Route as DashboardInvoicesIndexRouteImport } from &#39;./routes/dashboard.invoices.index&#39;
import { Route as DashboardUsersUserRouteImport } from &#39;./routes/dashboard.users.user&#39;
import { Route as DashboardInvoicesInvoiceIdRouteImport } from &#39;./routes/dashboard.invoices.$invoiceId&#39;

// Create/Update Routes

const LoginRoute = LoginRouteImport.update({
  id: &#39;/login&#39;,
  path: &#39;/login&#39;,
  getParentRoute: () =&gt; rootRoute,
} as any)

const PathlessLayoutRoute = PathlessLayoutRouteImport.update({
  id: &#39;/_pathlessLayout&#39;,
  getParentRoute: () =&gt; rootRoute,
} as any)

const AuthRoute = AuthRouteImport.update({
  id: &#39;/_auth&#39;,
  getParentRoute: () =&gt; rootRoute,
} as any)

const DashboardRouteRoute = DashboardRouteRouteImport.update({
  id: &#39;/dashboard&#39;,
  path: &#39;/dashboard&#39;,
  getParentRoute: () =&gt; rootRoute,
} as any)

const IndexRoute = IndexRouteImport.update({
  id: &#39;/&#39;,
  path: &#39;/&#39;,
  getParentRoute: () =&gt; rootRoute,
} as any)

const ExpensiveIndexRoute = ExpensiveIndexRouteImport.update({
  id: &#39;/expensive/&#39;,
  path: &#39;/expensive/&#39;,
  getParentRoute: () =&gt; rootRoute,
} as any)

const DashboardIndexRoute = DashboardIndexRouteImport.update({
  id: &#39;/&#39;,
  path: &#39;/&#39;,
  getParentRoute: () =&gt; DashboardRouteRoute,
} as any)

const PathlessLayoutRouteBRoute = PathlessLayoutRouteBRouteImport.update({
  id: &#39;/route-b&#39;,
  path: &#39;/route-b&#39;,
  getParentRoute: () =&gt; PathlessLayoutRoute,
} as any)

const PathlessLayoutRouteARoute = PathlessLayoutRouteARouteImport.update({
  id: &#39;/route-a&#39;,
  path: &#39;/route-a&#39;,
  getParentRoute: () =&gt; PathlessLayoutRoute,
} as any)

const AuthProfileRoute = AuthProfileRouteImport.update({
  id: &#39;/profile&#39;,
  path: &#39;/profile&#39;,
  getParentRoute: () =&gt; AuthRoute,
} as any)

const thisFolderIsNotInTheUrlRouteGroupRoute =
  thisFolderIsNotInTheUrlRouteGroupRouteImport.update({
    id: &#39;/(this-folder-is-not-in-the-url)/route-group&#39;,
    path: &#39;/route-group&#39;,
    getParentRoute: () =&gt; rootRoute,
  } as any)

const DashboardUsersRouteRoute = DashboardUsersRouteRouteImport.update({
  id: &#39;/users&#39;,
  path: &#39;/users&#39;,
  getParentRoute: () =&gt; DashboardRouteRoute,
} as any)

const DashboardInvoicesRouteRoute = DashboardInvoicesRouteRouteImport.update({
  id: &#39;/invoices&#39;,
  path: &#39;/invoices&#39;,
  getParentRoute: () =&gt; DashboardRouteRoute,
} as any)

const DashboardUsersIndexRoute = DashboardUsersIndexRouteImport.update({
  id: &#39;/&#39;,
  path: &#39;/&#39;,
  getParentRoute: () =&gt; DashboardUsersRouteRoute,
} as any)

const DashboardInvoicesIndexRoute = DashboardInvoicesIndexRouteImport.update({
  id: &#39;/&#39;,
  path: &#39;/&#39;,
  getParentRoute: () =&gt; DashboardInvoicesRouteRoute,
} as any)

const DashboardUsersUserRoute = DashboardUsersUserRouteImport.update({
  id: &#39;/user&#39;,
  path: &#39;/user&#39;,
  getParentRoute: () =&gt; DashboardUsersRouteRoute,
} as any)

const DashboardInvoicesInvoiceIdRoute =
  DashboardInvoicesInvoiceIdRouteImport.update({
    id: &#39;/$invoiceId&#39;,
    path: &#39;/$invoiceId&#39;,
    getParentRoute: () =&gt; DashboardInvoicesRouteRoute,
  } as any)

// Populate the FileRoutesByPath interface

declare module &#39;@tanstack/react-router&#39; {
  interface FileRoutesByPath {
    &#39;/&#39;: {
      id: &#39;/&#39;
      path: &#39;/&#39;
      fullPath: &#39;/&#39;
      preLoaderRoute: typeof IndexRouteImport
      parentRoute: typeof rootRoute
    }
    &#39;/dashboard&#39;: {
      id: &#39;/dashboard&#39;
      path: &#39;/dashboard&#39;
      fullPath: &#39;/dashboard&#39;
      preLoaderRoute: typeof DashboardRouteRouteImport
      parentRoute: typeof rootRoute
    }
    &#39;/_auth&#39;: {
      id: &#39;/_auth&#39;
      path: &#39;&#39;
      fullPath: &#39;&#39;
      preLoaderRoute: typeof AuthRouteImport
      parentRoute: typeof rootRoute
    }
    &#39;/_pathlessLayout&#39;: {
      id: &#39;/_pathlessLayout&#39;
      path: &#39;&#39;
      fullPath: &#39;&#39;
      preLoaderRoute: typeof PathlessLayoutRouteImport
      parentRoute: typeof rootRoute
    }
    &#39;/login&#39;: {
      id: &#39;/login&#39;
      path: &#39;/login&#39;
      fullPath: &#39;/login&#39;
      preLoaderRoute: typeof LoginRouteImport
      parentRoute: typeof rootRoute
    }
    &#39;/dashboard/invoices&#39;: {
      id: &#39;/dashboard/invoices&#39;
      path: &#39;/invoices&#39;
      fullPath: &#39;/dashboard/invoices&#39;
      preLoaderRoute: typeof DashboardInvoicesRouteRouteImport
      parentRoute: typeof DashboardRouteRouteImport
    }
    &#39;/dashboard/users&#39;: {
      id: &#39;/dashboard/users&#39;
      path: &#39;/users&#39;
      fullPath: &#39;/dashboard/users&#39;
      preLoaderRoute: typeof DashboardUsersRouteRouteImport
      parentRoute: typeof DashboardRouteRouteImport
    }
    &#39;/(this-folder-is-not-in-the-url)/route-group&#39;: {
      id: &#39;/(this-folder-is-not-in-the-url)/route-group&#39;
      path: &#39;/route-group&#39;
      fullPath: &#39;/route-group&#39;
      preLoaderRoute: typeof thisFolderIsNotInTheUrlRouteGroupRouteImport
      parentRoute: typeof rootRoute
    }
    &#39;/_auth/profile&#39;: {
      id: &#39;/_auth/profile&#39;
      path: &#39;/profile&#39;
      fullPath: &#39;/profile&#39;
      preLoaderRoute: typeof AuthProfileRouteImport
      parentRoute: typeof AuthRouteImport
    }
    &#39;/_pathlessLayout/route-a&#39;: {
      id: &#39;/_pathlessLayout/route-a&#39;
      path: &#39;/route-a&#39;
      fullPath: &#39;/route-a&#39;
      preLoaderRoute: typeof PathlessLayoutRouteARouteImport
      parentRoute: typeof PathlessLayoutRouteImport
    }
    &#39;/_pathlessLayout/route-b&#39;: {
      id: &#39;/_pathlessLayout/route-b&#39;
      path: &#39;/route-b&#39;
      fullPath: &#39;/route-b&#39;
      preLoaderRoute: typeof PathlessLayoutRouteBRouteImport
      parentRoute: typeof PathlessLayoutRouteImport
    }
    &#39;/dashboard/&#39;: {
      id: &#39;/dashboard/&#39;
      path: &#39;/&#39;
      fullPath: &#39;/dashboard/&#39;
      preLoaderRoute: typeof DashboardIndexRouteImport
      parentRoute: typeof DashboardRouteRouteImport
    }
    &#39;/expensive/&#39;: {
      id: &#39;/expensive/&#39;
      path: &#39;/expensive&#39;
      fullPath: &#39;/expensive&#39;
      preLoaderRoute: typeof ExpensiveIndexRouteImport
      parentRoute: typeof rootRoute
    }
    &#39;/dashboard/invoices/$invoiceId&#39;: {
      id: &#39;/dashboard/invoices/$invoiceId&#39;
      path: &#39;/$invoiceId&#39;
      fullPath: &#39;/dashboard/invoices/$invoiceId&#39;
      preLoaderRoute: typeof DashboardInvoicesInvoiceIdRouteImport
      parentRoute: typeof DashboardInvoicesRouteRouteImport
    }
    &#39;/dashboard/users/user&#39;: {
      id: &#39;/dashboard/users/user&#39;
      path: &#39;/user&#39;
      fullPath: &#39;/dashboard/users/user&#39;
      preLoaderRoute: typeof DashboardUsersUserRouteImport
      parentRoute: typeof DashboardUsersRouteRouteImport
    }
    &#39;/dashboard/invoices/&#39;: {
      id: &#39;/dashboard/invoices/&#39;
      path: &#39;/&#39;
      fullPath: &#39;/dashboard/invoices/&#39;
      preLoaderRoute: typeof DashboardInvoicesIndexRouteImport
      parentRoute: typeof DashboardInvoicesRouteRouteImport
    }
    &#39;/dashboard/users/&#39;: {
      id: &#39;/dashboard/users/&#39;
      path: &#39;/&#39;
      fullPath: &#39;/dashboard/users/&#39;
      preLoaderRoute: typeof DashboardUsersIndexRouteImport
      parentRoute: typeof DashboardUsersRouteRouteImport
    }
  }
}

// Create and export the route tree

interface DashboardInvoicesRouteRouteChildren {
  DashboardInvoicesInvoiceIdRoute: typeof DashboardInvoicesInvoiceIdRoute
  DashboardInvoicesIndexRoute: typeof DashboardInvoicesIndexRoute
}

const DashboardInvoicesRouteRouteChildren: DashboardInvoicesRouteRouteChildren =
  {
    DashboardInvoicesInvoiceIdRoute: DashboardInvoicesInvoiceIdRoute,
    DashboardInvoicesIndexRoute: DashboardInvoicesIndexRoute,
  }

const DashboardInvoicesRouteRouteWithChildren =
  DashboardInvoicesRouteRoute._addFileChildren(
    DashboardInvoicesRouteRouteChildren,
  )

interface DashboardUsersRouteRouteChildren {
  DashboardUsersUserRoute: typeof DashboardUsersUserRoute
  DashboardUsersIndexRoute: typeof DashboardUsersIndexRoute
}

const DashboardUsersRouteRouteChildren: DashboardUsersRouteRouteChildren = {
  DashboardUsersUserRoute: DashboardUsersUserRoute,
  DashboardUsersIndexRoute: DashboardUsersIndexRoute,
}

const DashboardUsersRouteRouteWithChildren =
  DashboardUsersRouteRoute._addFileChildren(DashboardUsersRouteRouteChildren)

interface DashboardRouteRouteChildren {
  DashboardInvoicesRouteRoute: typeof DashboardInvoicesRouteRouteWithChildren
  DashboardUsersRouteRoute: typeof DashboardUsersRouteRouteWithChildren
  DashboardIndexRoute: typeof DashboardIndexRoute
}

const DashboardRouteRouteChildren: DashboardRouteRouteChildren = {
  DashboardInvoicesRouteRoute: DashboardInvoicesRouteRouteWithChildren,
  DashboardUsersRouteRoute: DashboardUsersRouteRouteWithChildren,
  DashboardIndexRoute: DashboardIndexRoute,
}

const DashboardRouteRouteWithChildren = DashboardRouteRoute._addFileChildren(
  DashboardRouteRouteChildren,
)

interface AuthRouteChildren {
  AuthProfileRoute: typeof AuthProfileRoute
}

const AuthRouteChildren: AuthRouteChildren = {
  AuthProfileRoute: AuthProfileRoute,
}

const AuthRouteWithChildren = AuthRoute._addFileChildren(AuthRouteChildren)

interface PathlessLayoutRouteChildren {
  PathlessLayoutRouteARoute: typeof PathlessLayoutRouteARoute
  PathlessLayoutRouteBRoute: typeof PathlessLayoutRouteBRoute
}

const PathlessLayoutRouteChildren: PathlessLayoutRouteChildren = {
  PathlessLayoutRouteARoute: PathlessLayoutRouteARoute,
  PathlessLayoutRouteBRoute: PathlessLayoutRouteBRoute,
}

const PathlessLayoutRouteWithChildren = PathlessLayoutRoute._addFileChildren(
  PathlessLayoutRouteChildren,
)

export interface FileRoutesByFullPath {
  &#39;/&#39;: typeof IndexRoute
  &#39;/dashboard&#39;: typeof DashboardRouteRouteWithChildren
  &#39;&#39;: typeof PathlessLayoutRouteWithChildren
  &#39;/login&#39;: typeof LoginRoute
  &#39;/dashboard/invoices&#39;: typeof DashboardInvoicesRouteRouteWithChildren
  &#39;/dashboard/users&#39;: typeof DashboardUsersRouteRouteWithChildren
  &#39;/route-group&#39;: typeof thisFolderIsNotInTheUrlRouteGroupRoute
  &#39;/profile&#39;: typeof AuthProfileRoute
  &#39;/route-a&#39;: typeof PathlessLayoutRouteARoute
  &#39;/route-b&#39;: typeof PathlessLayoutRouteBRoute
  &#39;/dashboard/&#39;: typeof DashboardIndexRoute
  &#39;/expensive&#39;: typeof ExpensiveIndexRoute
  &#39;/dashboard/invoices/$invoiceId&#39;: typeof DashboardInvoicesInvoiceIdRoute
  &#39;/dashboard/users/user&#39;: typeof DashboardUsersUserRoute
  &#39;/dashboard/invoices/&#39;: typeof DashboardInvoicesIndexRoute
  &#39;/dashboard/users/&#39;: typeof DashboardUsersIndexRoute
}

export interface FileRoutesByTo {
  &#39;/&#39;: typeof IndexRoute
  &#39;&#39;: typeof PathlessLayoutRouteWithChildren
  &#39;/login&#39;: typeof LoginRoute
  &#39;/route-group&#39;: typeof thisFolderIsNotInTheUrlRouteGroupRoute
  &#39;/profile&#39;: typeof AuthProfileRoute
  &#39;/route-a&#39;: typeof PathlessLayoutRouteARoute
  &#39;/route-b&#39;: typeof PathlessLayoutRouteBRoute
  &#39;/dashboard&#39;: typeof DashboardIndexRoute
  &#39;/expensive&#39;: typeof ExpensiveIndexRoute
  &#39;/dashboard/invoices/$invoiceId&#39;: typeof DashboardInvoicesInvoiceIdRoute
  &#39;/dashboard/users/user&#39;: typeof DashboardUsersUserRoute
  &#39;/dashboard/invoices&#39;: typeof DashboardInvoicesIndexRoute
  &#39;/dashboard/users&#39;: typeof DashboardUsersIndexRoute
}

export interface FileRoutesById {
  __root__: typeof rootRoute
  &#39;/&#39;: typeof IndexRoute
  &#39;/dashboard&#39;: typeof DashboardRouteRouteWithChildren
  &#39;/_auth&#39;: typeof AuthRouteWithChildren
  &#39;/_pathlessLayout&#39;: typeof PathlessLayoutRouteWithChildren
  &#39;/login&#39;: typeof LoginRoute
  &#39;/dashboard/invoices&#39;: typeof DashboardInvoicesRouteRouteWithChildren
  &#39;/dashboard/users&#39;: typeof DashboardUsersRouteRouteWithChildren
  &#39;/(this-folder-is-not-in-the-url)/route-group&#39;: typeof thisFolderIsNotInTheUrlRouteGroupRoute
  &#39;/_auth/profile&#39;: typeof AuthProfileRoute
  &#39;/_pathlessLayout/route-a&#39;: typeof PathlessLayoutRouteARoute
  &#39;/_pathlessLayout/route-b&#39;: typeof PathlessLayoutRouteBRoute
  &#39;/dashboard/&#39;: typeof DashboardIndexRoute
  &#39;/expensive/&#39;: typeof ExpensiveIndexRoute
  &#39;/dashboard/invoices/$invoiceId&#39;: typeof DashboardInvoicesInvoiceIdRoute
  &#39;/dashboard/users/user&#39;: typeof DashboardUsersUserRoute
  &#39;/dashboard/invoices/&#39;: typeof DashboardInvoicesIndexRoute
  &#39;/dashboard/users/&#39;: typeof DashboardUsersIndexRoute
}

export interface FileRouteTypes {
  fileRoutesByFullPath: FileRoutesByFullPath
  fullPaths:
    | &#39;/&#39;
    | &#39;/dashboard&#39;
    | &#39;&#39;
    | &#39;/login&#39;
    | &#39;/dashboard/invoices&#39;
    | &#39;/dashboard/users&#39;
    | &#39;/route-group&#39;
    | &#39;/profile&#39;
    | &#39;/route-a&#39;
    | &#39;/route-b&#39;
    | &#39;/dashboard/&#39;
    | &#39;/expensive&#39;
    | &#39;/dashboard/invoices/$invoiceId&#39;
    | &#39;/dashboard/users/user&#39;
    | &#39;/dashboard/invoices/&#39;
    | &#39;/dashboard/users/&#39;
  fileRoutesByTo: FileRoutesByTo
  to:
    | &#39;/&#39;
    | &#39;&#39;
    | &#39;/login&#39;
    | &#39;/route-group&#39;
    | &#39;/profile&#39;
    | &#39;/route-a&#39;
    | &#39;/route-b&#39;
    | &#39;/dashboard&#39;
    | &#39;/expensive&#39;
    | &#39;/dashboard/invoices/$invoiceId&#39;
    | &#39;/dashboard/users/user&#39;
    | &#39;/dashboard/invoices&#39;
    | &#39;/dashboard/users&#39;
  id:
    | &#39;__root__&#39;
    | &#39;/&#39;
    | &#39;/dashboard&#39;
    | &#39;/_auth&#39;
    | &#39;/_pathlessLayout&#39;
    | &#39;/login&#39;
    | &#39;/dashboard/invoices&#39;
    | &#39;/dashboard/users&#39;
    | &#39;/(this-folder-is-not-in-the-url)/route-group&#39;
    | &#39;/_auth/profile&#39;
    | &#39;/_pathlessLayout/route-a&#39;
    | &#39;/_pathlessLayout/route-b&#39;
    | &#39;/dashboard/&#39;
    | &#39;/expensive/&#39;
    | &#39;/dashboard/invoices/$invoiceId&#39;
    | &#39;/dashboard/users/user&#39;
    | &#39;/dashboard/invoices/&#39;
    | &#39;/dashboard/users/&#39;
  fileRoutesById: FileRoutesById
}

export interface RootRouteChildren {
  IndexRoute: typeof IndexRoute
  DashboardRouteRoute: typeof DashboardRouteRouteWithChildren
  AuthRoute: typeof AuthRouteWithChildren
  PathlessLayoutRoute: typeof PathlessLayoutRouteWithChildren
  LoginRoute: typeof LoginRoute
  thisFolderIsNotInTheUrlRouteGroupRoute: typeof thisFolderIsNotInTheUrlRouteGroupRoute
  ExpensiveIndexRoute: typeof ExpensiveIndexRoute
}

const rootRouteChildren: RootRouteChildren = {
  IndexRoute: IndexRoute,
  DashboardRouteRoute: DashboardRouteRouteWithChildren,
  AuthRoute: AuthRouteWithChildren,
  PathlessLayoutRoute: PathlessLayoutRouteWithChildren,
  LoginRoute: LoginRoute,
  thisFolderIsNotInTheUrlRouteGroupRoute:
    thisFolderIsNotInTheUrlRouteGroupRoute,
  ExpensiveIndexRoute: ExpensiveIndexRoute,
}

export const routeTree = rootRoute
  ._addFileChildren(rootRouteChildren)
  ._addFileTypes&lt;FileRouteTypes&gt;()

/* ROUTE_MANIFEST_START
{
  &quot;routes&quot;: {
    &quot;__root__&quot;: {
      &quot;filePath&quot;: &quot;__root.tsx&quot;,
      &quot;children&quot;: [
        &quot;/&quot;,
        &quot;/dashboard&quot;,
        &quot;/_auth&quot;,
        &quot;/_pathlessLayout&quot;,
        &quot;/login&quot;,
        &quot;/(this-folder-is-not-in-the-url)/route-group&quot;,
        &quot;/expensive/&quot;
      ]
    },
    &quot;/&quot;: {
      &quot;filePath&quot;: &quot;index.tsx&quot;
    },
    &quot;/dashboard&quot;: {
      &quot;filePath&quot;: &quot;dashboard.route.tsx&quot;,
      &quot;children&quot;: [
        &quot;/dashboard/invoices&quot;,
        &quot;/dashboard/users&quot;,
        &quot;/dashboard/&quot;
      ]
    },
    &quot;/_auth&quot;: {
      &quot;filePath&quot;: &quot;_auth.tsx&quot;,
      &quot;children&quot;: [
        &quot;/_auth/profile&quot;
      ]
    },
    &quot;/_pathlessLayout&quot;: {
      &quot;filePath&quot;: &quot;_pathlessLayout.tsx&quot;,
      &quot;children&quot;: [
        &quot;/_pathlessLayout/route-a&quot;,
        &quot;/_pathlessLayout/route-b&quot;
      ]
    },
    &quot;/login&quot;: {
      &quot;filePath&quot;: &quot;login.tsx&quot;
    },
    &quot;/dashboard/invoices&quot;: {
      &quot;filePath&quot;: &quot;dashboard.invoices.route.tsx&quot;,
      &quot;parent&quot;: &quot;/dashboard&quot;,
      &quot;children&quot;: [
        &quot;/dashboard/invoices/$invoiceId&quot;,
        &quot;/dashboard/invoices/&quot;
      ]
    },
    &quot;/dashboard/users&quot;: {
      &quot;filePath&quot;: &quot;dashboard.users.route.tsx&quot;,
      &quot;parent&quot;: &quot;/dashboard&quot;,
      &quot;children&quot;: [
        &quot;/dashboard/users/user&quot;,
        &quot;/dashboard/users/&quot;
      ]
    },
    &quot;/(this-folder-is-not-in-the-url)/route-group&quot;: {
      &quot;filePath&quot;: &quot;(this-folder-is-not-in-the-url)/route-group.tsx&quot;
    },
    &quot;/_auth/profile&quot;: {
      &quot;filePath&quot;: &quot;_auth.profile.tsx&quot;,
      &quot;parent&quot;: &quot;/_auth&quot;
    },
    &quot;/_pathlessLayout/route-a&quot;: {
      &quot;filePath&quot;: &quot;_pathlessLayout.route-a.tsx&quot;,
      &quot;parent&quot;: &quot;/_pathlessLayout&quot;
    },
    &quot;/_pathlessLayout/route-b&quot;: {
      &quot;filePath&quot;: &quot;_pathlessLayout.route-b.tsx&quot;,
      &quot;parent&quot;: &quot;/_pathlessLayout&quot;
    },
    &quot;/dashboard/&quot;: {
      &quot;filePath&quot;: &quot;dashboard.index.tsx&quot;,
      &quot;parent&quot;: &quot;/dashboard&quot;
    },
    &quot;/expensive/&quot;: {
      &quot;filePath&quot;: &quot;expensive/index.tsx&quot;
    },
    &quot;/dashboard/invoices/$invoiceId&quot;: {
      &quot;filePath&quot;: &quot;dashboard.invoices.$invoiceId.tsx&quot;,
      &quot;parent&quot;: &quot;/dashboard/invoices&quot;
    },
    &quot;/dashboard/users/user&quot;: {
      &quot;filePath&quot;: &quot;dashboard.users.user.tsx&quot;,
      &quot;parent&quot;: &quot;/dashboard/users&quot;
    },
    &quot;/dashboard/invoices/&quot;: {
      &quot;filePath&quot;: &quot;dashboard.invoices.index.tsx&quot;,
      &quot;parent&quot;: &quot;/dashboard/invoices&quot;
    },
    &quot;/dashboard/users/&quot;: {
      &quot;filePath&quot;: &quot;dashboard.users.index.tsx&quot;,
      &quot;parent&quot;: &quot;/dashboard/users&quot;
    }
  }
}
ROUTE_MANIFEST_END */
">
<input type="hidden" name="project[files][src/styles.css]" value="@import &#39;tailwindcss&#39; source(&#39;../&#39;);

@layer base {
  *,
  ::after,
  ::before,
  ::backdrop,
  ::file-selector-button {
    border-color: var(--color-gray-200, currentcolor);
  }
}

html {
  color-scheme: light dark;
}
* {
  @apply border-gray-200 dark:border-gray-800;
}
body {
  @apply bg-gray-50 text-gray-950 dark:bg-gray-900 dark:text-gray-200;
}
">
<input type="hidden" name="project[files][src/components/Breadcrumbs.tsx]" value="import { isMatch, Link, useMatches } from &#39;@tanstack/react-router&#39;

export const Breadcrumbs = () =&gt; {
  const matches = useMatches()

  if (matches.some((match) =&gt; match.status === &#39;pending&#39;)) return null

  const matchesWithCrumbs = matches.filter((match) =&gt;
    isMatch(match, &#39;loaderData.crumb&#39;),
  )

  return (
    &lt;nav&gt;
      &lt;ul className=&quot;flex gap-2 items-center&quot;&gt;
        {matchesWithCrumbs.map((match, i) =&gt; (
          &lt;li className=&quot;flex gap-2&quot;&gt;
            &lt;Link className=&quot;text-blue-700&quot; from={match.fullPath}&gt;
              {match.loaderData?.crumb}
            &lt;/Link&gt;
            {i + 1 &lt; matchesWithCrumbs.length ? (
              &lt;span className=&quot;&quot;&gt;{&#39;&gt;&#39;}&lt;/span&gt;
            ) : null}
          &lt;/li&gt;
        ))}
      &lt;/ul&gt;
    &lt;/nav&gt;
  )
}
">
<input type="hidden" name="project[files][src/components/InvoiceFields.tsx]" value="/* eslint-disable @typescript-eslint/no-unnecessary-condition */
import * as React from &#39;react&#39;
import type { Invoice } from &#39;../utils/mockTodos&#39;

export function InvoiceFields({
  invoice,
  disabled,
}: {
  invoice: Invoice
  disabled?: boolean
}) {
  return (
    &lt;div className=&quot;space-y-2&quot;&gt;
      &lt;h2 className=&quot;font-bold text-lg&quot;&gt;
        &lt;input
          name=&quot;title&quot;
          defaultValue={invoice?.title}
          placeholder=&quot;Invoice Title&quot;
          className=&quot;border border-opacity-50 rounded-sm p-2 w-full&quot;
          disabled={disabled}
        /&gt;
      &lt;/h2&gt;
      &lt;div&gt;
        &lt;textarea
          name=&quot;body&quot;
          defaultValue={invoice?.body}
          rows={6}
          placeholder=&quot;Invoice Body...&quot;
          className=&quot;border border-opacity-50 p-2 rounded-sm w-full&quot;
          disabled={disabled}
        /&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  )
}
">
<input type="hidden" name="project[files][src/components/Spinner.tsx]" value="import * as React from &#39;react&#39;

export function Spinner({
  show,
  wait,
}: {
  show?: boolean
  wait?: `delay-${number}`
}) {
  return (
    &lt;div
      className={`inline-block animate-spin px-3 transition ${
        (show ?? true)
          ? `opacity-1 duration-500 ${wait ?? &#39;delay-300&#39;}`
          : &#39;duration-500 opacity-0 delay-0&#39;
      }`}
    &gt;
      ⍥
    &lt;/div&gt;
  )
}
">
<input type="hidden" name="project[files][src/hooks/useMutation.tsx]" value="import * as React from &#39;react&#39;

export function useMutation&lt;TVariables, TData, TError = Error&gt;(opts: {
  fn: (variables: TVariables) =&gt; Promise&lt;TData&gt;
  onSuccess?: (ctx: { data: TData }) =&gt; void | Promise&lt;void&gt;
}) {
  const [submittedAt, setSubmittedAt] = React.useState&lt;number | undefined&gt;()
  const [variables, setVariables] = React.useState&lt;TVariables | undefined&gt;()
  const [error, setError] = React.useState&lt;TError | undefined&gt;()
  const [data, setData] = React.useState&lt;TData | undefined&gt;()
  const [status, setStatus] = React.useState&lt;
    &#39;idle&#39; | &#39;pending&#39; | &#39;success&#39; | &#39;error&#39;
  &gt;(&#39;idle&#39;)

  const mutate = React.useCallback(
    async (variables: TVariables): Promise&lt;TData | undefined&gt; =&gt; {
      setStatus(&#39;pending&#39;)
      setSubmittedAt(Date.now())
      setVariables(variables)
      //
      try {
        const data = await opts.fn(variables)
        await opts.onSuccess?.({ data })
        setStatus(&#39;success&#39;)
        setError(undefined)
        setData(data)
        return data
      } catch (err: any) {
        setStatus(&#39;error&#39;)
        setError(err)
      }
    },
    [opts.fn],
  )

  return {
    status,
    variables,
    submittedAt,
    mutate,
    error,
    data,
  }
}
">
<input type="hidden" name="project[files][src/hooks/useSessionStorage.tsx]" value="import * as React from &#39;react&#39;

export function useSessionStorage&lt;T&gt;(key: string, initialValue: T) {
  const state = React.useState&lt;T&gt;(() =&gt; {
    const stored = sessionStorage.getItem(key)
    return stored ? JSON.parse(stored) : initialValue
  })

  React.useEffect(() =&gt; {
    sessionStorage.setItem(key, JSON.stringify(state[0]))
  }, [state[0]])

  return state
}
">
<input type="hidden" name="project[files][src/routes/__root.tsx]" value="import * as React from &#39;react&#39;
import {
  Link,
  Outlet,
  createRootRouteWithContext,
  useRouterState,
} from &#39;@tanstack/react-router&#39;
import { TanStackRouterDevtools } from &#39;@tanstack/react-router-devtools&#39;
import { Spinner } from &#39;../components/Spinner&#39;
import { Breadcrumbs } from &#39;../components/Breadcrumbs&#39;
import type { Auth } from &#39;../utils/auth&#39;

function RouterSpinner() {
  const isLoading = useRouterState({ select: (s) =&gt; s.status === &#39;pending&#39; })
  return &lt;Spinner show={isLoading} /&gt;
}

export const Route = createRootRouteWithContext&lt;{
  auth: Auth
}&gt;()({
  component: RootComponent,
})

function RootComponent() {
  return (
    &lt;&gt;
      &lt;div className={`min-h-screen flex flex-col`}&gt;
        &lt;div className={`flex items-center border-b gap-2`}&gt;
          &lt;h1 className={`text-3xl p-2`}&gt;Kitchen Sink&lt;/h1&gt;
          &lt;Breadcrumbs /&gt;
          {/* Show a global spinner when the router is transitioning */}
          &lt;div className={`text-3xl`}&gt;
            &lt;RouterSpinner /&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div className={`flex-1 flex`}&gt;
          &lt;div className={`divide-y w-56`}&gt;
            {(
              [
                [&#39;/&#39;, &#39;Home&#39;],
                [&#39;/dashboard&#39;, &#39;Dashboard&#39;],
                [&#39;/expensive&#39;, &#39;Expensive&#39;],
                [&#39;/route-a&#39;, &#39;Pathless Layout A&#39;],
                [&#39;/route-b&#39;, &#39;Pathless Layout B&#39;],
                [&#39;/profile&#39;, &#39;Profile&#39;],
                [&#39;/login&#39;, &#39;Login&#39;],
                [&#39;/route-group&#39;, &#39;Route Group&#39;],
              ] as const
            ).map(([to, label]) =&gt; {
              return (
                &lt;div key={to}&gt;
                  &lt;Link
                    to={to}
                    activeOptions={
                      {
                        // If the route points to the root of it&#39;s parent,
                        // make sure it&#39;s only active if it&#39;s exact
                        // exact: to === &#39;.&#39;,
                      }
                    }
                    preload=&quot;intent&quot;
                    className={`block py-2 px-3 text-blue-700`}
                    // Make &quot;active&quot; links bold
                    activeProps={{ className: `font-bold` }}
                  &gt;
                    {label}
                  &lt;/Link&gt;
                &lt;/div&gt;
              )
            })}
          &lt;/div&gt;
          &lt;div className={`flex-1 border-l`}&gt;
            {/* Render our first route match */}
            &lt;Outlet /&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      &lt;TanStackRouterDevtools position=&quot;bottom-right&quot; /&gt;
    &lt;/&gt;
  )
}
">
<input type="hidden" name="project[files][src/routes/_auth.profile.tsx]" value="import { createFileRoute } from &#39;@tanstack/react-router&#39;
import * as React from &#39;react&#39;

export const Route = createFileRoute(&#39;/_auth/profile&#39;)({
  component: ProfileComponent,
})

function ProfileComponent() {
  const { username } = Route.useRouteContext()

  return (
    &lt;div className=&quot;p-2 space-y-2&quot;&gt;
      &lt;div&gt;
        Username:&lt;strong&gt;{username}&lt;/strong&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  )
}
">
<input type="hidden" name="project[files][src/routes/_auth.tsx]" value="import { createFileRoute } from &#39;@tanstack/react-router&#39;
import { redirect } from &#39;@tanstack/react-router&#39;
import { auth } from &#39;../utils/auth&#39;

export const Route = createFileRoute(&#39;/_auth&#39;)({
  // Before loading, authenticate the user via our auth context
  // This will also happen during prefetching (e.g. hovering over links, etc)
  beforeLoad: ({ context, location }) =&gt; {
    // If the user is logged out, redirect them to the login page
    if (context.auth.status === &#39;loggedOut&#39;) {
      throw redirect({
        to: &#39;/login&#39;,
        search: {
          // Use the current location to power a redirect after login
          // (Do not use `router.state.resolvedLocation` as it can
          // potentially lag behind the actual current location)
          redirect: location.href,
        },
      })
    }

    // Otherwise, return the user in context
    return {
      username: auth.username,
    }
  },
})
">
<input type="hidden" name="project[files][src/routes/_pathlessLayout.route-a.tsx]" value="import { createFileRoute } from &#39;@tanstack/react-router&#39;
import * as React from &#39;react&#39;

export const Route = createFileRoute(&#39;/_pathlessLayout/route-a&#39;)({
  component: LayoutAComponent,
})

function LayoutAComponent() {
  return &lt;div&gt;I&#39;m A!&lt;/div&gt;
}
">
<input type="hidden" name="project[files][src/routes/_pathlessLayout.route-b.tsx]" value="import { createFileRoute } from &#39;@tanstack/react-router&#39;
import * as React from &#39;react&#39;

export const Route = createFileRoute(&#39;/_pathlessLayout/route-b&#39;)({
  component: LayoutBComponent,
})

function LayoutBComponent() {
  return &lt;div&gt;I&#39;m B!&lt;/div&gt;
}
">
<input type="hidden" name="project[files][src/routes/_pathlessLayout.tsx]" value="import { createFileRoute } from &#39;@tanstack/react-router&#39;
import * as React from &#39;react&#39;
import { Outlet } from &#39;@tanstack/react-router&#39;

export const Route = createFileRoute(&#39;/_pathlessLayout&#39;)({
  component: PathlessLayoutComponent,
})

function PathlessLayoutComponent() {
  return (
    &lt;div&gt;
      &lt;div&gt;Pathless Layout&lt;/div&gt;
      &lt;hr /&gt;
      &lt;Outlet /&gt;
    &lt;/div&gt;
  )
}
">
<input type="hidden" name="project[files][src/routes/dashboard.index.tsx]" value="import { createFileRoute } from &#39;@tanstack/react-router&#39;
import * as React from &#39;react&#39;

import { fetchInvoices } from &#39;../utils/mockTodos&#39;

export const Route = createFileRoute(&#39;/dashboard/&#39;)({
  loader: () =&gt; fetchInvoices(),
  component: DashboardIndexComponent,
})

function DashboardIndexComponent() {
  const invoices = Route.useLoaderData()

  return (
    &lt;div className=&quot;p-2&quot;&gt;
      &lt;div className=&quot;p-2&quot;&gt;
        Welcome to the dashboard! You have{&#39; &#39;}
        &lt;strong&gt;{invoices.length} total invoices&lt;/strong&gt;.
      &lt;/div&gt;
    &lt;/div&gt;
  )
}
">
<input type="hidden" name="project[files][src/routes/dashboard.invoices.$invoiceId.tsx]" value="import { createFileRoute } from &#39;@tanstack/react-router&#39;
import * as React from &#39;react&#39;
import { Link, useNavigate, useRouter } from &#39;@tanstack/react-router&#39;
import { z } from &#39;zod&#39;
import { InvoiceFields } from &#39;../components/InvoiceFields&#39;
import { useMutation } from &#39;../hooks/useMutation&#39;
import { fetchInvoiceById, patchInvoice } from &#39;../utils/mockTodos&#39;

export const Route = createFileRoute(&#39;/dashboard/invoices/$invoiceId&#39;)({
  params: {
    parse: (params) =&gt; ({
      invoiceId: z.number().int().parse(Number(params.invoiceId)),
    }),
    stringify: ({ invoiceId }) =&gt; ({ invoiceId: `${invoiceId}` }),
  },
  validateSearch: (search) =&gt;
    z
      .object({
        showNotes: z.boolean().optional(),
        notes: z.string().optional(),
      })
      .parse(search),
  loader: ({ params: { invoiceId } }) =&gt; fetchInvoiceById(invoiceId),
  component: InvoiceComponent,
})

function InvoiceComponent() {
  const search = Route.useSearch()
  const navigate = useNavigate({ from: Route.fullPath })
  const invoice = Route.useLoaderData()
  const router = useRouter()
  const updateInvoiceMutation = useMutation({
    fn: patchInvoice,
    onSuccess: () =&gt; router.invalidate(),
  })
  const [notes, setNotes] = React.useState(search.notes ?? &#39;&#39;)

  React.useEffect(() =&gt; {
    navigate({
      search: (old) =&gt; ({
        ...old,
        notes: notes ? notes : undefined,
      }),
      replace: true,
      params: true,
    })
  }, [notes])

  return (
    &lt;form
      key={invoice.id}
      onSubmit={(event) =&gt; {
        event.preventDefault()
        event.stopPropagation()
        const formData = new FormData(event.target as HTMLFormElement)
        updateInvoiceMutation.mutate({
          id: invoice.id,
          title: formData.get(&#39;title&#39;) as string,
          body: formData.get(&#39;body&#39;) as string,
        })
      }}
      className=&quot;p-2 space-y-2&quot;
    &gt;
      &lt;InvoiceFields
        invoice={invoice}
        disabled={updateInvoiceMutation.status === &#39;pending&#39;}
      /&gt;
      &lt;div&gt;
        &lt;Link
          from={Route.fullPath}
          search={(old) =&gt; ({
            ...old,
            showNotes: old.showNotes ? undefined : true,
          })}
          className=&quot;text-blue-700&quot;
          params={true}
        &gt;
          {search.showNotes ? &#39;Close Notes&#39; : &#39;Show Notes&#39;}{&#39; &#39;}
        &lt;/Link&gt;
        {search.showNotes ? (
          &lt;&gt;
            &lt;div&gt;
              &lt;div className=&quot;h-2&quot; /&gt;
              &lt;textarea
                value={notes}
                onChange={(e) =&gt; {
                  setNotes(e.target.value)
                }}
                rows={5}
                className=&quot;shadow-sm w-full p-2 rounded-sm&quot;
                placeholder=&quot;Write some notes here...&quot;
              /&gt;
              &lt;div className=&quot;italic text-xs&quot;&gt;
                Notes are stored in the URL. Try copying the URL into a new tab!
              &lt;/div&gt;
            &lt;/div&gt;
          &lt;/&gt;
        ) : null}
      &lt;/div&gt;
      &lt;div&gt;
        &lt;button
          className=&quot;bg-blue-500 rounded-sm p-2 uppercase text-white font-black disabled:opacity-50&quot;
          disabled={updateInvoiceMutation.status === &#39;pending&#39;}
        &gt;
          Save
        &lt;/button&gt;
      &lt;/div&gt;
      {updateInvoiceMutation.variables?.id === invoice.id ? (
        &lt;div key={updateInvoiceMutation.submittedAt}&gt;
          {updateInvoiceMutation.status === &#39;success&#39; ? (
            &lt;div className=&quot;inline-block px-2 py-1 rounded-sm bg-green-500 text-white animate-bounce [animation-iteration-count:2.5] [animation-duration:.3s]&quot;&gt;
              Saved!
            &lt;/div&gt;
          ) : updateInvoiceMutation.status === &#39;error&#39; ? (
            &lt;div className=&quot;inline-block px-2 py-1 rounded-sm bg-red-500 text-white animate-bounce [animation-iteration-count:2.5] [animation-duration:.3s]&quot;&gt;
              Failed to save.
            &lt;/div&gt;
          ) : null}
        &lt;/div&gt;
      ) : null}
    &lt;/form&gt;
  )
}
">
<input type="hidden" name="project[files][src/routes/dashboard.invoices.index.tsx]" value="import { createFileRoute } from &#39;@tanstack/react-router&#39;
import * as React from &#39;react&#39;
import { useRouter } from &#39;@tanstack/react-router&#39;
import { InvoiceFields } from &#39;../components/InvoiceFields&#39;
import { Spinner } from &#39;../components/Spinner&#39;
import { useMutation } from &#39;../hooks/useMutation&#39;
import { postInvoice } from &#39;../utils/mockTodos&#39;
import type { Invoice } from &#39;../utils/mockTodos&#39;

export const Route = createFileRoute(&#39;/dashboard/invoices/&#39;)({
  component: InvoicesIndexComponent,
})

function InvoicesIndexComponent() {
  const router = useRouter()

  const createInvoiceMutation = useMutation({
    fn: postInvoice,
    onSuccess: () =&gt; router.invalidate(),
  })

  return (
    &lt;&gt;
      &lt;div className=&quot;p-2&quot;&gt;
        &lt;form
          onSubmit={(event) =&gt; {
            event.preventDefault()
            event.stopPropagation()
            const formData = new FormData(event.target as HTMLFormElement)
            createInvoiceMutation.mutate({
              title: formData.get(&#39;title&#39;) as string,
              body: formData.get(&#39;body&#39;) as string,
            })
          }}
          className=&quot;space-y-2&quot;
        &gt;
          &lt;div&gt;Create a new Invoice:&lt;/div&gt;
          &lt;InvoiceFields invoice={{} as Invoice} /&gt;
          &lt;div&gt;
            &lt;button
              className=&quot;bg-blue-500 rounded-sm p-2 uppercase text-white font-black disabled:opacity-50&quot;
              disabled={createInvoiceMutation.status === &#39;pending&#39;}
            &gt;
              {createInvoiceMutation.status === &#39;pending&#39; ? (
                &lt;&gt;
                  Creating &lt;Spinner /&gt;
                &lt;/&gt;
              ) : (
                &#39;Create&#39;
              )}
            &lt;/button&gt;
          &lt;/div&gt;
          {createInvoiceMutation.status === &#39;success&#39; ? (
            &lt;div className=&quot;inline-block px-2 py-1 rounded-sm bg-green-500 text-white animate-bounce [animation-iteration-count:2.5] [animation-duration:.3s]&quot;&gt;
              Created!
            &lt;/div&gt;
          ) : createInvoiceMutation.status === &#39;error&#39; ? (
            &lt;div className=&quot;inline-block px-2 py-1 rounded-sm bg-red-500 text-white animate-bounce [animation-iteration-count:2.5] [animation-duration:.3s]&quot;&gt;
              Failed to create.
            &lt;/div&gt;
          ) : null}
        &lt;/form&gt;
      &lt;/div&gt;
    &lt;/&gt;
  )
}
">
<input type="hidden" name="project[files][src/routes/dashboard.invoices.route.tsx]" value="import { createFileRoute } from &#39;@tanstack/react-router&#39;
import * as React from &#39;react&#39;
import { Link, MatchRoute, Outlet } from &#39;@tanstack/react-router&#39;
import { Spinner } from &#39;../components/Spinner&#39;
import { fetchInvoices } from &#39;../utils/mockTodos&#39;

export const Route = createFileRoute(&#39;/dashboard/invoices&#39;)({
  loader: () =&gt; fetchInvoices(),
  component: InvoicesComponent,
})

function InvoicesComponent() {
  const invoices = Route.useLoaderData()

  return (
    &lt;div className=&quot;flex-1 flex&quot;&gt;
      &lt;div className=&quot;divide-y w-48&quot;&gt;
        {invoices.map((invoice) =&gt; {
          return (
            &lt;div key={invoice.id}&gt;
              &lt;Link
                to=&quot;/dashboard/invoices/$invoiceId&quot;
                params={{
                  invoiceId: invoice.id,
                }}
                preload=&quot;intent&quot;
                className=&quot;block py-2 px-3 text-blue-700&quot;
                activeProps={{ className: `font-bold` }}
              &gt;
                &lt;pre className=&quot;text-sm&quot;&gt;
                  #{invoice.id} - {invoice.title.slice(0, 10)}{&#39; &#39;}
                  &lt;MatchRoute
                    to=&quot;/dashboard/invoices/$invoiceId&quot;
                    params={{
                      invoiceId: invoice.id,
                    }}
                    pending
                  &gt;
                    {(match) =&gt; &lt;Spinner show={!!match} wait=&quot;delay-50&quot; /&gt;}
                  &lt;/MatchRoute&gt;
                &lt;/pre&gt;
              &lt;/Link&gt;
            &lt;/div&gt;
          )
        })}
      &lt;/div&gt;
      &lt;div className=&quot;flex-1 border-l&quot;&gt;
        &lt;Outlet /&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  )
}
">
<input type="hidden" name="project[files][src/routes/dashboard.route.tsx]" value="import { createFileRoute } from &#39;@tanstack/react-router&#39;
import * as React from &#39;react&#39;
import { Link, Outlet, linkOptions } from &#39;@tanstack/react-router&#39;

export const Route = createFileRoute(&#39;/dashboard&#39;)({
  component: DashboardComponent,
  loader: () =&gt; ({
    crumb: &#39;Dashboard&#39;,
  }),
})

const options = [
  linkOptions({
    to: &#39;/dashboard&#39;,
    label: &#39;Summary&#39;,
    activeOptions: { exact: true },
  }),
  linkOptions({
    to: &#39;/dashboard/invoices&#39;,
    label: &#39;Invoices&#39;,
  }),
  linkOptions({
    to: &#39;/dashboard/users&#39;,
    label: &#39;Users&#39;,
  }),
]

function DashboardComponent() {
  return (
    &lt;&gt;
      &lt;div className=&quot;flex items-center border-b&quot;&gt;
        &lt;h2 className=&quot;text-xl p-2&quot;&gt;Dashboard&lt;/h2&gt;
      &lt;/div&gt;

      &lt;div className=&quot;flex flex-wrap divide-x&quot;&gt;
        {options.map((option) =&gt; {
          return (
            &lt;Link
              key={option.to}
              {...option}
              activeProps={{ className: `font-bold` }}
              className=&quot;p-2&quot;
            &gt;
              {option.label}
            &lt;/Link&gt;
          )
        })}
      &lt;/div&gt;
      &lt;hr /&gt;

      &lt;Outlet /&gt;
    &lt;/&gt;
  )
}
">
<input type="hidden" name="project[files][src/routes/dashboard.users.index.tsx]" value="import { createFileRoute } from &#39;@tanstack/react-router&#39;
import * as React from &#39;react&#39;

export const Route = createFileRoute(&#39;/dashboard/users/&#39;)({
  component: UsersIndexComponent,
})

function UsersIndexComponent() {
  return (
    &lt;div className=&quot;p-2 space-y-2&quot;&gt;
      &lt;p&gt;
        Normally, setting default search parameters would either need to be done
        manually in every link to a page, or as a side-effect (not a great
        experience).
      &lt;/p&gt;
      &lt;p&gt;
        Instead, we can use &lt;strong&gt;search filters&lt;/strong&gt; to provide defaults
        or even persist search params for links to routes (and child routes).
      &lt;/p&gt;
      &lt;p&gt;
        A good example of this is the sorting and filtering of the users list.
        In a traditional router, both would be lost while navigating around
        individual users or even changing each sort/filter option unless each
        state was manually passed from the current route into each new link we
        created (that&#39;s a lot of tedious and error-prone work). With TanStack
        router and search filters, they are persisted with little effort.
      &lt;/p&gt;
    &lt;/div&gt;
  )
}
">
<input type="hidden" name="project[files][src/routes/dashboard.users.route.tsx]" value="import { createFileRoute } from &#39;@tanstack/react-router&#39;
import * as React from &#39;react&#39;
import {
  Link,
  MatchRoute,
  Outlet,
  retainSearchParams,
  useNavigate,
} from &#39;@tanstack/react-router&#39;
import { z } from &#39;zod&#39;
import { Spinner } from &#39;../components/Spinner&#39;
import { fetchUsers } from &#39;../utils/mockTodos&#39;

type UsersViewSortBy = &#39;name&#39; | &#39;id&#39; | &#39;email&#39;

export const Route = createFileRoute(&#39;/dashboard/users&#39;)({
  validateSearch: z.object({
    usersView: z
      .object({
        sortBy: z.enum([&#39;name&#39;, &#39;id&#39;, &#39;email&#39;]).optional(),
        filterBy: z.string().optional(),
      })
      .optional(),
  }).parse,
  search: {
    // Retain the usersView search param while navigating
    // within or to this route (or it&#39;s children!)
    middlewares: [retainSearchParams([&#39;usersView&#39;])],
  },
  loaderDeps: ({ search }) =&gt; ({
    filterBy: search.usersView?.filterBy,
    sortBy: search.usersView?.sortBy,
  }),
  loader: async ({ deps }) =&gt; {
    const users = await fetchUsers(deps)
    return { users, crumb: &#39;Users&#39; }
  },
  component: UsersComponent,
})

function UsersComponent() {
  const navigate = useNavigate({ from: Route.fullPath })
  const { usersView } = Route.useSearch()
  const { users } = Route.useLoaderData()
  const sortBy = usersView?.sortBy ?? &#39;name&#39;
  const filterBy = usersView?.filterBy

  const [filterDraft, setFilterDraft] = React.useState(filterBy ?? &#39;&#39;)

  React.useEffect(() =&gt; {
    setFilterDraft(filterBy ?? &#39;&#39;)
  }, [filterBy])

  const setSortBy = (sortBy: UsersViewSortBy) =&gt;
    navigate({
      search: (old) =&gt; {
        return {
          ...old,
          usersView: {
            ...(old.usersView ?? {}),
            sortBy,
          },
        }
      },
      replace: true,
    })

  React.useEffect(() =&gt; {
    navigate({
      search: (old) =&gt; {
        return {
          ...old,
          usersView: {
            ...old.usersView,
            filterBy: filterDraft || undefined,
          },
        }
      },
      replace: true,
    })
  }, [filterDraft])

  return (
    &lt;div className=&quot;flex-1 flex&quot;&gt;
      &lt;div className=&quot;divide-y&quot;&gt;
        &lt;div className=&quot;py-2 px-3 flex gap-2 items-center bg-gray-100 dark:bg-gray-800&quot;&gt;
          &lt;div&gt;Sort By:&lt;/div&gt;
          &lt;select
            value={sortBy}
            onChange={(e) =&gt; setSortBy(e.target.value as UsersViewSortBy)}
            className=&quot;flex-1 border p-1 px-2 rounded-sm&quot;
          &gt;
            {[&#39;name&#39;, &#39;id&#39;, &#39;email&#39;].map((d) =&gt; {
              return &lt;option key={d} value={d} children={d} /&gt;
            })}
          &lt;/select&gt;
        &lt;/div&gt;
        &lt;div className=&quot;py-2 px-3 flex gap-2 items-center bg-gray-100 dark:bg-gray-800&quot;&gt;
          &lt;div&gt;Filter By:&lt;/div&gt;
          &lt;input
            value={filterDraft}
            onChange={(e) =&gt; setFilterDraft(e.target.value)}
            placeholder=&quot;Search Names...&quot;
            className=&quot;min-w-0 flex-1 border p-1 px-2 rounded-sm&quot;
          /&gt;
        &lt;/div&gt;
        {users.map((user) =&gt; {
          return (
            &lt;div key={user.id}&gt;
              &lt;Link
                to=&quot;/dashboard/users/user&quot;
                search={{
                  userId: user.id,
                }}
                className=&quot;block py-2 px-3 text-blue-700&quot;
                activeProps={{ className: `font-bold` }}
              &gt;
                &lt;pre className=&quot;text-sm&quot;&gt;
                  {user.name}{&#39; &#39;}
                  &lt;MatchRoute
                    to=&quot;/dashboard/users/user&quot;
                    search={{
                      userId: user.id,
                    }}
                    pending
                  &gt;
                    {(match) =&gt; &lt;Spinner show={!!match} wait=&quot;delay-50&quot; /&gt;}
                  &lt;/MatchRoute&gt;
                &lt;/pre&gt;
              &lt;/Link&gt;
            &lt;/div&gt;
          )
        })}
      &lt;/div&gt;
      &lt;div className=&quot;flex-initial border-l&quot;&gt;
        &lt;Outlet /&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  )
}
">
<input type="hidden" name="project[files][src/routes/dashboard.users.user.tsx]" value="import { createFileRoute } from &#39;@tanstack/react-router&#39;
import * as React from &#39;react&#39;

import { z } from &#39;zod&#39;
import { fetchUserById } from &#39;../utils/mockTodos&#39;

export const Route = createFileRoute(&#39;/dashboard/users/user&#39;)({
  validateSearch: z.object({
    userId: z.number(),
  }),
  loaderDeps: ({ search: { userId } }) =&gt; ({ userId }),
  loader: async ({ deps: { userId } }) =&gt; {
    const user = await fetchUserById(userId)
    return {
      user,
      crumb: user?.name,
    }
  },
  component: UserComponent,
})

function UserComponent() {
  const data = Route.useLoaderData()

  return (
    &lt;&gt;
      &lt;h4 className=&quot;p-2 font-bold&quot;&gt;{data.user?.name}&lt;/h4&gt;
      &lt;pre className=&quot;text-sm whitespace-pre-wrap&quot;&gt;
        {JSON.stringify(data.user, null, 2)}
      &lt;/pre&gt;
    &lt;/&gt;
  )
}
">
<input type="hidden" name="project[files][src/routes/index.tsx]" value="import { createFileRoute } from &#39;@tanstack/react-router&#39;
import * as React from &#39;react&#39;
import { Link } from &#39;@tanstack/react-router&#39;

export const Route = createFileRoute(&#39;/&#39;)({
  component: IndexComponent,
})

function IndexComponent() {
  return (
    &lt;div className={`p-2`}&gt;
      &lt;div className={`text-lg`}&gt;Welcome Home!&lt;/div&gt;
      &lt;hr className={`my-2`} /&gt;
      &lt;Link
        to=&quot;/dashboard/invoices/$invoiceId&quot;
        params={{
          invoiceId: 3,
        }}
        className={`py-1 px-2 text-xs bg-blue-500 text-white rounded-full`}
      &gt;
        1 New Invoice
      &lt;/Link&gt;
      &lt;hr className={`my-2`} /&gt;
      &lt;div className={`max-w-xl`}&gt;
        As you navigate around take note of the UX. It should feel
        suspense-like, where routes are only rendered once all of their data and
        elements are ready.
        &lt;hr className={`my-2`} /&gt;
        To exaggerate async effects, play with the artificial request delay
        slider in the bottom-left corner.
        &lt;hr className={`my-2`} /&gt;
        The last 2 sliders determine if link-hover preloading is enabled (and
        how long those preloads stick around) and also whether to cache rendered
        route data (and for how long). Both of these default to 0 (or off).
      &lt;/div&gt;
    &lt;/div&gt;
  )
}
">
<input type="hidden" name="project[files][src/routes/login.tsx]" value="import { createFileRoute } from &#39;@tanstack/react-router&#39;
import * as React from &#39;react&#39;
import { useRouter } from &#39;@tanstack/react-router&#39;
import { z } from &#39;zod&#39;

export const Route = createFileRoute(&#39;/login&#39;)({
  validateSearch: z.object({
    redirect: z.string().optional(),
  }),
}).update({
  component: LoginComponent,
})

function LoginComponent() {
  const router = useRouter()
  const { auth, status } = Route.useRouteContext({
    select: ({ auth }) =&gt; ({ auth, status: auth.status }),
  })
  const search = Route.useSearch()
  const [username, setUsername] = React.useState(&#39;&#39;)

  const onSubmit = (e: React.FormEvent&lt;HTMLFormElement&gt;) =&gt; {
    e.preventDefault()
    auth.login(username)
    router.invalidate()
  }

  // Ah, the subtle nuances of client side auth. 🙄
  React.useLayoutEffect(() =&gt; {
    if (status === &#39;loggedIn&#39; &amp;&amp; search.redirect) {
      router.history.push(search.redirect)
    }
  }, [status, search.redirect])

  return status === &#39;loggedIn&#39; ? (
    &lt;div&gt;
      Logged in as &lt;strong&gt;{auth.username}&lt;/strong&gt;
      &lt;div className=&quot;h-2&quot; /&gt;
      &lt;button
        onClick={() =&gt; {
          auth.logout()
          router.invalidate()
        }}
        className=&quot;text-sm bg-blue-500 text-white border inline-block py-1 px-2 rounded-sm&quot;
      &gt;
        Log out
      &lt;/button&gt;
      &lt;div className=&quot;h-2&quot; /&gt;
    &lt;/div&gt;
  ) : (
    &lt;div className=&quot;p-2&quot;&gt;
      &lt;div&gt;You must log in!&lt;/div&gt;
      &lt;div className=&quot;h-2&quot; /&gt;
      &lt;form onSubmit={onSubmit} className=&quot;flex gap-2&quot;&gt;
        &lt;input
          value={username}
          onChange={(e) =&gt; setUsername(e.target.value)}
          placeholder=&quot;Username&quot;
          className=&quot;border p-1 px-2 rounded-sm&quot;
        /&gt;
        &lt;button
          type=&quot;submit&quot;
          className=&quot;text-sm bg-blue-500 text-white border inline-block py-1 px-2 rounded-sm&quot;
        &gt;
          Login
        &lt;/button&gt;
      &lt;/form&gt;
    &lt;/div&gt;
  )
}
">
<input type="hidden" name="project[files][src/utils/auth.tsx]" value="export const auth: Auth = {
  status: &#39;loggedOut&#39;,
  username: undefined,
  login: (username: string) =&gt; {
    auth.status = &#39;loggedIn&#39;
    auth.username = username
  },
  logout: () =&gt; {
    auth.status = &#39;loggedOut&#39;
    auth.username = undefined
  },
}

export type Auth = {
  login: (username: string) =&gt; void
  logout: () =&gt; void
  status: &#39;loggedOut&#39; | &#39;loggedIn&#39;
  username?: string
}
">
<input type="hidden" name="project[files][src/utils/mockTodos.ts]" value="import axios from &#39;redaxios&#39;
import { produce } from &#39;immer&#39;
import { actionDelayFn, loaderDelayFn, shuffle } from &#39;./utils&#39;

type PickAsRequired&lt;TValue, TKey extends keyof TValue&gt; = Omit&lt;TValue, TKey&gt; &amp;
  Required&lt;Pick&lt;TValue, TKey&gt;&gt;

export type Invoice = {
  id: number
  title: string
  body: string
}

export interface User {
  id: number
  name: string
  username: string
  email: string
  address: Address
  phone: string
  website: string
  company: Company
}

export interface Address {
  street: string
  suite: string
  city: string
  zipcode: string
  geo: Geo
}

export interface Geo {
  lat: string
  lng: string
}

export interface Company {
  name: string
  catchPhrase: string
  bs: string
}

let invoices: Array&lt;Invoice&gt; = null!
let users: Array&lt;User&gt; = null!

let invoicesPromise: Promise&lt;void&gt; | undefined = undefined
let usersPromise: Promise&lt;void&gt; | undefined = undefined

const ensureInvoices = async () =&gt; {
  if (!invoicesPromise) {
    invoicesPromise = Promise.resolve().then(async () =&gt; {
      const { data } = await axios.get(
        &#39;https://jsonplaceholder.typicode.com/posts&#39;,
      )
      invoices = data.slice(0, 10)
    })
  }

  await invoicesPromise
}

const ensureUsers = async () =&gt; {
  if (!usersPromise) {
    usersPromise = Promise.resolve().then(async () =&gt; {
      const { data } = await axios.get(
        &#39;https://jsonplaceholder.typicode.com/users&#39;,
      )
      users = data.slice(0, 10)
    })
  }

  await usersPromise
}

export async function fetchInvoices() {
  return loaderDelayFn(() =&gt; ensureInvoices().then(() =&gt; invoices))
}

export async function fetchInvoiceById(id: number) {
  return loaderDelayFn(() =&gt;
    ensureInvoices().then(() =&gt; {
      const invoice = invoices.find((d) =&gt; d.id === id)
      if (!invoice) {
        throw new Error(&#39;Invoice not found&#39;)
      }
      return invoice
    }),
  )
}

export async function postInvoice(partialInvoice: Partial&lt;Invoice&gt;) {
  return actionDelayFn(() =&gt; {
    if (partialInvoice.title?.includes(&#39;error&#39;)) {
      console.error(&#39;error&#39;)
      throw new Error(&#39;Ouch!&#39;)
    }
    const invoice = {
      id: invoices.length + 1,
      title:
        partialInvoice.title ?? `New Invoice ${String(Date.now()).slice(0, 5)}`,
      body:
        partialInvoice.body ??
        shuffle(
          `Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
      Fusce ac turpis quis ligula lacinia aliquet. Mauris ipsum. Nulla metus metus, ullamcorper vel, tincidunt sed, euismod in, nibh. Quisque volutpat condimentum velit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nam nec ante. 
      Vestibulum sapien. Proin quam. Etiam ultrices. Suspendisse in justo eu magna luctus suscipit. Sed lectus. Integer euismod lacus luctus magna.  Integer id quam. Morbi mi. Quisque nisl felis, venenatis tristique, dignissim in, ultrices sit amet, augue. Proin sodales libero eget ante.
      `.split(&#39; &#39;),
        ).join(&#39; &#39;),
    }
    invoices = [...invoices, invoice]
    return invoice
  })
}

export async function patchInvoice({
  id,
  ...updatedInvoice
}: PickAsRequired&lt;Partial&lt;Invoice&gt;, &#39;id&#39;&gt;) {
  return actionDelayFn(() =&gt; {
    invoices = produce(invoices, (draft) =&gt; {
      const invoice = draft.find((d) =&gt; d.id === id)
      if (!invoice) {
        throw new Error(&#39;Invoice not found.&#39;)
      }
      // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
      if (updatedInvoice.title?.toLocaleLowerCase()?.includes(&#39;error&#39;)) {
        throw new Error(&#39;Ouch!&#39;)
      }
      Object.assign(invoice, updatedInvoice)
    })

    return invoices.find((d) =&gt; d.id === id)
  })
}

export type UsersSortBy = &#39;name&#39; | &#39;id&#39; | &#39;email&#39;

export async function fetchUsers({
  filterBy,
  sortBy,
}: { filterBy?: string; sortBy?: UsersSortBy } = {}) {
  return loaderDelayFn(() =&gt;
    ensureUsers().then(() =&gt; {
      let usersDraft = users

      if (filterBy) {
        usersDraft = usersDraft.filter((d) =&gt;
          d.name.toLowerCase().includes(filterBy.toLowerCase()),
        )
      }

      if (sortBy) {
        usersDraft = [...usersDraft].sort((a, b) =&gt; {
          return a[sortBy] &gt; b[sortBy] ? 1 : -1
        })
      }

      return usersDraft
    }),
  )
}

export async function fetchUserById(id: number) {
  return loaderDelayFn(() =&gt;
    ensureUsers().then(() =&gt; users.find((d) =&gt; d.id === id)),
  )
}

export async function fetchRandomNumber() {
  return loaderDelayFn(() =&gt; {
    return Math.random()
  })
}
">
<input type="hidden" name="project[files][src/utils/utils.tsx]" value="export async function loaderDelayFn&lt;T&gt;(
  fn: (...args: Array&lt;any&gt;) =&gt; Promise&lt;T&gt; | T,
) {
  const delay = Number(sessionStorage.getItem(&#39;loaderDelay&#39;) ?? 0)
  const delayPromise = new Promise((r) =&gt; setTimeout(r, delay))

  await delayPromise
  const res = await fn()

  return res
}

export async function actionDelayFn&lt;T&gt;(
  fn: (...args: Array&lt;any&gt;) =&gt; Promise&lt;T&gt; | T,
) {
  const delay = Number(sessionStorage.getItem(&#39;actionDelay&#39;) ?? 0)
  await new Promise((r) =&gt; setTimeout(r, delay))
  return fn()
}

export function shuffle&lt;T&gt;(arr: Array&lt;T&gt;): Array&lt;T&gt; {
  let i = arr.length
  if (i == 0) return arr
  const copy = [...arr]
  while (--i) {
    const j = Math.floor(Math.random() * (i + 1))
    const a = copy[i]
    const b = copy[j]
    copy[i] = b!
    copy[j] = a!
  }
  return copy
}
">
<input type="hidden" name="project[files][src/routes/(this-folder-is-not-in-the-url)/route-group.tsx]" value="import { createFileRoute } from &#39;@tanstack/react-router&#39;
import * as React from &#39;react&#39;

export const Route = createFileRoute(
  &#39;/(this-folder-is-not-in-the-url)/route-group&#39;,
)({
  component: RouteGroupExample,
})

function RouteGroupExample() {
  return (
    &lt;div className={`p-2`}&gt;
      &lt;div className={`text-lg`}&gt;Welcome to the Route Group Example!&lt;/div&gt;
      &lt;hr className={`my-2`} /&gt;
    &lt;/div&gt;
  )
}
">
<input type="hidden" name="project[files][src/routes/expensive/index.tsx]" value="import { createFileRoute } from &#39;@tanstack/react-router&#39;
import Expensive from &#39;./-components/Expensive&#39;

export const Route = createFileRoute(&#39;/expensive/&#39;)({
  component: Expensive,
})
">
<input type="hidden" name="project[files][src/routes/expensive/-components/Expensive.tsx]" value="import * as React from &#39;react&#39;

export default function Expensive() {
  return (
    &lt;div className={`p-2`}&gt;
      I am an &quot;expensive&quot; component... which really just means that I was
      code-split 😉
    &lt;/div&gt;
  )
}
">
<input type="hidden" name="project[description]" value="generated by https://pkg.pr.new">
<input type="hidden" name="project[template]" value="node">
<input type="hidden" name="project[title]" value="tanstack-router-react-example-kitchen-sink-file-based">
</form>
<script>document.getElementById("mainForm").submit();</script>

</body></html>