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('') const [saving, setSaving] = useState(false) const [error, setError] = useState(null) useEffect(() => { if (open && user) { setName(user.name || user.email || '') setCompany(user.company ?? '') setError(null) } // 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]) async function handleSave() { if (!user || !name.trim()) return setSaving(true) setError(null) try { // Usamos fetch nativo en lugar de supabase.from().update() para evitar que esta // operación quede en la cola del processLock compartido. En el login, upsertUserOnLogin // y syncProfileFromDB adquieren ese lock; si el servidor tarda, la cola queda ocupada // y el save cuelga indefinidamente. El fetch nativo es independiente del lock. const token = getAccessToken() if (!token) throw new Error('Sesión no disponible — recargá la página e intentá de nuevo') const res = await 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: name.trim(), company: company.trim() || null, }), } ) if (!res.ok) { const detail = await res.text().catch(() => '') throw new Error(`Error ${res.status}${detail ? `: ${detail}` : ''}`) } updateUser({ name: name.trim(), company: company.trim() || undefined }) onOpenChange(false) } catch (err) { console.error('Error al guardar perfil:', err) setError(err instanceof Error ? err.message : 'Error al guardar perfil') } finally { setSaving(false) } } return ( Editar perfil
setName(e.target.value)} placeholder="Tu nombre" />
setCompany(e.target.value)} placeholder="InQuality" />
{error && (

{error}

)}
) }