All files / src/pages/suppliers/dialogs/DeleteSupplierDialog DeleteSupplierSearch.tsx

100% Statements 134/134
100% Branches 1/1
100% Functions 1/1
100% Lines 134/134

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 1351x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x  
/**
 * @file DeleteSupplierSearch.tsx
 * @module dialogs/DeleteSupplierDialog/DeleteSupplierSearch
 *
 * @summary
 * Search step for supplier deletion dialog.
 * Orchestrates search input, results, and empty state components.
 *
 * @enterprise
 * - Composes specialized search components
 * - Clean separation of concerns
 * - Pure presentation, no business logic
 */
 
import * as React from 'react';
import {
  DialogTitle,
  DialogContent,
  DialogActions,
  Button,
  Typography,
  Box,
  IconButton,
  Stack,
  Tooltip,
} from '@mui/material';
import HelpOutlineIcon from '@mui/icons-material/HelpOutline';
import { useTranslation } from 'react-i18next';
import { DeleteSupplierSearchInput } from './DeleteSupplierSearchInput';
import { DeleteSupplierSearchResults } from './DeleteSupplierSearchResults';
import { DeleteSupplierSearchEmpty } from './DeleteSupplierSearchEmpty';
import type { SupplierRow } from '../../../../api/suppliers/types';
 
/**
 * Props for DeleteSupplierSearch component.
 *
 * @interface DeleteSupplierSearchProps
 */
interface DeleteSupplierSearchProps {
  /** Search query value */
  searchQuery: string;
  /** Called when search query changes */
  onSearchQueryChange: (query: string) => Promise<void>;
  /** Search results to display */
  searchResults: SupplierRow[];
  /** Whether search is loading */
  searchLoading: boolean;
  /** Called when supplier is selected */
  onSelectSupplier: (supplier: SupplierRow) => void;
  /** Called when cancel button is clicked */
  onCancel: () => void;
  /** Called to open help */
  onHelp: () => void;
}
 
/**
 * Search step for supplier deletion dialog.
 *
 * Allows user to search for and select supplier to delete.
 * Composes search input, results list, and empty state components.
 *
 * @component
 * @param props - Component props
 * @returns JSX element with search form
 *
 * @example
 * ```tsx
 * <DeleteSupplierSearch
 *   searchQuery={query}
 *   onSearchQueryChange={handleSearch}
 *   searchResults={results}
 *   searchLoading={loading}
 *   onSelectSupplier={handleSelect}
 *   onCancel={handleCancel}
 *   onHelp={handleHelp}
 * />
 * ```
 */
export const DeleteSupplierSearch: React.FC<DeleteSupplierSearchProps> = ({
  searchQuery,
  onSearchQueryChange,
  searchResults,
  searchLoading,
  onSelectSupplier,
  onCancel,
  onHelp,
}) => {
  const { t } = useTranslation(['common', 'suppliers']);
 
  const hasSearched = searchQuery.trim().length >= 2;
 
  return (
    <>
      <DialogTitle sx={{ pt: 3.5 }}>
        <Stack direction="row" alignItems="center" justifyContent="space-between">
          <Box>{t('suppliers:dialogs.delete.title', 'Delete Supplier')}</Box>
          <Tooltip title={t('actions.help', 'Help')}>
            <IconButton size="small" onClick={onHelp}>
              <HelpOutlineIcon fontSize="small" />
            </IconButton>
          </Tooltip>
        </Stack>
      </DialogTitle>
 
      <DialogContent>
        <Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}>
          {t('suppliers:dialogs.delete.search.hint', 'Search for the supplier you want to delete')}
        </Typography>
 
        <DeleteSupplierSearchInput
          value={searchQuery}
          onChange={onSearchQueryChange}
          isLoading={searchLoading}
        />
 
        <DeleteSupplierSearchResults
          suppliers={searchResults}
          onSelectSupplier={onSelectSupplier}
        />
 
        <DeleteSupplierSearchEmpty
          hasSearched={hasSearched}
          isLoading={searchLoading}
        />
      </DialogContent>
 
      <DialogActions sx={{ p: 2 }}>
        <Button onClick={onCancel} disabled={searchLoading}>
          {t('common:actions.cancel', 'Cancel')}
        </Button>
      </DialogActions>
    </>
  );
};