kanban-app/frontend/src/hooks/useCardMutations.ts

130 lines
3.4 KiB
TypeScript

import { useApi } from './useApi';
import { useLoader } from '../context/loaders/useLoader';
import { useToast } from '../context/toasts/useToast';
import { Card } from '../types/kanban';
export function useCardMutations(boardId: number, onUpdate: () => void) {
const { createCard, updateCard, deleteCard } = useApi();
const { withLoader } = useLoader();
const { addNotification } = useToast();
const createNewCard = async (
listId: number,
cardData: {
name: string;
description?: string;
pos: number;
}
) => {
try {
const data = await withLoader(() => createCard(listId, cardData), 'Creating card...');
addNotification({
type: 'success',
title: 'Card Created',
message: `Card "${data.name}" created successfully.`,
duration: 3000,
});
return data;
} catch (err) {
const errorMessage = err instanceof Error ? err.message : 'Failed to create card';
addNotification({
type: 'error',
title: 'Error Creating Card',
message: errorMessage,
duration: 5000,
});
throw err;
}
};
const updateExistingCard = async (
cardId: number,
cardData: {
name: string;
description?: string;
pos: number;
list_id?: number;
}
) => {
try {
const data = await withLoader(() => updateCard(cardId, cardData), 'Updating card...');
addNotification({
type: 'success',
title: 'Card Updated',
message: `Card "${data.name}" updated successfully.`,
duration: 3000,
});
return data;
} catch (err) {
const errorMessage = err instanceof Error ? err.message : 'Failed to update card';
addNotification({
type: 'error',
title: 'Error Updating Card',
message: errorMessage,
duration: 5000,
});
throw err;
}
};
const moveCard = async (
card: Card,
fromListId: number,
toListId: number,
newPosition: number
) => {
try {
// Optimistic update - don't show loader for drag operations
await updateCard(card.id, {
name: card.name, // Placeholder, will be filled by server
pos: newPosition,
list_id: toListId,
});
onUpdate();
addNotification({
type: 'success',
title: 'Card Moved',
message: 'Card moved successfully.',
duration: 2000,
});
} catch (err) {
const errorMessage = err instanceof Error ? err.message : 'Failed to move card';
addNotification({
type: 'error',
title: 'Error Moving Card',
message: errorMessage,
duration: 5000,
});
throw err;
}
};
const removeCard = async (cardId: number) => {
try {
await withLoader(() => deleteCard(cardId), 'Deleting card...');
addNotification({
type: 'success',
title: 'Card Deleted',
message: 'Card deleted successfully.',
duration: 3000,
});
} catch (err) {
const errorMessage = err instanceof Error ? err.message : 'Failed to delete card';
addNotification({
type: 'error',
title: 'Error Deleting Card',
message: errorMessage,
duration: 5000,
});
throw err;
}
};
return {
createCard: createNewCard,
updateCard: updateExistingCard,
moveCard,
deleteCard: removeCard,
};
}