- Add POST /admin/users endpoint with password hashing and role support - Add user creation dialog to admin users page - Migrate web from Next.js to Vite + TanStack Router - Fix Dialog component positioning for Tailwind CSS v4 - Add @source directive for @sase/ui package scanning - Add pl24 integration parsers and vehicle decode flow - Backup old Next.js app to apps/web-nj Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
3.0 KiB
3.0 KiB
paths: "/*.ts", "/.tsx", "**/route.ts", "**/router*.ts"
TanStack Router v1 Corrections
Claude's training may have limited TanStack Router knowledge. This project uses TanStack Router v1.
File-Based Routing (Recommended)
/* ❌ Manual route definitions (verbose) */
const router = createRouter({
routeTree: rootRoute.addChildren([
indexRoute,
aboutRoute,
]),
})
/* ✅ File-based routing with routeTree.gen.ts */
// routes/__root.tsx, routes/index.tsx, routes/about.tsx
// Then import generated tree:
import { routeTree } from './routeTree.gen'
const router = createRouter({ routeTree })
Route File Structure
/* ❌ Wrong file naming */
// routes/About.tsx - capitalized won't work
// routes/about/page.tsx - Next.js convention
/* ✅ TanStack Router conventions */
// routes/__root.tsx - root layout
// routes/index.tsx - home page (/)
// routes/about.tsx - /about
// routes/posts/$postId.tsx - /posts/:postId (dynamic)
// routes/posts/index.tsx - /posts
createFileRoute vs createRoute
/* ❌ Using createRoute in file-based routing */
import { createRoute } from '@tanstack/react-router'
const Route = createRoute({...})
/* ✅ Use createFileRoute for file-based */
import { createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute('/about')({
component: AboutPage,
})
Loader Pattern
/* ❌ React Router style loader */
export async function loader({ params }) {
return fetch(`/api/posts/${params.id}`)
}
/* ✅ TanStack Router loader */
export const Route = createFileRoute('/posts/$postId')({
loader: async ({ params }) => {
return fetchPost(params.postId)
},
component: PostPage,
})
function PostPage() {
const post = Route.useLoaderData()
return <div>{post.title}</div>
}
Search Params
/* ❌ Manual URLSearchParams */
const params = new URLSearchParams(window.location.search)
/* ✅ Type-safe search params */
export const Route = createFileRoute('/search')({
validateSearch: (search) => ({
q: search.q as string || '',
page: Number(search.page) || 1,
}),
})
function SearchPage() {
const { q, page } = Route.useSearch()
}
Navigation
/* ❌ useNavigate like React Router */
import { useNavigate } from 'react-router-dom'
const navigate = useNavigate()
navigate('/about')
/* ✅ TanStack Router navigation */
import { useNavigate, Link } from '@tanstack/react-router'
const navigate = useNavigate()
navigate({ to: '/about' })
// Or type-safe Link
<Link to="/posts/$postId" params={{ postId: '123' }}>
View Post
</Link>
Quick Fixes
| If Claude suggests... | Use instead... |
|---|---|
createRoute in file-based |
createFileRoute |
routes/About.tsx |
routes/about.tsx (lowercase) |
loader({ params }) export |
loader inside createFileRoute |
useParams() |
Route.useParams() |
useSearchParams() |
Route.useSearch() with validateSearch |
navigate('/path') |
navigate({ to: '/path' }) |