All files / packages/app/components confirm-modal.tsx

100% Statements 12/12
100% Branches 8/8
100% Functions 3/3
100% Lines 12/12

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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                                          1878x                     2078x 2078x 2078x       2078x 2078x 11x 11x   2078x 6x 6x   2078x                                                                                  
import React from "react";
 
import { useTranslation } from "react-i18next";
 
import { useBooleanState } from "~app/hooks/use-boolean-state";
import { Button } from "~components/button";
import { Modal } from "~components/modal";
import { Text } from "~components/text";
 
type Props = {
	onConfirm: () => void;
	onCancel?: () => void;
	isLoading?: boolean;
	title: string;
	subtitle?: React.ReactNode;
	confirmText: string;
	yesText?: string;
	noText?: string;
	children: (controls: { openModal: () => void }) => React.ReactNode;
};
 
export const ConfirmModal: React.FC<Props> = ({
	onConfirm: action,
	onCancel,
	title,
	confirmText,
	subtitle,
	yesText,
	noText,
	isLoading,
	children,
}) => {
	const { t } = useTranslation("default");
	const defaultYesText = yesText ?? t("components.confirmModal.yes");
	const defaultNoText = noText ?? t("components.confirmModal.no");
	const [
		isModalOpen,
		{ switchValue: switchModalOpen, setFalse: closeModal, setTrue: openModal },
	] = useBooleanState();
	const onYesClick = React.useCallback(() => {
		closeModal();
		action();
	}, [action, closeModal]);
	const onNoClick = React.useCallback(() => {
		closeModal();
		onCancel?.();
	}, [closeModal, onCancel]);
	return (
		<>
			{children({ openModal })}
			<Modal
				closeButton
				label={title}
				isOpen={isModalOpen}
				onOpenChange={switchModalOpen}
				headerClassName="flex-col items-center"
				header={
					<>
						<Text variant="h3">{confirmText}</Text>
						{/* oxlint-disable-next-line typescript/strict-boolean-expressions */}
						{subtitle ? (
							typeof subtitle === "string" ? (
								<Text variant="h4" className="text-warning mt-2">
									{subtitle}
								</Text>
							) : (
								subtitle
							)
						) : null}
					</>
				}
				bodyClassName="flex-row justify-center gap-2"
			>
				<Button
					color="danger"
					onPress={onYesClick}
					isDisabled={isLoading}
					isLoading={isLoading}
				>
					{defaultYesText}
				</Button>
				<Button color="primary" onPress={onNoClick} isDisabled={isLoading}>
					{defaultNoText}
				</Button>
			</Modal>
		</>
	);
};