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 142 143 | 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 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 2x 2x 2x 2x 2x 2x 2x 2x 2x 1x 1x 1x 8x 8x 8x 2x 2x 2x 8x 8x 8x 8x 2x 2x 2x 8x 8x 8x 8x | /**
* @file EditSupplierSearchStep.tsx
* @module dialogs/EditSupplierDialog/EditSupplierSearchStep
*
* @summary
* Step 1 component for supplier search and selection.
* Displays search input and interactive results.
*
* @enterprise
* - Pure presentation component
* - Search with debouncing
* - Interactive supplier selection list
*/
import * as React from 'react';
import {
Box,
TextField,
CircularProgress,
Typography,
Paper,
List,
ListItemButton,
ListItemText,
Alert,
} from '@mui/material';
import { useTranslation } from 'react-i18next';
import type { SupplierRow } from '../../../../api/suppliers/types';
/**
* Props for EditSupplierSearchStep component.
*
* @interface EditSupplierSearchStepProps
*/
interface EditSupplierSearchStepProps {
/** Current search query */
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;
}
/**
* Step 1: Search and select supplier.
*
* Allows user to search for and select a supplier to edit.
* Displays autocomplete results with supplier details.
*
* @component
* @param props - Component props
* @returns JSX element with search form
*
* @example
* ```tsx
* <EditSupplierSearchStep
* searchQuery={query}
* onSearchQueryChange={handleSearch}
* searchResults={results}
* searchLoading={loading}
* onSelectSupplier={handleSelect}
* />
* ```
*/
export const EditSupplierSearchStep: React.FC<EditSupplierSearchStepProps> = ({
searchQuery,
onSearchQueryChange,
searchResults,
searchLoading,
onSelectSupplier,
}) => {
const { t } = useTranslation(['suppliers', 'common']);
return (
<Box>
<Typography variant="subtitle2" sx={{ fontWeight: 700, mb: 1 }}>
{t('suppliers:steps.selectSupplier', 'Step 1: Search and Select Supplier')}
</Typography>
<Box sx={{ position: 'relative', mb: 2 }}>
<TextField
fullWidth
size="small"
placeholder={t('suppliers:search.placeholder', 'Enter supplier name (min 2 chars)...')}
value={searchQuery}
onChange={(e) => onSearchQueryChange(e.target.value)}
disabled={searchLoading}
InputProps={{
endAdornment: searchLoading ? <CircularProgress size={20} /> : null,
}}
/>
{/* Search Results Dropdown */}
{searchResults.length > 0 && (
<Paper
elevation={2}
sx={{
position: 'absolute',
top: '100%',
left: 0,
right: 0,
zIndex: 10,
mt: 0.5,
maxHeight: 300,
overflow: 'auto',
}}
>
<List>
{searchResults.map((supplier) => (
<ListItemButton
key={supplier.id}
onClick={() => onSelectSupplier(supplier)}
>
<ListItemText
primary={supplier.name}
secondary={supplier.email || supplier.phone || supplier.contactName}
/>
</ListItemButton>
))}
</List>
</Paper>
)}
{searchQuery.length >= 2 && searchResults.length === 0 && !searchLoading && (
<Typography variant="caption" color="text.secondary" sx={{ mt: 1, display: 'block' }}>
{t('suppliers:search.noResults', 'No suppliers found')}
</Typography>
)}
</Box>
{searchQuery.length < 2 && searchQuery.length > 0 && (
<Alert severity="info">
{t('suppliers:search.typeToSearch', 'Type at least 2 characters to search')}
</Alert>
)}
</Box>
);
};
|