File size: 4,548 Bytes
9470652 | 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 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | import { useRef } from "react";
import {
Dialog,
DialogPanel,
Transition as HeadlessTransition,
TransitionChild as HeadlessTransitionChild,
} from "@headlessui/react";
import {
CheckCircleIcon,
ExclamationTriangleIcon,
InformationCircleIcon,
XCircleIcon,
} from "@heroicons/react/24/outline";
export enum AlertIcon {
Warning = "warning",
Success = "success",
Info = "info",
Error = "error",
}
export interface IAlertProps {
isOpen: boolean;
title: string;
message: string;
okText: string;
// color: string;
icon: AlertIcon;
onSuccess: () => void;
onCancel: () => void;
}
export function AlertModal({
isOpen,
title,
message,
okText,
icon,
onSuccess,
onCancel,
}: IAlertProps) {
const cancelButtonRef = useRef(null);
const getIconComponent = () => {
switch (icon) {
case AlertIcon.Warning:
return <ExclamationTriangleIcon className="h-6 w-6 text-red-600" />;
case AlertIcon.Success:
return <CheckCircleIcon className="h-6 w-6 text-green-600" />;
case AlertIcon.Info:
return <InformationCircleIcon className="h-6 w-6 text-blue-600" />;
case AlertIcon.Error:
default:
return <XCircleIcon className="h-6 w-6 text-gray-600" />;
}
};
return (
<HeadlessTransition show={isOpen}>
<Dialog
as="div"
className="relative z-10"
initialFocus={cancelButtonRef}
onClose={onCancel}
>
<HeadlessTransitionChild
enter="ease-out duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-in duration-200"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" />
</HeadlessTransitionChild>
<div className="fixed inset-0 z-10 w-screen overflow-y-auto">
<div className="flex min-h-full items-end justify-center p-4 text-center sm:items-center sm:p-0">
<HeadlessTransitionChild
enter="ease-out duration-300"
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
enterTo="opacity-100 translate-y-0 sm:scale-100"
leave="ease-in duration-200"
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
>
<DialogPanel className="relative transform overflow-hidden rounded-lg bg-white text-left shadow-xl transition-all sm:my-8 sm:w-full sm:max-w-lg lg:ml-72">
<div className="bg-white px-4 pb-4 pt-5 sm:p-6 sm:pb-4">
<div className="sm:flex sm:items-start">
<div className="mx-auto flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-full bg-red-100 sm:mx-0 sm:h-10 sm:w-10">
{getIconComponent()}
</div>
<div className="mt-3 text-center sm:ml-4 sm:mt-0 sm:text-left">
<Dialog.Title
as="h3"
className="text-base font-semibold leading-6 text-gray-900"
>
{title}
</Dialog.Title>
<div className="mt-2">
<p className="text-sm text-gray-500">{message}</p>
</div>
</div>
</div>
</div>
<div className="bg-gray-50 px-4 py-3 sm:flex sm:flex-row-reverse sm:px-6">
<button
type="button"
className="inline-flex w-full justify-center rounded-md bg-red-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-red-500 sm:ml-3 sm:w-auto"
onClick={onSuccess}
>
{okText}
</button>
<button
type="button"
className="mt-3 inline-flex w-full justify-center rounded-md bg-white px-3 py-2 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50 sm:mt-0 sm:w-auto"
onClick={onCancel}
ref={cancelButtonRef}
>
Cancel
</button>
</div>
</DialogPanel>
</HeadlessTransitionChild>
</div>
</div>
</Dialog>
</HeadlessTransition>
);
}
|