feat: update frontend for account-based subscriptions

Replace all team_id/team_admin references with account_id/owner across
types, store, hooks, API clients, components, and pages. Add new
AccountSettingsPage, UpgradePrompt, CheckoutButton, useSubscription
hook, and accounts API client. AuthStore now parallel-fetches account
and subscription data alongside user profile.

Also fix folder sidebar not refreshing after tree deletion by
dispatching the folder-changed event in handleDeleteTree.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
chihlasm
2026-02-07 02:39:15 -05:00
parent e0089a9c5a
commit 7a6f839ef4
26 changed files with 786 additions and 38 deletions

View File

@@ -49,6 +49,7 @@ export function AppLayout() {
const navItems = [
{ path: '/trees', label: 'Trees' },
{ path: '/sessions', label: 'Sessions' },
{ path: '/account', label: 'Account' },
{ path: '/settings', label: 'Settings' },
]
@@ -98,12 +99,12 @@ export function AppLayout() {
className={cn(
'hidden rounded-full px-2 py-0.5 text-xs font-medium sm:inline-block',
effectiveRole === 'super_admin' && 'bg-red-500/10 text-red-600 dark:text-red-400',
effectiveRole === 'team_admin' && 'bg-blue-500/10 text-blue-600 dark:text-blue-400',
effectiveRole === 'owner' && 'bg-blue-500/10 text-blue-600 dark:text-blue-400',
effectiveRole === 'viewer' && 'bg-gray-500/10 text-gray-600 dark:text-gray-400'
)}
>
{effectiveRole === 'super_admin' ? 'Super Admin' :
effectiveRole === 'team_admin' ? 'Team Admin' :
effectiveRole === 'owner' ? 'Owner' :
'Viewer'}
</span>
)}
@@ -158,12 +159,12 @@ export function AppLayout() {
className={cn(
'mt-1 inline-block rounded-full px-2 py-0.5 text-xs font-medium',
effectiveRole === 'super_admin' && 'bg-red-500/10 text-red-600 dark:text-red-400',
effectiveRole === 'team_admin' && 'bg-blue-500/10 text-blue-600 dark:text-blue-400',
effectiveRole === 'owner' && 'bg-blue-500/10 text-blue-600 dark:text-blue-400',
effectiveRole === 'viewer' && 'bg-gray-500/10 text-gray-600 dark:text-gray-400'
)}
>
{effectiveRole === 'super_admin' ? 'Super Admin' :
effectiveRole === 'team_admin' ? 'Team Admin' :
effectiveRole === 'owner' ? 'Owner' :
'Viewer'}
</span>
)}

View File

@@ -27,7 +27,7 @@ export function ProtectedRoute({ requiredRole, children }: ProtectedRouteProps)
if (requiredRole) {
const ROLE_HIERARCHY: Record<EffectiveRole, number> = {
super_admin: 4,
team_admin: 3,
owner: 3,
engineer: 2,
viewer: 1,
}