helloya20's picture
Upload 2345 files
f0743f4 verified
import React, { useState } from 'react';
import { motion } from 'framer-motion';
import { REGEXP_ONLY_DIGITS, REGEXP_ONLY_DIGITS_AND_CHARS } from 'input-otp';
import {
Button,
InputOTP,
InputOTPGroup,
InputOTPSlot,
InputOTPSeparator,
Spinner,
} from '@librechat/client';
import { useLocalize } from '~/hooks';
const fadeAnimation = {
initial: { opacity: 0, y: 20 },
animate: { opacity: 1, y: 0 },
exit: { opacity: 0, y: -20 },
transition: { duration: 0.2 },
};
interface DisablePhaseProps {
onSuccess?: () => void;
onError?: (error: Error) => void;
onDisable: (token: string, useBackup: boolean) => void;
isDisabling: boolean;
}
export const DisablePhase: React.FC<DisablePhaseProps> = ({ onDisable, isDisabling }) => {
const localize = useLocalize();
const [token, setToken] = useState('');
const [useBackup, setUseBackup] = useState(false);
return (
<motion.div {...fadeAnimation} className="space-y-8">
<div className="flex justify-center">
<InputOTP
value={token}
onChange={setToken}
maxLength={useBackup ? 8 : 6}
pattern={useBackup ? REGEXP_ONLY_DIGITS_AND_CHARS : REGEXP_ONLY_DIGITS}
className="gap-2"
>
{useBackup ? (
<InputOTPGroup>
<InputOTPSlot index={0} />
<InputOTPSlot index={1} />
<InputOTPSlot index={2} />
<InputOTPSlot index={3} />
<InputOTPSlot index={4} />
<InputOTPSlot index={5} />
<InputOTPSlot index={6} />
<InputOTPSlot index={7} />
</InputOTPGroup>
) : (
<>
<InputOTPGroup>
<InputOTPSlot index={0} />
<InputOTPSlot index={1} />
<InputOTPSlot index={2} />
</InputOTPGroup>
<InputOTPSeparator />
<InputOTPGroup>
<InputOTPSlot index={3} />
<InputOTPSlot index={4} />
<InputOTPSlot index={5} />
</InputOTPGroup>
</>
)}
</InputOTP>
</div>
<Button
variant="destructive"
onClick={() => onDisable(token, useBackup)}
disabled={isDisabling || token.length !== (useBackup ? 8 : 6)}
className="w-full rounded-xl px-6 py-3 transition-all disabled:opacity-50"
>
{isDisabling && <Spinner className="mr-2" />}
{isDisabling ? localize('com_ui_disabling') : localize('com_ui_2fa_disable')}
</Button>
<button
onClick={() => setUseBackup(!useBackup)}
className="text-sm text-primary hover:underline"
>
{useBackup ? localize('com_ui_use_2fa_code') : localize('com_ui_use_backup_code')}
</button>
</motion.div>
);
};