// ARQUIVO COMPLETO PARA: app/patient/profile/page.tsx "use client"; import { useState, useEffect, useRef } from "react"; import PatientLayout from "@/components/patient-layout"; import { useAuthLayout } from "@/hooks/useAuthLayout"; import { patientsService } from "@/services/patientsApi.mjs"; import { api } from "@/services/api.mjs"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Textarea } from "@/components/ui/textarea"; import { User, Mail, Phone, Calendar, Upload } from "lucide-react"; import { toast } from "@/hooks/use-toast"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; interface PatientProfileData { name: string; email: string; phone: string; cpf: string; birthDate: string; cep: string; street: string; number: string; city: string; avatarFullUrl?: string; } export default function PatientProfile() { const { user, isLoading: isAuthLoading } = useAuthLayout({ requiredRole: 'patient' }); const [patientData, setPatientData] = useState(null); const [isEditing, setIsEditing] = useState(false); const [isSaving, setIsSaving] = useState(false); const fileInputRef = useRef(null); useEffect(() => { if (user?.id) { const fetchPatientDetails = async () => { try { const patientDetails = await patientsService.getById(user.id); setPatientData({ name: patientDetails.full_name || user.name, email: user.email, phone: patientDetails.phone_mobile || '', cpf: patientDetails.cpf || '', birthDate: patientDetails.birth_date || '', cep: patientDetails.cep || '', street: patientDetails.street || '', number: patientDetails.number || '', city: patientDetails.city || '', avatarFullUrl: user.avatarFullUrl, }); } catch (error) { console.error("Erro ao buscar detalhes do paciente:", error); toast({ title: "Erro", description: "Não foi possível carregar seus dados completos.", variant: "destructive" }); } }; fetchPatientDetails(); } }, [user]); const handleInputChange = (field: keyof PatientProfileData, value: string) => { setPatientData((prev) => (prev ? { ...prev, [field]: value } : null)); }; const handleSave = async () => { if (!patientData || !user) return; setIsSaving(true); try { const patientPayload = { full_name: patientData.name, cpf: patientData.cpf, birth_date: patientData.birthDate, phone_mobile: patientData.phone, cep: patientData.cep, street: patientData.street, number: patientData.number, city: patientData.city, }; await patientsService.update(user.id, patientPayload); toast({ title: "Sucesso!", description: "Seus dados foram atualizados." }); setIsEditing(false); } catch (error) { console.error("Erro ao salvar dados:", error); toast({ title: "Erro", description: "Não foi possível salvar suas alterações.", variant: "destructive" }); } finally { setIsSaving(false); } }; const handleAvatarClick = () => { fileInputRef.current?.click(); }; const handleAvatarUpload = async (event: React.ChangeEvent) => { const file = event.target.files?.[0]; if (!file || !user) return; const fileExt = file.name.split('.').pop(); // *** A CORREÇÃO ESTÁ AQUI *** // O caminho salvo no banco de dados não deve conter o nome do bucket. const filePath = `${user.id}/avatar.${fileExt}`; try { await api.storage.upload('avatars', filePath, file); await api.patch(`/rest/v1/profiles?id=eq.${user.id}`, { avatar_url: filePath }); const newFullUrl = `https://yuanqfswhberkoevtmfr.supabase.co/storage/v1/object/public/avatars/${filePath}?t=${new Date().getTime()}`; setPatientData(prev => prev ? { ...prev, avatarFullUrl: newFullUrl } : null); toast({ title: "Sucesso!", description: "Sua foto de perfil foi atualizada." }); } catch (error) { console.error("Erro no upload do avatar:", error); toast({ title: "Erro de Upload", description: "Não foi possível enviar sua foto.", variant: "destructive" }); } }; if (isAuthLoading || !patientData) { return
Carregando seus dados...
; } return (

Meus Dados

Gerencie suas informações pessoais

Informações Pessoais
handleInputChange("name", e.target.value)} disabled={!isEditing} />
handleInputChange("cpf", e.target.value)} disabled={!isEditing} />
handleInputChange("birthDate", e.target.value)} disabled={!isEditing} />
Contato e Endereço
handleInputChange("phone", e.target.value)} disabled={!isEditing} />
handleInputChange("cep", e.target.value)} disabled={!isEditing} />
handleInputChange("street", e.target.value)} disabled={!isEditing} />
handleInputChange("number", e.target.value)} disabled={!isEditing} />
handleInputChange("city", e.target.value)} disabled={!isEditing} />
Resumo do Perfil
{patientData.name.split(" ").map((n) => n[0]).join("")}

{patientData.name}

Paciente

{patientData.email}
{patientData.phone || "Não informado"}
{patientData.birthDate ? new Date(patientData.birthDate).toLocaleDateString("pt-BR", { timeZone: 'UTC' }) : "Não informado"}
); }