5b73389d64
This commit introduces filtering capabilities to the administrators table, allowing users to refine the list based on specific criteria. A new `ListHeader` component has been implemented, which now contains the "Create Admin" button and a new "Filter" button. Clicking the filter button opens a modal containing the `AdminListFilters` form. The state for managing the filter modal's visibility is handled within the `useAdminsPresenter` hook. A new `FilterIcon` has also been added to support this feature.
94 lines
2.6 KiB
TypeScript
94 lines
2.6 KiB
TypeScript
import { CrossIcon } from "@/assets/icons";
|
|
import { useIsMutating } from "@tanstack/react-query";
|
|
import { ReactNode, useEffect, useState } from "react";
|
|
import { createPortal } from "react-dom";
|
|
import IsVisible from "./IsVisible";
|
|
|
|
interface ModalProps {
|
|
isOpen: boolean;
|
|
onClose: () => void;
|
|
onConfirm?: () => void;
|
|
children: ReactNode;
|
|
confirmText?: string;
|
|
cancelText?: string;
|
|
showButtons?: boolean;
|
|
classNames?: string;
|
|
}
|
|
|
|
const Modal: React.FC<ModalProps> = ({
|
|
isOpen,
|
|
onClose,
|
|
children,
|
|
onConfirm,
|
|
confirmText = "confirm",
|
|
cancelText = "close",
|
|
showButtons = true,
|
|
classNames,
|
|
}) => {
|
|
const [mounted, setMounted] = useState(false);
|
|
const isMutating = useIsMutating();
|
|
useEffect(() => {
|
|
setMounted(true);
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
if (isOpen) {
|
|
document.body.style.overflow = "hidden";
|
|
} else {
|
|
document.body.style.overflow = "unset";
|
|
}
|
|
|
|
return () => {
|
|
document.body.style.overflow = "unset";
|
|
};
|
|
}, [isOpen]);
|
|
|
|
if (!mounted || !isOpen) return null;
|
|
|
|
const modalContent = (
|
|
<div
|
|
className="fixed inset-0 z-999999 flex items-center justify-center bg-dark/50 dark:bg-black/50"
|
|
onClick={onClose}
|
|
>
|
|
<div
|
|
className={`max-h-[90vh] max-w-[90vw] overflow-auto rounded-lg bg-white p-5 shadow-4 dark:bg-dark-2 ${classNames}`}
|
|
onClick={(e) => e.stopPropagation()}
|
|
>
|
|
<button
|
|
onClick={onClose}
|
|
className="float-right mb-2.5 cursor-pointer border-none bg-transparent p-0 text-2xl text-dark-5 hover:text-primary dark:text-gray-5 dark:hover:text-primary"
|
|
>
|
|
<CrossIcon />
|
|
</button>
|
|
<div className="clear-both">{children}</div>
|
|
<div className="flex gap-5">
|
|
<IsVisible condition={showButtons}>
|
|
<button
|
|
type="submit"
|
|
className="mt-6 flex w-fit justify-center rounded-lg bg-primary p-[13px] font-medium capitalize text-white hover:bg-opacity-90"
|
|
onClick={onConfirm}
|
|
>
|
|
{isMutating ? (
|
|
<div className="h-5 w-5 animate-spin rounded-full border-b-2 border-gray-1"></div>
|
|
) : (
|
|
<span>{confirmText}</span>
|
|
)}
|
|
</button>
|
|
<button
|
|
type="button"
|
|
className="mt-6 flex w-fit justify-center rounded-lg bg-error p-[13px] font-medium capitalize text-white hover:bg-opacity-90"
|
|
onClick={onClose}
|
|
>
|
|
{cancelText}
|
|
</button>
|
|
</IsVisible>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
|
|
return createPortal(modalContent, document.body);
|
|
};
|
|
|
|
export default Modal;
|