Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
POSTGRES_PASSWORD=password
NODE_ENV=development
PORT=3009
DATABASE_URL=postgresql://postgres:password@localhost:5432/db_name
APP_NAME=altstack
APP_NAME=Altstack
BETTER_AUTH_URL=http://localhost:3010
BETTER_AUTH_SECRET=your-better-auth-secret
BETTER_AUTH_TRUSTED_ORIGINS=http://localhost:3010,http://<internal-ip>:3010,https://dokploy.example.com
CORS_ORIGINS=http://localhost:3010,http://<internal-ip>:3010,https://dokploy.example.com

VITE_APP_NAME=altstack
VITE_APP_NAME=Altstack
VITE_APP_URL=http://localhost:3010
VITE_SERVER_URL=http://localhost:3009
Comment thread
mrboxs marked this conversation as resolved.
Outdated
9 changes: 9 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,14 @@
"editor.formatOnSaveMode": "file",
"editor.codeActionsOnSave": {
"source.fixAll.oxc": "explicit"
},
"files.watcherExclude": {
"**/routeTree.gen.ts": true
},
"search.exclude": {
"**/routeTree.gen.ts": true
},
"files.readonlyInclude": {
"**/routeTree.gen.ts": true
}
}
17 changes: 17 additions & 0 deletions apps/dashboard/.cta.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"projectName": "dashboard",
"mode": "file-router",
"typescript": true,
"packageManager": "bun",
"includeExamples": false,
"tailwind": true,
"projectPreset": "default",
"addOnOptions": {},
"git": false,
"install": false,
"intent": true,
"routerOnly": false,
"version": 1,
"framework": "react",
"chosenAddOns": ["nitro", "compiler"]
}
13 changes: 13 additions & 0 deletions apps/dashboard/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
node_modules
.DS_Store
dist
dist-ssr
*.local
.env
Comment thread
mrboxs marked this conversation as resolved.
.nitro
.tanstack
.wrangler
.output
.vinxi
__unconfig*
todos.json
192 changes: 192 additions & 0 deletions apps/dashboard/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
Welcome to your new TanStack Start app!

# Getting Started

To run this application:

```bash
bun install
bun --bun run dev
```

# Building For Production

To build this application for production:

```bash
bun --bun run build
```

## Styling

This project uses [Tailwind CSS](https://tailwindcss.com/) for styling.

### Removing Tailwind CSS

If you prefer not to use Tailwind CSS:

1. Remove the demo pages in `src/routes/demo/`
2. Replace the Tailwind import in `src/styles.css` with your own styles
3. Remove `tailwindcss()` from the plugins array in `vite.config.ts`
4. Remove `@tailwindcss/vite` and `tailwindcss` from `package.json`

## Deploy with Nitro

This project uses Nitro as a generic server adapter, so it can run on any Node-compatible host.

```bash
npm run build
node dist/server/index.mjs
```

The build output is a self-contained Node server. To deploy, push the `dist/` directory to your host (Render, Fly.io, your own VPS, etc.) and run the server command above.

For host-specific presets (Vercel, Netlify, Cloudflare, AWS Lambda, etc.) and tuning, see https://v3.nitro.build/deploy.

## Routing

This project uses [TanStack Router](https://tanstack.com/router) with file-based routing. Routes are managed as files in `src/routes`.

### Adding A Route

To add a new route to your application just add a new file in the `./src/routes` directory.

TanStack will automatically generate the content of the route file for you.

Now that you have two routes you can use a `Link` component to navigate between them.

### Adding Links

To use SPA (Single Page Application) navigation you will need to import the `Link` component from `@tanstack/react-router`.

```tsx
import { Link } from '@tanstack/react-router'
```

Then anywhere in your JSX you can use it like so:

```tsx
<Link to="/about">About</Link>
```

This will create a link that will navigate to the `/about` route.

More information on the `Link` component can be found in the [Link documentation](https://tanstack.com/router/v1/docs/framework/react/api/router/linkComponent).

### Using A Layout

In the File Based Routing setup the layout is located in `src/routes/__root.tsx`. Anything you add to the root route will appear in all the routes. The route content will appear in the JSX where you render `{children}` in the `shellComponent`.

Here is an example layout that includes a header:

```tsx
import { HeadContent, Scripts, createRootRoute } from '@tanstack/react-router'

export const Route = createRootRoute({
head: () => ({
meta: [
{ charSet: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ title: 'My App' },
],
}),
shellComponent: ({ children }) => (
<html lang="en">
<head>
<HeadContent />
</head>
<body>
<header>
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
</nav>
</header>
{children}
<Scripts />
</body>
</html>
),
})
```

More information on layouts can be found in the [Layouts documentation](https://tanstack.com/router/latest/docs/framework/react/guide/routing-concepts#layouts).

## Server Functions

TanStack Start provides server functions that allow you to write server-side code that seamlessly integrates with your client components.

```tsx
import { createServerFn } from '@tanstack/react-start'

const getServerTime = createServerFn({
method: 'GET',
}).handler(async () => {
return new Date().toISOString()
})

// Use in a component
function MyComponent() {
const [time, setTime] = useState('')

useEffect(() => {
getServerTime().then(setTime)
}, [])

return <div>Server time: {time}</div>
}
```

## API Routes

You can create API routes by using the `server` property in your route definitions:

```tsx
import { createFileRoute } from '@tanstack/react-router'
import { json } from '@tanstack/react-start'

export const Route = createFileRoute('/api/hello')({
server: {
handlers: {
GET: () => json({ message: 'Hello, World!' }),
},
},
})
```

## Data Fetching

There are multiple ways to fetch data in your application. You can use TanStack Query to fetch data from a server. But you can also use the `loader` functionality built into TanStack Router to load the data for a route before it's rendered.

For example:

```tsx
import { createFileRoute } from '@tanstack/react-router'

export const Route = createFileRoute('/people')({
loader: async () => {
const response = await fetch('https://swapi.dev/api/people')
return response.json()
},
component: PeopleComponent,
})

function PeopleComponent() {
const data = Route.useLoaderData()
return (
<ul>
{data.results.map((person) => (
<li key={person.name}>{person.name}</li>
))}
</ul>
)
}
```

Loaders simplify your data fetching logic dramatically. Check out more information in the [Loader documentation](https://tanstack.com/router/latest/docs/framework/react/guide/data-loading#loader-parameters).

# Learn More

You can learn more about all of the offerings from TanStack in the [TanStack documentation](https://tanstack.com).

For TanStack Start specific documentation, visit [TanStack Start](https://tanstack.com/start).
13 changes: 13 additions & 0 deletions apps/dashboard/nitro.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import evlog from 'evlog/nitro/v3'
import { defineConfig } from 'nitro'

export default defineConfig({
experimental: {
asyncContext: true,
},
modules: [
evlog({
env: { service: 'altstack-dashboard' },
}),
],
})
59 changes: 59 additions & 0 deletions apps/dashboard/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
{
"name": "dashboard",
"private": true,
"type": "module",
"imports": {
"#/*": "./src/*"
},
"scripts": {
"dev": "vp dev",
"generate-routes": "tsr generate",
"preview": "vp preview",
"test": "vp test run"
Comment thread
mrboxs marked this conversation as resolved.
},
"dependencies": {
"@altstack/api": "workspace:*",
"@altstack/auth": "workspace:*",
"@altstack/env": "workspace:*",
"@altstack/ui": "workspace:*",
"@orpc/client": "catalog:",
"@orpc/server": "catalog:",
"@orpc/tanstack-query": "catalog:",
"@tabler/icons-react": "catalog:",
"@tanstack/react-devtools": "catalog:",
"@tanstack/react-query": "catalog:",
"@tanstack/react-query-devtools": "catalog:",
"@tanstack/react-router": "catalog:",
"@tanstack/react-router-devtools": "catalog:",
"@tanstack/react-router-ssr-query": "catalog:",
"@tanstack/react-start": "catalog:",
"better-auth": "catalog:",
"evlog": "catalog:",
"nitro": "catalog:",
"react": "catalog:",
"react-dom": "catalog:",
"reicon-react": "catalog:"
},
"devDependencies": {
"@altstack/config": "workspace:*",
"@rolldown/plugin-babel": "catalog:",
"@tailwindcss/vite": "catalog:",
"@tanstack/devtools-vite": "catalog:",
"@tanstack/router-cli": "catalog:",
"@types/node": "catalog:",
"@types/react": "catalog:",
"@types/react-dom": "catalog:",
"@vitejs/plugin-react": "catalog:",
"babel-plugin-react-compiler": "catalog:",
"tailwindcss": "catalog:",
"typescript": "catalog:",
"vite": "catalog:",
"vite-plus": "catalog:"
},
"pnpm": {
"onlyBuiltDependencies": [
"esbuild",
"lightningcss"
]
}
}
Binary file added apps/dashboard/public/favicon.ico
Binary file not shown.
Binary file added apps/dashboard/public/logo192.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/dashboard/public/logo512.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 25 additions & 0 deletions apps/dashboard/public/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"short_name": "TanStack App",
"name": "Create TanStack App Sample",
Comment thread
mrboxs marked this conversation as resolved.
Outdated
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}
3 changes: 3 additions & 0 deletions apps/dashboard/public/robots.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:
Comment thread
mrboxs marked this conversation as resolved.
Outdated
7 changes: 7 additions & 0 deletions apps/dashboard/server/plugins/evlog-drain.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { createFsDrain } from 'evlog/fs'
import { definePlugin } from 'nitro'

export default definePlugin((nitroApp) => {
if (!import.meta.dev) return
nitroApp.hooks.hook('evlog:drain', createFsDrain())
})
13 changes: 13 additions & 0 deletions apps/dashboard/server/plugins/evlog-enrich.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import {
createUserAgentEnricher,
createRequestSizeEnricher,
} from 'evlog/enrichers'
import { definePlugin } from 'nitro'

export default definePlugin((nitroApp) => {
const enrichers = [createUserAgentEnricher(), createRequestSizeEnricher()]

nitroApp.hooks.hook('evlog:enrich', (ctx) => {
for (const enricher of enrichers) enricher(ctx)
})
})
7 changes: 7 additions & 0 deletions apps/dashboard/src/functions/get-auth-fn.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { createServerFn } from '@tanstack/react-start'

import { authMiddleware } from '#/middlewares/auth-middleware.ts'

export const getAuthFn = createServerFn({ method: 'GET' })
.middleware([authMiddleware])
.handler(({ context }) => context.auth)
Loading