aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/async-button.tsx
blob: 7d2bf9355f0d3a550968b884d58c6d670436692e (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
'use client'
import { Button, ButtonProps } from '@/components/ui/button'
import { Loader2 } from 'lucide-react'
import { ReactNode, useState } from 'react'

type Props = ButtonProps & {
  action?: () => Promise<void>
  loadingContent?: ReactNode
}

export function AsyncButton({
  action,
  children,
  loadingContent,
  ...props
}: Props) {
  const [loading, setLoading] = useState(false)
  return (
    <Button
      onClick={async () => {
        try {
          setLoading(true)
          await action?.()
        } catch (err) {
          console.error(err)
        } finally {
          setLoading(false)
        }
      }}
      {...props}
    >
      {loading ? (
        <>
          <Loader2 className="w-4 h-4 mr-2 animate-spin" />{' '}
          {loadingContent ?? children}
        </>
      ) : (
        children
      )}
    </Button>
  )
}