Added check spelling for country names
This commit is contained in:
parent
0108719a84
commit
9cb6ffbfb4
26
frontend/package-lock.json
generated
26
frontend/package-lock.json
generated
@ -1,11 +1,11 @@
|
|||||||
{
|
{
|
||||||
"name": "mheidi-frontend-v2",
|
"name": "heidi-frontend-v2",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "mheidi-frontend-v2",
|
"name": "heidi-frontend-v2",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@aldabil/react-scheduler": "^2.9.5",
|
"@aldabil/react-scheduler": "^2.9.5",
|
||||||
@ -27,6 +27,7 @@
|
|||||||
"dotenv": "^16.4.7",
|
"dotenv": "^16.4.7",
|
||||||
"exceljs": "^4.4.0",
|
"exceljs": "^4.4.0",
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
|
"fuse.js": "^7.0.0",
|
||||||
"openapi-typescript-codegen": "^0.29.0",
|
"openapi-typescript-codegen": "^0.29.0",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-big-calendar": "^1.15.0",
|
"react-big-calendar": "^1.15.0",
|
||||||
@ -1160,9 +1161,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint/plugin-kit": {
|
"node_modules/@eslint/plugin-kit": {
|
||||||
"version": "0.2.2",
|
"version": "0.2.4",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.4.tgz",
|
||||||
"integrity": "sha512-CXtq5nR4Su+2I47WPOlWud98Y5Lv8Kyxp2ukhgFx/eW6Blm18VXJO5WuQylPugRo8nbluoi6GvvxBLqHcvqUUw==",
|
"integrity": "sha512-zSkKow6H5Kdm0ZUQUB2kV5JIXqoG0+uH5YADhaEHswm664N9Db8dXSi0nMJpacpMf+MyyglF1vnZohpEg5yUtg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -4225,6 +4226,15 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/fuse.js": {
|
||||||
|
"version": "7.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-7.0.0.tgz",
|
||||||
|
"integrity": "sha512-14F4hBIxqKvD4Zz/XjDc3y94mNZN6pRv3U13Udo0lNLCWRBUsrMv2xwcF/y/Z5sV6+FQW+/ow68cHpm4sunt8Q==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/gensync": {
|
"node_modules/gensync": {
|
||||||
"version": "1.0.0-beta.2",
|
"version": "1.0.0-beta.2",
|
||||||
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
|
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
|
||||||
@ -5071,9 +5081,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/nanoid": {
|
"node_modules/nanoid": {
|
||||||
"version": "3.3.7",
|
"version": "3.3.8",
|
||||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
|
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz",
|
||||||
"integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
|
"integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
"start-test": "vite --mode test",
|
"start-test": "vite --mode test",
|
||||||
"start-prod": "vite --mode prod",
|
"start-prod": "vite --mode prod",
|
||||||
"watch:openapi": "node fetch-openapi.js"
|
"watch:openapi": "node fetch-openapi.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@aldabil/react-scheduler": "^2.9.5",
|
"@aldabil/react-scheduler": "^2.9.5",
|
||||||
"@bitnoi.se/react-scheduler": "^0.3.1",
|
"@bitnoi.se/react-scheduler": "^0.3.1",
|
||||||
@ -33,6 +33,7 @@
|
|||||||
"dotenv": "^16.4.7",
|
"dotenv": "^16.4.7",
|
||||||
"exceljs": "^4.4.0",
|
"exceljs": "^4.4.0",
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
|
"fuse.js": "^7.0.0",
|
||||||
"openapi-typescript-codegen": "^0.29.0",
|
"openapi-typescript-codegen": "^0.29.0",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-big-calendar": "^1.15.0",
|
"react-big-calendar": "^1.15.0",
|
||||||
|
198
frontend/src/components/CountryList.tsx
Normal file
198
frontend/src/components/CountryList.tsx
Normal file
@ -0,0 +1,198 @@
|
|||||||
|
export const CountryList = [
|
||||||
|
'Afghanistan',
|
||||||
|
'Albania',
|
||||||
|
'Algeria',
|
||||||
|
'Andorra',
|
||||||
|
'Angola',
|
||||||
|
'Antigua and Barbuda',
|
||||||
|
'Argentina',
|
||||||
|
'Armenia',
|
||||||
|
'Australia',
|
||||||
|
'Austria',
|
||||||
|
'Azerbaijan',
|
||||||
|
'Bahamas',
|
||||||
|
'Bahrain',
|
||||||
|
'Bangladesh',
|
||||||
|
'Barbados',
|
||||||
|
'Belarus',
|
||||||
|
'Belgium',
|
||||||
|
'Belize',
|
||||||
|
'Benin',
|
||||||
|
'Bhutan',
|
||||||
|
'Bolivia',
|
||||||
|
'Bosnia and Herzegovina',
|
||||||
|
'Botswana',
|
||||||
|
'Brazil',
|
||||||
|
'Brunei',
|
||||||
|
'Bulgaria',
|
||||||
|
'Burkina Faso',
|
||||||
|
'Burundi',
|
||||||
|
'Cabo Verde',
|
||||||
|
'Cambodia',
|
||||||
|
'Cameroon',
|
||||||
|
'Canada',
|
||||||
|
'Central African Republic',
|
||||||
|
'Chad',
|
||||||
|
'Chile',
|
||||||
|
'China',
|
||||||
|
'Colombia',
|
||||||
|
'Comoros',
|
||||||
|
'Congo (Congo-Brazzaville)',
|
||||||
|
'Costa Rica',
|
||||||
|
'Croatia',
|
||||||
|
'Cuba',
|
||||||
|
'Cyprus',
|
||||||
|
'Czechia (Czech Republic)',
|
||||||
|
'Denmark',
|
||||||
|
'Djibouti',
|
||||||
|
'Dominica',
|
||||||
|
'Dominican Republic',
|
||||||
|
'Ecuador',
|
||||||
|
'Egypt',
|
||||||
|
'El Salvador',
|
||||||
|
'Equatorial Guinea',
|
||||||
|
'Eritrea',
|
||||||
|
'Estonia',
|
||||||
|
'Eswatini (fmr. "Swaziland")',
|
||||||
|
'Ethiopia',
|
||||||
|
'Fiji',
|
||||||
|
'Finland',
|
||||||
|
'France',
|
||||||
|
'Gabon',
|
||||||
|
'Gambia',
|
||||||
|
'Georgia',
|
||||||
|
'Germany',
|
||||||
|
'Ghana',
|
||||||
|
'Greece',
|
||||||
|
'Grenada',
|
||||||
|
'Guatemala',
|
||||||
|
'Guinea',
|
||||||
|
'Guinea-Bissau',
|
||||||
|
'Guyana',
|
||||||
|
'Haiti',
|
||||||
|
'Holy See',
|
||||||
|
'Honduras',
|
||||||
|
'Hungary',
|
||||||
|
'Iceland',
|
||||||
|
'India',
|
||||||
|
'Indonesia',
|
||||||
|
'Iran',
|
||||||
|
'Iraq',
|
||||||
|
'Ireland',
|
||||||
|
'Israel',
|
||||||
|
'Italy',
|
||||||
|
'Jamaica',
|
||||||
|
'Japan',
|
||||||
|
'Jordan',
|
||||||
|
'Kazakhstan',
|
||||||
|
'Kenya',
|
||||||
|
'Kiribati',
|
||||||
|
'Korea (North)',
|
||||||
|
'Korea (South)',
|
||||||
|
'Kosovo',
|
||||||
|
'Kuwait',
|
||||||
|
'Kyrgyzstan',
|
||||||
|
'Laos',
|
||||||
|
'Latvia',
|
||||||
|
'Lebanon',
|
||||||
|
'Lesotho',
|
||||||
|
'Liberia',
|
||||||
|
'Libya',
|
||||||
|
'Liechtenstein',
|
||||||
|
'Lithuania',
|
||||||
|
'Luxembourg',
|
||||||
|
'Madagascar',
|
||||||
|
'Malawi',
|
||||||
|
'Malaysia',
|
||||||
|
'Maldives',
|
||||||
|
'Mali',
|
||||||
|
'Malta',
|
||||||
|
'Marshall Islands',
|
||||||
|
'Mauritania',
|
||||||
|
'Mauritius',
|
||||||
|
'Mexico',
|
||||||
|
'Micronesia',
|
||||||
|
'Moldova',
|
||||||
|
'Monaco',
|
||||||
|
'Mongolia',
|
||||||
|
'Montenegro',
|
||||||
|
'Morocco',
|
||||||
|
'Mozambique',
|
||||||
|
'Myanmar (formerly Burma)',
|
||||||
|
'Namibia',
|
||||||
|
'Nauru',
|
||||||
|
'Nepal',
|
||||||
|
'Netherlands',
|
||||||
|
'New Zealand',
|
||||||
|
'Nicaragua',
|
||||||
|
'Niger',
|
||||||
|
'Nigeria',
|
||||||
|
'North Macedonia (formerly Macedonia)',
|
||||||
|
'Norway',
|
||||||
|
'Oman',
|
||||||
|
'Pakistan',
|
||||||
|
'Palau',
|
||||||
|
'Palestine State',
|
||||||
|
'Panama',
|
||||||
|
'Papua New Guinea',
|
||||||
|
'Paraguay',
|
||||||
|
'Peru',
|
||||||
|
'Philippines',
|
||||||
|
'Poland',
|
||||||
|
'Portugal',
|
||||||
|
'Qatar',
|
||||||
|
'Romania',
|
||||||
|
'Russia',
|
||||||
|
'Rwanda',
|
||||||
|
'Saint Kitts and Nevis',
|
||||||
|
'Saint Lucia',
|
||||||
|
'Saint Vincent and the Grenadines',
|
||||||
|
'Samoa',
|
||||||
|
'San Marino',
|
||||||
|
'Sao Tome and Principe',
|
||||||
|
'Saudi Arabia',
|
||||||
|
'Senegal',
|
||||||
|
'Serbia',
|
||||||
|
'Seychelles',
|
||||||
|
'Sierra Leone',
|
||||||
|
'Singapore',
|
||||||
|
'Slovakia',
|
||||||
|
'Slovenia',
|
||||||
|
'Solomon Islands',
|
||||||
|
'Somalia',
|
||||||
|
'South Africa',
|
||||||
|
'South Sudan',
|
||||||
|
'Spain',
|
||||||
|
'Sri Lanka',
|
||||||
|
'Sudan',
|
||||||
|
'Suriname',
|
||||||
|
'Sweden',
|
||||||
|
'Switzerland',
|
||||||
|
'Syria',
|
||||||
|
'Tajikistan',
|
||||||
|
'Tanzania',
|
||||||
|
'Thailand',
|
||||||
|
'Timor-Leste',
|
||||||
|
'Togo',
|
||||||
|
'Tonga',
|
||||||
|
'Trinidad and Tobago',
|
||||||
|
'Tunisia',
|
||||||
|
'Turkey',
|
||||||
|
'Turkmenistan',
|
||||||
|
'Tuvalu',
|
||||||
|
'Uganda',
|
||||||
|
'Ukraine',
|
||||||
|
'United Arab Emirates',
|
||||||
|
'United Kingdom',
|
||||||
|
'United States of America',
|
||||||
|
'Uruguay',
|
||||||
|
'Uzbekistan',
|
||||||
|
'Vanuatu',
|
||||||
|
'Venezuela',
|
||||||
|
'Vietnam',
|
||||||
|
'Yemen',
|
||||||
|
'Zambia',
|
||||||
|
'Zimbabwe',
|
||||||
|
];
|
||||||
|
|
||||||
|
export default CountryList
|
@ -1,4 +1,5 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
import Fuse from 'fuse.js';
|
||||||
import {
|
import {
|
||||||
Box, Button, TextField, Typography, Select, MenuItem, Stack, FormControl, InputLabel
|
Box, Button, TextField, Typography, Select, MenuItem, Stack, FormControl, InputLabel
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
@ -9,6 +10,7 @@ import {
|
|||||||
OpenAPI, ShipmentCreate, ShipmentsService
|
OpenAPI, ShipmentCreate, ShipmentsService
|
||||||
} from '../../openapi';
|
} from '../../openapi';
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
|
import { CountryList } from './CountryList'; // Import the list of countries
|
||||||
|
|
||||||
const MAX_COMMENTS_LENGTH = 200;
|
const MAX_COMMENTS_LENGTH = 200;
|
||||||
|
|
||||||
@ -18,7 +20,14 @@ interface ShipmentFormProps {
|
|||||||
refreshShipments: () => void;
|
refreshShipments: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set up Fuse.js for fuzzy searching
|
||||||
|
const fuse = new Fuse(CountryList, {
|
||||||
|
threshold: 0.3,
|
||||||
|
includeScore: true,
|
||||||
|
});
|
||||||
|
|
||||||
const ShipmentForm: React.FC<ShipmentFormProps> = ({ sx = {}, onCancel, refreshShipments }) => {
|
const ShipmentForm: React.FC<ShipmentFormProps> = ({ sx = {}, onCancel, refreshShipments }) => {
|
||||||
|
const [countrySuggestions, setCountrySuggestions] = React.useState<string[]>([]);
|
||||||
const [contactPersons, setContactPersons] = React.useState<ContactPerson[]>([]);
|
const [contactPersons, setContactPersons] = React.useState<ContactPerson[]>([]);
|
||||||
const [returnAddresses, setReturnAddresses] = React.useState<Address[]>([]);
|
const [returnAddresses, setReturnAddresses] = React.useState<Address[]>([]);
|
||||||
const [proposals, setProposals] = React.useState<Proposal[]>([]);
|
const [proposals, setProposals] = React.useState<Proposal[]>([]);
|
||||||
@ -95,6 +104,19 @@ const ShipmentForm: React.FC<ShipmentFormProps> = ({ sx = {}, onCancel, refreshS
|
|||||||
getProposals();
|
getProposals();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const handleCountryInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
const value = event.target.value;
|
||||||
|
|
||||||
|
setNewReturnAddress({ ...newReturnAddress, country: value });
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
const suggestions = fuse.search(value).map((result) => result.item);
|
||||||
|
setCountrySuggestions(suggestions);
|
||||||
|
} else {
|
||||||
|
setCountrySuggestions([]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const validateEmail = (email: string) => /\S+@\S+\.\S+/.test(email);
|
const validateEmail = (email: string) => /\S+@\S+\.\S+/.test(email);
|
||||||
const validatePhoneNumber = (phone: string) => /^\+?[1-9]\d{1,14}$/.test(phone);
|
const validatePhoneNumber = (phone: string) => /^\+?[1-9]\d{1,14}$/.test(phone);
|
||||||
const validateZipCode = (zipcode: string) => {
|
const validateZipCode = (zipcode: string) => {
|
||||||
@ -410,10 +432,37 @@ const ShipmentForm: React.FC<ShipmentFormProps> = ({ sx = {}, onCancel, refreshS
|
|||||||
label="Country"
|
label="Country"
|
||||||
name="country"
|
name="country"
|
||||||
value={newReturnAddress.country}
|
value={newReturnAddress.country}
|
||||||
onChange={(e) => setNewReturnAddress({ ...newReturnAddress, country: e.target.value })}
|
onChange={handleCountryInputChange} // Ensure this matches the function name exactly
|
||||||
fullWidth
|
fullWidth
|
||||||
required
|
required
|
||||||
|
error={!newReturnAddress.country} // Optional: Add an error indicator if the input is empty
|
||||||
|
helperText={!newReturnAddress.country ? 'Country is required' : ''}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{/* Render country suggestions below the input field */}
|
||||||
|
{countrySuggestions.length > 0 && (
|
||||||
|
<Box sx={{ marginTop: '0.5rem', border: '1px solid #ccc', borderRadius: '4px', padding: '0.5rem' }}>
|
||||||
|
{countrySuggestions.map((suggestion, index) => (
|
||||||
|
<Typography
|
||||||
|
key={index}
|
||||||
|
sx={{
|
||||||
|
cursor: 'pointer',
|
||||||
|
padding: '0.2rem 0',
|
||||||
|
'&:hover': {
|
||||||
|
backgroundColor: '#f0f0f0',
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
onClick={() => {
|
||||||
|
// Update country field with selected suggestion
|
||||||
|
setNewReturnAddress({ ...newReturnAddress, country: suggestion });
|
||||||
|
setCountrySuggestions([]); // Clear suggestions
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{suggestion}
|
||||||
|
</Typography>
|
||||||
|
))}
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
<Button
|
<Button
|
||||||
variant="contained"
|
variant="contained"
|
||||||
color="primary"
|
color="primary"
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import Fuse from 'fuse.js';
|
||||||
|
import { CountryList } from '../components/CountryList';
|
||||||
import {
|
import {
|
||||||
Container, Typography, List, ListItem, IconButton, TextField, Box, ListItemText, ListItemSecondaryAction, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle, Button
|
Container, Typography, List, ListItem, IconButton, TextField, Box, ListItemText, ListItemSecondaryAction, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle, Button
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
@ -9,7 +11,13 @@ import AddIcon from '@mui/icons-material/Add';
|
|||||||
import { AddressesService } from '../../openapi';
|
import { AddressesService } from '../../openapi';
|
||||||
import type { Address, AddressCreate, AddressUpdate } from '../models/Address';
|
import type { Address, AddressCreate, AddressUpdate } from '../models/Address';
|
||||||
|
|
||||||
|
const fuse = new Fuse(CountryList, {
|
||||||
|
threshold: 0.3, // Lower threshold for stricter matches
|
||||||
|
includeScore: true,
|
||||||
|
});
|
||||||
|
|
||||||
const AddressManager: React.FC = () => {
|
const AddressManager: React.FC = () => {
|
||||||
|
const [countrySuggestions, setCountrySuggestions] = React.useState<string[]>([]);
|
||||||
const [addresses, setAddresses] = React.useState<Address[]>([]);
|
const [addresses, setAddresses] = React.useState<Address[]>([]);
|
||||||
const [newAddress, setNewAddress] = React.useState<Partial<Address>>({
|
const [newAddress, setNewAddress] = React.useState<Partial<Address>>({
|
||||||
street: '',
|
street: '',
|
||||||
@ -21,6 +29,20 @@ const AddressManager: React.FC = () => {
|
|||||||
const [errorMessage, setErrorMessage] = React.useState<string | null>(null);
|
const [errorMessage, setErrorMessage] = React.useState<string | null>(null);
|
||||||
const [dialogOpen, setDialogOpen] = React.useState(false);
|
const [dialogOpen, setDialogOpen] = React.useState(false);
|
||||||
const [selectedAddress, setSelectedAddress] = React.useState<Address | null>(null);
|
const [selectedAddress, setSelectedAddress] = React.useState<Address | null>(null);
|
||||||
|
const handleCountryInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
const { value } = event.target;
|
||||||
|
|
||||||
|
// Update the corresponding field in `newAddress`
|
||||||
|
setNewAddress({ ...newAddress, country: value });
|
||||||
|
|
||||||
|
// Perform fuzzy search using Fuse.js
|
||||||
|
if (value) {
|
||||||
|
const suggestions = fuse.search(value).map((result) => result.item);
|
||||||
|
setCountrySuggestions(suggestions); // Update suggestions state
|
||||||
|
} else {
|
||||||
|
setCountrySuggestions([]); // Clear suggestions if the input is empty
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
const fetchAddresses = async () => {
|
const fetchAddresses = async () => {
|
||||||
@ -102,7 +124,65 @@ const AddressManager: React.FC = () => {
|
|||||||
<TextField label="Street" name="street" value={newAddress.street || ''} onChange={handleInputChange} />
|
<TextField label="Street" name="street" value={newAddress.street || ''} onChange={handleInputChange} />
|
||||||
<TextField label="City" name="city" value={newAddress.city || ''} onChange={handleInputChange} />
|
<TextField label="City" name="city" value={newAddress.city || ''} onChange={handleInputChange} />
|
||||||
<TextField label="Zipcode" name="zipcode" value={newAddress.zipcode || ''} onChange={handleInputChange} />
|
<TextField label="Zipcode" name="zipcode" value={newAddress.zipcode || ''} onChange={handleInputChange} />
|
||||||
<TextField label="Country" name="country" value={newAddress.country || ''} onChange={handleInputChange} />
|
<TextField
|
||||||
|
label="Country"
|
||||||
|
name="country"
|
||||||
|
value={newAddress.country || ''}
|
||||||
|
onChange={handleCountryInputChange}
|
||||||
|
fullWidth
|
||||||
|
required
|
||||||
|
error={
|
||||||
|
!!((editAddressId !== null || newAddress.street || newAddress.city || newAddress.zipcode) && !newAddress.country)
|
||||||
|
} // Show an error only if in add/edit mode and country is empty
|
||||||
|
helperText={
|
||||||
|
!!((editAddressId !== null || newAddress.street || newAddress.city || newAddress.zipcode) && !newAddress.country)
|
||||||
|
? 'Country is required'
|
||||||
|
: ''
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* Render suggestions dynamically */}
|
||||||
|
<Box sx={{ position: 'relative' }}>
|
||||||
|
<TextField
|
||||||
|
label="Country"
|
||||||
|
name="country"
|
||||||
|
value={newAddress.country || ''}
|
||||||
|
onChange={handleCountryInputChange}
|
||||||
|
fullWidth
|
||||||
|
/>
|
||||||
|
|
||||||
|
{countrySuggestions.length > 0 && (
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
border: '1px solid #ccc',
|
||||||
|
borderRadius: '4px',
|
||||||
|
background: 'white',
|
||||||
|
marginTop: '4px', /* Add space below the input */
|
||||||
|
position: 'absolute',
|
||||||
|
width: '100%', /* Match the TextField width */
|
||||||
|
zIndex: 10, /* Ensure it is above other UI elements */
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{countrySuggestions.map((suggestion, index) => (
|
||||||
|
<Typography
|
||||||
|
key={index}
|
||||||
|
sx={{
|
||||||
|
padding: '8px',
|
||||||
|
cursor: 'pointer',
|
||||||
|
'&:hover': { background: '#f5f5f5' },
|
||||||
|
}}
|
||||||
|
onClick={() => {
|
||||||
|
// Update country field with the clicked suggestion
|
||||||
|
setNewAddress({ ...newAddress, country: suggestion });
|
||||||
|
setCountrySuggestions([]); // Clear suggestions
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{suggestion}
|
||||||
|
</Typography>
|
||||||
|
))}
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
<IconButton color="primary" onClick={handleAddOrUpdateAddress}>
|
<IconButton color="primary" onClick={handleAddOrUpdateAddress}>
|
||||||
{editAddressId !== null ? <SaveIcon /> : <AddIcon />}
|
{editAddressId !== null ? <SaveIcon /> : <AddIcon />}
|
||||||
</IconButton>
|
</IconButton>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user