130 lines
3.4 KiB
TypeScript
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,
|
|
};
|
|
}
|