All files / src/hooks useConfirm.tsx

100% Statements 118/118
100% Branches 15/15
100% Functions 3/3
100% Lines 118/118

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 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 1191x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 93x 93x 93x 93x 93x 93x 93x 93x 93x 93x 93x 29x 29x 29x 29x 29x 29x 29x 29x 29x 29x 93x 93x 93x 12x 12x 12x 12x 93x 93x 93x 6x 6x 6x 6x 93x 93x 93x 93x 93x 93x 93x 93x 93x 93x 93x 93x 93x 93x 93x 93x 93x 93x 93x 93x 93x 93x 93x 93x 93x 93x 93x 93x 93x 1x 1x 18x 18x 18x 18x 18x 5x 5x 5x 5x 5x 18x 18x 18x 18x 18x 18x 1x 19x 19x 19x 19x 19x 5x 5x 5x 5x 5x 19x 19x 19x 19x 19x 19x  
"use client";
 
import React, { useState, useCallback } from "react";
import ConfirmDialog from "@/components/ui/ConfirmDialog";
import { ConfirmDialogVariant } from "@/types/ui";
 
interface ConfirmOptions {
  title: string;
  message: string;
  confirmText?: string;
  cancelText?: string;
  variant?: ConfirmDialogVariant;
}
 
interface ConfirmState extends ConfirmOptions {
  isOpen: boolean;
  resolve: ((value: boolean) => void) | null;
}
 
export function useConfirm() {
  const [state, setState] = useState<ConfirmState>({
    isOpen: false,
    title: "",
    message: "",
    confirmText: "Confirm",
    cancelText: "Cancel",
    variant: "info",
    resolve: null});
 
  const confirm = useCallback((options: ConfirmOptions): Promise<boolean> => {
    return new Promise((resolve) => {
      setState({
        isOpen: true,
        title: options.title,
        message: options.message,
        confirmText: options.confirmText || "Confirm",
        cancelText: options.cancelText || "Cancel",
        variant: options.variant || "info",
        resolve});
    });
  }, []);
 
  const handleConfirm = useCallback(() => {
    if (state.resolve) {
      state.resolve(true);
    }
    setState((prev) => ({ ...prev, isOpen: false, resolve: null }));
  }, [state]);
 
  const handleCancel = useCallback(() => {
    if (state.resolve) {
      state.resolve(false);
    }
    setState((prev) => ({ ...prev, isOpen: false, resolve: null }));
  }, [state]);
 
  const ConfirmDialogComponent = useCallback(
    () => (
      <ConfirmDialog
        isOpen={state.isOpen}
        title={state.title}
        message={state.message}
        confirmText={state.confirmText}
        cancelText={state.cancelText}
        variant={state.variant}
        onConfirm={handleConfirm}
        onCancel={handleCancel}
      />
    ),
    [
      state.isOpen,
      state.title,
      state.message,
      state.confirmText,
      state.cancelText,
      state.variant,
      handleConfirm,
      handleCancel,
    ]
  );
 
  return { confirm, ConfirmDialog: ConfirmDialogComponent };
}
 
// Convenience functions for common dialog types
export function useDeleteConfirm() {
  const { confirm, ConfirmDialog } = useConfirm();
 
  const confirmDelete = useCallback(
    (itemName: string) =>
      confirm({
        title: "Confirm Deletion",
        message: `Are you sure you want to delete "${itemName}"? This action cannot be undone.`,
        confirmText: "Delete",
        cancelText: "Cancel",
        variant: "danger"}),
    [confirm]
  );
 
  return { confirmDelete, ConfirmDialog };
}
 
export function useClearConfirm() {
  const { confirm, ConfirmDialog } = useConfirm();
 
  const confirmClear = useCallback(
    (itemName: string) =>
      confirm({
        title: "Clear Items",
        message: `Are you sure you want to clear ${itemName}? This action cannot be undone.`,
        confirmText: "Clear",
        cancelText: "Cancel",
        variant: "warning"}),
    [confirm]
  );
 
  return { confirmClear, ConfirmDialog };
}