2026-02-27 12:41:44 +00:00
|
|
|
import { useApi } from './useApi';
|
|
|
|
|
import { useLoader } from '../context/loaders/useLoader';
|
|
|
|
|
import { useToast } from '../context/toasts/useToast';
|
|
|
|
|
|
|
|
|
|
export function useCardDetailMutations(cardId: number, currentCard: any, onUpdate: () => void) {
|
2026-04-30 18:19:11 +00:00
|
|
|
const { updateCard, deleteCard, createComment, updateComment, deleteComment, createLinkedCard } =
|
|
|
|
|
useApi();
|
2026-02-27 12:41:44 +00:00
|
|
|
const { withLoader } = useLoader();
|
|
|
|
|
const { addNotification } = useToast();
|
|
|
|
|
|
|
|
|
|
const updateCardNameAndDescription = async (name: string, description: string) => {
|
|
|
|
|
try {
|
|
|
|
|
await withLoader(
|
|
|
|
|
() =>
|
|
|
|
|
updateCard(cardId, {
|
|
|
|
|
name: name,
|
|
|
|
|
description: description,
|
|
|
|
|
pos: currentCard?.pos || 0,
|
|
|
|
|
}),
|
|
|
|
|
'Updating card...'
|
|
|
|
|
);
|
|
|
|
|
onUpdate();
|
|
|
|
|
addNotification({
|
|
|
|
|
type: 'success',
|
|
|
|
|
title: 'Card Updated',
|
|
|
|
|
message: 'Card has been updated successfully.',
|
|
|
|
|
duration: 3000,
|
|
|
|
|
});
|
|
|
|
|
return true;
|
|
|
|
|
} catch (err) {
|
|
|
|
|
const errorMessage = err instanceof Error ? err.message : 'Failed to update card';
|
|
|
|
|
addNotification({
|
|
|
|
|
type: 'error',
|
|
|
|
|
title: 'Error',
|
|
|
|
|
message: errorMessage,
|
|
|
|
|
duration: 5000,
|
|
|
|
|
});
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const deleteCardWithConfirmation = async (onSuccess: () => void) => {
|
|
|
|
|
try {
|
|
|
|
|
await withLoader(() => deleteCard(cardId), 'Deleting card...');
|
|
|
|
|
addNotification({
|
|
|
|
|
type: 'success',
|
|
|
|
|
title: 'Card Deleted',
|
|
|
|
|
message: 'Card has been deleted successfully.',
|
|
|
|
|
duration: 3000,
|
|
|
|
|
});
|
|
|
|
|
onSuccess();
|
|
|
|
|
} catch (err) {
|
|
|
|
|
const errorMessage = err instanceof Error ? err.message : 'Failed to delete card';
|
|
|
|
|
addNotification({
|
|
|
|
|
type: 'error',
|
|
|
|
|
title: 'Error',
|
|
|
|
|
message: errorMessage,
|
|
|
|
|
duration: 5000,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const addComment = async (text: string) => {
|
|
|
|
|
try {
|
|
|
|
|
await withLoader(() => createComment(cardId, { text }), 'Adding comment...');
|
|
|
|
|
onUpdate();
|
|
|
|
|
addNotification({
|
|
|
|
|
type: 'success',
|
|
|
|
|
title: 'Comment Added',
|
|
|
|
|
message: 'Your comment has been added successfully.',
|
|
|
|
|
duration: 3000,
|
|
|
|
|
});
|
|
|
|
|
return true;
|
|
|
|
|
} catch (err) {
|
|
|
|
|
const errorMessage = err instanceof Error ? err.message : 'Failed to add comment';
|
|
|
|
|
addNotification({
|
|
|
|
|
type: 'error',
|
|
|
|
|
title: 'Error',
|
|
|
|
|
message: errorMessage,
|
|
|
|
|
duration: 5000,
|
|
|
|
|
});
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const editComment = async (commentId: number, text: string) => {
|
|
|
|
|
try {
|
|
|
|
|
await withLoader(() => updateComment(commentId, { text }), 'Updating comment...');
|
|
|
|
|
onUpdate();
|
|
|
|
|
addNotification({
|
|
|
|
|
type: 'success',
|
|
|
|
|
title: 'Comment Updated',
|
|
|
|
|
message: 'Comment has been updated successfully.',
|
|
|
|
|
duration: 3000,
|
|
|
|
|
});
|
|
|
|
|
return true;
|
|
|
|
|
} catch (err) {
|
|
|
|
|
const errorMessage = err instanceof Error ? err.message : 'Failed to update comment';
|
|
|
|
|
addNotification({
|
|
|
|
|
type: 'error',
|
|
|
|
|
title: 'Error',
|
|
|
|
|
message: errorMessage,
|
|
|
|
|
duration: 5000,
|
|
|
|
|
});
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const deleteCommentWithConfirmation = async (commentId: number, onSuccess: () => void) => {
|
|
|
|
|
try {
|
|
|
|
|
await withLoader(() => deleteComment(commentId), 'Deleting comment...');
|
|
|
|
|
onUpdate();
|
|
|
|
|
addNotification({
|
|
|
|
|
type: 'success',
|
|
|
|
|
title: 'Comment Deleted',
|
|
|
|
|
message: 'Comment has been deleted successfully.',
|
|
|
|
|
duration: 3000,
|
|
|
|
|
});
|
|
|
|
|
onSuccess();
|
|
|
|
|
} catch (err) {
|
|
|
|
|
const errorMessage = err instanceof Error ? err.message : 'Failed to delete comment';
|
|
|
|
|
addNotification({
|
|
|
|
|
type: 'error',
|
|
|
|
|
title: 'Error',
|
|
|
|
|
message: errorMessage,
|
|
|
|
|
duration: 5000,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2026-04-30 18:19:11 +00:00
|
|
|
const createLinkedCardFromModal = async (
|
|
|
|
|
name: string,
|
|
|
|
|
description: string,
|
|
|
|
|
listId: number,
|
|
|
|
|
refreshLinks: () => Promise<void>
|
|
|
|
|
) => {
|
|
|
|
|
try {
|
|
|
|
|
await withLoader(
|
|
|
|
|
() =>
|
|
|
|
|
createLinkedCard(cardId, {
|
|
|
|
|
name,
|
|
|
|
|
list_id: listId,
|
|
|
|
|
description,
|
|
|
|
|
copy_labels: true,
|
|
|
|
|
copy_epics: true,
|
|
|
|
|
}),
|
|
|
|
|
'Creating linked card...'
|
|
|
|
|
);
|
|
|
|
|
await refreshLinks();
|
|
|
|
|
addNotification({
|
|
|
|
|
type: 'success',
|
|
|
|
|
title: 'Linked Card Created',
|
|
|
|
|
message: `"${name}" created and linked.`,
|
|
|
|
|
duration: 3000,
|
|
|
|
|
});
|
|
|
|
|
return true;
|
|
|
|
|
} catch (err) {
|
|
|
|
|
console.error(err);
|
|
|
|
|
addNotification({
|
|
|
|
|
type: 'error',
|
|
|
|
|
title: 'Error',
|
|
|
|
|
message: 'Failed to create linked card.',
|
|
|
|
|
duration: 5000,
|
|
|
|
|
});
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const convertCheckItemToCard = async (
|
|
|
|
|
itemName: string,
|
|
|
|
|
itemId: number,
|
|
|
|
|
listId: number,
|
|
|
|
|
removeCheckItem: (itemId: number) => Promise<boolean>,
|
|
|
|
|
refreshLinks: () => Promise<void>
|
|
|
|
|
) => {
|
|
|
|
|
try {
|
|
|
|
|
await withLoader(
|
|
|
|
|
() =>
|
|
|
|
|
createLinkedCard(cardId, {
|
|
|
|
|
name: itemName,
|
|
|
|
|
list_id: listId,
|
|
|
|
|
}),
|
|
|
|
|
'Converting to card...'
|
|
|
|
|
);
|
|
|
|
|
await removeCheckItem(itemId);
|
|
|
|
|
onUpdate();
|
|
|
|
|
await refreshLinks();
|
|
|
|
|
addNotification({
|
|
|
|
|
type: 'success',
|
|
|
|
|
title: 'Converted to Card',
|
|
|
|
|
message: `"${itemName}" is now a linked card.`,
|
|
|
|
|
duration: 3000,
|
|
|
|
|
});
|
|
|
|
|
} catch (err) {
|
|
|
|
|
console.error(err);
|
|
|
|
|
addNotification({
|
|
|
|
|
type: 'error',
|
|
|
|
|
title: 'Error',
|
|
|
|
|
message: 'Failed to convert item to card.',
|
|
|
|
|
duration: 5000,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2026-02-27 12:41:44 +00:00
|
|
|
return {
|
|
|
|
|
updateCardNameAndDescription,
|
|
|
|
|
deleteCardWithConfirmation,
|
|
|
|
|
addComment,
|
|
|
|
|
editComment,
|
|
|
|
|
deleteCommentWithConfirmation,
|
2026-04-30 18:19:11 +00:00
|
|
|
createLinkedCardFromModal,
|
|
|
|
|
convertCheckItemToCard,
|
2026-02-27 12:41:44 +00:00
|
|
|
};
|
|
|
|
|
}
|