All files / src/pages/inventory/dialogs/DeleteItemDialog useDeleteItemHandlers.ts

100% Statements 141/141
100% Branches 15/15
100% Functions 1/1
100% Lines 141/141

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 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 1421x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 2x 2x 10x 10x 10x 10x 10x 10x 10x 10x 10x 1x 1x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 2x 1x 1x 1x 1x 1x 1x 1x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 6x 6x 1x 1x 1x 1x 1x 5x 5x 6x 1x 1x 1x 1x 1x 4x 4x 6x 1x 1x 1x 1x 1x 3x 3x 3x 3x 3x 3x 3x 3x 2x 6x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 6x 1x 1x 1x 1x 1x 10x 10x 10x 10x 10x 10x 10x 10x 10x 1x 1x  
/**
 * useDeleteItemHandlers - Event handlers and deletion workflow
 *
 * Manages: form submission, deletion confirmation, API call execution
 * Responsibility: Business logic orchestration with error handling
 * Dependencies: state setters, queries, API mutations, error handler
 */
 
import * as React from 'react';
import { useTranslation } from 'react-i18next';
import { useToast } from '../../../../context/toast';
import { deleteItem } from '../../../../api/inventory/mutations';
import { handleDeleteError } from './deleteItemErrorHandler';
import type { UseDeleteItemStateReturn } from './useDeleteItemState';
import type { UseDeleteItemQueriesReturn } from './useDeleteItemQueries';
 
export function useDeleteItemHandlers(
  state: UseDeleteItemStateReturn,
  _queries: UseDeleteItemQueriesReturn,
  onClose: () => void,
  onItemDeleted: () => void,
  readOnly: boolean = false
) {
  const { t } = useTranslation(['common', 'inventory', 'errors']);
  const toast = useToast();
 
  /**
   * Close dialog handler
   * Action: calls provided onClose callback + resets all local state
   * Effect: makes dialog invisible and clears selection/form data
   * Usage: triggered by cancel buttons or successful deletion
   */
  const handleClose = React.useCallback(() => {
    state.resetAll();
    onClose();
  }, [state, onClose]);
 
  /**
   * Cancel confirmation handler
   * Action: close confirmation dialog, return to form
   * Effect: shows toast notification of cancellation
   * Usage: when user clicks "No" on confirmation dialog
   */
  const handleCancelConfirmation = React.useCallback(() => {
    toast(t('inventory:status.operationCanceled', 'Operation cancelled'), 'info');
    state.setShowConfirmation(false);
  }, [state, t, toast]);
 
  /**
   * Form submission handler
   * Validation: ensures item is selected
   * Action: shows confirmation dialog with warning
   * Usage: triggered by "Delete" button in form view
   */
  const onSubmit = state.handleSubmit(
    React.useCallback(async () => {
    if (!state.selectedItem) {
      state.setFormError(
        t('errors:inventory.selection.noItemSelected', 'Please select an item.')
      );
      return;
    }
    // Validation passed: show confirmation dialog
    state.setShowConfirmation(true);
    }, [state, t])
  );
 
  /**
   * Confirmed deletion handler
   * Validation: item selected, reason provided, not in readonly mode
   * Action: calls DELETE API with item ID and reason
   * Response: success closes dialog, error shows message
   * Error handling: delegates to deleteItemErrorHandler for user messages
   */
  const onConfirmedDelete = React.useCallback(async () => {
    // Validation: item required
    if (!state.selectedItem) {
      state.setFormError(
        t('errors:inventory.selection.noItemSelected', 'Please select an item.')
      );
      return;
    }
 
    // Validation: reason required
    if (!state.deletionReason) {
      state.setFormError(
        t('errors:inventory.selection.noReasonSelected', 'Please select a deletion reason.')
      );
      return;
    }
 
    // Guard: readonly mode blocks actual deletion
    if (readOnly) {
      state.setFormError(
        t('common.demoDisabled', 'You are in demo mode and cannot perform this operation.')
      );
      return;
    }
 
    // Clear previous errors before submission
    state.setFormError('');
    state.setShowConfirmation(false);
 
    try {
      // Execute deletion: calls DELETE /api/inventory/{id}?reason=...
      const success = await deleteItem(state.selectedItem.id, state.deletionReason);
 
      if (success.ok) {
        // Success path: show message + close + notify parent
        toast(
          t(
            'inventory:status.itemDeletedSuccessfully',
            'Operation successful. Item was removed from inventory!'
          ),
          'success'
        );
        onItemDeleted();
        handleClose();
      } else {
        // Error path: use error handler to map backend error to user message
        const errorResult = handleDeleteError(success.error, t);
        state.setFormError(errorResult.message);
        state.setShowConfirmation(false);
      }
    } catch (error) {
      console.error('Delete item error:', error);
      state.setFormError(
        t('errors:inventory.requests.failedToDeleteItem', 'Failed to delete item. Please try again.')
      );
    }
  }, [state, readOnly, t, toast, onItemDeleted, handleClose]);
 
  return {
    handleClose,
    handleCancelConfirmation,
    onSubmit,
    onConfirmedDelete,
  };
}
 
export type UseDeleteItemHandlersReturn = ReturnType<typeof useDeleteItemHandlers>;