Skip to content

Commit bfa7bf6

Browse files
committed
Implement add email address step
1 parent 0e0d647 commit bfa7bf6

1 file changed

Lines changed: 113 additions & 7 deletions

File tree

packages/ui/src/components/ConfigureSSO/steps/ProvideEmailStep.tsx

Lines changed: 113 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,130 @@
1-
import { Flow, Text } from '@/customizables';
1+
import { useReverification, useUser } from '@clerk/shared/react/index';
2+
import React from 'react';
3+
4+
import { Col, Flow, Form, Heading, Icon, Input, localizationKeys, Text, useLocalizations } from '@/customizables';
5+
import { useCardState } from '@/elements/contexts';
6+
import { DuotoneAtSymbol } from '@/icons';
7+
import { handleError } from '@/utils/errorHandler';
28

39
import { useConfigureSSOWizard, useRegisterContinueAction } from '../wizard';
410
import { StepLayout } from './StepLayout';
511

612
export const ProvideEmail = (): JSX.Element => {
713
const { goNext } = useConfigureSSOWizard();
14+
const { user } = useUser();
15+
const card = useCardState();
16+
const { t } = useLocalizations();
17+
const [email, setEmail] = React.useState('');
18+
const [isSubmitting, setIsSubmitting] = React.useState(false);
19+
const createEmailAddress = useReverification((value: string) => user?.createEmailAddress({ email: value }));
20+
21+
const canSubmit = !isSubmitting;
22+
23+
const submit = React.useCallback(async () => {
24+
if (!canSubmit) {
25+
return;
26+
}
27+
28+
setIsSubmitting(true);
29+
card.setError(undefined);
30+
31+
try {
32+
await createEmailAddress(email);
33+
await goNext();
34+
} catch (err) {
35+
handleError(err as Error, [], card.setError);
36+
} finally {
37+
setIsSubmitting(false);
38+
}
39+
}, [canSubmit, email, createEmailAddress, card, goNext]);
840

941
useRegisterContinueAction({
10-
handler: () => {
11-
return goNext();
12-
},
42+
handler: submit,
43+
isDisabled: !canSubmit,
44+
isLoading: isSubmitting,
1345
});
1446

47+
// Clear any stale card error when this step mounts so it doesn't leak in
48+
// from a previous flow / step
49+
React.useEffect(() => {
50+
card.setError(undefined);
51+
return () => card.setError(undefined);
52+
// eslint-disable-next-line react-hooks/exhaustive-deps
53+
}, []);
54+
1555
return (
1656
<Flow.Part part='provideEmail'>
1757
<StepLayout
18-
title='Verify your domain'
19-
subtitle='Verify the domain you want to enable the enterprise connection on.'
58+
title={localizationKeys('configureSSO.verifyEmailDomainStep.title')}
59+
subtitle={localizationKeys('configureSSO.verifyEmailDomainStep.subtitle')}
2060
>
21-
<Text as='p'>UI goes here</Text>
61+
<Form
62+
onSubmit={e => {
63+
e.preventDefault();
64+
void submit();
65+
}}
66+
sx={{ flex: 1, display: 'flex' }}
67+
>
68+
<Col
69+
align='center'
70+
sx={t => ({
71+
flex: 1,
72+
justifyContent: 'center',
73+
gap: t.space.$5,
74+
maxWidth: t.sizes.$66,
75+
marginInline: 'auto',
76+
textAlign: 'center',
77+
width: '100%',
78+
paddingBlock: t.space.$8,
79+
})}
80+
>
81+
<Icon
82+
icon={DuotoneAtSymbol}
83+
sx={t => ({
84+
width: t.sizes.$8,
85+
height: t.sizes.$8,
86+
color: t.colors.$neutralAlpha600,
87+
})}
88+
/>
89+
90+
<Col sx={t => ({ gap: t.space.$1 })}>
91+
<Heading
92+
textVariant='h2'
93+
sx={t => ({ color: t.colors.$colorForeground })}
94+
localizationKey={localizationKeys('configureSSO.verifyEmailDomainStep.addEmailAddress.formTitle')}
95+
/>
96+
<Text
97+
as='p'
98+
variant='body'
99+
sx={t => ({ color: t.colors.$colorMutedForeground })}
100+
localizationKey={localizationKeys('configureSSO.verifyEmailDomainStep.addEmailAddress.formSubtitle')}
101+
/>
102+
</Col>
103+
104+
<Col sx={t => ({ gap: t.space.$1x5, width: '100%' })}>
105+
<Input
106+
type='email'
107+
// eslint-disable-next-line jsx-a11y/no-autofocus
108+
autoFocus
109+
placeholder={t(localizationKeys('configureSSO.verifyEmailDomainStep.addEmailAddress.inputPlaceholder'))}
110+
value={email}
111+
onChange={e => setEmail(e.currentTarget.value)}
112+
hasError={Boolean(card.error)}
113+
isDisabled={isSubmitting}
114+
aria-label={t(localizationKeys('configureSSO.verifyEmailDomainStep.addEmailAddress.inputLabel'))}
115+
/>
116+
{card.error ? (
117+
<Text
118+
as='p'
119+
variant='body'
120+
sx={t => ({ color: t.colors.$danger500, fontSize: t.fontSizes.$sm, textAlign: 'start' })}
121+
>
122+
{card.error}
123+
</Text>
124+
) : null}
125+
</Col>
126+
</Col>
127+
</Form>
22128
</StepLayout>
23129
</Flow.Part>
24130
);

0 commit comments

Comments
 (0)