From ce1655bba6cf8cdff41d1a722c38270d60364d5c Mon Sep 17 00:00:00 2001 From: hsiegeln <37154749+hsiegeln@users.noreply.github.com> Date: Thu, 9 Apr 2026 19:51:28 +0200 Subject: [PATCH] fix: add error states to OrgResolver, DashboardPage, AdminTenantsPage Co-Authored-By: Claude Sonnet 4.6 --- ui/src/auth/OrgResolver.tsx | 16 +++++++++++++--- ui/src/pages/AdminTenantsPage.tsx | 26 +++++++++++++++++++------- ui/src/pages/DashboardPage.tsx | 15 +++++++++++++-- 3 files changed, 45 insertions(+), 12 deletions(-) diff --git a/ui/src/auth/OrgResolver.tsx b/ui/src/auth/OrgResolver.tsx index bfe0be2..0537c95 100644 --- a/ui/src/auth/OrgResolver.tsx +++ b/ui/src/auth/OrgResolver.tsx @@ -1,6 +1,6 @@ import { useEffect } from 'react'; import { useLogto } from '@logto/react'; -import { Spinner } from '@cameleer/design-system'; +import { Button, EmptyState, Spinner } from '@cameleer/design-system'; import { useMe } from '../api/hooks'; import { useOrgStore } from './useOrganization'; import { fetchConfig } from '../config'; @@ -11,7 +11,7 @@ import { fetchConfig } from '../config'; * Renders children once resolved. */ export function OrgResolver({ children }: { children: React.ReactNode }) { - const { data: me, isLoading, isError } = useMe(); + const { data: me, isLoading, isError, refetch } = useMe(); const { getAccessToken } = useLogto(); const { getIdTokenClaims } = useLogto(); const { setOrganizations, setCurrentOrg, setScopes, setUsername, currentOrgId } = useOrgStore(); @@ -86,7 +86,17 @@ export function OrgResolver({ children }: { children: React.ReactNode }) { } if (isError) { - return null; + return ( +
+ + +
+ ); } return <>{children}; diff --git a/ui/src/pages/AdminTenantsPage.tsx b/ui/src/pages/AdminTenantsPage.tsx index 9c8063c..e6ba343 100644 --- a/ui/src/pages/AdminTenantsPage.tsx +++ b/ui/src/pages/AdminTenantsPage.tsx @@ -3,6 +3,7 @@ import { Badge, Card, DataTable, + EmptyState, Spinner, } from '@cameleer/design-system'; import type { Column } from '@cameleer/design-system'; @@ -29,12 +30,12 @@ const columns: Column[] = [ /> ), }, - { key: 'createdAt', header: 'Created' }, + { key: 'createdAt', header: 'Created', render: (_: unknown, row: TenantResponse) => new Date(row.createdAt).toLocaleDateString() }, ]; export function AdminTenantsPage() { const navigate = useNavigate(); - const { data: tenants, isLoading } = useAllTenants(); + const { data: tenants, isLoading, isError } = useAllTenants(); const { setCurrentOrg } = useOrgStore(); if (isLoading) { @@ -45,6 +46,17 @@ export function AdminTenantsPage() { ); } + if (isError) { + return ( +
+ +
+ ); + } + const handleRowClick = (tenant: TenantResponse) => { // Find the matching org from the store and switch context const orgs = useOrgStore.getState().organizations; @@ -65,11 +77,11 @@ export function AdminTenantsPage() { - + {(!tenants || tenants.length === 0) ? ( + + ) : ( + + )} ); diff --git a/ui/src/pages/DashboardPage.tsx b/ui/src/pages/DashboardPage.tsx index f67d1e5..3eb80e7 100644 --- a/ui/src/pages/DashboardPage.tsx +++ b/ui/src/pages/DashboardPage.tsx @@ -14,8 +14,8 @@ import { tierColor } from '../utils/tier'; export function DashboardPage() { const { tenantId } = useAuth(); - const { data: tenant, isLoading: tenantLoading } = useTenant(tenantId ?? ''); - const { data: license, isLoading: licenseLoading } = useLicense(tenantId ?? ''); + const { data: tenant, isLoading: tenantLoading, isError: tenantError } = useTenant(tenantId ?? ''); + const { data: license, isLoading: licenseLoading, isError: licenseError } = useLicense(tenantId ?? ''); const isLoading = tenantLoading || licenseLoading; @@ -47,6 +47,17 @@ export function DashboardPage() { ); } + if (tenantError || licenseError) { + return ( +
+ +
+ ); + } + if (!tenantId) { return (