fix: replace invalid TanStack Router search casts with typed defaults
Some checks failed
Build & Release / build (push) Failing after 32s
Some checks failed
Build & Release / build (push) Failing after 32s
Newer TanStack Router enforces strict types on search params — 'search: {} as Record<string, unknown>' no longer satisfies routes with validateSearch. Replace all occurrences with the correct search shape for each destination route (pagination defaults for list routes, tab/field defaults for detail routes).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -67,7 +67,7 @@ function NavLink({ to, icon, label, collapsed }: { to: string; icon: React.React
|
|||||||
return (
|
return (
|
||||||
<Link
|
<Link
|
||||||
to={to as '/accounts'}
|
to={to as '/accounts'}
|
||||||
search={{} as Record<string, unknown>}
|
search={{ page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const }}
|
||||||
className="flex items-center gap-2 px-3 py-2 rounded-md text-sm text-sidebar-foreground hover:bg-sidebar-accent"
|
className="flex items-center gap-2 px-3 py-2 rounded-md text-sm text-sidebar-foreground hover:bg-sidebar-accent"
|
||||||
activeProps={{ className: 'flex items-center gap-2 px-3 py-2 rounded-md text-sm bg-sidebar-accent text-sidebar-accent-foreground' }}
|
activeProps={{ className: 'flex items-center gap-2 px-3 py-2 rounded-md text-sm bg-sidebar-accent text-sidebar-accent-foreground' }}
|
||||||
title={collapsed ? label : undefined}
|
title={collapsed ? label : undefined}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ function AccountEnrollmentsTab() {
|
|||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<p className="text-sm text-muted-foreground">{data?.pagination.total ?? 0} enrollment(s)</p>
|
<p className="text-sm text-muted-foreground">{data?.pagination.total ?? 0} enrollment(s)</p>
|
||||||
{hasPermission('lessons.edit') && (
|
{hasPermission('lessons.edit') && (
|
||||||
<Button size="sm" onClick={() => navigate({ to: '/lessons/enrollments/new', search: {} as Record<string, unknown> })}>
|
<Button size="sm" onClick={() => navigate({ to: '/lessons/enrollments/new', search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })}>
|
||||||
<Plus className="h-4 w-4 mr-1" />Enroll a Member
|
<Plus className="h-4 w-4 mr-1" />Enroll a Member
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
@@ -55,7 +55,7 @@ function AccountEnrollmentsTab() {
|
|||||||
total={data?.data?.length ?? 0}
|
total={data?.data?.length ?? 0}
|
||||||
onPageChange={() => {}}
|
onPageChange={() => {}}
|
||||||
onSort={() => {}}
|
onSort={() => {}}
|
||||||
onRowClick={(e) => navigate({ to: '/lessons/enrollments/$enrollmentId', params: { enrollmentId: e.id }, search: {} as Record<string, unknown> })}
|
onRowClick={(e) => navigate({ to: '/lessons/enrollments/$enrollmentId', params: { enrollmentId: e.id }, search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -281,7 +281,7 @@ function MembersTab() {
|
|||||||
<DropdownMenuItem onClick={() => navigate({
|
<DropdownMenuItem onClick={() => navigate({
|
||||||
to: '/members/$memberId',
|
to: '/members/$memberId',
|
||||||
params: { memberId: m.id },
|
params: { memberId: m.id },
|
||||||
search: {} as Record<string, unknown>,
|
search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const },
|
||||||
})}>
|
})}>
|
||||||
<Pencil className="mr-2 h-4 w-4" />
|
<Pencil className="mr-2 h-4 w-4" />
|
||||||
Edit
|
Edit
|
||||||
|
|||||||
@@ -2,6 +2,6 @@ import { createFileRoute, redirect } from '@tanstack/react-router'
|
|||||||
|
|
||||||
export const Route = createFileRoute('/_authenticated/')({
|
export const Route = createFileRoute('/_authenticated/')({
|
||||||
beforeLoad: () => {
|
beforeLoad: () => {
|
||||||
throw redirect({ to: '/accounts', search: {} as Record<string, unknown> })
|
throw redirect({ to: '/accounts', search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ function ProductDetailPage() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
function setTab(t: string) {
|
function setTab(t: string) {
|
||||||
navigate({ to: '/inventory/$productId', params: { productId }, search: { tab: t } as Record<string, unknown> })
|
navigate({ to: '/inventory/$productId', params: { productId }, search: { tab: t } })
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleQtySave() {
|
function handleQtySave() {
|
||||||
@@ -192,7 +192,7 @@ function ProductDetailPage() {
|
|||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<Button variant="ghost" size="sm" onClick={() => navigate({ to: '/inventory', search: {} as Record<string, unknown> })}>
|
<Button variant="ghost" size="sm" onClick={() => navigate({ to: '/inventory', search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })}>
|
||||||
<ArrowLeft className="h-4 w-4" />
|
<ArrowLeft className="h-4 w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
<div className="min-w-0">
|
<div className="min-w-0">
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ function InventoryPage() {
|
|||||||
queryClient.invalidateQueries({ queryKey: productKeys.all })
|
queryClient.invalidateQueries({ queryKey: productKeys.all })
|
||||||
toast.success('Product created')
|
toast.success('Product created')
|
||||||
setCreateOpen(false)
|
setCreateOpen(false)
|
||||||
navigate({ to: '/inventory/$productId', params: { productId: product.id }, search: {} as Record<string, unknown> })
|
navigate({ to: '/inventory/$productId', params: { productId: product.id }, search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })
|
||||||
},
|
},
|
||||||
onError: (err) => toast.error(err.message),
|
onError: (err) => toast.error(err.message),
|
||||||
})
|
})
|
||||||
@@ -83,23 +83,23 @@ function InventoryPage() {
|
|||||||
|
|
||||||
function handleCategoryChange(v: string) {
|
function handleCategoryChange(v: string) {
|
||||||
setCategoryFilter(v === 'all' ? '' : v)
|
setCategoryFilter(v === 'all' ? '' : v)
|
||||||
navigate({ to: '/inventory', search: { ...search, categoryId: v === 'all' ? undefined : v, page: 1 } as Record<string, unknown> })
|
navigate({ to: '/inventory', search: { ...search, categoryId: v === 'all' ? undefined : v, page: 1 } })
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleActiveChange(v: string) {
|
function handleActiveChange(v: string) {
|
||||||
setActiveFilter(v === 'all' ? '' : v)
|
setActiveFilter(v === 'all' ? '' : v)
|
||||||
navigate({ to: '/inventory', search: { ...search, isActive: v === 'all' ? undefined : v, page: 1 } as Record<string, unknown> })
|
navigate({ to: '/inventory', search: { ...search, isActive: v === 'all' ? undefined : v, page: 1 } })
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleTypeChange(v: string) {
|
function handleTypeChange(v: string) {
|
||||||
setTypeFilter(v === 'all' ? '' : v)
|
setTypeFilter(v === 'all' ? '' : v)
|
||||||
navigate({ to: '/inventory', search: { ...search, type: v === 'all' ? undefined : v, page: 1 } as Record<string, unknown> })
|
navigate({ to: '/inventory', search: { ...search, type: v === 'all' ? undefined : v, page: 1 } })
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleLowStockChange(v: string) {
|
function handleLowStockChange(v: string) {
|
||||||
const on = v === 'true'
|
const on = v === 'true'
|
||||||
setLowStockFilter(on)
|
setLowStockFilter(on)
|
||||||
navigate({ to: '/inventory', search: { ...search, lowStock: on ? 'true' : undefined, page: 1 } as Record<string, unknown> })
|
navigate({ to: '/inventory', search: { ...search, lowStock: on ? 'true' : undefined, page: 1 } })
|
||||||
}
|
}
|
||||||
|
|
||||||
const columns: Column<Product>[] = [
|
const columns: Column<Product>[] = [
|
||||||
@@ -246,7 +246,7 @@ function InventoryPage() {
|
|||||||
order={params.order}
|
order={params.order}
|
||||||
onPageChange={setPage}
|
onPageChange={setPage}
|
||||||
onSort={setSort}
|
onSort={setSort}
|
||||||
onRowClick={(p) => navigate({ to: '/inventory/$productId', params: { productId: p.id }, search: {} as Record<string, unknown> })}
|
onRowClick={(p) => navigate({ to: '/inventory/$productId', params: { productId: p.id }, search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ function EnrollmentDetailPage() {
|
|||||||
const tab = search.tab
|
const tab = search.tab
|
||||||
|
|
||||||
function setTab(t: string) {
|
function setTab(t: string) {
|
||||||
navigate({ to: '/lessons/enrollments/$enrollmentId', params: { enrollmentId }, search: { tab: t } as Record<string, unknown> })
|
navigate({ to: '/lessons/enrollments/$enrollmentId', params: { enrollmentId }, search: { tab: t } })
|
||||||
}
|
}
|
||||||
|
|
||||||
const { data: enrollment, isLoading } = useQuery(enrollmentDetailOptions(enrollmentId))
|
const { data: enrollment, isLoading } = useQuery(enrollmentDetailOptions(enrollmentId))
|
||||||
@@ -131,7 +131,7 @@ function EnrollmentDetailPage() {
|
|||||||
return (
|
return (
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
<div className="flex items-center gap-4">
|
<div className="flex items-center gap-4">
|
||||||
<Button variant="ghost" size="sm" onClick={() => navigate({ to: '/lessons/enrollments', search: {} as Record<string, unknown> })}>
|
<Button variant="ghost" size="sm" onClick={() => navigate({ to: '/lessons/enrollments', search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })}>
|
||||||
<ArrowLeft className="h-4 w-4 mr-1" />Back
|
<ArrowLeft className="h-4 w-4 mr-1" />Back
|
||||||
</Button>
|
</Button>
|
||||||
<div className="flex-1">
|
<div className="flex-1">
|
||||||
@@ -344,7 +344,7 @@ function SessionsTab({ enrollmentId, onGenerate, generating }: { enrollmentId: s
|
|||||||
total={data?.data?.length ?? 0}
|
total={data?.data?.length ?? 0}
|
||||||
onPageChange={() => {}}
|
onPageChange={() => {}}
|
||||||
onSort={() => {}}
|
onSort={() => {}}
|
||||||
onRowClick={(s) => navigate({ to: '/lessons/sessions/$sessionId', params: { sessionId: s.id }, search: {} as Record<string, unknown> })}
|
onRowClick={(s) => navigate({ to: '/lessons/sessions/$sessionId', params: { sessionId: s.id }, search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
@@ -383,7 +383,7 @@ function LessonPlanTab({ enrollmentId, memberId, canEdit }: { enrollmentId: stri
|
|||||||
queryClient.invalidateQueries({ queryKey: lessonPlanKeys.all })
|
queryClient.invalidateQueries({ queryKey: lessonPlanKeys.all })
|
||||||
toast.success('Plan created from template')
|
toast.success('Plan created from template')
|
||||||
setTemplatePickerOpen(false)
|
setTemplatePickerOpen(false)
|
||||||
navigate({ to: '/lessons/plans/$planId', params: { planId: plan.id }, search: {} as Record<string, unknown> })
|
navigate({ to: '/lessons/plans/$planId', params: { planId: plan.id }, search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })
|
||||||
},
|
},
|
||||||
onError: (err) => toast.error(err.message),
|
onError: (err) => toast.error(err.message),
|
||||||
})
|
})
|
||||||
@@ -401,7 +401,7 @@ function LessonPlanTab({ enrollmentId, memberId, canEdit }: { enrollmentId: stri
|
|||||||
{Math.round(activePlan.progress)}% complete
|
{Math.round(activePlan.progress)}% complete
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<Button variant="outline" size="sm" onClick={() => navigate({ to: '/lessons/plans/$planId', params: { planId: activePlan.id }, search: {} as Record<string, unknown> })}>
|
<Button variant="outline" size="sm" onClick={() => navigate({ to: '/lessons/plans/$planId', params: { planId: activePlan.id }, search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })}>
|
||||||
View Plan
|
View Plan
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ function EnrollmentsListPage() {
|
|||||||
function handleStatusChange(v: string) {
|
function handleStatusChange(v: string) {
|
||||||
const s = v === 'all' ? '' : v
|
const s = v === 'all' ? '' : v
|
||||||
setStatusFilter(s)
|
setStatusFilter(s)
|
||||||
navigate({ to: '/lessons/enrollments', search: { ...search, status: s || undefined, page: 1 } as Record<string, unknown> })
|
navigate({ to: '/lessons/enrollments', search: { ...search, status: s || undefined, page: 1 } })
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -80,7 +80,7 @@ function EnrollmentsListPage() {
|
|||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<h1 className="text-2xl font-bold">Enrollments</h1>
|
<h1 className="text-2xl font-bold">Enrollments</h1>
|
||||||
{hasPermission('lessons.edit') && (
|
{hasPermission('lessons.edit') && (
|
||||||
<Button onClick={() => navigate({ to: '/lessons/enrollments/new', search: {} as Record<string, unknown> })}>
|
<Button onClick={() => navigate({ to: '/lessons/enrollments/new', search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })}>
|
||||||
<Plus className="mr-2 h-4 w-4" />New Enrollment
|
<Plus className="mr-2 h-4 w-4" />New Enrollment
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
@@ -125,7 +125,7 @@ function EnrollmentsListPage() {
|
|||||||
order={params.order}
|
order={params.order}
|
||||||
onPageChange={setPage}
|
onPageChange={setPage}
|
||||||
onSort={setSort}
|
onSort={setSort}
|
||||||
onRowClick={(e) => navigate({ to: '/lessons/enrollments/$enrollmentId', params: { enrollmentId: e.id }, search: {} as Record<string, unknown> })}
|
onRowClick={(e) => navigate({ to: '/lessons/enrollments/$enrollmentId', params: { enrollmentId: e.id }, search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ function NewEnrollmentPage() {
|
|||||||
},
|
},
|
||||||
onSuccess: (enrollment) => {
|
onSuccess: (enrollment) => {
|
||||||
toast.success('Enrollment created')
|
toast.success('Enrollment created')
|
||||||
navigate({ to: '/lessons/enrollments/$enrollmentId', params: { enrollmentId: enrollment.id }, search: {} as Record<string, unknown> })
|
navigate({ to: '/lessons/enrollments/$enrollmentId', params: { enrollmentId: enrollment.id }, search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })
|
||||||
},
|
},
|
||||||
onError: (err) => toast.error(err.message),
|
onError: (err) => toast.error(err.message),
|
||||||
})
|
})
|
||||||
@@ -141,7 +141,7 @@ function NewEnrollmentPage() {
|
|||||||
return (
|
return (
|
||||||
<div className="space-y-6 max-w-2xl">
|
<div className="space-y-6 max-w-2xl">
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<Button variant="ghost" size="sm" onClick={() => navigate({ to: '/lessons/enrollments', search: {} as Record<string, unknown> })}>
|
<Button variant="ghost" size="sm" onClick={() => navigate({ to: '/lessons/enrollments', search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })}>
|
||||||
<ArrowLeft className="h-4 w-4" />
|
<ArrowLeft className="h-4 w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
<h1 className="text-2xl font-bold">New Enrollment</h1>
|
<h1 className="text-2xl font-bold">New Enrollment</h1>
|
||||||
@@ -282,7 +282,7 @@ function NewEnrollmentPage() {
|
|||||||
<Button type="submit" disabled={mutation.isPending || !selectedMember || !selectedSlotId || !startDate} size="lg">
|
<Button type="submit" disabled={mutation.isPending || !selectedMember || !selectedSlotId || !startDate} size="lg">
|
||||||
{mutation.isPending ? 'Creating...' : 'Create Enrollment'}
|
{mutation.isPending ? 'Creating...' : 'Create Enrollment'}
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="secondary" type="button" size="lg" onClick={() => navigate({ to: '/lessons/enrollments', search: {} as Record<string, unknown> })}>
|
<Button variant="secondary" type="button" size="lg" onClick={() => navigate({ to: '/lessons/enrollments', search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })}>
|
||||||
Cancel
|
Cancel
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ function LessonPlanDetailPage() {
|
|||||||
return (
|
return (
|
||||||
<div className="space-y-6 max-w-3xl">
|
<div className="space-y-6 max-w-3xl">
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<Button variant="ghost" size="sm" onClick={() => navigate({ to: '/lessons/plans', search: {} as Record<string, unknown> })}>
|
<Button variant="ghost" size="sm" onClick={() => navigate({ to: '/lessons/plans', search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })}>
|
||||||
<ArrowLeft className="h-4 w-4" />
|
<ArrowLeft className="h-4 w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
<div className="flex-1">
|
<div className="flex-1">
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ function LessonPlansPage() {
|
|||||||
order={params.order}
|
order={params.order}
|
||||||
onPageChange={setPage}
|
onPageChange={setPage}
|
||||||
onSort={setSort}
|
onSort={setSort}
|
||||||
onRowClick={(p) => navigate({ to: '/lessons/plans/$planId', params: { planId: p.id }, search: {} as Record<string, unknown> })}
|
onRowClick={(p) => navigate({ to: '/lessons/plans/$planId', params: { planId: p.id }, search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ function ScheduleHubPage() {
|
|||||||
const canAdmin = hasPermission('lessons.admin')
|
const canAdmin = hasPermission('lessons.admin')
|
||||||
|
|
||||||
function setTab(t: string) {
|
function setTab(t: string) {
|
||||||
navigate({ to: '/lessons/schedule', search: { ...search, tab: t, page: 1 } as Record<string, unknown> })
|
navigate({ to: '/lessons/schedule', search: { ...search, tab: t, page: 1 } })
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -152,7 +152,7 @@ function InstructorsTab({ canAdmin, search: _search }: { canAdmin: boolean; sear
|
|||||||
order={params.order}
|
order={params.order}
|
||||||
onPageChange={setPage}
|
onPageChange={setPage}
|
||||||
onSort={setSort}
|
onSort={setSort}
|
||||||
onRowClick={(i) => navigate({ to: '/lessons/schedule/instructors/$instructorId', params: { instructorId: i.id }, search: {} as Record<string, unknown> })}
|
onRowClick={(i) => navigate({ to: '/lessons/schedule/instructors/$instructorId', params: { instructorId: i.id }, search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ function InstructorDetailPage() {
|
|||||||
const tab = search.tab
|
const tab = search.tab
|
||||||
|
|
||||||
function setTab(t: string) {
|
function setTab(t: string) {
|
||||||
navigate({ to: '/lessons/schedule/instructors/$instructorId', params: { instructorId }, search: { tab: t } as Record<string, unknown> })
|
navigate({ to: '/lessons/schedule/instructors/$instructorId', params: { instructorId }, search: { tab: t } })
|
||||||
}
|
}
|
||||||
|
|
||||||
const { data: instructor, isLoading } = useQuery(instructorDetailOptions(instructorId))
|
const { data: instructor, isLoading } = useQuery(instructorDetailOptions(instructorId))
|
||||||
@@ -62,7 +62,7 @@ function InstructorDetailPage() {
|
|||||||
return (
|
return (
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
<div className="flex items-center gap-4">
|
<div className="flex items-center gap-4">
|
||||||
<Button variant="ghost" size="sm" onClick={() => navigate({ to: '/lessons/schedule', search: { tab: 'instructors' } as Record<string, unknown> })}>
|
<Button variant="ghost" size="sm" onClick={() => navigate({ to: '/lessons/schedule', search: { tab: 'instructors', page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })}>
|
||||||
<ArrowLeft className="h-4 w-4 mr-1" />Back
|
<ArrowLeft className="h-4 w-4 mr-1" />Back
|
||||||
</Button>
|
</Button>
|
||||||
<div className="flex-1">
|
<div className="flex-1">
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ function SessionDetailPage() {
|
|||||||
return (
|
return (
|
||||||
<div className="space-y-6 max-w-3xl">
|
<div className="space-y-6 max-w-3xl">
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<Button variant="ghost" size="sm" onClick={() => navigate({ to: '/lessons/sessions', search: {} as Record<string, unknown> })}>
|
<Button variant="ghost" size="sm" onClick={() => navigate({ to: '/lessons/sessions', search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })}>
|
||||||
<ArrowLeft className="h-4 w-4" />
|
<ArrowLeft className="h-4 w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
<div className="flex-1">
|
<div className="flex-1">
|
||||||
@@ -137,7 +137,7 @@ function SessionDetailPage() {
|
|||||||
<Link
|
<Link
|
||||||
to="/lessons/enrollments/$enrollmentId"
|
to="/lessons/enrollments/$enrollmentId"
|
||||||
params={{ enrollmentId: enrollment.id }}
|
params={{ enrollmentId: enrollment.id }}
|
||||||
search={{} as Record<string, unknown>}
|
search={{ tab: 'details' }}
|
||||||
className="text-sm text-primary hover:underline"
|
className="text-sm text-primary hover:underline"
|
||||||
>
|
>
|
||||||
View Enrollment
|
View Enrollment
|
||||||
|
|||||||
@@ -92,13 +92,13 @@ function SessionsPage() {
|
|||||||
const weekEnd = endOfWeek(weekStart, { weekStartsOn: 0 })
|
const weekEnd = endOfWeek(weekStart, { weekStartsOn: 0 })
|
||||||
|
|
||||||
function setView(v: 'list' | 'week') {
|
function setView(v: 'list' | 'week') {
|
||||||
navigate({ to: '/lessons/sessions', search: { ...search, view: v, page: 1 } as Record<string, unknown> })
|
navigate({ to: '/lessons/sessions', search: { ...search, view: v, page: 1 } })
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleStatusChange(v: string) {
|
function handleStatusChange(v: string) {
|
||||||
const s = v === 'all' ? '' : v
|
const s = v === 'all' ? '' : v
|
||||||
setStatusFilter(s)
|
setStatusFilter(s)
|
||||||
navigate({ to: '/lessons/sessions', search: { ...search, status: s || undefined, page: 1 } as Record<string, unknown> })
|
navigate({ to: '/lessons/sessions', search: { ...search, status: s || undefined, page: 1 } })
|
||||||
}
|
}
|
||||||
|
|
||||||
// List query
|
// List query
|
||||||
@@ -189,7 +189,7 @@ function SessionsPage() {
|
|||||||
order={params.order}
|
order={params.order}
|
||||||
onPageChange={setPage}
|
onPageChange={setPage}
|
||||||
onSort={setSort}
|
onSort={setSort}
|
||||||
onRowClick={(s) => navigate({ to: '/lessons/sessions/$sessionId', params: { sessionId: s.id }, search: {} as Record<string, unknown> })}
|
onRowClick={(s) => navigate({ to: '/lessons/sessions/$sessionId', params: { sessionId: s.id }, search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
@@ -249,7 +249,7 @@ function SessionsPage() {
|
|||||||
{daySessions.map((s) => (
|
{daySessions.map((s) => (
|
||||||
<button
|
<button
|
||||||
key={s.id}
|
key={s.id}
|
||||||
onClick={() => navigate({ to: '/lessons/sessions/$sessionId', params: { sessionId: s.id }, search: {} as Record<string, unknown> })}
|
onClick={() => navigate({ to: '/lessons/sessions/$sessionId', params: { sessionId: s.id }, search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })}
|
||||||
className={`w-full text-left rounded border px-1.5 py-1 text-xs hover:opacity-80 transition-opacity ${STATUS_COLORS[s.status] ?? STATUS_COLORS.scheduled}`}
|
className={`w-full text-left rounded border px-1.5 py-1 text-xs hover:opacity-80 transition-opacity ${STATUS_COLORS[s.status] ?? STATUS_COLORS.scheduled}`}
|
||||||
>
|
>
|
||||||
<p className="font-semibold">{formatTime(s.scheduledTime)}</p>
|
<p className="font-semibold">{formatTime(s.scheduledTime)}</p>
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ function TemplateDetailPage() {
|
|||||||
return (
|
return (
|
||||||
<div className="space-y-6 max-w-3xl">
|
<div className="space-y-6 max-w-3xl">
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<Button variant="ghost" size="sm" onClick={() => navigate({ to: '/lessons/templates', search: {} as Record<string, unknown> })}>
|
<Button variant="ghost" size="sm" onClick={() => navigate({ to: '/lessons/templates', search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })}>
|
||||||
<ArrowLeft className="h-4 w-4" />
|
<ArrowLeft className="h-4 w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
<div className="flex-1">
|
<div className="flex-1">
|
||||||
@@ -218,7 +218,7 @@ function InstantiateDialog({ template, templateId, open, onClose }: {
|
|||||||
}),
|
}),
|
||||||
onSuccess: (plan) => {
|
onSuccess: (plan) => {
|
||||||
toast.success('Plan created from template')
|
toast.success('Plan created from template')
|
||||||
navigate({ to: '/lessons/plans/$planId', params: { planId: plan.id }, search: {} as Record<string, unknown> })
|
navigate({ to: '/lessons/plans/$planId', params: { planId: plan.id }, search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })
|
||||||
},
|
},
|
||||||
onError: (err) => toast.error(err.message),
|
onError: (err) => toast.error(err.message),
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ function TemplatesListPage() {
|
|||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<h1 className="text-2xl font-bold">Lesson Plan Templates</h1>
|
<h1 className="text-2xl font-bold">Lesson Plan Templates</h1>
|
||||||
{canAdmin && (
|
{canAdmin && (
|
||||||
<Button onClick={() => navigate({ to: '/lessons/templates/new', search: {} as Record<string, unknown> })}>
|
<Button onClick={() => navigate({ to: '/lessons/templates/new', search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })}>
|
||||||
<Plus className="mr-2 h-4 w-4" />New Template
|
<Plus className="mr-2 h-4 w-4" />New Template
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
@@ -126,7 +126,7 @@ function TemplatesListPage() {
|
|||||||
order={params.order}
|
order={params.order}
|
||||||
onPageChange={setPage}
|
onPageChange={setPage}
|
||||||
onSort={setSort}
|
onSort={setSort}
|
||||||
onRowClick={(t) => navigate({ to: '/lessons/templates/$templateId', params: { templateId: t.id }, search: {} as Record<string, unknown> })}
|
onRowClick={(t) => navigate({ to: '/lessons/templates/$templateId', params: { templateId: t.id }, search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ function NewTemplatePage() {
|
|||||||
}),
|
}),
|
||||||
onSuccess: (template) => {
|
onSuccess: (template) => {
|
||||||
toast.success('Template created')
|
toast.success('Template created')
|
||||||
navigate({ to: '/lessons/templates/$templateId', params: { templateId: template.id }, search: {} as Record<string, unknown> })
|
navigate({ to: '/lessons/templates/$templateId', params: { templateId: template.id }, search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })
|
||||||
},
|
},
|
||||||
onError: (err) => toast.error(err.message),
|
onError: (err) => toast.error(err.message),
|
||||||
})
|
})
|
||||||
@@ -63,7 +63,7 @@ function NewTemplatePage() {
|
|||||||
return (
|
return (
|
||||||
<form onSubmit={handleSubmit} className="space-y-6 max-w-3xl">
|
<form onSubmit={handleSubmit} className="space-y-6 max-w-3xl">
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<Button type="button" variant="ghost" size="sm" onClick={() => navigate({ to: '/lessons/templates', search: {} as Record<string, unknown> })}>
|
<Button type="button" variant="ghost" size="sm" onClick={() => navigate({ to: '/lessons/templates', search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })}>
|
||||||
<ArrowLeft className="h-4 w-4" />
|
<ArrowLeft className="h-4 w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
<h1 className="text-2xl font-bold">New Template</h1>
|
<h1 className="text-2xl font-bold">New Template</h1>
|
||||||
@@ -112,7 +112,7 @@ function NewTemplatePage() {
|
|||||||
<Button type="submit" disabled={mutation.isPending || !name.trim() || !allSectionsValid} size="lg">
|
<Button type="submit" disabled={mutation.isPending || !name.trim() || !allSectionsValid} size="lg">
|
||||||
{mutation.isPending ? 'Creating...' : 'Create Template'}
|
{mutation.isPending ? 'Creating...' : 'Create Template'}
|
||||||
</Button>
|
</Button>
|
||||||
<Button type="button" variant="secondary" size="lg" onClick={() => navigate({ to: '/lessons/templates', search: {} as Record<string, unknown> })}>
|
<Button type="button" variant="secondary" size="lg" onClick={() => navigate({ to: '/lessons/templates', search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })}>
|
||||||
Cancel
|
Cancel
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -161,7 +161,7 @@ function MemberDetailPage() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
function setTab(t: string) {
|
function setTab(t: string) {
|
||||||
navigate({ to: '/members/$memberId', params: { memberId }, search: { tab: t } as Record<string, unknown> })
|
navigate({ to: '/members/$memberId', params: { memberId }, search: { tab: t } })
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
@@ -188,7 +188,7 @@ function MemberDetailPage() {
|
|||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<Button variant="ghost" size="sm" onClick={() => navigate({ to: '/accounts/$accountId/members', params: { accountId: member.accountId }, search: {} as Record<string, unknown> })}>
|
<Button variant="ghost" size="sm" onClick={() => navigate({ to: '/accounts/$accountId/members', params: { accountId: member.accountId }, search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })}>
|
||||||
<ArrowLeft className="h-4 w-4" />
|
<ArrowLeft className="h-4 w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
<div>
|
<div>
|
||||||
@@ -293,7 +293,7 @@ function MemberDetailPage() {
|
|||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<p className="text-sm text-muted-foreground">{enrollmentsData?.pagination.total ?? 0} enrollment(s)</p>
|
<p className="text-sm text-muted-foreground">{enrollmentsData?.pagination.total ?? 0} enrollment(s)</p>
|
||||||
{hasPermission('lessons.edit') && (
|
{hasPermission('lessons.edit') && (
|
||||||
<Button size="sm" onClick={() => navigate({ to: '/lessons/enrollments/new', search: { memberId } as Record<string, unknown> })}>
|
<Button size="sm" onClick={() => navigate({ to: '/lessons/enrollments/new', search: { memberId } })}>
|
||||||
<Plus className="h-4 w-4 mr-1" />Enroll
|
<Plus className="h-4 w-4 mr-1" />Enroll
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
@@ -307,7 +307,7 @@ function MemberDetailPage() {
|
|||||||
total={enrollmentsData?.data?.length ?? 0}
|
total={enrollmentsData?.data?.length ?? 0}
|
||||||
onPageChange={() => {}}
|
onPageChange={() => {}}
|
||||||
onSort={() => {}}
|
onSort={() => {}}
|
||||||
onRowClick={(e) => navigate({ to: '/lessons/enrollments/$enrollmentId', params: { enrollmentId: e.id }, search: {} as Record<string, unknown> })}
|
onRowClick={(e) => navigate({ to: '/lessons/enrollments/$enrollmentId', params: { enrollmentId: e.id }, search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ function MembersListPage() {
|
|||||||
</Button>
|
</Button>
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent align="end">
|
<DropdownMenuContent align="end">
|
||||||
<DropdownMenuItem onClick={() => navigate({ to: '/members/$memberId', params: { memberId: row.id }, search: {} as Record<string, unknown> })}>
|
<DropdownMenuItem onClick={() => navigate({ to: '/members/$memberId', params: { memberId: row.id }, search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })}>
|
||||||
<Pencil className="mr-2 h-4 w-4" />
|
<Pencil className="mr-2 h-4 w-4" />
|
||||||
Edit
|
Edit
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
@@ -134,7 +134,7 @@ function MembersListPage() {
|
|||||||
order={params.order}
|
order={params.order}
|
||||||
onPageChange={setPage}
|
onPageChange={setPage}
|
||||||
onSort={setSort}
|
onSort={setSort}
|
||||||
onRowClick={(member) => navigate({ to: '/members/$memberId', params: { memberId: member.id }, search: {} as Record<string, unknown> })}
|
onRowClick={(member) => navigate({ to: '/members/$memberId', params: { memberId: member.id }, search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -96,12 +96,12 @@ function RepairBatchDetailPage() {
|
|||||||
const totalActual = tickets.reduce((sum, t) => sum + (t.actualCost ? parseFloat(t.actualCost) : 0), 0)
|
const totalActual = tickets.reduce((sum, t) => sum + (t.actualCost ? parseFloat(t.actualCost) : 0), 0)
|
||||||
|
|
||||||
function handleTicketClick(ticket: RepairTicket) {
|
function handleTicketClick(ticket: RepairTicket) {
|
||||||
navigate({ to: '/repairs/$ticketId', params: { ticketId: ticket.id }, search: {} as Record<string, unknown> })
|
navigate({ to: '/repairs/$ticketId', params: { ticketId: ticket.id }, search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleAddRepair() {
|
function handleAddRepair() {
|
||||||
// Navigate to new repair with batch and account pre-linked
|
// Navigate to new repair with batch and account pre-linked
|
||||||
navigate({ to: '/repairs/new', search: { batchId, batchName: batch!.batchNumber ?? '', accountId: batch!.accountId, contactName: batch!.contactName ?? '' } as Record<string, unknown> })
|
navigate({ to: '/repairs/new', search: { batchId, batchName: batch!.batchNumber ?? '', accountId: batch!.accountId, contactName: batch!.contactName ?? '' } })
|
||||||
}
|
}
|
||||||
|
|
||||||
async function generateBatchPdf() {
|
async function generateBatchPdf() {
|
||||||
@@ -233,7 +233,7 @@ function RepairBatchDetailPage() {
|
|||||||
return (
|
return (
|
||||||
<div className="space-y-6 max-w-5xl">
|
<div className="space-y-6 max-w-5xl">
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<Button variant="ghost" size="sm" onClick={() => navigate({ to: '/repair-batches', search: {} as Record<string, unknown> })}>
|
<Button variant="ghost" size="sm" onClick={() => navigate({ to: '/repair-batches', search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })}>
|
||||||
<ArrowLeft className="h-4 w-4" />
|
<ArrowLeft className="h-4 w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
<div className="flex-1">
|
<div className="flex-1">
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ function RepairBatchesListPage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleRowClick(batch: RepairBatch) {
|
function handleRowClick(batch: RepairBatch) {
|
||||||
navigate({ to: '/repair-batches/$batchId', params: { batchId: batch.id }, search: {} as Record<string, unknown> })
|
navigate({ to: '/repair-batches/$batchId', params: { batchId: batch.id }, search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ function NewRepairBatchPage() {
|
|||||||
mutationFn: repairBatchMutations.create,
|
mutationFn: repairBatchMutations.create,
|
||||||
onSuccess: (batch) => {
|
onSuccess: (batch) => {
|
||||||
toast.success('Repair batch created')
|
toast.success('Repair batch created')
|
||||||
navigate({ to: '/repair-batches/$batchId', params: { batchId: batch.id }, search: {} as Record<string, unknown> })
|
navigate({ to: '/repair-batches/$batchId', params: { batchId: batch.id }, search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })
|
||||||
},
|
},
|
||||||
onError: (err) => toast.error(err.message),
|
onError: (err) => toast.error(err.message),
|
||||||
})
|
})
|
||||||
@@ -78,7 +78,7 @@ function NewRepairBatchPage() {
|
|||||||
return (
|
return (
|
||||||
<div className="space-y-6 max-w-3xl">
|
<div className="space-y-6 max-w-3xl">
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<Button variant="ghost" size="sm" onClick={() => navigate({ to: '/repair-batches', search: {} as Record<string, unknown> })}>
|
<Button variant="ghost" size="sm" onClick={() => navigate({ to: '/repair-batches', search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })}>
|
||||||
<ArrowLeft className="h-4 w-4" />
|
<ArrowLeft className="h-4 w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
<h1 className="text-2xl font-bold">New Repair Batch</h1>
|
<h1 className="text-2xl font-bold">New Repair Batch</h1>
|
||||||
@@ -176,7 +176,7 @@ function NewRepairBatchPage() {
|
|||||||
<Button type="submit" disabled={mutation.isPending} size="lg">
|
<Button type="submit" disabled={mutation.isPending} size="lg">
|
||||||
{mutation.isPending ? 'Creating...' : 'Create Batch'}
|
{mutation.isPending ? 'Creating...' : 'Create Batch'}
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="secondary" type="button" size="lg" onClick={() => navigate({ to: '/repair-batches', search: {} as Record<string, unknown> })}>
|
<Button variant="secondary" type="button" size="lg" onClick={() => navigate({ to: '/repair-batches', search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })}>
|
||||||
Cancel
|
Cancel
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ function RepairTicketDetailPage() {
|
|||||||
<div className="space-y-4 max-w-5xl">
|
<div className="space-y-4 max-w-5xl">
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<Button variant="ghost" size="sm" onClick={() => navigate({ to: '/repairs', search: {} as Record<string, unknown> })}>
|
<Button variant="ghost" size="sm" onClick={() => navigate({ to: '/repairs', search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })}>
|
||||||
<ArrowLeft className="h-4 w-4" />
|
<ArrowLeft className="h-4 w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
<div className="flex-1">
|
<div className="flex-1">
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ function RepairsListPage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleRowClick(ticket: RepairTicket) {
|
function handleRowClick(ticket: RepairTicket) {
|
||||||
navigate({ to: '/repairs/$ticketId', params: { ticketId: ticket.id }, search: {} as Record<string, unknown> })
|
navigate({ to: '/repairs/$ticketId', params: { ticketId: ticket.id }, search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -137,7 +137,7 @@ function RepairsListPage() {
|
|||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<h1 className="text-2xl font-bold">Repairs</h1>
|
<h1 className="text-2xl font-bold">Repairs</h1>
|
||||||
{hasPermission('repairs.edit') && (
|
{hasPermission('repairs.edit') && (
|
||||||
<Button onClick={() => navigate({ to: '/repairs/new', search: {} as Record<string, unknown> })}>
|
<Button onClick={() => navigate({ to: '/repairs/new', search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })}>
|
||||||
<Plus className="mr-2 h-4 w-4" />
|
<Plus className="mr-2 h-4 w-4" />
|
||||||
New Repair
|
New Repair
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ function NewRepairPage() {
|
|||||||
},
|
},
|
||||||
onSuccess: (ticket) => {
|
onSuccess: (ticket) => {
|
||||||
toast.success('Repair ticket created')
|
toast.success('Repair ticket created')
|
||||||
navigate({ to: '/repairs/$ticketId', params: { ticketId: ticket.id }, search: {} as Record<string, unknown> })
|
navigate({ to: '/repairs/$ticketId', params: { ticketId: ticket.id }, search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })
|
||||||
},
|
},
|
||||||
onError: (err) => toast.error(err.message),
|
onError: (err) => toast.error(err.message),
|
||||||
})
|
})
|
||||||
@@ -210,7 +210,7 @@ function NewRepairPage() {
|
|||||||
return (
|
return (
|
||||||
<div className="space-y-6 max-w-4xl">
|
<div className="space-y-6 max-w-4xl">
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<Button variant="ghost" size="sm" onClick={() => navigate({ to: '/repairs', search: {} as Record<string, unknown> })}>
|
<Button variant="ghost" size="sm" onClick={() => navigate({ to: '/repairs', search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })}>
|
||||||
<ArrowLeft className="h-4 w-4" />
|
<ArrowLeft className="h-4 w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
<h1 className="text-2xl font-bold">New Repair Ticket</h1>
|
<h1 className="text-2xl font-bold">New Repair Ticket</h1>
|
||||||
@@ -486,7 +486,7 @@ function NewRepairPage() {
|
|||||||
<Button type="submit" disabled={mutation.isPending} size="lg">
|
<Button type="submit" disabled={mutation.isPending} size="lg">
|
||||||
{mutation.isPending ? 'Creating...' : 'Create Ticket'}
|
{mutation.isPending ? 'Creating...' : 'Create Ticket'}
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="secondary" type="button" size="lg" onClick={() => navigate({ to: '/repairs', search: {} as Record<string, unknown> })}>
|
<Button variant="secondary" type="button" size="lg" onClick={() => navigate({ to: '/repairs', search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })}>
|
||||||
Cancel
|
Cancel
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ function RoleDetailPage() {
|
|||||||
return (
|
return (
|
||||||
<div className="space-y-6 max-w-2xl">
|
<div className="space-y-6 max-w-2xl">
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<Button variant="ghost" size="sm" onClick={() => navigate({ to: '/roles', search: {} as Record<string, unknown> })}>
|
<Button variant="ghost" size="sm" onClick={() => navigate({ to: '/roles', search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })}>
|
||||||
<ArrowLeft className="h-4 w-4" />
|
<ArrowLeft className="h-4 w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
<div>
|
<div>
|
||||||
@@ -177,7 +177,7 @@ function RoleDetailPage() {
|
|||||||
<Button onClick={handleSave} disabled={updateMutation.isPending}>
|
<Button onClick={handleSave} disabled={updateMutation.isPending}>
|
||||||
{updateMutation.isPending ? 'Saving...' : 'Save Changes'}
|
{updateMutation.isPending ? 'Saving...' : 'Save Changes'}
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="secondary" onClick={() => navigate({ to: '/roles', search: {} as Record<string, unknown> })}>
|
<Button variant="secondary" onClick={() => navigate({ to: '/roles', search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })}>
|
||||||
Cancel
|
Cancel
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ function NewRolePage() {
|
|||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
queryClient.invalidateQueries({ queryKey: rbacKeys.roles })
|
queryClient.invalidateQueries({ queryKey: rbacKeys.roles })
|
||||||
toast.success('Role created')
|
toast.success('Role created')
|
||||||
navigate({ to: '/roles', search: {} as Record<string, unknown> })
|
navigate({ to: '/roles', search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })
|
||||||
},
|
},
|
||||||
onError: (err) => toast.error(err.message),
|
onError: (err) => toast.error(err.message),
|
||||||
})
|
})
|
||||||
@@ -153,7 +153,7 @@ function NewRolePage() {
|
|||||||
<Button onClick={handleSubmit} disabled={mutation.isPending}>
|
<Button onClick={handleSubmit} disabled={mutation.isPending}>
|
||||||
{mutation.isPending ? 'Creating...' : 'Create Role'}
|
{mutation.isPending ? 'Creating...' : 'Create Role'}
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="secondary" onClick={() => navigate({ to: '/roles', search: {} as Record<string, unknown> })}>
|
<Button variant="secondary" onClick={() => navigate({ to: '/roles', search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })}>
|
||||||
Cancel
|
Cancel
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ export const Route = createFileRoute('/login')({
|
|||||||
beforeLoad: () => {
|
beforeLoad: () => {
|
||||||
const { token } = useAuthStore.getState()
|
const { token } = useAuthStore.getState()
|
||||||
if (token) {
|
if (token) {
|
||||||
throw redirect({ to: '/accounts', search: {} as Record<string, unknown> })
|
throw redirect({ to: '/accounts', search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
component: LoginPage,
|
component: LoginPage,
|
||||||
@@ -30,7 +30,7 @@ function LoginPage() {
|
|||||||
const res = await login(email, password)
|
const res = await login(email, password)
|
||||||
setAuth(res.token, res.user)
|
setAuth(res.token, res.user)
|
||||||
await router.invalidate()
|
await router.invalidate()
|
||||||
await router.navigate({ to: '/accounts', search: {} as Record<string, unknown>, replace: true })
|
await router.navigate({ to: '/accounts', search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const }, replace: true })
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
setError(err instanceof Error ? err.message : 'Login failed')
|
setError(err instanceof Error ? err.message : 'Login failed')
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
Reference in New Issue
Block a user