aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/async-button.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/async-button.tsx')
-rw-r--r--src/components/async-button.tsx42
1 files changed, 42 insertions, 0 deletions
diff --git a/src/components/async-button.tsx b/src/components/async-button.tsx
new file mode 100644
index 0000000..7d2bf93
--- /dev/null
+++ b/src/components/async-button.tsx
@@ -0,0 +1,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>
+ )
+}