import { useCallback, useEffect, useState, type ReactNode } from 'react' import { Loader2, ShieldAlert, ShieldCheck } from 'lucide-react' import { diagnoseWebCryptoEnvironment } from '../lib/crypto' import { t, type Language } from '../i18n/translations' export type WebCryptoCheckStatus = | 'idle' | 'checking' | 'secure' | 'insecure' | 'unsupported' interface WebCryptoEnvironmentCheckProps { language: Language variant?: 'card' | 'compact' onStatusChange?: (status: WebCryptoCheckStatus) => void } export function WebCryptoEnvironmentCheck({ language, variant = 'card', onStatusChange, }: WebCryptoEnvironmentCheckProps) { const [status, setStatus] = useState('idle') const [summary, setSummary] = useState(null) useEffect(() => { onStatusChange?.(status) }, [onStatusChange, status]) const runCheck = useCallback(() => { setStatus('checking') setSummary(null) setTimeout(() => { const result = diagnoseWebCryptoEnvironment() setSummary( t('environmentCheck.summary', language, { origin: result.origin || 'N/A', protocol: result.protocol || 'unknown', }) ) if (!result.isBrowser || !result.hasSubtleCrypto) { setStatus('unsupported') return } if (!result.isSecureContext) { setStatus('insecure') return } setStatus('secure') }, 0) }, [language, t]) useEffect(() => { runCheck() }, [runCheck]) const isCompact = variant === 'compact' const containerClass = isCompact ? 'p-3 rounded border border-gray-700 bg-gray-900 space-y-3' : 'p-4 rounded border border-[#2B3139] bg-[#0B0E11] space-y-4' const descriptionColor = isCompact ? '#CBD5F5' : '#A1AEC8' const showInfo = status !== 'idle' const statusRendererMap: Record ReactNode> = { secure: () => (
{t('environmentCheck.secureTitle', language)}
{t('environmentCheck.secureDesc', language)}
), insecure: () => (
{t('environmentCheck.insecureTitle', language)}
{t('environmentCheck.insecureDesc', language)}
{t('environmentCheck.tipsTitle', language)}
  • {t('environmentCheck.tipHTTPS', language)}
  • {t('environmentCheck.tipLocalhost', language)}
  • {t('environmentCheck.tipIframe', language)}
), unsupported: () => (
{t('environmentCheck.unsupportedTitle', language)}
{t('environmentCheck.unsupportedDesc', language)}
), checking: () => (
{t('environmentCheck.checking', language)}
), idle: () => null, } const renderStatus = () => statusRendererMap[status]() return (
{showInfo && (
{summary ?? t('environmentCheck.description', language)}
)}
{showInfo &&
{renderStatus()}
}
) }