From 4e2dd7f77e4bf8dac1ef0a90fa83f3fe61f5b3d0 Mon Sep 17 00:00:00 2001 From: rever-tecnologia Date: Mon, 15 Dec 2025 11:17:22 -0300 Subject: [PATCH] =?UTF-8?q?feat(settings):=20adiciona=20op=C3=A7=C3=A3o=20?= =?UTF-8?q?de=20remover=20foto=20de=20perfil?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Adiciona endpoint DELETE em /api/profile/avatar - Mostra dois botões ao hover: câmera (upload) e lixeira (remover) - Lixeira só aparece quando há uma foto definida 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/app/api/profile/avatar/route.ts | 27 +++++++++- src/components/settings/settings-content.tsx | 55 +++++++++++++++++--- 2 files changed, 73 insertions(+), 9 deletions(-) diff --git a/src/app/api/profile/avatar/route.ts b/src/app/api/profile/avatar/route.ts index fce3604..5404823 100644 --- a/src/app/api/profile/avatar/route.ts +++ b/src/app/api/profile/avatar/route.ts @@ -1,6 +1,7 @@ /** - * API de Upload de Avatar + * API de Avatar * POST - Faz upload de uma nova foto de perfil + * DELETE - Remove a foto de perfil (volta ao padrão) */ import { NextRequest, NextResponse } from "next/server" @@ -86,3 +87,27 @@ export async function POST(request: NextRequest) { return NextResponse.json({ error: "Erro interno do servidor" }, { status: 500 }) } } + +export async function DELETE() { + try { + const session = await getServerSession() + + if (!session?.user?.id) { + return NextResponse.json({ error: "Não autorizado" }, { status: 401 }) + } + + // Remove a imagem do usuário (volta ao padrão) + await prisma.authUser.update({ + where: { id: session.user.id }, + data: { image: null }, + }) + + return NextResponse.json({ + success: true, + message: "Foto removida com sucesso", + }) + } catch (error) { + console.error("[profile/avatar] Erro ao remover:", error) + return NextResponse.json({ error: "Erro interno do servidor" }, { status: 500 }) + } +} diff --git a/src/components/settings/settings-content.tsx b/src/components/settings/settings-content.tsx index 8540abd..f78e502 100644 --- a/src/components/settings/settings-content.tsx +++ b/src/components/settings/settings-content.tsx @@ -22,6 +22,7 @@ import { Clock, Camera, Loader2, + Trash2, } from "lucide-react" import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar" @@ -384,6 +385,30 @@ function ProfileEditCard({ } } + async function handleRemoveAvatar() { + if (!localAvatarUrl) return + + setIsUploadingAvatar(true) + try { + const res = await fetch("/api/profile/avatar", { + method: "DELETE", + }) + + if (!res.ok) { + const data = await res.json().catch(() => ({ error: "Erro ao remover foto" })) + throw new Error(data.error || "Erro ao remover foto") + } + + setLocalAvatarUrl(null) + toast.success("Foto removida com sucesso!") + } catch (error) { + console.error("Erro ao remover foto:", error) + toast.error(error instanceof Error ? error.message : "Erro ao remover foto") + } finally { + setIsUploadingAvatar(false) + } + } + const hasChanges = useMemo(() => { const nameChanged = editName.trim() !== name const emailChanged = editEmail.trim().toLowerCase() !== email.toLowerCase() @@ -465,18 +490,32 @@ function ProfileEditCard({ onChange={handleAvatarUpload} className="hidden" /> - + {localAvatarUrl && ( + + )} + )} - +
{name || "Usuário"}