-
-
Notifications
You must be signed in to change notification settings - Fork 35
Expand file tree
/
Copy pathLocationCardMfaEmailView.tsx
More file actions
99 lines (92 loc) · 3.34 KB
/
Copy pathLocationCardMfaEmailView.tsx
File metadata and controls
99 lines (92 loc) · 3.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import { useCallback, useEffect, useState } from 'react';
import { ThemeSpacing } from '../../../../types';
import { isPresent } from '../../../../utils/isPresent';
import { Button } from '../../../Button/Button';
import { ButtonVariant } from '../../../Button/types';
import { CodeInput } from '../../../CodeInput/CodeInput';
import { Controls } from '../../../Controls/Controls';
import { Divider } from '../../../Divider/Divider';
import { IconKind } from '../../../Icon';
import { IconButton } from '../../../IconButton/IconButton';
import { IconButtonVariant } from '../../../IconButton/types';
import { SizedBox } from '../../../SizedBox/SizedBox';
import { MfaStartMethod } from '../../api/startClientMfaSession';
import { LocationViewHeader } from '../../components/LocationViewHeader/LocationViewHeader';
import { useLocationCardContext } from '../../context/context';
import { LocationCardViews } from '../../context/types';
import { useMfaConnect } from '../../hooks/useMfaConnect';
import { LocationCardMfaStartLoader } from '../LocationCardMfaStartLoader/LocationCardMfaStartLoader';
const MIN_POSTURE_LOADER_MS = 500;
export const LocationCardMfaEmailView = () => {
const { setView, location } = useLocationCardContext();
const { verifyCode, isVerifying, verifyError, isStarting, startError } = useMfaConnect(
MfaStartMethod.Email,
{
debounceMs: location.posture_check_required ? MIN_POSTURE_LOADER_MS : 0,
},
);
const [emailCode, setEmailCode] = useState<string | null>(null);
const [error, setError] = useState<string | null>(null);
const handleVerify = useCallback(() => {
if (!isPresent(emailCode)) {
setError('Enter code');
return;
}
if (emailCode.length !== 6) {
setError('6 digits are required');
return;
}
verifyCode(emailCode);
}, [emailCode, verifyCode]);
// biome-ignore lint/correctness/useExhaustiveDependencies: side effect of code input
useEffect(() => {
setError(null);
}, [emailCode, setError]);
// Reflect server-side verify errors into the local error state
useEffect(() => {
if (verifyError) setError(verifyError);
}, [verifyError]);
// Show loader when posture is being evaluated
const showLoader = location.posture_check_required && isStarting && !startError;
if (showLoader) {
return <LocationCardMfaStartLoader />;
}
return (
<div
className="location-card-mfa-email-view"
onKeyDown={(e) => {
if (e.key === 'Enter') handleVerify();
}}
>
<Divider spacing={ThemeSpacing.Md} />
<LocationViewHeader title="Email verification">
<p>Enter the 6-digit code sent to your email address.</p>
</LocationViewHeader>
<SizedBox height={ThemeSpacing.Xl} />
<CodeInput
length={6}
value={emailCode}
onChange={setEmailCode}
error={startError ?? error}
/>
<Controls>
<IconButton
variant={IconButtonVariant.BigSelected}
icon={IconKind.ArrowBig}
iconRotation="left"
onClick={() => {
setView(LocationCardViews.Default);
}}
/>
<div className="right">
<Button
text="Verify"
variant={ButtonVariant.Primary}
onClick={handleVerify}
loading={isStarting || isVerifying}
/>
</div>
</Controls>
</div>
);
};