mirror of
https://github.com/documenso/documenso.git
synced 2025-11-14 08:42:12 +10:00
chore: add pin input to all 2FA components
Adds the pin input to the currently used 2FA components sunsetting the standard input that was previously used.
This commit is contained in:
@ -18,7 +18,7 @@ import {
|
|||||||
FormLabel,
|
FormLabel,
|
||||||
FormMessage,
|
FormMessage,
|
||||||
} from '@documenso/ui/primitives/form/form';
|
} from '@documenso/ui/primitives/form/form';
|
||||||
import { Input } from '@documenso/ui/primitives/input';
|
import { PinInput, PinInputGroup, PinInputSlot } from '@documenso/ui/primitives/pin-input';
|
||||||
|
|
||||||
import { EnableAuthenticatorAppDialog } from '~/components/forms/2fa/enable-authenticator-app-dialog';
|
import { EnableAuthenticatorAppDialog } from '~/components/forms/2fa/enable-authenticator-app-dialog';
|
||||||
|
|
||||||
@ -138,7 +138,15 @@ export const DocumentActionAuth2FA = ({
|
|||||||
<FormLabel required>2FA token</FormLabel>
|
<FormLabel required>2FA token</FormLabel>
|
||||||
|
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input {...field} placeholder="Token" />
|
<PinInput {...field} value={field.value ?? ''} maxLength={6}>
|
||||||
|
{Array(6)
|
||||||
|
.fill(null)
|
||||||
|
.map((_, i) => (
|
||||||
|
<PinInputGroup key={i}>
|
||||||
|
<PinInputSlot index={i} />
|
||||||
|
</PinInputGroup>
|
||||||
|
))}
|
||||||
|
</PinInput>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
|
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
|
|||||||
@ -28,7 +28,7 @@ import {
|
|||||||
FormItem,
|
FormItem,
|
||||||
FormMessage,
|
FormMessage,
|
||||||
} from '@documenso/ui/primitives/form/form';
|
} from '@documenso/ui/primitives/form/form';
|
||||||
import { Input } from '@documenso/ui/primitives/input';
|
import { PinInput, PinInputGroup, PinInputSlot } from '@documenso/ui/primitives/pin-input';
|
||||||
import { useToast } from '@documenso/ui/primitives/use-toast';
|
import { useToast } from '@documenso/ui/primitives/use-toast';
|
||||||
|
|
||||||
export const ZDisable2FAForm = z.object({
|
export const ZDisable2FAForm = z.object({
|
||||||
@ -107,7 +107,15 @@ export const DisableAuthenticatorAppDialog = () => {
|
|||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input {...field} placeholder="Token" />
|
<PinInput {...field} value={field.value ?? ''} maxLength={6}>
|
||||||
|
{Array(6)
|
||||||
|
.fill(null)
|
||||||
|
.map((_, i) => (
|
||||||
|
<PinInputGroup key={i}>
|
||||||
|
<PinInputSlot index={i} />
|
||||||
|
</PinInputGroup>
|
||||||
|
))}
|
||||||
|
</PinInput>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|||||||
@ -30,7 +30,7 @@ import {
|
|||||||
FormLabel,
|
FormLabel,
|
||||||
FormMessage,
|
FormMessage,
|
||||||
} from '@documenso/ui/primitives/form/form';
|
} from '@documenso/ui/primitives/form/form';
|
||||||
import { Input } from '@documenso/ui/primitives/input';
|
import { PinInput, PinInputGroup, PinInputSlot } from '@documenso/ui/primitives/pin-input';
|
||||||
import { useToast } from '@documenso/ui/primitives/use-toast';
|
import { useToast } from '@documenso/ui/primitives/use-toast';
|
||||||
|
|
||||||
import { RecoveryCodeList } from './recovery-code-list';
|
import { RecoveryCodeList } from './recovery-code-list';
|
||||||
@ -212,7 +212,15 @@ export const EnableAuthenticatorAppDialog = ({ onSuccess }: EnableAuthenticatorA
|
|||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel className="text-muted-foreground">Token</FormLabel>
|
<FormLabel className="text-muted-foreground">Token</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input {...field} type="text" value={field.value ?? ''} />
|
<PinInput {...field} value={field.value ?? ''} maxLength={6}>
|
||||||
|
{Array(6)
|
||||||
|
.fill(null)
|
||||||
|
.map((_, i) => (
|
||||||
|
<PinInputGroup key={i}>
|
||||||
|
<PinInputSlot index={i} />
|
||||||
|
</PinInputGroup>
|
||||||
|
))}
|
||||||
|
</PinInput>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|||||||
@ -30,7 +30,7 @@ import {
|
|||||||
FormItem,
|
FormItem,
|
||||||
FormMessage,
|
FormMessage,
|
||||||
} from '@documenso/ui/primitives/form/form';
|
} from '@documenso/ui/primitives/form/form';
|
||||||
import { Input } from '@documenso/ui/primitives/input';
|
import { PinInput, PinInputGroup, PinInputSlot } from '@documenso/ui/primitives/pin-input';
|
||||||
|
|
||||||
import { RecoveryCodeList } from './recovery-code-list';
|
import { RecoveryCodeList } from './recovery-code-list';
|
||||||
|
|
||||||
@ -115,7 +115,15 @@ export const ViewRecoveryCodesDialog = () => {
|
|||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input {...field} placeholder="Token" />
|
<PinInput {...field} value={field.value ?? ''} maxLength={6}>
|
||||||
|
{Array(6)
|
||||||
|
.fill(null)
|
||||||
|
.map((_, i) => (
|
||||||
|
<PinInputGroup key={i}>
|
||||||
|
<PinInputSlot index={i} />
|
||||||
|
</PinInputGroup>
|
||||||
|
))}
|
||||||
|
</PinInput>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|||||||
@ -38,6 +38,7 @@ import {
|
|||||||
} from '@documenso/ui/primitives/form/form';
|
} from '@documenso/ui/primitives/form/form';
|
||||||
import { Input } from '@documenso/ui/primitives/input';
|
import { Input } from '@documenso/ui/primitives/input';
|
||||||
import { PasswordInput } from '@documenso/ui/primitives/password-input';
|
import { PasswordInput } from '@documenso/ui/primitives/password-input';
|
||||||
|
import { PinInput, PinInputGroup, PinInputSlot } from '@documenso/ui/primitives/pin-input';
|
||||||
import { useToast } from '@documenso/ui/primitives/use-toast';
|
import { useToast } from '@documenso/ui/primitives/use-toast';
|
||||||
|
|
||||||
const ERROR_MESSAGES: Partial<Record<keyof typeof ErrorCode, string>> = {
|
const ERROR_MESSAGES: Partial<Record<keyof typeof ErrorCode, string>> = {
|
||||||
@ -372,9 +373,17 @@ export const SignInForm = ({ className, initialEmail, isGoogleSSOEnabled }: Sign
|
|||||||
name="totpCode"
|
name="totpCode"
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel>Authentication Token</FormLabel>
|
<FormLabel>Token</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input type="text" {...field} />
|
<PinInput {...field} value={field.value ?? ''} maxLength={6}>
|
||||||
|
{Array(6)
|
||||||
|
.fill(null)
|
||||||
|
.map((_, i) => (
|
||||||
|
<PinInputGroup key={i}>
|
||||||
|
<PinInputSlot index={i} />
|
||||||
|
</PinInputGroup>
|
||||||
|
))}
|
||||||
|
</PinInput>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|||||||
@ -2,9 +2,10 @@
|
|||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
|
||||||
import { cn } from '@/lib/utils';
|
|
||||||
import { DashIcon } from '@radix-ui/react-icons';
|
|
||||||
import { OTPInput, OTPInputContext } from 'input-otp';
|
import { OTPInput, OTPInputContext } from 'input-otp';
|
||||||
|
import { Minus } from 'lucide-react';
|
||||||
|
|
||||||
|
import { cn } from '../lib/utils';
|
||||||
|
|
||||||
const PinInput = React.forwardRef<
|
const PinInput = React.forwardRef<
|
||||||
React.ElementRef<typeof OTPInput>,
|
React.ElementRef<typeof OTPInput>,
|
||||||
@ -43,7 +44,7 @@ const PinInputSlot = React.forwardRef<
|
|||||||
<div
|
<div
|
||||||
ref={ref}
|
ref={ref}
|
||||||
className={cn(
|
className={cn(
|
||||||
'border-input relative flex h-9 w-9 items-center justify-center border-y border-r text-sm shadow-sm transition-all first:rounded-l-md first:border-l last:rounded-r-md',
|
'border-input relative flex h-10 w-10 items-center justify-center border-y border-r font-mono shadow-sm transition-all first:rounded-l-md first:border-l last:rounded-r-md',
|
||||||
isActive && 'ring-ring z-10 ring-1',
|
isActive && 'ring-ring z-10 ring-1',
|
||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
@ -66,7 +67,7 @@ const PinInputSeparator = React.forwardRef<
|
|||||||
React.ComponentPropsWithoutRef<'div'>
|
React.ComponentPropsWithoutRef<'div'>
|
||||||
>(({ ...props }, ref) => (
|
>(({ ...props }, ref) => (
|
||||||
<div ref={ref} role="separator" {...props}>
|
<div ref={ref} role="separator" {...props}>
|
||||||
<DashIcon />
|
<Minus className="h-5 w-5" />
|
||||||
</div>
|
</div>
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user