fix(onboarding): skip org name prompt for vendor-created admins
All checks were successful
CI / build (push) Successful in 2m11s
CI / docker (push) Successful in 1m40s

Vendor-created tenant admins already have an org membership. When they
land on /onboarding (first login, token lacks org claims), detect the
existing tenant via /api/me and trigger a re-auth to pick up org
membership instead of showing the org name form.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-04-28 20:05:29 +02:00
parent 345bc4a92b
commit 029f2ef0de

View File

@@ -1,8 +1,9 @@
import { useState, useEffect, useRef } from 'react';
import { useLogto } from '@logto/react';
import { Card, Input, Button, FormField, Alert } from '@cameleer/design-system';
import { Card, Input, Button, FormField, Alert, Spinner } from '@cameleer/design-system';
import cameleerLogo from '@cameleer/design-system/assets/cameleer-logo.svg';
import { api, errorMessage } from '../api/client';
import { useMe } from '../api/hooks';
import { toSlug } from '../utils/slug';
import styles from './OnboardingPage.module.css';
@@ -15,6 +16,7 @@ interface TenantResponse {
export function OnboardingPage() {
const { signIn } = useLogto();
const { data: me, isLoading: meLoading } = useMe();
const [name, setName] = useState('');
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
@@ -24,6 +26,14 @@ export function OnboardingPage() {
const slug = toSlug(name);
// Vendor-created admins already have an org — skip onboarding and re-auth
// to pick up org membership in the token
useEffect(() => {
if (!meLoading && me && me.tenants.length > 0) {
signIn(`${window.location.origin}/platform/callback`);
}
}, [me, meLoading, signIn]);
useEffect(() => {
setSlugAvailable(null);
if (!slug) return;
@@ -66,6 +76,17 @@ export function OnboardingPage() {
}
}
// Show spinner while checking org membership or redirecting
if (meLoading || (me && me.tenants.length > 0)) {
return (
<div className={styles.page}>
<div style={{ display: 'flex', justifyContent: 'center', padding: 64 }}>
<Spinner />
</div>
</div>
);
}
return (
<div className={styles.page}>
<div className={styles.wrapper}>