From 747fd57f1490776fbb2c299e1cdada14a2d685a7 Mon Sep 17 00:00:00 2001 From: Sosokker Date: Thu, 7 Nov 2024 04:21:17 +0700 Subject: [PATCH] fix: user can update avatar after first upload --- next.config.mjs | 8 ++- src/app/(user)/profile/[uid]/edit/page.tsx | 37 +++++++++-- src/lib/data/profileMutate.ts | 74 ++++++++++------------ 3 files changed, 74 insertions(+), 45 deletions(-) diff --git a/next.config.mjs b/next.config.mjs index 881ad15..ff1f0fe 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -10,6 +10,12 @@ const nextConfig = { port: "", pathname: "/storage/v1/object/sign/**", }, + { + protocol: "https", + hostname: SUPABASE_URL, + port: "", + pathname: "/storage/v1/object/public/**", + }, { protocol: "https", hostname: "upload.wikimedia.org", @@ -19,7 +25,7 @@ const nextConfig = { protocol: "https", hostname: "avatars.githubusercontent.com", pathname: "/**", - } + }, ], }, }; diff --git a/src/app/(user)/profile/[uid]/edit/page.tsx b/src/app/(user)/profile/[uid]/edit/page.tsx index 3046e2d..97abc85 100644 --- a/src/app/(user)/profile/[uid]/edit/page.tsx +++ b/src/app/(user)/profile/[uid]/edit/page.tsx @@ -39,29 +39,56 @@ export default function EditProfilePage({ params }: { params: { uid: string } }) const onProfileSubmit = async (updates: z.infer) => { const { avatars, username, full_name } = updates; + let avatarUrl = null; try { - let avatarUrl = null; - if (avatars instanceof File) { + const { data: currentProfile, error: fetchError } = await client + .from("profiles") + .select("avatar_url") + .eq("id", uid) + .single(); + + if (fetchError) { + throw new Error("Failed to fetch existing profile data"); + } + + if (currentProfile?.avatar_url) { + const oldAvatarPath = currentProfile.avatar_url.split("/").pop(); + const { error: deleteError } = await client.storage.from("avatars").remove([oldAvatarPath]); + + if (deleteError) { + console.warn("Failed to delete old avatar:", deleteError.message); + } + } + const avatarData = await uploadAvatar(client, avatars, uid); avatarUrl = avatarData?.path ? `${process.env.NEXT_PUBLIC_SUPABASE_URL}/storage/v1/object/public/avatars/${avatarData.path}` : null; } - const result = await updateProfile(client, uid, { + const updateData = { username, full_name, bio: bioContent, ...(avatarUrl && { avatar_url: avatarUrl }), - }); + }; + + const hasChanges = Object.values(updateData).some((value) => value !== undefined && value !== null); + + if (!hasChanges) { + toast.error("No fields to update!"); + return; + } + + const result = await updateProfile(client, uid, updateData); if (result) { toast.success("Profile updated successfully!"); router.push(`/profile/${uid}`); } else { - toast.error("No fields to update!"); + toast.error("Failed to update profile!"); } } catch (error) { toast.error("Error updating profile!"); diff --git a/src/lib/data/profileMutate.ts b/src/lib/data/profileMutate.ts index 97f5777..6b755a4 100644 --- a/src/lib/data/profileMutate.ts +++ b/src/lib/data/profileMutate.ts @@ -1,48 +1,44 @@ import { SupabaseClient } from "@supabase/supabase-js"; interface UpdateData { - username?: string; - full_name?: string; - bio?: string; - updated_at?: Date; + username?: string; + full_name?: string; + bio?: string; + updated_at?: Date; + avatar_url?: string | null; } -export async function updateProfile( - supabase: SupabaseClient, - userId: string, - updates: UpdateData, -) { - const updateData: { [key: string]: any | undefined } = {}; +export async function updateProfile(supabase: SupabaseClient, userId: string, updates: UpdateData) { + const updateData: { [key: string]: any | undefined } = {}; - if (updates.username || updates.username != "") { - updateData.username = updates.username; - } - if (updates.full_name || updates.full_name != "") { - updateData.full_name = updates.full_name; - } - if (updates.bio || updates.bio != "") { - updateData.bio = updates.bio; + if (updates.username || updates.username != "") { + updateData.username = updates.username; + } + if (updates.full_name || updates.full_name != "") { + updateData.full_name = updates.full_name; + } + if (updates.bio || updates.bio != "") { + updateData.bio = updates.bio; + } + if (updates.avatar_url || updates.avatar_url != "") { + updateData.avatar_url = updates.avatar_url; + } + updateData.updated_at = new Date(); + console.log(updateData); + if ( + updateData.username != undefined || + updateData.full_name != undefined || + updateData.bio != undefined || + updateData.avatar_url != undefined + ) { + const { error } = await supabase.from("profiles").update(updateData).eq("id", userId); + + if (error) { + throw error; } - updateData.updated_at = new Date(); - - if ( - updateData.username != undefined || updateData.full_name != undefined || - updateData.bio != undefined - ) { - const { error } = await supabase - .from("profiles") - .update(updateData) - .eq("id", userId); - - if (error) { - console.error("Error updating profile:", error); - throw error; - } - - return true; - } else { - console.log("No fields to update."); - return null; - } + return true; + } else { + return null; + } }