Add accounts UI with list, create, edit, detail tabs for all sub-entities
Accounts list with paginated table, search, sort. Account detail page with tabs for members, payment methods, tax exemptions, and processor links. All sub-entities have create/edit dialogs and delete actions. Forms use shared Zod schemas via react-hook-form.
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
import { createFileRoute, Outlet, Link, useParams } from '@tanstack/react-router'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { accountDetailOptions } from '@/api/accounts'
|
||||
import { Skeleton } from '@/components/ui/skeleton'
|
||||
import { Badge } from '@/components/ui/badge'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
export const Route = createFileRoute('/_authenticated/accounts/$accountId')({
|
||||
component: AccountDetailLayout,
|
||||
})
|
||||
|
||||
const tabs = [
|
||||
{ label: 'Overview', to: '/accounts/$accountId' },
|
||||
{ label: 'Members', to: '/accounts/$accountId/members' },
|
||||
{ label: 'Payment Methods', to: '/accounts/$accountId/payment-methods' },
|
||||
{ label: 'Tax Exemptions', to: '/accounts/$accountId/tax-exemptions' },
|
||||
{ label: 'Processor Links', to: '/accounts/$accountId/processor-links' },
|
||||
] as const
|
||||
|
||||
function AccountDetailLayout() {
|
||||
const { accountId } = useParams({ from: '/_authenticated/accounts/$accountId' })
|
||||
const { data: account, isLoading } = useQuery(accountDetailOptions(accountId))
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<Skeleton className="h-8 w-64" />
|
||||
<Skeleton className="h-4 w-96" />
|
||||
<Skeleton className="h-10 w-full" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
if (!account) {
|
||||
return <p className="text-muted-foreground">Account not found</p>
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<div>
|
||||
<div className="flex items-center gap-3">
|
||||
<h1 className="text-2xl font-bold">{account.name}</h1>
|
||||
<Badge variant="secondary">{account.billingMode}</Badge>
|
||||
</div>
|
||||
{account.email && <p className="text-muted-foreground">{account.email}</p>}
|
||||
</div>
|
||||
|
||||
<nav className="flex gap-1 border-b">
|
||||
{tabs.map((tab) => (
|
||||
<Link
|
||||
key={tab.to}
|
||||
to={tab.to}
|
||||
params={{ accountId }}
|
||||
activeOptions={{ exact: tab.to === '/accounts/$accountId' }}
|
||||
className={cn(
|
||||
'px-4 py-2 text-sm font-medium border-b-2 -mb-px transition-colors',
|
||||
'text-muted-foreground border-transparent hover:text-foreground hover:border-border',
|
||||
)}
|
||||
activeProps={{
|
||||
className: 'text-foreground border-primary',
|
||||
}}
|
||||
>
|
||||
{tab.label}
|
||||
</Link>
|
||||
))}
|
||||
</nav>
|
||||
|
||||
<Outlet />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user