"use client"; import { useEffect, useState } from "react"; import { useRouter } from "next/navigation"; import { Button } from "@/components/ui/button"; import { Alert, AlertDescription } from "@/components/ui/alert"; import { Badge } from "@/components/ui/badge"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { Label } from "@/components/ui/label"; import { Input } from "@/components/ui/input"; import { UploadAvatar } from "@/components/ui/upload-avatar"; import { AlertCircle, ArrowLeft, CheckCircle, XCircle } from "lucide-react"; import { getUserInfoById } from "@/lib/api"; import { useAuth } from "@/hooks/useAuth"; import { formatTelefone, formatCEP, validarCEP, buscarCEP } from "@/lib/utils"; interface UserProfile { user: { id: string; email: string; created_at: string; last_sign_in_at: string | null; email_confirmed_at: string | null; }; profile: { id: string; full_name: string | null; email: string | null; phone: string | null; avatar_url: string | null; cep?: string | null; street?: string | null; number?: string | null; complement?: string | null; neighborhood?: string | null; city?: string | null; state?: string | null; disabled: boolean; created_at: string; updated_at: string; } | null; roles: string[]; permissions: { isAdmin: boolean; isManager: boolean; isDoctor: boolean; isSecretary: boolean; isAdminOrManager: boolean; }; } export default function PerfilPage() { const router = useRouter(); const { user: authUser, updateUserProfile } = useAuth(); const [userInfo, setUserInfo] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [isEditing, setIsEditing] = useState(false); const [editingData, setEditingData] = useState<{ phone?: string; full_name?: string; avatar_url?: string; cep?: string; street?: string; number?: string; complement?: string; neighborhood?: string; city?: string; state?: string; }>({}); const [cepLoading, setCepLoading] = useState(false); const [cepValid, setCepValid] = useState(null); useEffect(() => { async function loadUserInfo() { try { setLoading(true); if (!authUser?.id) { throw new Error("ID do usuário não encontrado"); } console.log('[PERFIL] Chamando getUserInfoById com ID:', authUser.id); // Para admin/gestor, usar getUserInfoById com o ID do usuário logado const info = await getUserInfoById(authUser.id); console.log('[PERFIL] Sucesso ao carregar info:', info); setUserInfo(info as UserProfile); setError(null); } catch (err: any) { console.error('[PERFIL] Erro ao carregar:', err); setError(err?.message || "Erro ao carregar informações do perfil"); setUserInfo(null); } finally { setLoading(false); } } if (authUser) { console.log('[PERFIL] useEffect acionado, authUser:', authUser); loadUserInfo(); } }, [authUser]); if (authUser?.userType !== 'administrador') { return (
Você não tem permissão para acessar esta página.
); } if (loading) { return (
); } if (error) { return (
{error}
); } if (!userInfo) { return (
Nenhuma informação de perfil disponível.
); } const getInitials = (name: string | null | undefined) => { if (!name) return "AD"; return name .split(" ") .map((n) => n[0]) .join("") .toUpperCase() .slice(0, 2); }; const handleEditClick = () => { if (!isEditing && userInfo) { setEditingData({ full_name: userInfo.profile?.full_name || "", phone: userInfo.profile?.phone || "", avatar_url: userInfo.profile?.avatar_url || "", cep: userInfo.profile?.cep || "", street: userInfo.profile?.street || "", number: userInfo.profile?.number || "", complement: userInfo.profile?.complement || "", neighborhood: userInfo.profile?.neighborhood || "", city: userInfo.profile?.city || "", state: userInfo.profile?.state || "", }); // Se já existe CEP, marcar como válido if (userInfo.profile?.cep) { setCepValid(true); } } setIsEditing(!isEditing); }; const handleSaveEdit = async () => { try { // Aqui você implementaria a chamada para atualizar o perfil console.log('[PERFIL] Salvando alterações:', editingData); // await atualizarPerfil(userInfo?.user.id, editingData); setIsEditing(false); setUserInfo((prev) => prev ? { ...prev, profile: prev.profile ? { ...prev.profile, full_name: editingData.full_name || prev.profile.full_name, phone: editingData.phone || prev.profile.phone, avatar_url: editingData.avatar_url || prev.profile.avatar_url, cep: editingData.cep || prev.profile.cep, street: editingData.street || prev.profile.street, number: editingData.number || prev.profile.number, complement: editingData.complement || prev.profile.complement, neighborhood: editingData.neighborhood || prev.profile.neighborhood, city: editingData.city || prev.profile.city, state: editingData.state || prev.profile.state, } : null, } : null ); // Also update global auth profile so header/avatar updates immediately try { if (typeof updateUserProfile === 'function') { updateUserProfile({ // Persist common keys used across the app foto_url: editingData.avatar_url || undefined, telefone: editingData.phone || undefined }); } else { // Fallback: try to persist directly to localStorage so next reload shows it try { const raw = localStorage.getItem('auth_user') if (raw) { const u = JSON.parse(raw) u.profile = u.profile || {} if (editingData.avatar_url) { u.profile.foto_url = editingData.avatar_url; u.profile.avatar_url = editingData.avatar_url } if (editingData.phone) u.profile.telefone = editingData.phone localStorage.setItem('auth_user', JSON.stringify(u)) } } catch (_e) {} } } catch (err) { console.warn('[PERFIL] Falha ao sincronizar profile global:', err) } } catch (err: any) { console.error('[PERFIL] Erro ao salvar:', err); } }; const handleCancelEdit = () => { setIsEditing(false); setEditingData({}); setCepValid(null); }; const handleCepChange = async (cepValue: string) => { // Formatar CEP const formatted = formatCEP(cepValue); setEditingData({...editingData, cep: formatted}); // Validar CEP const isValid = validarCEP(cepValue); setCepValid(isValid ? null : false); // null = não validado ainda, false = inválido if (isValid) { setCepLoading(true); try { const resultado = await buscarCEP(cepValue); if (resultado) { setCepValid(true); // Preencher campos automaticamente setEditingData(prev => ({ ...prev, street: resultado.street, neighborhood: resultado.neighborhood, city: resultado.city, state: resultado.state, })); console.log('[PERFIL] CEP preenchido com sucesso:', resultado); } else { setCepValid(false); } } catch (err) { console.error('[PERFIL] Erro ao buscar CEP:', err); setCepValid(false); } finally { setCepLoading(false); } } }; const handlePhoneChange = (phoneValue: string) => { const formatted = formatTelefone(phoneValue); setEditingData({...editingData, phone: formatted}); }; return (
{/* Header com Título e Botão */}

Meu Perfil

Bem-vindo à sua área exclusiva.

{!isEditing ? ( ) : (
)}
{/* Grid de 2 colunas */}
{/* Coluna Esquerda - Informações Pessoais */}
{/* Informações Pessoais */}

Informações Pessoais

{/* Nome Completo */}
{isEditing ? ( setEditingData({...editingData, full_name: e.target.value})} className="mt-2" /> ) : ( <>
{userInfo.profile?.full_name || "Não preenchido"}

Este campo não pode ser alterado

)}
{/* Email */}
{userInfo.user.email}

Este campo não pode ser alterado

{/* UUID */}
{userInfo.user.id}

Este campo não pode ser alterado

{/* Permissões */}
{userInfo.roles && userInfo.roles.length > 0 ? ( userInfo.roles.map((role) => ( {role} )) ) : ( Nenhuma permissão atribuída )}
{/* Endereço e Contato */}

Endereço e Contato

{/* Telefone */}
{isEditing ? ( handlePhoneChange(e.target.value)} className="mt-2" placeholder="(00) 00000-0000" maxLength={15} /> ) : (
{userInfo.profile?.phone || "Não preenchido"}
)}
{/* Endereço */}
{isEditing ? ( setEditingData({...editingData, street: e.target.value})} className="mt-2" placeholder="Rua, avenida, etc." /> ) : (
{userInfo.profile?.street || "Não preenchido"}
)}
{/* Número */}
{isEditing ? ( setEditingData({...editingData, number: e.target.value})} className="mt-2" placeholder="123" /> ) : (
{userInfo.profile?.number || "Não preenchido"}
)}
{/* Complemento */}
{isEditing ? ( setEditingData({...editingData, complement: e.target.value})} className="mt-2" placeholder="Apto 42, Bloco B, etc." /> ) : (
{userInfo.profile?.complement || "Não preenchido"}
)}
{/* Bairro */}
{isEditing ? ( setEditingData({...editingData, neighborhood: e.target.value})} className="mt-2" placeholder="Vila, bairro, etc." /> ) : (
{userInfo.profile?.neighborhood || "Não preenchido"}
)}
{/* Cidade */}
{isEditing ? ( setEditingData({...editingData, city: e.target.value})} className="mt-2" placeholder="São Paulo" /> ) : (
{userInfo.profile?.city || "Não preenchido"}
)}
{/* Estado */}
{isEditing ? ( setEditingData({...editingData, state: e.target.value})} className="mt-2" placeholder="SP" maxLength={2} /> ) : (
{userInfo.profile?.state || "Não preenchido"}
)}
{/* CEP */}
{isEditing ? (
handleCepChange(e.target.value)} className="mt-2" placeholder="00000-000" maxLength={9} disabled={cepLoading} />
{cepValid === true && ( )} {cepValid === false && ( )}
{cepLoading && (

Buscando CEP...

)} {cepValid === false && (

CEP inválido ou não encontrado

)} {cepValid === true && (

✓ CEP preenchido com sucesso

)}
) : (
{userInfo.profile?.cep || "Não preenchido"}
)}
{/* Coluna Direita - Foto do Perfil */}

Foto do Perfil

{isEditing ? (
{ setEditingData({...editingData, avatar_url: newUrl}) try { if (typeof updateUserProfile === 'function') { updateUserProfile({ foto_url: newUrl }) } else { const raw = localStorage.getItem('auth_user') if (raw) { const u = JSON.parse(raw) u.profile = u.profile || {} u.profile.foto_url = newUrl u.profile.avatar_url = newUrl localStorage.setItem('auth_user', JSON.stringify(u)) } } } catch (err) { console.warn('[PERFIL] erro ao persistir avatar no auth_user localStorage', err) } }} userName={editingData.full_name || userInfo.profile?.full_name || "Usuário"} />
) : (
{getInitials(userInfo.profile?.full_name)}

{getInitials(userInfo.profile?.full_name)}

)} {/* Informações de Status */}
{userInfo.profile?.disabled ? "Desabilitado" : "Ativo"}
{/* Botão Voltar */}
); }