Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x | /**
* useSubmit — form submission wrapper with toast feedback.
*/
import {useCallback, useState} from 'react';
import type {IBlongError} from '../types/action.js';
import {useToast} from './useToast.js';
export interface IUseSubmitOptions {
successMessage?: string;
errorMessage?: string;
/** Called on successful submission */
onSuccess?: (result: unknown) => void;
/** Called on error */
onError?: (error: IBlongError | Error) => void;
}
export interface IUseSubmitResult<T extends Record<string, unknown>> {
submitting: boolean;
submit: (values: T) => Promise<unknown>;
}
export function useSubmit<T extends Record<string, unknown>>(
fn: (values: T) => Promise<unknown>,
options: IUseSubmitOptions = {},
): IUseSubmitResult<T> {
const {successMessage = 'Saved successfully', errorMessage = 'An error occurred'} = options;
const [submitting, setSubmitting] = useState(false);
const toast = useToast();
const submit = useCallback(
async (values: T) => {
setSubmitting(true);
try {
const result = await fn(values);
toast.success(successMessage);
options.onSuccess?.(result);
return result;
} catch (err) {
const error = err as IBlongError | Error;
toast.error(
'type' in error ? ((error as IBlongError).print ?? errorMessage) : errorMessage,
);
options.onError?.(error);
throw err;
} finally {
setSubmitting(false);
}
},
[fn, successMessage, errorMessage, toast, options],
);
return {submitting, submit};
}
|