You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
48 lines
1.1 KiB
48 lines
1.1 KiB
2 years ago
|
import { Button, ButtonProps } from "@mantine/core";
|
||
|
import { useCallback, useState } from "react";
|
||
|
import { UseMutationResult } from "react-query";
|
||
|
|
||
|
type MutateButtonProps<DATA, VAR> = Omit<
|
||
|
ButtonProps<"button">,
|
||
|
"onClick" | "loading" | "color"
|
||
|
> & {
|
||
|
mutation: UseMutationResult<DATA, unknown, VAR>;
|
||
|
args: () => VAR | null;
|
||
|
onSuccess?: (args: DATA) => void;
|
||
|
onError?: () => void;
|
||
|
noReset?: boolean;
|
||
|
};
|
||
|
|
||
|
function MutateButton<DATA, VAR>({
|
||
|
mutation,
|
||
|
noReset,
|
||
|
onSuccess,
|
||
|
onError,
|
||
|
args,
|
||
|
...props
|
||
|
}: MutateButtonProps<DATA, VAR>) {
|
||
|
const { mutateAsync } = mutation;
|
||
|
|
||
|
const [isLoading, setLoading] = useState(false);
|
||
|
|
||
|
const onClick = useCallback(async () => {
|
||
|
setLoading(true);
|
||
|
try {
|
||
|
const argument = args();
|
||
|
if (argument !== null) {
|
||
|
const data = await mutateAsync(argument);
|
||
|
onSuccess?.(data);
|
||
|
} else {
|
||
|
onError?.();
|
||
|
}
|
||
|
} catch (error) {
|
||
|
onError?.();
|
||
|
}
|
||
|
setLoading(false);
|
||
|
}, [args, mutateAsync, onError, onSuccess]);
|
||
|
|
||
|
return <Button {...props} loading={isLoading} onClick={onClick}></Button>;
|
||
|
}
|
||
|
|
||
|
export default MutateButton;
|