Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 0 additions & 19 deletions app/api/artist/remove/route.ts

This file was deleted.

17 changes: 8 additions & 9 deletions components/ArtistSetting/DeleteModal.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,22 @@
import { useArtistProvider } from "@/providers/ArtistProvider";
import { ArtistRecord } from "@/types/Artist";
import useDeleteArtist from "@/hooks/useDeleteArtist";

interface DeleteModalProps {
toggleModal: () => void;
}

const DeleteModal = ({ toggleModal }: DeleteModalProps) => {
const { editableArtist, artists, setArtists, toggleSettingModal } =
useArtistProvider();
const { editableArtist, toggleSettingModal } = useArtistProvider();
const { deleteArtist } = useDeleteArtist();

const handleDelete = async () => {
const temp = artists.filter(
(artistEle: ArtistRecord) =>
artistEle.account_id !== editableArtist?.account_id,
);
setArtists([...temp]);
const artistId = editableArtist?.account_id;
if (!artistId) {
return;
}
toggleModal();
toggleSettingModal();
await fetch(`/api/artist/remove?artistId=${editableArtist?.account_id}`);
await deleteArtist(artistId);
};

return (
Expand Down
15 changes: 6 additions & 9 deletions components/Artists/DropDown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,16 @@ import { ArtistRecord } from "@/types/Artist";
import { Trash2 } from "lucide-react";
import { containerPatterns, textPatterns } from "@/lib/styles/patterns";
import { cn } from "@/lib/utils";
import useDeleteArtist from "@/hooks/useDeleteArtist";

const DropDown = ({ artist }: { artist: ArtistRecord }) => {
const { setArtists, artists, setMenuVisibleArtistId, getArtists } =
useArtistProvider();
const { setMenuVisibleArtistId } = useArtistProvider();
const { deleteArtist } = useDeleteArtist();

const handleDelete = async () => {
const temp = artists.filter(
(artistEle: ArtistRecord) => artistEle.account_id !== artist.account_id,
);
setArtists([...temp]);
setMenuVisibleArtistId(null);
await fetch(`/api/artist/remove?artistId=${artist.account_id}`);
getArtists();
await deleteArtist(artist.account_id, {
onSuccess: () => setMenuVisibleArtistId(null),
});
};

return (
Expand Down
50 changes: 50 additions & 0 deletions hooks/useDeleteArtist.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { usePrivy } from "@privy-io/react-auth";
import { toast } from "sonner";
import { deleteArtist } from "@/lib/artists/deleteArtist";
import { useArtistProvider } from "@/providers/ArtistProvider";

interface DeleteArtistOptions {
onSuccess?: () => void;
}

interface UseDeleteArtistReturn {
deleteArtist: (artistId: string, options?: DeleteArtistOptions) => Promise<void>;
}

export default function useDeleteArtist(): UseDeleteArtistReturn {
const { getAccessToken } = usePrivy();
const { artists, setArtists, getArtists } = useArtistProvider();

const deleteArtistHandler = async (
artistId: string,
options?: DeleteArtistOptions,
): Promise<void> => {
const previousArtists = artists;
const nextArtists = artists.filter(artist => artist.account_id !== artistId);
setArtists(nextArtists);

try {
const accessToken = await getAccessToken();
if (!accessToken) {
throw new Error("Please sign in to delete an artist");
}

await deleteArtist(accessToken, artistId);
options?.onSuccess?.();
} catch (error) {
setArtists(previousArtists);
toast.error(error instanceof Error ? error.message : "Failed to delete artist");
return;
}

Comment on lines +33 to +39
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai bot Apr 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: If onSuccess throws, the catch block rolls back the optimistic removal even though the server-side delete already succeeded. Move options?.onSuccess?.() after the first try-catch to match the stated intent of only rolling back on delete API failure.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At hooks/useDeleteArtist.ts, line 33:

<comment>If `onSuccess` throws, the catch block rolls back the optimistic removal even though the server-side delete already succeeded. Move `options?.onSuccess?.()` after the first try-catch to match the stated intent of only rolling back on delete API failure.</comment>

<file context>
@@ -0,0 +1,50 @@
+      }
+
+      await deleteArtist(accessToken, artistId);
+      options?.onSuccess?.();
+    } catch (error) {
+      setArtists(previousArtists);
</file context>
Suggested change
options?.onSuccess?.();
} catch (error) {
setArtists(previousArtists);
toast.error(error instanceof Error ? error.message : "Failed to delete artist");
return;
}
} catch (error) {
setArtists(previousArtists);
toast.error(error instanceof Error ? error.message : "Failed to delete artist");
return;
}
options?.onSuccess?.();
Fix with Cubic

try {
await getArtists();
} catch {
toast.error("Artist deleted, but failed to refresh the artist list");
}
};

return {
deleteArtist: deleteArtistHandler,
};
}
27 changes: 27 additions & 0 deletions lib/artists/deleteArtist.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { getClientApiBaseUrl } from "@/lib/api/getClientApiBaseUrl";

interface DeleteArtistResponse {
success?: boolean;
error?: string;
}

/**
* Deletes an artist through the dedicated API.
*
* @param accessToken - Privy access token for Bearer auth
* @param artistId - Artist account ID to delete
*/
export async function deleteArtist(accessToken: string, artistId: string): Promise<void> {
const response = await fetch(`${getClientApiBaseUrl()}/api/artists/${artistId}`, {
method: "DELETE",
headers: {
Authorization: `Bearer ${accessToken}`,
},
});

const data: DeleteArtistResponse = await response.json();

if (!response.ok || !data.success) {
throw new Error(data.error || "Failed to delete artist");
}
}
Loading