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

125 lines
3.8 KiB
TypeScript
Raw Normal View History

2026-02-27 07:53:36 +00:00
import { useState, useEffect, useCallback } from 'react';
import { useApi } from './useApi';
import { useLoader } from '../context/loaders/useLoader';
import { useToast } from '../context/toasts/useToast';
import { Board } from '../types/kanban';
export function useBoards() {
const [boards, setBoards] = useState<Board[]>([]);
const [error, setError] = useState<Error | null>(null);
const { getBoards, createBoard, updateBoard, deleteBoard } = useApi();
const { withLoader } = useLoader();
const { addNotification } = useToast();
2026-02-27 07:53:36 +00:00
const fetchBoards = useCallback(async () => {
try {
setError(null);
const data = await withLoader(() => getBoards(), 'Loading boards...');
setBoards(data);
return data;
} catch (err) {
const errorMessage = err instanceof Error ? err.message : 'Failed to load boards';
setError(err instanceof Error ? err : new Error(errorMessage));
addNotification({
type: 'error',
title: 'Error Loading Boards',
message: errorMessage,
duration: 5000,
});
return [];
}
2026-02-27 07:53:36 +00:00
}, [getBoards, withLoader, addNotification]);
const createNewBoard = async (boardData: { name: string; description?: string }) => {
try {
setError(null);
const data = await withLoader(() => createBoard(boardData), 'Creating board...');
setBoards((prev) => [...prev, data]);
addNotification({
type: 'success',
title: 'Board Created',
message: `Board "${data.name}" created successfully.`,
duration: 3000,
});
return data;
} catch (err) {
const errorMessage = err instanceof Error ? err.message : 'Failed to create board';
setError(err instanceof Error ? err : new Error(errorMessage));
addNotification({
type: 'error',
title: 'Error Creating Board',
message: errorMessage,
duration: 5000,
});
throw err;
}
};
const updateExistingBoard = async (
id: number,
boardData: { name: string; description?: string }
) => {
try {
setError(null);
const data = await withLoader(() => updateBoard(id, boardData), 'Updating board...');
setBoards((prev) => prev.map((board) => (board.id === id ? data : board)));
addNotification({
type: 'success',
title: 'Board Updated',
message: `Board "${data.name}" updated successfully.`,
duration: 3000,
});
return data;
} catch (err) {
const errorMessage = err instanceof Error ? err.message : 'Failed to update board';
setError(err instanceof Error ? err : new Error(errorMessage));
addNotification({
type: 'error',
title: 'Error Updating Board',
message: errorMessage,
duration: 5000,
});
throw err;
}
};
const removeBoard = async (id: number) => {
try {
setError(null);
await withLoader(() => deleteBoard(id), 'Deleting board...');
setBoards((prev) => prev.filter((board) => board.id !== id));
addNotification({
type: 'success',
title: 'Board Deleted',
message: 'Board deleted successfully.',
duration: 3000,
});
} catch (err) {
const errorMessage = err instanceof Error ? err.message : 'Failed to delete board';
setError(err instanceof Error ? err : new Error(errorMessage));
addNotification({
type: 'error',
title: 'Error Deleting Board',
message: errorMessage,
duration: 5000,
});
throw err;
}
};
useEffect(() => {
fetchBoards();
2026-02-27 07:53:36 +00:00
}, [fetchBoards]);
return {
boards,
error, // For debugging, not for UI display
loading: false, // Loading is handled by global loader
fetchBoards,
createBoard: createNewBoard,
updateBoard: updateExistingBoard,
deleteBoard: removeBoard,
};
}