import React, { useCallback, useEffect, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { Undo2, X } from 'lucide-react';
import { Button } from '@/components/ui/Button';
import { useUndoLastAction } from '@/api/entityHistory';
interface UndoToastProps {
message: string;
onUndo: () => void;
onDismiss: () => void;
isUndoing: boolean;
}
/**
* Undo toast shown after delete actions.
* Auto-dismisses after 5 seconds and is manually dismissable.
*/
export function UndoToast({ message, onUndo, onDismiss, isUndoing }: UndoToastProps) {
const { t } = useTranslation();
return (
{message}
}
>
{t('undoToast.undo', 'Undo')}
);
}
interface UndoToastState {
message: string;
entityType: string;
entityId: string;
}
/**
* Hook that shows an undo toast after a delete action and provides the undo function.
*
* Returns:
* - `showUndoToast(message, entityType, entityId)`: trigger the toast
* - `undoToast`: the JSX element to render (render it once in the page)
*/
export function useUndoToast() {
const { t } = useTranslation();
const [state, setState] = useState(null);
const timerRef = useRef | null>(null);
const undoMutation = useUndoLastAction();
const clearTimer = useCallback(() => {
if (timerRef.current) {
clearTimeout(timerRef.current);
timerRef.current = null;
}
}, []);
const dismiss = useCallback(() => {
clearTimer();
setState(null);
}, [clearTimer]);
const showUndoToast = useCallback(
(message: string, entityType: string, entityId: string) => {
clearTimer();
setState({ message, entityType, entityId });
timerRef.current = setTimeout(() => {
setState(null);
timerRef.current = null;
}, 5000);
},
[clearTimer]
);
const handleUndo = useCallback(async () => {
if (!state) return;
try {
await undoMutation.mutateAsync({
entityType: state.entityType,
entityId: state.entityId,
});
dismiss();
} catch {
// Keep the toast visible so the user can retry; the mutation error is surfaced elsewhere.
}
}, [state, undoMutation, dismiss]);
// Cleanup timer on unmount
useEffect(() => clearTimer, [clearTimer]);
const undoToast = state ? (
) : null;
return { showUndoToast, undoToast };
}