'use client'; import { useState, useEffect } from 'react'; import { settingsStore } from '@/lib/store/settings-store'; import { Lock } from 'lucide-react'; import { verifyEnvPassword, isEnvPasswordRequired } from '@/lib/actions/auth'; const ACCESS_GRANTED_KEY = 'kvideo-access-granted'; export function PasswordGate({ children }: { children: React.ReactNode }) { const [isLocked, setIsLocked] = useState(true); const [password, setPassword] = useState(''); const [loading, setLoading] = useState(true); const [error, setError] = useState(false); const [isClient, setIsClient] = useState(false); useEffect(() => { setIsClient(true); checkLockStatus(); }, []); const checkLockStatus = async () => { const isAccessGranted = localStorage.getItem(ACCESS_GRANTED_KEY) === 'true'; if (isAccessGranted) { setIsLocked(false); setLoading(false); return; } const envRequired = await isEnvPasswordRequired(); const settings = settingsStore.getSettings(); if (!envRequired && !settings.passwordAccess) { setIsLocked(false); } else { setIsLocked(true); } setLoading(false); }; const handleUnlock = async (e: React.FormEvent) => { e.preventDefault(); setLoading(true); // Check against ENV password first const isEnvValid = await verifyEnvPassword(password); if (isEnvValid) { localStorage.setItem(ACCESS_GRANTED_KEY, 'true'); setIsLocked(false); setError(false); setLoading(false); return; } // Check against local settings passwords const settings = settingsStore.getSettings(); if (settings.accessPasswords.includes(password)) { localStorage.setItem(ACCESS_GRANTED_KEY, 'true'); setIsLocked(false); setError(false); setLoading(false); return; } // Invalid password setError(true); setLoading(false); // Shake animation trigger const form = document.getElementById('password-form'); form?.classList.add('animate-shake'); setTimeout(() => form?.classList.remove('animate-shake'), 500); }; if (!isClient || loading) return null; // Prevent hydration mismatch and show nothing while checking if (!isLocked) { return <>{children}; } return (

访问受限

请输入访问密码以继续

{ setPassword(e.target.value); setError(false); }} placeholder="输入密码..." className={`w-full px-4 py-3 rounded-[var(--radius-2xl)] bg-[var(--glass-bg)] border ${error ? 'border-red-500' : 'border-[var(--glass-border)]' } focus:outline-none focus:border-[var(--accent-color)] focus:shadow-[0_0_0_3px_color-mix(in_srgb,var(--accent-color)_30%,transparent)] transition-all duration-[0.4s] cubic-bezier(0.2,0.8,0.2,1) text-[var(--text-color)] placeholder-[var(--text-color-secondary)]`} autoFocus /> {error && (

密码错误

)}
); }