fix(admin): move detail routes to directory structure to fix rendering
All checks were successful
CI / ci (push) Successful in 1m54s
CI / e2e (push) Has been skipped
CI / deploy (push) Successful in 18s

Admin item/tag edit pages weren't rendering because TanStack Router treated
them as children of the list route (which had no Outlet). Moving to
directory-based routing (items/index.tsx + items/$itemId.tsx) makes them
siblings that render directly in the admin layout.

Also adds UAT results for phases 35-38 and backlog item 999.12 (Admin UX Polish).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-20 21:40:57 +02:00
parent 88c5339b98
commit 31a9e3c1ff
11 changed files with 322 additions and 88 deletions

View File

@@ -22,11 +22,11 @@ import { Route as UsersUserIdRouteImport } from './routes/users/$userId'
import { Route as SetupsSetupIdRouteImport } from './routes/setups/$setupId'
import { Route as ItemsItemIdRouteImport } from './routes/items/$itemId'
import { Route as GlobalItemsGlobalItemIdRouteImport } from './routes/global-items/$globalItemId'
import { Route as AdminTagsRouteImport } from './routes/admin/tags'
import { Route as AdminItemsRouteImport } from './routes/admin/items'
import { Route as ThreadsThreadIdIndexRouteImport } from './routes/threads/$threadId/index'
import { Route as AdminTagsTagIdRouteImport } from './routes/admin/tags.$tagId'
import { Route as AdminItemsItemIdRouteImport } from './routes/admin/items.$itemId'
import { Route as AdminTagsIndexRouteImport } from './routes/admin/tags/index'
import { Route as AdminItemsIndexRouteImport } from './routes/admin/items/index'
import { Route as AdminTagsTagIdRouteImport } from './routes/admin/tags/$tagId'
import { Route as AdminItemsItemIdRouteImport } from './routes/admin/items/$itemId'
import { Route as ThreadsThreadIdCandidatesCandidateIdRouteImport } from './routes/threads/$threadId/candidates/$candidateId'
const SettingsRoute = SettingsRouteImport.update({
@@ -94,30 +94,30 @@ const GlobalItemsGlobalItemIdRoute = GlobalItemsGlobalItemIdRouteImport.update({
path: '/global-items/$globalItemId',
getParentRoute: () => rootRouteImport,
} as any)
const AdminTagsRoute = AdminTagsRouteImport.update({
id: '/tags',
path: '/tags',
getParentRoute: () => AdminRoute,
} as any)
const AdminItemsRoute = AdminItemsRouteImport.update({
id: '/items',
path: '/items',
getParentRoute: () => AdminRoute,
} as any)
const ThreadsThreadIdIndexRoute = ThreadsThreadIdIndexRouteImport.update({
id: '/threads/$threadId/',
path: '/threads/$threadId/',
getParentRoute: () => rootRouteImport,
} as any)
const AdminTagsIndexRoute = AdminTagsIndexRouteImport.update({
id: '/tags/',
path: '/tags/',
getParentRoute: () => AdminRoute,
} as any)
const AdminItemsIndexRoute = AdminItemsIndexRouteImport.update({
id: '/items/',
path: '/items/',
getParentRoute: () => AdminRoute,
} as any)
const AdminTagsTagIdRoute = AdminTagsTagIdRouteImport.update({
id: '/$tagId',
path: '/$tagId',
getParentRoute: () => AdminTagsRoute,
id: '/tags/$tagId',
path: '/tags/$tagId',
getParentRoute: () => AdminRoute,
} as any)
const AdminItemsItemIdRoute = AdminItemsItemIdRouteImport.update({
id: '/$itemId',
path: '/$itemId',
getParentRoute: () => AdminItemsRoute,
id: '/items/$itemId',
path: '/items/$itemId',
getParentRoute: () => AdminRoute,
} as any)
const ThreadsThreadIdCandidatesCandidateIdRoute =
ThreadsThreadIdCandidatesCandidateIdRouteImport.update({
@@ -132,8 +132,6 @@ export interface FileRoutesByFullPath {
'/login': typeof LoginRoute
'/profile': typeof ProfileRoute
'/settings': typeof SettingsRoute
'/admin/items': typeof AdminItemsRouteWithChildren
'/admin/tags': typeof AdminTagsRouteWithChildren
'/global-items/$globalItemId': typeof GlobalItemsGlobalItemIdRoute
'/items/$itemId': typeof ItemsItemIdRoute
'/setups/$setupId': typeof SetupsSetupIdRoute
@@ -144,6 +142,8 @@ export interface FileRoutesByFullPath {
'/setups/': typeof SetupsIndexRoute
'/admin/items/$itemId': typeof AdminItemsItemIdRoute
'/admin/tags/$tagId': typeof AdminTagsTagIdRoute
'/admin/items/': typeof AdminItemsIndexRoute
'/admin/tags/': typeof AdminTagsIndexRoute
'/threads/$threadId/': typeof ThreadsThreadIdIndexRoute
'/threads/$threadId/candidates/$candidateId': typeof ThreadsThreadIdCandidatesCandidateIdRoute
}
@@ -152,8 +152,6 @@ export interface FileRoutesByTo {
'/login': typeof LoginRoute
'/profile': typeof ProfileRoute
'/settings': typeof SettingsRoute
'/admin/items': typeof AdminItemsRouteWithChildren
'/admin/tags': typeof AdminTagsRouteWithChildren
'/global-items/$globalItemId': typeof GlobalItemsGlobalItemIdRoute
'/items/$itemId': typeof ItemsItemIdRoute
'/setups/$setupId': typeof SetupsSetupIdRoute
@@ -164,6 +162,8 @@ export interface FileRoutesByTo {
'/setups': typeof SetupsIndexRoute
'/admin/items/$itemId': typeof AdminItemsItemIdRoute
'/admin/tags/$tagId': typeof AdminTagsTagIdRoute
'/admin/items': typeof AdminItemsIndexRoute
'/admin/tags': typeof AdminTagsIndexRoute
'/threads/$threadId': typeof ThreadsThreadIdIndexRoute
'/threads/$threadId/candidates/$candidateId': typeof ThreadsThreadIdCandidatesCandidateIdRoute
}
@@ -174,8 +174,6 @@ export interface FileRoutesById {
'/login': typeof LoginRoute
'/profile': typeof ProfileRoute
'/settings': typeof SettingsRoute
'/admin/items': typeof AdminItemsRouteWithChildren
'/admin/tags': typeof AdminTagsRouteWithChildren
'/global-items/$globalItemId': typeof GlobalItemsGlobalItemIdRoute
'/items/$itemId': typeof ItemsItemIdRoute
'/setups/$setupId': typeof SetupsSetupIdRoute
@@ -186,6 +184,8 @@ export interface FileRoutesById {
'/setups/': typeof SetupsIndexRoute
'/admin/items/$itemId': typeof AdminItemsItemIdRoute
'/admin/tags/$tagId': typeof AdminTagsTagIdRoute
'/admin/items/': typeof AdminItemsIndexRoute
'/admin/tags/': typeof AdminTagsIndexRoute
'/threads/$threadId/': typeof ThreadsThreadIdIndexRoute
'/threads/$threadId/candidates/$candidateId': typeof ThreadsThreadIdCandidatesCandidateIdRoute
}
@@ -197,8 +197,6 @@ export interface FileRouteTypes {
| '/login'
| '/profile'
| '/settings'
| '/admin/items'
| '/admin/tags'
| '/global-items/$globalItemId'
| '/items/$itemId'
| '/setups/$setupId'
@@ -209,6 +207,8 @@ export interface FileRouteTypes {
| '/setups/'
| '/admin/items/$itemId'
| '/admin/tags/$tagId'
| '/admin/items/'
| '/admin/tags/'
| '/threads/$threadId/'
| '/threads/$threadId/candidates/$candidateId'
fileRoutesByTo: FileRoutesByTo
@@ -217,8 +217,6 @@ export interface FileRouteTypes {
| '/login'
| '/profile'
| '/settings'
| '/admin/items'
| '/admin/tags'
| '/global-items/$globalItemId'
| '/items/$itemId'
| '/setups/$setupId'
@@ -229,6 +227,8 @@ export interface FileRouteTypes {
| '/setups'
| '/admin/items/$itemId'
| '/admin/tags/$tagId'
| '/admin/items'
| '/admin/tags'
| '/threads/$threadId'
| '/threads/$threadId/candidates/$candidateId'
id:
@@ -238,8 +238,6 @@ export interface FileRouteTypes {
| '/login'
| '/profile'
| '/settings'
| '/admin/items'
| '/admin/tags'
| '/global-items/$globalItemId'
| '/items/$itemId'
| '/setups/$setupId'
@@ -250,6 +248,8 @@ export interface FileRouteTypes {
| '/setups/'
| '/admin/items/$itemId'
| '/admin/tags/$tagId'
| '/admin/items/'
| '/admin/tags/'
| '/threads/$threadId/'
| '/threads/$threadId/candidates/$candidateId'
fileRoutesById: FileRoutesById
@@ -364,20 +364,6 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof GlobalItemsGlobalItemIdRouteImport
parentRoute: typeof rootRouteImport
}
'/admin/tags': {
id: '/admin/tags'
path: '/tags'
fullPath: '/admin/tags'
preLoaderRoute: typeof AdminTagsRouteImport
parentRoute: typeof AdminRoute
}
'/admin/items': {
id: '/admin/items'
path: '/items'
fullPath: '/admin/items'
preLoaderRoute: typeof AdminItemsRouteImport
parentRoute: typeof AdminRoute
}
'/threads/$threadId/': {
id: '/threads/$threadId/'
path: '/threads/$threadId'
@@ -385,19 +371,33 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof ThreadsThreadIdIndexRouteImport
parentRoute: typeof rootRouteImport
}
'/admin/tags/': {
id: '/admin/tags/'
path: '/tags'
fullPath: '/admin/tags/'
preLoaderRoute: typeof AdminTagsIndexRouteImport
parentRoute: typeof AdminRoute
}
'/admin/items/': {
id: '/admin/items/'
path: '/items'
fullPath: '/admin/items/'
preLoaderRoute: typeof AdminItemsIndexRouteImport
parentRoute: typeof AdminRoute
}
'/admin/tags/$tagId': {
id: '/admin/tags/$tagId'
path: '/$tagId'
path: '/tags/$tagId'
fullPath: '/admin/tags/$tagId'
preLoaderRoute: typeof AdminTagsTagIdRouteImport
parentRoute: typeof AdminTagsRoute
parentRoute: typeof AdminRoute
}
'/admin/items/$itemId': {
id: '/admin/items/$itemId'
path: '/$itemId'
path: '/items/$itemId'
fullPath: '/admin/items/$itemId'
preLoaderRoute: typeof AdminItemsItemIdRouteImport
parentRoute: typeof AdminItemsRoute
parentRoute: typeof AdminRoute
}
'/threads/$threadId/candidates/$candidateId': {
id: '/threads/$threadId/candidates/$candidateId'
@@ -409,40 +409,20 @@ declare module '@tanstack/react-router' {
}
}
interface AdminItemsRouteChildren {
AdminItemsItemIdRoute: typeof AdminItemsItemIdRoute
}
const AdminItemsRouteChildren: AdminItemsRouteChildren = {
AdminItemsItemIdRoute: AdminItemsItemIdRoute,
}
const AdminItemsRouteWithChildren = AdminItemsRoute._addFileChildren(
AdminItemsRouteChildren,
)
interface AdminTagsRouteChildren {
AdminTagsTagIdRoute: typeof AdminTagsTagIdRoute
}
const AdminTagsRouteChildren: AdminTagsRouteChildren = {
AdminTagsTagIdRoute: AdminTagsTagIdRoute,
}
const AdminTagsRouteWithChildren = AdminTagsRoute._addFileChildren(
AdminTagsRouteChildren,
)
interface AdminRouteChildren {
AdminItemsRoute: typeof AdminItemsRouteWithChildren
AdminTagsRoute: typeof AdminTagsRouteWithChildren
AdminIndexRoute: typeof AdminIndexRoute
AdminItemsItemIdRoute: typeof AdminItemsItemIdRoute
AdminTagsTagIdRoute: typeof AdminTagsTagIdRoute
AdminItemsIndexRoute: typeof AdminItemsIndexRoute
AdminTagsIndexRoute: typeof AdminTagsIndexRoute
}
const AdminRouteChildren: AdminRouteChildren = {
AdminItemsRoute: AdminItemsRouteWithChildren,
AdminTagsRoute: AdminTagsRouteWithChildren,
AdminIndexRoute: AdminIndexRoute,
AdminItemsItemIdRoute: AdminItemsItemIdRoute,
AdminTagsTagIdRoute: AdminTagsTagIdRoute,
AdminItemsIndexRoute: AdminItemsIndexRoute,
AdminTagsIndexRoute: AdminTagsIndexRoute,
}
const AdminRouteWithChildren = AdminRoute._addFileChildren(AdminRouteChildren)

View File

@@ -4,8 +4,8 @@ import {
useAdminGlobalItem,
useDeleteAdminGlobalItem,
useUpdateAdminGlobalItem,
} from "../../hooks/useAdminGlobalItems";
import { apiGet } from "../../lib/api";
} from "../../../hooks/useAdminGlobalItems";
import { apiGet } from "../../../lib/api";
export const Route = createFileRoute("/admin/items/$itemId")({
component: AdminItemEditPage,

View File

@@ -1,10 +1,10 @@
import { createFileRoute, useNavigate } from "@tanstack/react-router";
import { useEffect, useRef, useState } from "react";
import { useAdminGlobalItems } from "../../hooks/useAdminGlobalItems";
import { useFormatters } from "../../hooks/useFormatters";
import { useTags } from "../../hooks/useTags";
import { useAdminGlobalItems } from "../../../hooks/useAdminGlobalItems";
import { useFormatters } from "../../../hooks/useFormatters";
import { useTags } from "../../../hooks/useTags";
export const Route = createFileRoute("/admin/items")({
export const Route = createFileRoute("/admin/items/")({
component: AdminItemsPage,
});

View File

@@ -6,7 +6,7 @@ import {
useAdminTags,
useDeleteAdminTag,
useUpdateAdminTag,
} from "../../hooks/useAdminTags";
} from "../../../hooks/useAdminTags";
export const Route = createFileRoute("/admin/tags/$tagId")({
component: AdminTagEditPage,

View File

@@ -4,10 +4,10 @@ import {
type AdminTag,
useAdminTags,
useCreateAdminTag,
} from "../../hooks/useAdminTags";
import { LucideIcon } from "../../lib/iconData";
} from "../../../hooks/useAdminTags";
import { LucideIcon } from "../../../lib/iconData";
export const Route = createFileRoute("/admin/tags")({
export const Route = createFileRoute("/admin/tags/")({
component: AdminTagsPage,
});