initial commit
This commit is contained in:
693
src/pages/nearle/customers/customers.js
Normal file
693
src/pages/nearle/customers/customers.js
Normal file
@@ -0,0 +1,693 @@
|
||||
import { React, useState, useEffect, useRef, useMemo } from 'react';
|
||||
import { Empty } from 'antd';
|
||||
import axios from 'axios';
|
||||
import { FaRegEdit } from 'react-icons/fa';
|
||||
import { RiEdit2Fill } from 'react-icons/ri';
|
||||
import { useTheme } from '@mui/material/styles';
|
||||
import LoaderWithImage from 'components/nearle_components/LoaderWithImage';
|
||||
|
||||
// material-ui
|
||||
import {
|
||||
Box,
|
||||
Divider,
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableContainer,
|
||||
TableHead,
|
||||
TableRow,
|
||||
Grid,
|
||||
Typography,
|
||||
IconButton,
|
||||
Stack,
|
||||
Tooltip,
|
||||
Dialog,
|
||||
DialogActions,
|
||||
DialogTitle,
|
||||
DialogContent,
|
||||
Button,
|
||||
TextField,
|
||||
Autocomplete
|
||||
} from '@mui/material';
|
||||
import Geocode from 'react-geocode';
|
||||
import LocationOnIcon from '@mui/icons-material/LocationOn';
|
||||
import parse from 'autosuggest-highlight/parse';
|
||||
import { debounce } from '@mui/material/utils';
|
||||
// project imports
|
||||
import MainCard from 'components/MainCard';
|
||||
import Loader from 'components/Loader';
|
||||
import DebounceSearchBar from 'components/nearle_components/DebounceSearchBar';
|
||||
import LocationAutocomplete from 'components/nearle_components/LocationAutocomplete';
|
||||
import { useInfiniteQuery, useQuery } from '@tanstack/react-query';
|
||||
import { getallcustomers, getcustomersummary } from 'pages/api/api';
|
||||
import { OpenToast } from 'components/third-party/OpenToast';
|
||||
import { OrdersTableSkeleton } from '../orders/OrdersTableSkeleton';
|
||||
|
||||
// ==============================|| google address ||============================== //
|
||||
const GOOGLE_MAPS_API_KEY = process.env.REACT_APP_GOOGLE_MAPS_API_KEY;
|
||||
|
||||
function loadScript(src, position, id) {
|
||||
if (!position) {
|
||||
return;
|
||||
}
|
||||
|
||||
const script = document.createElement('script');
|
||||
script.setAttribute('async', '');
|
||||
script.setAttribute('id', id);
|
||||
script.src = src;
|
||||
position.appendChild(script);
|
||||
}
|
||||
|
||||
const autocompleteService = { current: null };
|
||||
|
||||
// ==============================|| MUI TABLE - ENHANCED ||============================== //
|
||||
|
||||
export default function Customers() {
|
||||
const containerRef = useRef();
|
||||
const loadMoreRef = useRef();
|
||||
const [rowsPerPage] = useState(50);
|
||||
const [page] = useState(0);
|
||||
const theme = useTheme();
|
||||
const [appId, setAppId] = useState(0);
|
||||
const [locaName, setLocoName] = useState('All');
|
||||
const [selectedCustomer, setSelectedCustomer] = useState({}); // to edit
|
||||
const [open, setOpen] = useState(false);
|
||||
const [address, setAddress] = useState('');
|
||||
const [latlong, setLatlong] = useState({});
|
||||
const [city, setCity] = useState('');
|
||||
const [postcode, setPostcode] = useState('');
|
||||
const [state, setState] = useState('');
|
||||
const [suburb, setSuburb] = useState('');
|
||||
const [searchword, setSearchword] = useState('');
|
||||
const [debouncedSearch, setDebouncedSearch] = useState('');
|
||||
|
||||
// ==============================|| for google address ||============================== //
|
||||
const [value, setValue] = useState(null);
|
||||
const [inputValue, setInputValue] = useState('');
|
||||
const [options, setOptions] = useState([]);
|
||||
const loaded = useRef(false);
|
||||
if (typeof window !== 'undefined' && !loaded.current) {
|
||||
if (!document.querySelector('#google-maps')) {
|
||||
loadScript(
|
||||
`https://maps.googleapis.com/maps/api/js?key=${GOOGLE_MAPS_API_KEY}&libraries=places`,
|
||||
document.querySelector('head'),
|
||||
'google-maps'
|
||||
);
|
||||
}
|
||||
|
||||
loaded.current = true;
|
||||
}
|
||||
const fetch = useMemo(
|
||||
() =>
|
||||
debounce((request, callback) => {
|
||||
autocompleteService.current.getPlacePredictions(request, callback);
|
||||
}, 400),
|
||||
[]
|
||||
);
|
||||
useEffect(() => {
|
||||
let active = true;
|
||||
|
||||
if (!autocompleteService.current && window.google) {
|
||||
autocompleteService.current = new window.google.maps.places.AutocompleteService();
|
||||
}
|
||||
if (!autocompleteService.current) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (inputValue === '') {
|
||||
setOptions(value ? [value] : []);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
fetch({ input: inputValue }, (results) => {
|
||||
if (active) {
|
||||
let newOptions = [];
|
||||
|
||||
if (value) {
|
||||
newOptions = [value];
|
||||
}
|
||||
|
||||
if (results) {
|
||||
newOptions = [...newOptions, ...results];
|
||||
}
|
||||
|
||||
setOptions(newOptions);
|
||||
}
|
||||
});
|
||||
|
||||
return () => {
|
||||
active = false;
|
||||
};
|
||||
}, [value, inputValue, fetch]);
|
||||
|
||||
Geocode.setApiKey(process.env.REACT_APP_GOOGLE_MAPS_API_KEY);
|
||||
useEffect(() => {
|
||||
try {
|
||||
console.log('selected address =>', address);
|
||||
Geocode.fromAddress(address).then(
|
||||
(response) => {
|
||||
console.log('lat long response =>', response.results[0]);
|
||||
if (response.status == 'OK') {
|
||||
const { lat, lng } = response.results[0].geometry.location;
|
||||
setLatlong({
|
||||
lat,
|
||||
lng
|
||||
});
|
||||
// setSelectedCustomer({
|
||||
// ...selectedCustomer,
|
||||
// latitude: lat,
|
||||
// longitude: lng
|
||||
// });
|
||||
if (response.results[0].address_components) {
|
||||
let place = response.results[0];
|
||||
let city1, zipcode1, state1, suburb1;
|
||||
for (let i = 0; i < place.address_components.length; i++) {
|
||||
for (let j = 0; j < place.address_components[i].types.length; j++) {
|
||||
switch (place.address_components[i].types[j]) {
|
||||
case 'locality':
|
||||
city1 = place.address_components[i].long_name;
|
||||
break;
|
||||
case 'administrative_area_level_1':
|
||||
state1 = place.address_components[i].long_name;
|
||||
break;
|
||||
case 'postal_code':
|
||||
zipcode1 = place.address_components[i].long_name;
|
||||
break;
|
||||
case 'sublocality':
|
||||
suburb1 = place.address_components[i].long_name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
setCity(city1 || '');
|
||||
setState(state1 || '');
|
||||
setPostcode(zipcode1 || '');
|
||||
setSuburb(suburb1 || '');
|
||||
setSelectedCustomer((prev) => ({
|
||||
...prev,
|
||||
city: city1 || '',
|
||||
state: state1 || '',
|
||||
postcode: zipcode1 || '',
|
||||
suburb: suburb1 || '',
|
||||
latitude: lat || '',
|
||||
longitude: lng || ''
|
||||
}));
|
||||
}
|
||||
}
|
||||
},
|
||||
(error) => {
|
||||
console.log(error);
|
||||
}
|
||||
);
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
}, [address]);
|
||||
|
||||
// useEffect(() => {
|
||||
// selectedCustomer &&
|
||||
// setLatlong({
|
||||
// lat: selectedCustomer.latitude,
|
||||
// lng: selectedCustomer.longitude
|
||||
// });
|
||||
// }, [selectedCustomer]);
|
||||
|
||||
// ==============================|| getallcustomers (customers) ||============================== //
|
||||
|
||||
const {
|
||||
data,
|
||||
isLoading: customersIsLoading,
|
||||
isFetchingNextPage,
|
||||
fetchNextPage,
|
||||
hasNextPage,
|
||||
refetch: getallcustomersRefetch
|
||||
} = useInfiniteQuery({
|
||||
queryKey: ['getAllCustomers', appId, debouncedSearch, rowsPerPage],
|
||||
queryFn: getallcustomers,
|
||||
getNextPageParam: (lastPage) => lastPage.nextPage,
|
||||
keepPreviousData: true
|
||||
});
|
||||
const rows = data?.pages.flatMap((page) => page.data) || [];
|
||||
|
||||
useEffect(() => {
|
||||
if (!hasNextPage) return;
|
||||
const observer = new IntersectionObserver(
|
||||
(entries) => {
|
||||
if (entries[0].isIntersecting) {
|
||||
fetchNextPage();
|
||||
}
|
||||
},
|
||||
{
|
||||
root: document.querySelector('.MuiTableContainer-root'), // 👈 or explicitly TableContainer
|
||||
rootMargin: '0px',
|
||||
threshold: 1.0
|
||||
}
|
||||
);
|
||||
if (loadMoreRef.current) observer.observe(loadMoreRef.current);
|
||||
return () => {
|
||||
if (loadMoreRef.current) observer.unobserve(loadMoreRef.current);
|
||||
};
|
||||
}, [hasNextPage, fetchNextPage]);
|
||||
|
||||
const handleScroll = (event) => {
|
||||
const { scrollTop, scrollHeight, clientHeight } = event.currentTarget;
|
||||
if (scrollTop + clientHeight >= scrollHeight - 50) {
|
||||
if (hasNextPage && !isFetchingNextPage) {
|
||||
fetchNextPage();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// ==============================|| getcustomersummary (customers) ||============================== //
|
||||
|
||||
const { data: pageCount, isLoading: customerSummaryIsLoading } = useQuery({
|
||||
queryKey: ['customersummary', appId],
|
||||
queryFn: getcustomersummary
|
||||
});
|
||||
useEffect(() => {
|
||||
console.log('pageCount', pageCount);
|
||||
}, [pageCount]);
|
||||
// ==============================|| updateCustomer (post)||============================== //
|
||||
const updateCustomer = async () => {
|
||||
console.log('selectedCustomer', selectedCustomer);
|
||||
|
||||
if (!selectedCustomer.firstname) {
|
||||
OpenToast('Enter Door NO', 'warning', 1500);
|
||||
} else if (!selectedCustomer.contactno) {
|
||||
OpenToast('Enter Contact Number ', 'warning', 1500);
|
||||
} else if (!selectedCustomer.address) {
|
||||
OpenToast('Enter Valid Address', 'warning', 1500);
|
||||
} else if (!selectedCustomer.suburb) {
|
||||
OpenToast('Enter Suburb', 'warning', 1500);
|
||||
} else if (!selectedCustomer.city) {
|
||||
OpenToast('Enter City ', 'warning', 1500);
|
||||
} else if (!selectedCustomer.state) {
|
||||
OpenToast('Enter State', 'warning', 1500);
|
||||
} else if (!selectedCustomer.postcode) {
|
||||
OpenToast('Enter PostCode', 'warning', 1500);
|
||||
} else if (!selectedCustomer.landmark) {
|
||||
OpenToast('Enter Landmark', 'warning', 1500);
|
||||
} else if (!selectedCustomer.latitude) {
|
||||
OpenToast('Enter Latitude', 'warning', 1500);
|
||||
} else if (!selectedCustomer.longitude) {
|
||||
OpenToast('Enter Longitude', 'warning', 1500);
|
||||
} else {
|
||||
try {
|
||||
const postUpdateResponse = await axios.put(`${process.env.REACT_APP_URL}/customers/update`, {
|
||||
customerid: selectedCustomer.customerid,
|
||||
configid: 1,
|
||||
firstname: selectedCustomer.firstname,
|
||||
applocationid: selectedCustomer.applocationid,
|
||||
profileimage: '',
|
||||
dialcode: '+91',
|
||||
contactno: selectedCustomer.contactno,
|
||||
devicetype: '',
|
||||
deviceid: '',
|
||||
customertoken: '123',
|
||||
address: selectedCustomer.address,
|
||||
suburb: suburb,
|
||||
city: city,
|
||||
state: state,
|
||||
postcode: postcode,
|
||||
landmark: selectedCustomer.landmark,
|
||||
doorno: selectedCustomer.doorno,
|
||||
latitude: selectedCustomer.latitude.toString(),
|
||||
longitude: selectedCustomer.longitude.toString()
|
||||
});
|
||||
|
||||
console.log('postUpdateResponse', postUpdateResponse);
|
||||
if (postUpdateResponse.data.status) {
|
||||
OpenToast(postUpdateResponse.data.message, 'success', 1500);
|
||||
setOpen(false);
|
||||
getallcustomersRefetch();
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('postUpdate error', error);
|
||||
}
|
||||
}
|
||||
};
|
||||
return (
|
||||
<>
|
||||
{(customerSummaryIsLoading || customersIsLoading) && (
|
||||
<>
|
||||
{/* <CircularLoader /> */}
|
||||
<Loader />
|
||||
</>
|
||||
)}
|
||||
{/* <TitleCard title={'Customers'} /> */}
|
||||
<MainCard
|
||||
content={false}
|
||||
sx={{}}
|
||||
title={
|
||||
<Stack sx={{ m: 2 }}>
|
||||
<Stack
|
||||
direction={{ xs: 'column', sm: 'row' }}
|
||||
alignItems={{ xs: 'flex-start', sm: 'center' }}
|
||||
justifyContent="space-between"
|
||||
spacing={2}
|
||||
sx={{ width: '100%' }}
|
||||
>
|
||||
{/* Left: Title */}
|
||||
<Typography variant="h3">Customers</Typography>
|
||||
{/* Right: Controls */}
|
||||
<Stack direction={{ xs: 'column', sm: 'row' }} spacing={2} alignItems="center" width={{ xs: '100%', sm: 'auto' }}>
|
||||
<LocationAutocomplete
|
||||
locaName={locaName}
|
||||
setAppId={setAppId}
|
||||
setLocoName={setLocoName}
|
||||
sx={{
|
||||
width: { xs: '100%', sm: 320 },
|
||||
zIndex: 100
|
||||
}}
|
||||
/>
|
||||
|
||||
<DebounceSearchBar
|
||||
value={searchword}
|
||||
onChange={setSearchword}
|
||||
onDebouncedChange={setDebouncedSearch}
|
||||
placeholder={`Search ${pageCount?.Total || ''} Customer (ctrl+k)`}
|
||||
sx={{
|
||||
width: { xs: '100%', sm: 320 }
|
||||
}}
|
||||
/>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Stack>
|
||||
}
|
||||
>
|
||||
<TableContainer ref={containerRef} onScroll={handleScroll} sx={{ maxHeight: 'calc(100vh - 180px)' }}>
|
||||
<Table stickyHeader>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell sx={{ position: 'sticky !important' }}>#</TableCell>
|
||||
<TableCell sx={{ position: 'sticky !important' }}>Name</TableCell>
|
||||
<TableCell sx={{ position: 'sticky !important' }}>Contact</TableCell>
|
||||
<TableCell sx={{ position: 'sticky !important' }}>Address</TableCell>
|
||||
<TableCell sx={{ position: 'sticky !important' }}>Location</TableCell>
|
||||
<TableCell sx={{ position: 'sticky !important' }}>Action</TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
|
||||
<TableBody>
|
||||
{customersIsLoading && <OrdersTableSkeleton />}
|
||||
{rows?.length == 0 && !customersIsLoading ? (
|
||||
<TableRow>
|
||||
<TableCell colSpan={6}>
|
||||
<Stack width={'100%'} direction={'row'} justifyContent={'center'}>
|
||||
<Empty />
|
||||
</Stack>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
) : (
|
||||
rows?.map((row, index) => {
|
||||
return (
|
||||
<TableRow key={row.name}>
|
||||
<TableCell padding="none">{index + 1 + page * rowsPerPage}</TableCell>
|
||||
<TableCell align="left">
|
||||
<Typography align="left" variant="subtitle1">
|
||||
{row.firstname}
|
||||
</Typography>
|
||||
<Typography align="left" variant="caption" color="secondary">
|
||||
Id : {row.customerid}
|
||||
</Typography>
|
||||
</TableCell>
|
||||
<TableCell align="left">
|
||||
<Typography align="left" variant="subtitle1">
|
||||
{row.contactno}
|
||||
</Typography>
|
||||
<Typography align="left" variant="caption" color="secondary">
|
||||
{row.email}
|
||||
</Typography>
|
||||
</TableCell>
|
||||
<TableCell align="left">{row.address}</TableCell>
|
||||
<TableCell align="left">{row.suburb}</TableCell>
|
||||
<TableCell align="center">
|
||||
<Tooltip title={'To Edit'}>
|
||||
<IconButton
|
||||
onClick={() => {
|
||||
console.log('row', row);
|
||||
setSelectedCustomer(row);
|
||||
setTimeout(() => {
|
||||
setOpen(true);
|
||||
}, 0);
|
||||
}}
|
||||
>
|
||||
<RiEdit2Fill
|
||||
fontSize={'large'}
|
||||
style={{
|
||||
cursor: 'pointer',
|
||||
color: theme.palette.primary.main
|
||||
}}
|
||||
/>
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
})
|
||||
)}
|
||||
{rows?.length != 0 && (
|
||||
<TableRow>
|
||||
<TableCell colSpan={15} rowSpan={3}>
|
||||
<div ref={loadMoreRef} style={{ height: 40, textAlign: 'center' }}>
|
||||
{isFetchingNextPage ? <LoaderWithImage /> : hasNextPage ? <LoaderWithImage /> : 'No More Orders'}
|
||||
</div>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
<Divider />
|
||||
</MainCard>
|
||||
{/* ======================================== || Edit Dialog || ======================================== */}
|
||||
<Dialog
|
||||
open={open}
|
||||
onClose={() => setOpen(false)}
|
||||
aria-labelledby="alert-dialog-title"
|
||||
aria-describedby="alert-dialog-description"
|
||||
maxWidth="lg"
|
||||
fullWidth
|
||||
>
|
||||
<DialogTitle id="alert-dialog-title" sx={{ bgcolor: theme.palette.primary.main, color: 'white' }}>
|
||||
<Stack direction={'row'} alignItems={'center'} spacing={1}>
|
||||
<FaRegEdit style={{ fontSize: 25 }} /> <Typography variant="h3">Edit Customer</Typography>
|
||||
</Stack>
|
||||
</DialogTitle>
|
||||
<DialogContent>
|
||||
<Grid container spacing={2} sx={{ mt: 2 }}>
|
||||
<Grid item xs={6}>
|
||||
<Typography sx={{ mb: 1 }}>Customer Name</Typography>
|
||||
<TextField
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
defaultValue={selectedCustomer?.firstname}
|
||||
onChange={(e) => {
|
||||
setSelectedCustomer({
|
||||
...selectedCustomer,
|
||||
firstname: e.target.value
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
<Typography sx={{ mb: 1 }}>Contact Number</Typography>
|
||||
<Stack direction={'row'} spacing={1}>
|
||||
<TextField readonly variant="outlined" value={'+91'} sx={{ width: 60 }} />
|
||||
<TextField
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
type="text"
|
||||
value={selectedCustomer?.contactno || ''}
|
||||
inputProps={{
|
||||
maxLength: 10,
|
||||
inputMode: 'numeric', // mobile numeric keypad
|
||||
pattern: '[0-9]*'
|
||||
}}
|
||||
onChange={(e) => {
|
||||
const value = e.target.value.replace(/\D/g, ''); // allow only digits
|
||||
|
||||
setSelectedCustomer((prev) => ({
|
||||
...prev,
|
||||
contactno: value
|
||||
}));
|
||||
}}
|
||||
/>
|
||||
</Stack>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Typography sx={{ mb: 1 }}>Address</Typography>
|
||||
<Autocomplete
|
||||
id="google-map-demo"
|
||||
sx={{}}
|
||||
fullWidth
|
||||
getOptionLabel={(option) => (typeof option === 'string' ? option : option?.description || '')}
|
||||
filterOptions={(x) => x}
|
||||
options={options}
|
||||
autoComplete
|
||||
includeInputInList
|
||||
filterSelectedOptions
|
||||
value={selectedCustomer?.address}
|
||||
noOptionsText="No locations"
|
||||
onChange={(event, newValue) => {
|
||||
setOptions(newValue ? [newValue, ...options] : options);
|
||||
setValue(newValue);
|
||||
console.log('newValue', newValue || '');
|
||||
setAddress(newValue?.description);
|
||||
setSelectedCustomer({
|
||||
...selectedCustomer,
|
||||
address: newValue?.description
|
||||
});
|
||||
}}
|
||||
onInputChange={(event, newInputValue) => {
|
||||
setInputValue(newInputValue);
|
||||
}}
|
||||
renderInput={(params) => <TextField {...params} fullWidth />}
|
||||
renderOption={(props, option) => {
|
||||
const matches = option.structured_formatting.main_text_matched_substrings || [];
|
||||
|
||||
const parts = parse(
|
||||
option.structured_formatting.main_text,
|
||||
matches.map((match) => [match.offset, match.offset + match.length])
|
||||
);
|
||||
|
||||
return (
|
||||
<li {...props}>
|
||||
<Grid container alignItems="center">
|
||||
<Grid item sx={{ display: 'flex', width: 44 }}>
|
||||
<LocationOnIcon sx={{ color: 'text.secondary' }} />
|
||||
</Grid>
|
||||
<Grid
|
||||
item
|
||||
sx={{
|
||||
width: 'calc(100% - 44px)',
|
||||
wordWrap: 'break-word'
|
||||
}}
|
||||
>
|
||||
{parts?.map((part, index) => (
|
||||
<Box
|
||||
key={index}
|
||||
component="span"
|
||||
sx={{
|
||||
fontWeight: part.highlight ? 'bold' : 'regular'
|
||||
}}
|
||||
>
|
||||
{part.text}
|
||||
</Box>
|
||||
))}
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
{option?.structured_formatting.secondary_text}
|
||||
</Typography>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</li>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
<Typography sx={{ mb: 1 }}>Location</Typography>
|
||||
<TextField
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
value={selectedCustomer?.suburb}
|
||||
onChange={(e) => {
|
||||
const value = e.target.value;
|
||||
setSelectedCustomer((prev) => ({
|
||||
...prev,
|
||||
suburb: value
|
||||
}));
|
||||
// setSuburb(e.target.value);
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
<Typography sx={{ mb: 1 }}>City</Typography>
|
||||
<TextField
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
value={selectedCustomer.city || city || ''}
|
||||
onChange={(e) => {
|
||||
const value = e.target.value;
|
||||
setSelectedCustomer((prev) => ({
|
||||
...prev,
|
||||
city: value
|
||||
}));
|
||||
// setCity(e.target.value);
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
<Typography sx={{ mb: 1 }}>State</Typography>
|
||||
<TextField
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
value={selectedCustomer.state || state || ''}
|
||||
onChange={(e) => {
|
||||
const value = e.target.value;
|
||||
setSelectedCustomer((prev) => ({
|
||||
...prev,
|
||||
state: value
|
||||
}));
|
||||
// setState(e.target.value);
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
<Typography sx={{ mb: 1 }}>Postcode</Typography>
|
||||
<TextField
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
value={postcode == '' ? selectedCustomer.postcode : postcode}
|
||||
onChange={(e) => {
|
||||
const value = e.target.value;
|
||||
setSelectedCustomer((prev) => ({
|
||||
...prev,
|
||||
postcode: value
|
||||
}));
|
||||
// setPostcode(e.target.value);
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Typography sx={{ mb: 1 }}>Landmark</Typography>
|
||||
<TextField
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
defaultValue={selectedCustomer.landmark}
|
||||
onChange={(e) => {
|
||||
setSelectedCustomer({
|
||||
...selectedCustomer,
|
||||
landmark: e.target.value
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={6} sx={{ cursor: 'not-allowed' }}>
|
||||
<Typography sx={{ mb: 1 }}>Latitude</Typography>
|
||||
<TextField variant="outlined" fullWidth value={latlong.lat} sx={{ cursor: 'not-allowed' }} />
|
||||
</Grid>
|
||||
<Grid item xs={6} sx={{ cursor: 'not-allowed' }}>
|
||||
<Typography sx={{ mb: 1 }}>Longitude</Typography>
|
||||
<TextField readonly variant="outlined" fullWidth value={latlong.lng} />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</DialogContent>
|
||||
<DialogActions sx={{ mr: 2, mb: 2 }}>
|
||||
<Button onClick={() => setOpen(false)} variant="contained" color="error" sx={{ mr: 2 }}>
|
||||
Close
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => {
|
||||
updateCustomer();
|
||||
}}
|
||||
variant="contained"
|
||||
autoFocus
|
||||
>
|
||||
Update
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user