2026-04-05 02:50:51 +02:00
|
|
|
import { useNavigate } from 'react-router';
|
|
|
|
|
import {
|
|
|
|
|
Badge,
|
|
|
|
|
Card,
|
|
|
|
|
DataTable,
|
|
|
|
|
Spinner,
|
|
|
|
|
} from '@cameleer/design-system';
|
|
|
|
|
import type { Column } from '@cameleer/design-system';
|
|
|
|
|
import { useAllTenants } from '../api/hooks';
|
|
|
|
|
import { useOrgStore } from '../auth/useOrganization';
|
|
|
|
|
import type { TenantResponse } from '../types/api';
|
2026-04-09 19:49:32 +02:00
|
|
|
import styles from '../styles/platform.module.css';
|
2026-04-05 02:50:51 +02:00
|
|
|
|
|
|
|
|
const columns: Column<TenantResponse>[] = [
|
|
|
|
|
{ key: 'name', header: 'Name' },
|
|
|
|
|
{ key: 'slug', header: 'Slug' },
|
|
|
|
|
{
|
|
|
|
|
key: 'tier',
|
|
|
|
|
header: 'Tier',
|
|
|
|
|
render: (_v: unknown, row: TenantResponse) => <Badge label={row.tier} color="primary" />,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: 'status',
|
|
|
|
|
header: 'Status',
|
|
|
|
|
render: (_v: unknown, row: TenantResponse) => (
|
|
|
|
|
<Badge
|
|
|
|
|
label={row.status}
|
|
|
|
|
color={row.status === 'ACTIVE' ? 'success' : 'warning'}
|
|
|
|
|
/>
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
{ key: 'createdAt', header: 'Created' },
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
export function AdminTenantsPage() {
|
|
|
|
|
const navigate = useNavigate();
|
|
|
|
|
const { data: tenants, isLoading } = useAllTenants();
|
|
|
|
|
const { setCurrentOrg } = useOrgStore();
|
|
|
|
|
|
|
|
|
|
if (isLoading) {
|
|
|
|
|
return (
|
|
|
|
|
<div className="flex items-center justify-center h-64">
|
|
|
|
|
<Spinner />
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const handleRowClick = (tenant: TenantResponse) => {
|
|
|
|
|
// Find the matching org from the store and switch context
|
|
|
|
|
const orgs = useOrgStore.getState().organizations;
|
|
|
|
|
const match = orgs.find(
|
|
|
|
|
(o) => o.name === tenant.name || o.slug === tenant.slug,
|
|
|
|
|
);
|
|
|
|
|
if (match) {
|
|
|
|
|
setCurrentOrg(match.id);
|
|
|
|
|
navigate('/');
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div className="space-y-6 p-6">
|
|
|
|
|
<div className="flex items-center justify-between">
|
2026-04-09 19:49:32 +02:00
|
|
|
<h1 className={styles.heading}>All Tenants</h1>
|
2026-04-05 02:50:51 +02:00
|
|
|
<Badge label="Platform Admin" color="warning" />
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<Card title={`${tenants?.length ?? 0} Tenants`}>
|
|
|
|
|
<DataTable
|
|
|
|
|
columns={columns}
|
|
|
|
|
data={tenants ?? []}
|
|
|
|
|
onRowClick={handleRowClick}
|
|
|
|
|
/>
|
|
|
|
|
</Card>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|