Skip to content

Commit a8a1f16

Browse files
committed
Add useConfirm hook for confirmation dialogs with modal support
1 parent 66b7d1c commit a8a1f16

File tree

2 files changed

+73
-0
lines changed

2 files changed

+73
-0
lines changed

src/hooks/use-confirm.tsx

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import { useState } from "react";
2+
3+
import { Button, type ButtonProps } from "@/components/ui/button";
4+
import { ResponsiveModal } from "@/components/responsive-modal";
5+
import {
6+
Card,
7+
CardContent,
8+
CardDescription,
9+
CardHeader,
10+
CardTitle,
11+
} from "@/components/ui/card";
12+
13+
export const useConfirm = (
14+
title: string,
15+
message: string,
16+
variant: ButtonProps["variant"] = "primary"
17+
): [() => JSX.Element, () => Promise<unknown>] => {
18+
const [promise, setPromise] = useState<{
19+
resolve: (value: boolean) => void;
20+
} | null>(null);
21+
22+
const confirm = () => {
23+
return new Promise((resolve) => {
24+
setPromise({ resolve });
25+
});
26+
};
27+
28+
const handleClose = () => {
29+
setPromise(null);
30+
};
31+
32+
const handleConfirm = () => {
33+
promise?.resolve(true);
34+
handleClose();
35+
};
36+
37+
const handleCancel = () => {
38+
promise?.resolve(false);
39+
handleClose();
40+
};
41+
42+
const ConfirmDialog = () => (
43+
<ResponsiveModal open={promise !== null} onOpenChange={handleClose}>
44+
<Card className="w-full h-full border-none shadow-none">
45+
<CardContent className="pt-8">
46+
<CardHeader className="p-0">
47+
<CardTitle>{title}</CardTitle>
48+
<CardDescription>{message}</CardDescription>
49+
</CardHeader>
50+
<div className="pt-4 w-full flex flex-col gap-y-2 lg:flex-row gap-x-2 items-center justify-end ">
51+
<Button
52+
onClick={handleCancel}
53+
variant={"outline"}
54+
className="w-full lg:w-auto"
55+
>
56+
Cancel
57+
</Button>
58+
<Button
59+
onClick={handleConfirm}
60+
variant={variant}
61+
className="w-full lg:w-auto"
62+
>
63+
Confirm
64+
</Button>
65+
</div>
66+
</CardContent>
67+
</Card>
68+
</ResponsiveModal>
69+
);
70+
71+
return [ConfirmDialog, confirm];
72+
};

tailwind.config.ts

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const config: Config = {
77
"./src/components/**/*.{js,ts,jsx,tsx,mdx}",
88
"./src/app/**/*.{js,ts,jsx,tsx,mdx}",
99
"./src/features/**/*.{js,ts,jsx,tsx,mdx}",
10+
"./src/hooks/**/*.{js,ts,jsx,tsx,mdx}",
1011
],
1112
theme: {
1213
extend: {

0 commit comments

Comments
 (0)