aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/async-button.tsx
diff options
context:
space:
mode:
authorSebastien Castiel <sebastien@castiel.me>2023-12-06 15:08:52 -0500
committerSebastien Castiel <sebastien@castiel.me>2023-12-06 15:08:52 -0500
commit570aa713b1b2becf7c06c89610c75d2cb119b532 (patch)
treeb6e3ae339bd55a7a00d77ee64532ece9fc43c13f /src/components/async-button.tsx
parentfee1963284eafa6db7887103a156799b7610e13d (diff)
Delete expense
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>
+ )
+}