aboutsummaryrefslogtreecommitdiffhomepage
path: root/frontend/src/components/async/MutateButton.tsx
blob: 5de836278c2f3da3a9fdd7b3f4fd0d1501684c75 (plain)
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
import { useCallback, useState } from "react";
import { UseMutationResult } from "react-query";
import { Button, ButtonProps } from "@mantine/core";

type MutateButtonProps<DATA, VAR> = Omit<
  ButtonProps,
  "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;