'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 (