initialisation on the doormile express console with astryx

This commit is contained in:
2026-07-29 18:16:25 +05:30
parent d5bde7d1ac
commit 7d672139b5
108 changed files with 12536 additions and 21351 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,545 +0,0 @@
import { React, useEffect, useState, useRef } from 'react';
import { useTheme } from '@mui/material/styles';
import { Button, Grid, InputLabel, MenuItem, Select, Stack, TextField, Typography, IconButton, Autocomplete, useMediaQuery } from '@mui/material';
import MainCard from 'components/MainCard';
import axios from 'axios';
import Loader from 'components/Loader';
import Geocode from 'react-geocode';
import { enqueueSnackbar } from 'notistack';
import { useNavigate } from 'react-router';
import CloseIcon from '@mui/icons-material/Close';
import LocationAutocomplete from 'components/nearle_components/LocationAutocomplete';
import { OpenToast } from 'components/third-party/OpenToast';
const CreateCustomer = () => {
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down('md'));
const [appId, setAppId] = useState(0);
const locationRef = useRef(null);
const [mobilenumber, setMobilenumber] = useState('');
const [emailaddress, setEmailaddress] = useState('');
const [address, setAddress] = useState('');
const [firstname, setFirstname] = useState('');
const [doorno, setDoorno] = useState('');
const [landmark, setLandmark] = useState('');
const [inputValue2, setInputValue2] = useState('');
const [appLocaLat, setAppLocaLat] = useState();
const [appLocaLng, setAppLocaLng] = useState();
const [appLocaRadius, setAppLocaRadius] = useState();
const [locaName, setLocoName] = useState('Select Location');
const [tenantlist, setTenantlist] = useState([]);
const [tid, setTid] = useState(0);
const [pickCust, setPickCust] = useState({});
const [startPoint, setStartPoint] = useState({ latitude: 0, longitude: 0 });
const [loading, setLoading] = useState(false);
const navigate = useNavigate();
Geocode.setApiKey(process.env.REACT_APP_GOOGLE_MAPS_API_KEY);
useEffect(() => {
// Initialize Google Maps Autocomplete
if (inputValue2) {
const autocompleteInput = document.getElementById('addressAuto1');
const autocomplete = new window.google.maps.places.Autocomplete(autocompleteInput, {
// types: ['(cities)'], // You can adjust the types parameter based on your requirements
strictBounds: true,
bounds: new window.google.maps.Circle({
// center: new window.google.maps.LatLng(11.0050707, 76.9509083),
// radius: 100000
center: new window.google.maps.LatLng(appLocaLat, appLocaLng),
radius: appLocaRadius * 1000
}).getBounds()
});
// Event listener for autocomplete place changed
autocomplete.addListener('place_changed', () => {
const place = autocomplete.getPlace();
setInputValue2(`${place.name}, ${place.formatted_address}`);
console.log('new place', place); // Do something with the selected place
console.log(' pick (new place) lat lng', { lat: place.geometry.location.lat(), lng: place.geometry.location.lng() }); // Do something with the selected place
// to trigger getDistance
setStartPoint({ latitude: place.geometry.location.lat(), longitude: place.geometry.location.lng() });
setAddress(`${place.name} ${place.formatted_address}`);
setPickCust({ ...pickCust, address: `${place.name} ${place.formatted_address}` });
const address = {
address: `${place.name} ${place.formatted_address}`,
street_number: '',
route: '',
locality: '',
sublocality_level_1: '',
administrative_area_level_3: '',
administrative_area_level_1: '',
country: '',
postal_code: ''
};
place.address_components.forEach((component) => {
component.types.forEach((type) => {
switch (type) {
case 'street_number':
address.street_number = component.long_name;
break;
case 'route':
address.route = component.long_name;
break;
case 'locality':
address.locality = component.long_name;
break;
case 'sublocality_level_1':
address.sublocality_level_1 = component.long_name;
break;
case 'administrative_area_level_3':
address.administrative_area_level_3 = component.long_name;
break;
case 'administrative_area_level_1':
address.administrative_area_level_1 = component.long_name;
break;
case 'country':
address.country = component.long_name;
break;
case 'postal_code':
address.postal_code = component.long_name;
break;
// Add more cases as needed for other types
}
});
});
// Use address object as per your requirements
setPickCust({
...pickCust,
address: address.address,
doorno: `${address.street_number} ${address.route}`,
suburb: address.administrative_area_level_3,
city: address.locality,
state: address.administrative_area_level_1,
postcode: address.postal_code,
latitude: place.geometry.location.lat(),
longitude: place.geometry.location.lng()
});
console.log('Pick Address:', address);
});
}
}, [inputValue2]);
// ==================================================== || getapplocations || ====================================================
const getapplocations = async () => {
setLoading(true);
await axios
.get(`${process.env.REACT_APP_URL}/utils/getapplocations/?applocationid=${appId}`)
.then((res) => {
console.log('getapplocations', res);
const { latitude, longitude, radius } = res.data.details[0];
if (res.data.status) {
setAppLocaLat(latitude);
setAppLocaLng(longitude);
setAppLocaRadius(radius);
console.log('radius', radius);
}
setLoading(false);
})
.catch((err) => {
console.log(err);
setLoading(false);
});
};
useEffect(() => {
if (appId) {
getapplocations();
}
}, [appId]);
// ===================================================== || fetchtenantinfolist || =====================================================
const fetchtenantinfolist = async (id) => {
setLoading(true);
await axios
.get(`${process.env.REACT_APP_URL}/tenants/gettenants/?applocationid=${id}&status=active`)
.then((res) => {
console.log(res);
if (res.data.status) {
let arr = [];
res.data.details.map((val) => {
arr.push({
...val,
label: `${val.tenantname}`
});
});
setTenantlist(arr);
}
setLoading(false);
})
.catch((err) => {
console.log(err);
setLoading(false);
});
};
useEffect(() => {
appId && fetchtenantinfolist(appId);
}, [appId]);
// ============================================= || gettenantlocations (branches) || =============================================
const gettenantlocations = async (id) => {
try {
const res = await axios.get(`${process.env.REACT_APP_URL}/tenants/gettenantlocations/?tenantid=${id}`);
console.log('gettenantlocations', res.data.details);
if (res.data.details.length == 1) {
} else {
}
} catch (err) {
console.log('gettenantlocations', err);
}
};
const opentoast = (message) => {
enqueueSnackbar(message, {
variant: 'error',
anchorOrigin: { vertical: 'top', horizontal: 'right' },
autoHideDuration: 2000
});
};
const createprofile = async () => {
let obj = {
applocationid: +appId,
tenantid: +tid,
customerid: 0,
configid: 1,
firstname: firstname,
dialcode: '+91',
contactno: mobilenumber,
email: emailaddress,
doorno: doorno,
address: pickCust.address,
suburb: pickCust.suburb,
city: pickCust.city,
state: pickCust.state,
postcode: pickCust.postcode,
landmark: landmark,
latitude: startPoint.latitude.toString(),
longitude: startPoint.longitude.toString(),
profileimage: '',
devicetype: '',
deviceid: '',
customertoken: '',
primaryaddress: 1
};
console.log(obj);
setLoading(true);
try {
await axios
.post(`${process.env.REACT_APP_URL}/customers/create`, obj)
.then((res) => {
console.log(res);
if (res.data.status) {
enqueueSnackbar(' Created Successfully ', {
variant: 'success',
anchorOrigin: { vertical: 'top', horizontal: 'right' },
autoHideDuration: 2000
});
navigate('/nearle/customers');
} else if (res.data.message == 'Customer Already available') {
enqueueSnackbar('Customer Already available', {
variant: 'error',
anchorOrigin: { vertical: 'top', horizontal: 'right' },
autoHideDuration: 2000
});
}
setLoading(false);
})
.catch((err) => {
console.log(err);
setLoading(false);
enqueueSnackbar(err.message, {
variant: 'error',
anchorOrigin: { vertical: 'top', horizontal: 'right' },
autoHideDuration: 2000
});
});
} catch (err) {
console.log(err);
setLoading(false);
}
};
return (
<>
{loading && <Loader />}
<Grid item xs={12} sx={{ mb: 2 }}>
<Stack direction="row" justifyContent="space-between" alignItems="center">
<Typography variant="h3">Create Customer</Typography>
</Stack>
</Grid>
<MainCard sx={{ p: { xs: 1.5, md: 3 } }}>
<Grid container spacing={{ xs: 2, md: 3 }}>
<Grid item xs={12}>
<Grid container spacing={{ xs: 2, md: 3 }}>
{/* ===================================================== || Choose location || ===================================================== */}
<Grid item xs={12} md={6}>
<LocationAutocomplete ref={locationRef} locaName={locaName} setAppId={setAppId} setLocoName={setLocoName} sx={{}} />
</Grid>
{/* ===================================================== || Choose client || ===================================================== */}
<Grid item xs={12} md={6}>
<Autocomplete
fullWidth
disabled={appId == 0}
id="free-solo-demo"
sx={{}}
options={tenantlist || []}
renderInput={(params) => <TextField {...params} label="Choose Client" focused />}
onChange={(e, val, reason) => {
if (val) {
console.log('Client', val);
gettenantlocations(val.tenantid);
setTid(val.tenantid);
} else {
setClientinfo({});
setTenantid('');
}
if (reason == 'clear') {
}
}}
/>{' '}
</Grid>
{/* ===================================================== || Name|| ===================================================== */}
<Grid item xs={12} sm={6}>
<Stack spacing={1.25}>
<InputLabel htmlFor="personal-last-name">Name</InputLabel>
<TextField
fullWidth
id="personal-last-name"
placeholder="Name"
onChange={(e) => setFirstname(e.target.value)}
value={firstname}
autoComplete="off"
/>
</Stack>
</Grid>
{/* ===================================================== || Phone Number || ===================================================== */}
<Grid item xs={12} sm={6}>
<Stack spacing={1.25}>
<InputLabel htmlFor="personal-phone">Phone Number</InputLabel>
<Stack direction="row" justifyContent="space-between" alignItems="center" spacing={2}>
<Select defaultValue="+1" disabled sx={{ cursor: 'not-allowed' }}>
<MenuItem value="+1">+91</MenuItem>
</Select>
<TextField
type="number"
id="personal-phone"
fullWidth
placeholder="Phone Number"
onChange={(e) => {
if (e.target.value.toString().length <= 10) {
setMobilenumber(e.target.value);
}
}}
value={mobilenumber}
autoComplete="off"
// disabled
sx={{ cursor: 'not-allowed' }}
/>
</Stack>
</Stack>
</Grid>
{/* ===================================================== || Email|| ===================================================== */}
<Grid item xs={12} sm={6}>
<Stack spacing={1.25}>
<InputLabel htmlFor="personal-email">Email </InputLabel>
<TextField
type="email"
fullWidth
id="personal-email"
placeholder="Email "
onChange={(e) => setEmailaddress(e.target.value)}
value={emailaddress}
autoComplete="off"
/>
</Stack>
</Grid>
{/* ===================================================== || door no || ===================================================== */}
<Grid item xs={12} sm={6}>
<Stack spacing={1.25}>
<InputLabel htmlFor="personal-location">Door No</InputLabel>
<TextField
fullWidth
// defaultValue="New York"
id="personal-location"
placeholder="Door No"
onChange={(e) => setDoorno(e.target.value)}
value={doorno}
autoComplete="off"
/>
</Stack>
</Grid>
{/* ===================================================== || Address || ===================================================== */}
<Grid item xs={12}>
<Stack spacing={1.25}>
<InputLabel htmlFor="personal-email"> Address</InputLabel>
<TextField
variant="outlined"
id="addressAuto1"
fullWidth
value={inputValue2}
onChange={(e) => {
if (appId) {
appId && setInputValue2(e.target.value);
} else {
OpenToast('Select Location First', 'warning', 3000);
}
}}
InputProps={{
endAdornment: (
<IconButton
onClick={() => {
setInputValue2('');
setPickCust({
...pickCust,
doorno: '',
suburb: '',
city: '',
postcode: '',
landmark: ''
});
setStartPoint({ latitude: 0, longitude: 0 });
}}
size="small"
>
<CloseIcon />
</IconButton>
)
}}
/>
</Stack>
</Grid>
<Grid item xs={12} sm={6}>
<Stack spacing={1.25}>
<InputLabel htmlFor="personal-location">Location</InputLabel>
<TextField
fullWidth
// defaultValue="New York"
id="personal-location"
placeholder="Location"
onChange={(e) => setPickCust({ ...pickCust, suburb: e.target.value })}
value={pickCust.suburb}
autoComplete="off"
/>
</Stack>
</Grid>
<Grid item xs={12} sm={6}>
<Stack spacing={1.25}>
<InputLabel htmlFor="personal-zipcode">City</InputLabel>
<TextField
fullWidth
id="personal-zipcode"
placeholder="City"
onChange={(e) => setPickCust({ ...pickCust, city: e.target.value })}
value={pickCust.city}
autoComplete="off"
/>
</Stack>
</Grid>
<Grid item xs={12} sm={6}>
<Stack spacing={1.25}>
<InputLabel htmlFor="personal-location">State</InputLabel>
<TextField
fullWidth
// defaultValue="New York"
id="personal-location"
placeholder="State"
onChange={(e) => setPickCust({ ...pickCust, state: e.target.value })}
value={pickCust.state}
autoComplete="off"
/>
</Stack>
</Grid>
<Grid item xs={12} sm={6}>
<Stack spacing={1.25}>
<InputLabel htmlFor="personal-zipcode">Post Code</InputLabel>
<TextField
fullWidth
// defaultValue="956754"
type="number"
id="personal-zipcode"
placeholder="Zipcode"
onChange={(e) => setPickCust({ ...pickCust, postcode: e.target.value })}
value={pickCust.postcode}
autoComplete="off"
/>
</Stack>
</Grid>
<Grid item xs={12}>
<Stack spacing={1.25}>
<InputLabel htmlFor="personal-email">Landmark</InputLabel>
<TextField
type="email"
fullWidth
// defaultValue="stebin.ben@gmail.com"
id="personal-email"
placeholder="Landmark"
onChange={(e) => setLandmark(e.target.value)}
value={landmark}
autoComplete="off"
/>
</Stack>
</Grid>
</Grid>
</Grid>
<Grid item xs={12}>
<Stack
direction={{ xs: 'column', sm: 'row' }}
justifyContent="flex-end"
alignItems={{ xs: 'stretch', sm: 'center' }}
spacing={2}
>
<Button
variant="contained"
fullWidth={isMobile}
onClick={() => {
if (appId === '') {
opentoast('Select Applocation ');
} else if (tid === '') {
opentoast('Select Tenant');
} else if (firstname === '') {
opentoast('Enter Name');
} else if (mobilenumber === '') {
opentoast('Enter Mobile Number ');
} else if (address === '') {
opentoast('Enter Address ');
} else if (pickCust.city === '') {
opentoast('Enter City ');
} else if (pickCust.state === '') {
opentoast('Enter State ');
} else if (pickCust.suburb === '') {
opentoast('Enter location ');
} else if (pickCust.postcode === '') {
opentoast('Enter Post Code ');
} else if (landmark === '') {
opentoast('Enter Land Mark ');
} else if (pickCust.latitude === '') {
opentoast('Invalid latitude ');
} else if (pickCust.longitude === '') {
opentoast('Invaiid Longitude ');
} else {
createprofile();
}
}}
>
Create
</Button>
</Stack>
</Grid>
</Grid>
</MainCard>
</>
);
};
export default CreateCustomer;

View File

@@ -2,7 +2,8 @@ import { useEffect, useState } from 'react';
// material-ui
import { useTheme } from '@mui/material/styles';
import { Box, Button, FormLabel, Grid, InputLabel, MenuItem, Select, Stack, TextField, Typography, useMediaQuery } from '@mui/material';
import { Avatar, Box, Button, FormLabel, Grid, InputLabel, MenuItem, Paper, Select, Stack, TextField, Typography, useMediaQuery } from '@mui/material';
import { MdPersonAddAlt1 } from 'react-icons/md';
// third-party
// import { PatternFormat } from 'react-number-format';
@@ -15,6 +16,7 @@ import Loader from 'components/Loader';
import Geocode from 'react-geocode';
import { enqueueSnackbar } from 'notistack';
import { useNavigate } from 'react-router';
import { DT, tint } from 'themes/dt/tokens';
// import { setLocationType } from 'react-geocode';
// const avatarImage = require.context('assets/images/users', true);
@@ -145,12 +147,6 @@ const Createclient = () => {
});
};
useEffect(() => {
if (selectedImage) {
setAvatar(URL.createObjectURL(selectedImage));
}
}, [selectedImage]);
const { ref: materialRef } = usePlacesWidget({
apiKey: process.env.REACT_APP_GOOGLE_MAPS_API_KEY,
onPlaceSelected: (place) => {
@@ -296,11 +292,28 @@ const Createclient = () => {
{loading && <Loader />}
<Grid item xs={12} sx={{ mb: 2 }}>
<Stack direction="row" justifyContent="space-between" alignItems="center">
<Typography variant="h3">Create Client</Typography>
</Stack>
<Paper
sx={{
p: 2.5,
borderRadius: DT.radiusCard + 'px',
boxShadow: DT.shadowSoft,
border: '1px solid',
borderColor: DT.borderSubtle,
background: `linear-gradient(135deg, ${tint('#C01227')} 0%, ${tint('#D25463')} 100%)`
}}
>
<Stack direction="row" spacing={1.5} alignItems="center">
<Avatar sx={{ width: 48, height: 48, bgcolor: DT.brand }}>
<MdPersonAddAlt1 size={22} />
</Avatar>
<Typography variant="h3">Create Client</Typography>
</Stack>
</Paper>
</Grid>
<MainCard contentSX={{ p: { xs: 1.5, md: 3 } }}>
<MainCard
contentSX={{ p: { xs: 1.5, md: 3 } }}
sx={{ borderRadius: DT.radiusCard + 'px', boxShadow: DT.shadowSoft, borderColor: DT.borderSubtle }}
>
<Grid container spacing={isMobile ? 2 : 3}>
{/* <Grid item xs={12} sm={4} >
<MainCard title="Personal Information" sx={{ height: '100%' }}>