'use client'; import { useState, useEffect } from 'react'; import { getSession, setSession } from '@/lib/store/auth-store'; import { useSubscriptionSync } from '@/lib/hooks/useSubscriptionSync'; import { settingsStore } from '@/lib/store/settings-store'; import { Lock } from 'lucide-react'; export function PasswordGate({ children, hasAuth: initialHasAuth }: { children: React.ReactNode, hasAuth: boolean }) { // Enable background subscription syncing globally useSubscriptionSync(); const [isLocked, setIsLocked] = useState(true); const [password, setPassword] = useState(''); const [error, setError] = useState(false); const [isClient, setIsClient] = useState(false); const [hasAuth, setHasAuth] = useState(initialHasAuth); const [persistSession, setPersistSession] = useState(true); const [isValidating, setIsValidating] = useState(false); useEffect(() => { let mounted = true; const init = async () => { // Check if already has a valid session const session = getSession(); const isAuthenticated = !!session; // Initial fast check const localLocked = initialHasAuth && !isAuthenticated; if (mounted) { setIsLocked(localLocked); setIsClient(true); } // Fetch remote config & sync try { const res = await fetch('/api/auth'); if (!res.ok) throw new Error('Failed to fetch auth config'); const data = await res.json(); if (mounted) { setHasAuth(data.hasAuth); setPersistSession(data.persistSession); // Sync subscriptions if (data.subscriptionSources) { settingsStore.syncEnvSubscriptions(data.subscriptionSources); } // Re-evaluate lock status with confirmed server state const confirmLocked = data.hasAuth && !isAuthenticated; setIsLocked(confirmLocked); } } catch (e) { console.error("PasswordGate init failed:", e); } }; init(); return () => { mounted = false; }; }, [initialHasAuth]); const handleUnlock = async (e: React.FormEvent) => { e.preventDefault(); setIsValidating(true); try { const res = await fetch('/api/auth', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ password }), }); const data = await res.json(); if (data.valid) { setSession({ profileId: data.profileId, name: data.name, role: data.role, }, data.persistSession ?? persistSession); // Reload to re-initialize stores with profiled keys window.location.reload(); return; } } catch { // API error } // Password didn't match setError(true); setIsValidating(false); const form = document.getElementById('password-form'); form?.classList.add('animate-shake'); setTimeout(() => form?.classList.remove('animate-shake'), 500); }; if (!isClient) return null; // Prevent hydration mismatch if (!isLocked) { return <>{children}>; } return (