dstpabuaran.com/resources/js/components/auth/manage-two-factor.tsx
Yoga Pangestu 166419134f Refactor component imports for consistency and organization
- Updated import paths for various components to align with new directory structure.
- Changed imports from 'row-actions', 'confirm-dialog', 'image-preview-button', and 'file-upload' to their respective new locations in 'data-display', 'dialogs', and 'inputs'.
- Adjusted imports in multiple pages including purchase, restock, transaction, category, customer, product, raw-material, supplier, roles, and settings.
- Ensured all relevant components are imported from their new locations to maintain functionality.
2026-08-07 13:48:46 +07:00

135 lines
5.2 KiB
TypeScript

import { Form } from '@inertiajs/react';
import { ShieldCheck } from 'lucide-react';
import { useEffect, useRef, useState } from 'react';
import { toast } from 'sonner';
import { Heading } from '@/components/layout';
import { TwoFactorRecoveryCodes, TwoFactorSetupModal } from '@/components/auth';
import { Button } from '@/components/ui/button';
import { useTwoFactorAuth } from '@/hooks/use-two-factor-auth';
import { disable, enable } from '@/routes/two-factor';
export type Props = {
canManageTwoFactor?: boolean;
requiresConfirmation?: boolean;
twoFactorEnabled?: boolean;
};
export default function ManageTwoFactor(props: Props) {
const requiresConfirmation = props.requiresConfirmation ?? false;
const twoFactorEnabled = props.twoFactorEnabled ?? false;
const {
qrCodeSvg,
hasSetupData,
manualSetupKey,
clearSetupData,
clearTwoFactorAuthData,
fetchSetupData,
recoveryCodesList,
fetchRecoveryCodes,
errors,
} = useTwoFactorAuth();
const [showSetupModal, setShowSetupModal] = useState<boolean>(false);
const prevTwoFactorEnabled = useRef(twoFactorEnabled);
useEffect(() => {
if (prevTwoFactorEnabled.current && !twoFactorEnabled) {
clearTwoFactorAuthData();
}
prevTwoFactorEnabled.current = twoFactorEnabled;
}, [twoFactorEnabled, clearTwoFactorAuthData]);
if (!(props.canManageTwoFactor ?? false)) {
return null;
}
return (
<div className="space-y-6">
<Heading
variant="small"
title="Two-factor authentication"
description="Manage your two-factor authentication settings"
/>
{twoFactorEnabled ? (
<div className="flex flex-col items-start justify-start space-y-4">
<p className="text-sm text-muted-foreground">
You will be prompted for a secure, random pin during
login, which you can retrieve from the TOTP-supported
application on your phone.
</p>
<div className="relative inline">
<Form
{...disable.form()}
onError={() => {
toast.error('Terjadi kesalahan saat menyimpan data. Silakan periksa kembali input Anda.');
}}
>
{({ processing }) => (
<Button
variant="destructive"
type="submit"
disabled={processing}
>
Disable 2FA
</Button>
)}
</Form>
</div>
<TwoFactorRecoveryCodes
recoveryCodesList={recoveryCodesList}
fetchRecoveryCodes={fetchRecoveryCodes}
errors={errors}
/>
</div>
) : (
<div className="flex flex-col items-start justify-start space-y-4">
<p className="text-sm text-muted-foreground">
When you enable two-factor authentication, you will be
prompted for a secure pin during login. This pin can be
retrieved from a TOTP-supported application on your
phone.
</p>
<div>
{hasSetupData ? (
<Button onClick={() => setShowSetupModal(true)}>
<ShieldCheck />
Continue setup
</Button>
) : (
<Form
{...enable.form()}
onSuccess={() => setShowSetupModal(true)}
onError={() => {
toast.error('Terjadi kesalahan saat menyimpan data. Silakan periksa kembali input Anda.');
}}
>
{({ processing }) => (
<Button type="submit" disabled={processing}>
Enable 2FA
</Button>
)}
</Form>
)}
</div>
</div>
)}
<TwoFactorSetupModal
isOpen={showSetupModal}
onClose={() => setShowSetupModal(false)}
requiresConfirmation={requiresConfirmation}
twoFactorEnabled={twoFactorEnabled}
qrCodeSvg={qrCodeSvg}
manualSetupKey={manualSetupKey}
clearSetupData={clearSetupData}
fetchSetupData={fetchSetupData}
errors={errors}
/>
</div>
);
}