'use client'; import { useState, useContext } from 'react'; import { SessionContext } from '@/context/SessionContext'; import { useTranslations } from 'next-intl'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faLock, faShieldAlt, faEye, faEyeSlash } from '@fortawesome/free-solid-svg-icons'; interface OfflinePinSetupProps { onClose?: () => void; onSuccess?: () => void; showOnFirstLogin?: boolean; } export default function OfflinePinSetup({ onClose, onSuccess, showOnFirstLogin }: OfflinePinSetupProps) { const t = useTranslations(); const { session } = useContext(SessionContext); const [pin, setPin] = useState(''); const [confirmPin, setConfirmPin] = useState(''); const [showPin, setShowPin] = useState(false); const [error, setError] = useState(''); const [isLoading, setIsLoading] = useState(false); // Only allow PIN setup if authenticated if (!session?.isConnected || !session?.user) { return null; } const validatePin = (): boolean => { if (pin.length < 4) { setError(t('offline.pin.errors.tooShort')); return false; } if (pin.length > 8) { setError(t('offline.pin.errors.tooLong')); return false; } if (!/^\d+$/.test(pin)) { setError(t('offline.pin.errors.digitsOnly')); return false; } if (pin !== confirmPin) { setError(t('offline.pin.errors.mismatch')); return false; } return true; }; const handleSetPin = async () => { if (!validatePin()) return; setIsLoading(true); setError(''); try { if (window.electron) { const result = await window.electron.offlinePinSet(pin); if (result.success) { await window.electron.offlineModeSet(true, 30); // 30 days sync interval onSuccess?.(); } else { setError(result.error || t('offline.pin.errors.setupFailed')); } } } catch (error) { console.error('[OfflinePin] Error setting PIN:', error); setError(t('offline.pin.errors.setupFailed')); } finally { setIsLoading(false); } }; return (
{t('offline.pin.setup.subtitle')}
{error}
{t('offline.pin.setup.footer')}