1 import type { ReactNode } from 'react';
2 import { type FC, useMemo } from 'react';
4 import { c } from 'ttag';
6 import { Icon, type IconName, RadioGroup } from '@proton/components';
7 import { useConnectivity } from '@proton/pass/components/Core/ConnectivityProvider';
8 import { LockTTLField } from '@proton/pass/components/Lock/LockTTLField';
9 import { PassPlusPromotionButton } from '@proton/pass/components/Upsell/PassPlusPromotionButton';
10 import { useLockSetup } from '@proton/pass/hooks/useLockSetup';
11 import { LockMode } from '@proton/pass/lib/auth/lock/types';
12 import { prop } from '@proton/pass/utils/fp/lens';
13 import { isMac } from '@proton/shared/lib/helpers/browser';
14 import clsx from '@proton/utils/clsx';
16 type LockModeOption = {
20 needsUpgrade?: boolean;
24 export const OnboardingLockSetup: FC = () => {
25 const online = useConnectivity();
26 const { setLockMode, setLockTTL, lock, biometrics, password } = useLockSetup();
28 const lockModes = useMemo<LockModeOption[]>(() => {
29 const options: LockModeOption[] = [
31 value: LockMode.SESSION,
32 label: c('Label').t`PIN code`,
33 icon: 'pass-lockmode-pin',
37 value: LockMode.PASSWORD,
38 label: c('Label').t`Password`,
39 icon: 'pass-lockmode-password',
40 active: password.enabled,
43 value: LockMode.BIOMETRICS,
44 label: c('Label').t`Biometrics`,
45 icon: isMac() ? 'fingerprint' : 'pass-lockmode-biometrics',
46 needsUpgrade: biometrics.needsUpgrade,
47 active: DESKTOP_BUILD && password.enabled && biometrics.enabled,
53 <span className="mr-2">{c('Label').t`None`}</span>
54 <span className="color-weak text-sm align-end">({c('Info').t`Not recommended`})</span>
57 icon: 'pass-lockmode-none',
58 active: !lock.orgControlled,
62 return options.filter(prop('active'));
63 }, [lock, password, biometrics]);
69 onChange={setLockMode}
71 className={clsx('pass-onboarding-modal--radio w-full', !online && 'opacity-70 pointer-events-none')}
72 disableChange={!online || lock.loading}
73 options={lockModes.map(({ value, icon, label, needsUpgrade }) => ({
76 <div className="pass-onboarding-modal--option rounded-xl flex items-center w-full py-3 px-4">
77 <Icon name={icon} size={6} />
78 <div className={clsx('flex-1 px-4', lock.mode === value && 'text-bold')}>{label}</div>
79 {lock.mode === value && (
80 <Icon name="checkmark-circle-filled" size={6} color="var(--interaction-norm)" />
82 {needsUpgrade && <PassPlusPromotionButton />}
88 <hr className="mt-2 mb-4 border-weak shrink-0" />
92 disabled={!online || lock.ttl.disabled || lock.loading}
96 {c('Label').t`Auto-lock after`}
97 {lock.orgControlled && (
98 <span className="color-weak text-sm">{` (${c('Info').t`Set by your organization`})`}</span>