import { useEffect, useState } from 'react' import { Check } from 'lucide-react' import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetFooter } from '@/components/ui/sheet' import { Label } from '@/components/ui/label' import { Input } from '@/components/ui/input' import { Button } from '@/components/ui/button' import { SUPABASE_URL, SUPABASE_ANON_KEY } from '@/lib/supabase' import { useAuth } from '@/auth/AuthContext' interface ProfileSheetProps { open: boolean onOpenChange: (open: boolean) => void } // Lee el access token de localStorage sin pasar por el processLock de Supabase. // El token es escrito por GoTrueClient tras cada login/refresh y siempre está vigente // mientras la sesión esté activa. function getAccessToken(): string | null { try { const key = Object.keys(localStorage).find( (k) => k.startsWith('sb-') && k.endsWith('-auth-token') ) if (!key) return null const stored = JSON.parse(localStorage.getItem(key) ?? 'null') as Record | null return (stored?.access_token as string | undefined) ?? null } catch { return null } } export function ProfileSheet({ open, onOpenChange }: ProfileSheetProps) { const { user, updateUser } = useAuth() const [name, setName] = useState('') const [company, setCompany] = useState('') useEffect(() => { if (open && user) { setName(user.name || user.email || '') setCompany(user.company ?? '') } // Intencional: solo inicializar cuando el sheet se abre, no en cada cambio de `user` // (evita resetear el formulario mientras el usuario está editando). // eslint-disable-next-line react-hooks/exhaustive-deps }, [open]) function handleSave() { if (!user || !name.trim()) return const savedName = name.trim() const savedCompany = company.trim() || undefined // Actualización optimista: aplicar cambios localmente y cerrar el Sheet de inmediato. // El Sheet nunca queda abierto esperando la respuesta del servidor. // La modal de Radix bloquea todo el UI mientras está abierta, así que cerramos // ANTES del await para que el usuario pueda seguir trabajando sin demora. updateUser({ name: savedName, company: savedCompany }) onOpenChange(false) // Persistir en Supabase en background — fire & forget. // Si falla (red lenta, token vencido, cold start de Supabase), el estado local // ya tiene el nuevo nombre. En el próximo login, syncProfileFromDB recupera el DB. const token = getAccessToken() if (!token) return void fetch( `${SUPABASE_URL}/rest/v1/users?id=eq.${encodeURIComponent(user.id)}`, { method: 'PATCH', headers: { apikey: SUPABASE_ANON_KEY, Authorization: `Bearer ${token}`, 'Content-Type': 'application/json', Prefer: 'return=minimal', }, body: JSON.stringify({ name: savedName, company: savedCompany ?? null }), signal: AbortSignal.timeout(10000), } ) .then((res) => { if (!res.ok) console.error('[ProfileSheet] Error guardando perfil:', res.status) }) .catch((err) => { console.error('[ProfileSheet] Error guardando perfil:', err) }) } return ( Editar perfil
setName(e.target.value)} placeholder="Tu nombre" />
setCompany(e.target.value)} placeholder="InQuality" />
) }