Skip to content

Commit 03bd313

Browse files
authored
refactor: align onboarding tenant creation form (#8007)
1 parent 91a7d80 commit 03bd313

File tree

3 files changed

+49
-29
lines changed

3 files changed

+49
-29
lines changed

packages/console/src/consts/tenants.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,5 @@ export const adminTenantEndpoint = getAdminTenantEndpoint();
158158

159159
export const mainTitle = isCloud ? 'Logto Cloud' : 'Logto Console';
160160

161-
// Manually maintaining the list of regions to avoid unexpected changes. We may consider using an API in the future.
162-
export const availableRegions = Object.freeze(['EU', 'US', 'AU', 'JP'] as const);
163-
164161
// The threshold days to show the convert to production card in the get started page
165162
export const convertToProductionThresholdDays = 7;
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.error {
2+
color: var(--color-error);
3+
font: var(--font-body-2);
4+
}

packages/console/src/onboarding/pages/CreateTenant/index.tsx

Lines changed: 45 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { emailRegEx } from '@logto/core-kit';
22
import { useLogto } from '@logto/react';
33
import { TenantRole, Theme } from '@logto/schemas';
4-
import { useCallback, useContext } from 'react';
4+
import { useCallback, useContext, useMemo } from 'react';
55
import { Controller, FormProvider, useForm } from 'react-hook-form';
66
import { toast } from 'react-hot-toast';
77
import { useTranslation } from 'react-i18next';
@@ -13,27 +13,36 @@ import ActionBar from '@/components/ActionBar';
1313
import { GtagConversionId, reportToGoogle } from '@/components/Conversion/utils';
1414
import { type CreateTenantData } from '@/components/CreateTenantModal/types';
1515
import PageMeta from '@/components/PageMeta';
16-
import { StaticRegion, defaultRegionName } from '@/components/Region';
17-
import { availableRegions } from '@/consts';
16+
import Region, { defaultRegionName } from '@/components/Region';
1817
import { TenantsContext } from '@/contexts/TenantsProvider';
1918
import Button from '@/ds-components/Button';
2019
import DangerousRaw from '@/ds-components/DangerousRaw';
2120
import FormField from '@/ds-components/FormField';
2221
import OverlayScrollbar from '@/ds-components/OverlayScrollbar';
2322
import RadioGroup, { Radio } from '@/ds-components/RadioGroup';
23+
import { Ring } from '@/ds-components/Spinner';
2424
import TextInput from '@/ds-components/TextInput';
25+
import useAvailableRegions from '@/hooks/use-available-regions';
2526
import useTheme from '@/hooks/use-theme';
2627
import useUserOnboardingData from '@/onboarding/hooks/use-user-onboarding-data';
2728
import pageLayout from '@/onboarding/scss/layout.module.scss';
2829
import InviteEmailsInput from '@/pages/TenantSettings/TenantMembers/InviteEmailsInput';
2930
import { type InviteeEmailItem } from '@/pages/TenantSettings/TenantMembers/types';
3031
import { trySubmitSafe } from '@/utils/form';
3132

32-
type CreateTenantForm = Omit<CreateTenantData, 'tag'> & { collaboratorEmails: InviteeEmailItem[] };
33+
import styles from './index.module.scss';
34+
35+
type CreateTenantForm = Omit<CreateTenantData, 'tag'> & {
36+
collaboratorEmails: InviteeEmailItem[];
37+
};
3338

3439
function CreateTenant() {
3540
const methods = useForm<CreateTenantForm>({
36-
defaultValues: { name: 'My project', regionName: defaultRegionName, collaboratorEmails: [] },
41+
defaultValues: {
42+
name: 'My project',
43+
regionName: defaultRegionName,
44+
collaboratorEmails: [],
45+
},
3746
});
3847
const {
3948
control,
@@ -63,6 +72,12 @@ function CreateTenant() {
6372
const { isAuthenticated, getOrganizationToken } = useLogto();
6473
const cloudApi = useCloudApi();
6574
const { currentTenant } = useContext(TenantsContext);
75+
const { regions, regionsError } = useAvailableRegions();
76+
77+
const publicRegions = useMemo(
78+
() => regions?.filter((region) => !region.isPrivate) ?? [],
79+
[regions]
80+
);
6681

6782
const onCreateClick = handleSubmit(
6883
trySubmitSafe(async ({ name, regionName, collaboratorEmails }: CreateTenantForm) => {
@@ -122,27 +137,31 @@ function CreateTenant() {
122137
title="tenants.settings.tenant_region"
123138
tip={t('tenants.settings.tenant_region_description')}
124139
>
125-
<Controller
126-
control={control}
127-
name="regionName"
128-
rules={{ required: true }}
129-
render={({ field: { onChange, value, name } }) => (
130-
<RadioGroup type="small" name={name} value={value} onChange={onChange}>
131-
{availableRegions.map((region) => (
132-
<Radio
133-
key={region}
134-
title={
135-
<DangerousRaw>
136-
<StaticRegion regionName={region} />
137-
</DangerousRaw>
138-
}
139-
value={region}
140-
isDisabled={isSubmitting}
141-
/>
142-
))}
143-
</RadioGroup>
144-
)}
145-
/>
140+
{!regions && !regionsError && <Ring />}
141+
{regionsError && <span className={styles.error}>{regionsError.message}</span>}
142+
{regions && !regionsError && (
143+
<Controller
144+
control={control}
145+
name="regionName"
146+
rules={{ required: true }}
147+
render={({ field: { onChange, value, name } }) => (
148+
<RadioGroup type="small" name={name} value={value} onChange={onChange}>
149+
{publicRegions.map((region) => (
150+
<Radio
151+
key={region.name}
152+
title={
153+
<DangerousRaw>
154+
<Region region={region} />
155+
</DangerousRaw>
156+
}
157+
value={region.name}
158+
isDisabled={isSubmitting}
159+
/>
160+
))}
161+
</RadioGroup>
162+
)}
163+
/>
164+
)}
146165
</FormField>
147166
<FormField title="cloud.create_tenant.invite_collaborators">
148167
<Controller

0 commit comments

Comments
 (0)