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

105 lines
3.1 KiB
TypeScript

import { useState, useEffect, useCallback } from 'react';
import { useApi } from './useApi';
import { useLoader } from '../context/loaders/useLoader';
import { useToast } from '../context/toasts/useToast';
import type { Epic, UpdateEpicRequest } from '../types/epic';
function useEpicDetail(epicId: string) {
const [epic, setEpic] = useState<Epic | null>(null);
const [error, setError] = useState<Error | null>(null);
const { getEpic, updateEpic: apiUpdateEpic, deleteEpic: apiDeleteEpic } = useApi();
const { withLoader } = useLoader();
const { addNotification } = useToast();
const fetchEpic = useCallback(async () => {
try {
setError(null);
const data = await withLoader(() => getEpic(Number(epicId)), 'Loading epic...');
setEpic(data);
return data;
} catch (err) {
const errorMessage = err instanceof Error ? err.message : 'Failed to load epic';
setError(err instanceof Error ? err : new Error(errorMessage));
addNotification({
type: 'error',
title: 'Error Loading Epic',
message: errorMessage,
duration: 5000,
});
return null;
}
}, [epicId, getEpic, withLoader, addNotification]);
const updateEpic = useCallback(
async (epicData: UpdateEpicRequest) => {
try {
setError(null);
const updatedEpic = await withLoader(
() => apiUpdateEpic(Number(epicId), epicData),
'Updating epic...'
);
setEpic(updatedEpic);
addNotification({
type: 'success',
title: 'Epic Updated',
message: 'Epic updated successfully.',
duration: 3000,
});
return updatedEpic;
} catch (err) {
const errorMessage = err instanceof Error ? err.message : 'Failed to update epic';
setError(err instanceof Error ? err : new Error(errorMessage));
addNotification({
type: 'error',
title: 'Error Updating Epic',
message: errorMessage,
duration: 5000,
});
throw err;
}
},
[epicId, apiUpdateEpic, withLoader, addNotification]
);
const deleteEpic = useCallback(async () => {
try {
setError(null);
await withLoader(() => apiDeleteEpic(Number(epicId)), 'Deleting epic...');
addNotification({
type: 'success',
title: 'Epic Deleted',
message: 'Epic deleted successfully.',
duration: 3000,
});
return true;
} catch (err) {
const errorMessage = err instanceof Error ? err.message : 'Failed to delete epic';
setError(err instanceof Error ? err : new Error(errorMessage));
addNotification({
type: 'error',
title: 'Error Deleting Epic',
message: errorMessage,
duration: 5000,
});
throw err;
}
}, [epicId, apiDeleteEpic, withLoader, addNotification]);
useEffect(() => {
if (epicId) {
fetchEpic();
}
}, [epicId, fetchEpic]);
return {
epic,
error, // For debugging, not for UI display
loading: false, // Loading is handled by global loader
updateEpic,
deleteEpic,
refetch: fetchEpic,
};
}
export default useEpicDetail;