Files
thrilltrack-explorer/src-old/hooks/useAutoSave.ts

59 lines
1.3 KiB
TypeScript

import { useEffect, useRef, useState } from 'react';
import { useDebounce } from './useDebounce';
export type AutoSaveOptions<T> = {
data: T;
onSave: (data: T) => Promise<void>;
debounceMs?: number;
enabled?: boolean;
isValid?: boolean;
};
export const useAutoSave = <T,>({
data,
onSave,
debounceMs = 3000,
enabled = true,
isValid = true
}: AutoSaveOptions<T>) => {
const [isSaving, setIsSaving] = useState(false);
const [lastSaved, setLastSaved] = useState<Date | null>(null);
const [error, setError] = useState<string | null>(null);
const debouncedData = useDebounce(data, debounceMs);
const initialRender = useRef(true);
useEffect(() => {
// Skip initial render
if (initialRender.current) {
initialRender.current = false;
return;
}
// Skip if disabled or invalid
if (!enabled || !isValid) return;
const save = async () => {
setIsSaving(true);
setError(null);
try {
await onSave(debouncedData);
setLastSaved(new Date());
} catch (err) {
setError(err instanceof Error ? err.message : 'Failed to auto-save');
} finally {
setIsSaving(false);
}
};
save();
}, [debouncedData, enabled, isValid, onSave]);
return {
isSaving,
lastSaved,
error,
resetError: () => setError(null)
};
};