Updates from beta testing
This commit is contained in:
@@ -1,3 +1,3 @@
|
|||||||
VITE_API_URL=https://beta.backend.ditchtheagent.com/api/
|
VITE_API_URL=https://beta.backend.ditchtheagent.com/api/
|
||||||
ENABLE_REGISTRATION=true
|
ENABLE_REGISTRATION=true
|
||||||
USE_LIVE_DATA=false
|
USE_LIVE_DATA=true
|
||||||
|
|||||||
6
ditch-the-agent/package-lock.json
generated
6
ditch-the-agent/package-lock.json
generated
@@ -27,6 +27,7 @@
|
|||||||
"formik": "^2.4.6",
|
"formik": "^2.4.6",
|
||||||
"js-cookie": "^3.0.5",
|
"js-cookie": "^3.0.5",
|
||||||
"jwt-decode": "^4.0.0",
|
"jwt-decode": "^4.0.0",
|
||||||
|
"lodash.debounce": "^4.0.8",
|
||||||
"lucide-react": "^0.525.0",
|
"lucide-react": "^0.525.0",
|
||||||
"material-ui-popup-state": "^5.1.0",
|
"material-ui-popup-state": "^5.1.0",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
@@ -4689,6 +4690,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
|
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
|
||||||
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
|
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
|
||||||
},
|
},
|
||||||
|
"node_modules/lodash.debounce": {
|
||||||
|
"version": "4.0.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
|
||||||
|
"integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="
|
||||||
|
},
|
||||||
"node_modules/lodash.defaults": {
|
"node_modules/lodash.defaults": {
|
||||||
"version": "4.2.0",
|
"version": "4.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz",
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build": "tsc && vite build",
|
"build": "tsc && vite build",
|
||||||
"build:beta": "vite build --mode beta",
|
"build:beta": "vite build --mode beta && cp -r ./dist/* /var/www/beta.app.ditchtheagent/html/",
|
||||||
"build:prod": "tsc && vite build --mode production",
|
"build:prod": "vite build --mode production",
|
||||||
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
|
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"predeploy": "vite build && cp ./dist/index.html ./dist/404.html",
|
"predeploy": "vite build && cp ./dist/index.html ./dist/404.html",
|
||||||
@@ -33,6 +33,7 @@
|
|||||||
"formik": "^2.4.6",
|
"formik": "^2.4.6",
|
||||||
"js-cookie": "^3.0.5",
|
"js-cookie": "^3.0.5",
|
||||||
"jwt-decode": "^4.0.0",
|
"jwt-decode": "^4.0.0",
|
||||||
|
"lodash.debounce": "^4.0.8",
|
||||||
"lucide-react": "^0.525.0",
|
"lucide-react": "^0.525.0",
|
||||||
"material-ui-popup-state": "^5.1.0",
|
"material-ui-popup-state": "^5.1.0",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect, useMemo, useCallback } from 'react';
|
||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
DialogTitle,
|
DialogTitle,
|
||||||
@@ -13,7 +13,7 @@ import {
|
|||||||
Alert,
|
Alert,
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import { axiosInstance, axiosRealEstateApi } from '../../../../../axiosApi';
|
import { axiosInstance, axiosRealEstateApi } from '../../../../../axiosApi';
|
||||||
|
import debounce from 'lodash/debounce';
|
||||||
import MapComponent from '../../../../base/MapComponent';
|
import MapComponent from '../../../../base/MapComponent';
|
||||||
import {
|
import {
|
||||||
AutocompleteDataResponseAPI,
|
AutocompleteDataResponseAPI,
|
||||||
@@ -41,6 +41,26 @@ export interface PlacePrediction {
|
|||||||
place_id: string;
|
place_id: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fetchAutocompleteOptions = async (
|
||||||
|
value: string,
|
||||||
|
setAutocompleteOptions: (options: any[]) => void,
|
||||||
|
) => {
|
||||||
|
// ... your existing API call logic from handleAddressAutocompleteInputChange
|
||||||
|
try {
|
||||||
|
let { data } = await axiosInstance.post<AutocompleteResponseAPI>('autocomplete-proxy/', {
|
||||||
|
search: value,
|
||||||
|
search_types: ['A'],
|
||||||
|
});
|
||||||
|
let temp = data.data.map((item) => ({ description: item.address, place_id: item.id }));
|
||||||
|
console.log(temp);
|
||||||
|
|
||||||
|
setAutocompleteOptions(temp);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Autocomplete fetch failed:', error);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const AddPropertyDialog: React.FC<AddPropertyDialogProps> = ({ open, onClose, onAddProperty }) => {
|
const AddPropertyDialog: React.FC<AddPropertyDialogProps> = ({ open, onClose, onAddProperty }) => {
|
||||||
const initalValues: Omit<PropertiesAPI, 'id' | 'owner' | 'created_at' | 'last_updated'> = {
|
const initalValues: Omit<PropertiesAPI, 'id' | 'owner' | 'created_at' | 'last_updated'> = {
|
||||||
address: '',
|
address: '',
|
||||||
@@ -76,6 +96,11 @@ const AddPropertyDialog: React.FC<AddPropertyDialogProps> = ({ open, onClose, on
|
|||||||
const [formErrors, setFormErrors] = useState<{ [key: string]: string }>({});
|
const [formErrors, setFormErrors] = useState<{ [key: string]: string }>({});
|
||||||
const [selectedPlace, setSelectedPlace] = useState<PlacePrediction | null>(null);
|
const [selectedPlace, setSelectedPlace] = useState<PlacePrediction | null>(null);
|
||||||
|
|
||||||
|
const debouncedFetch = useMemo(
|
||||||
|
() => debounce(fetchAutocompleteOptions, 200),
|
||||||
|
[], // Dependency array ensures the debounced function is created only once
|
||||||
|
);
|
||||||
|
|
||||||
// Initialize Google Maps Places Service (requires Google Maps API key loaded globally)
|
// Initialize Google Maps Places Service (requires Google Maps API key loaded globally)
|
||||||
// This is a simplified approach. For a more robust solution, use @vis.gl/react-google-maps useMapsLibrary hook
|
// This is a simplified approach. For a more robust solution, use @vis.gl/react-google-maps useMapsLibrary hook
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -84,7 +109,6 @@ const AddPropertyDialog: React.FC<AddPropertyDialogProps> = ({ open, onClose, on
|
|||||||
// You might want to handle this by displaying a message or disabling autocomplete
|
// You might want to handle this by displaying a message or disabling autocomplete
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
const { name, value } = e.target;
|
const { name, value } = e.target;
|
||||||
setNewProperty((prev) => ({ ...prev, [name]: value }));
|
setNewProperty((prev) => ({ ...prev, [name]: value }));
|
||||||
@@ -96,51 +120,81 @@ const AddPropertyDialog: React.FC<AddPropertyDialogProps> = ({ open, onClose, on
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
const handleAddressAutocompleteInputChange = useCallback(
|
||||||
|
(event: React.SyntheticEvent, value: string) => {
|
||||||
|
// 1. Update the local state immediately for a smooth input experience
|
||||||
|
setNewProperty((prev) => ({ ...prev, address: value })); // <--- THIS IS THE CRITICAL LINE
|
||||||
|
|
||||||
const handleAddressAutocompleteInputChange = async (
|
// 2. Clear options if the value is too short
|
||||||
event: React.SyntheticEvent,
|
if (value.length < 3) {
|
||||||
value: string,
|
setAutocompleteOptions([]);
|
||||||
) => {
|
// Important: Cancel any pending debounced calls
|
||||||
const test: boolean = !import.meta.env.USE_LIVE_DATA;
|
debouncedFetch.cancel();
|
||||||
let data: AutocompleteDataResponseAPI[] = [];
|
return;
|
||||||
if (value.length > 2) {
|
|
||||||
if (test) {
|
|
||||||
data = test_autocomplete.data.filter((item) => item.address.includes(value));
|
|
||||||
// filter the data here
|
|
||||||
} else {
|
|
||||||
const { data } = await axiosRealEstateApi.post<AutocompleteDataResponseAPI[]>(
|
|
||||||
'AutoComplete',
|
|
||||||
{
|
|
||||||
search: value,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
setAutocompleteOptions(
|
console.log('attempting the function');
|
||||||
data.map((item) => ({
|
|
||||||
description: item.address,
|
|
||||||
place_id: item.id,
|
|
||||||
})),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
console.log('we need more characters');
|
|
||||||
}
|
|
||||||
|
|
||||||
setNewProperty((prev) => ({ ...prev, address: value }));
|
// 3. Call the debounced function, which will fire the API call
|
||||||
// if (value.length > 2 && window.google && window.google.maps && window.google.maps.places) {
|
// only after 300ms of inactivity.
|
||||||
// setAutocompleteLoading(true);
|
const result = debouncedFetch(value, setAutocompleteOptions);
|
||||||
// const service = new window.google.maps.places.AutocompleteService();
|
console.log(result);
|
||||||
// service.getPlacePredictions({ input: value }, (predictions, status) => {
|
},
|
||||||
// if (status === window.google.maps.places.PlacesServiceStatus.OK && predictions) {
|
[debouncedFetch],
|
||||||
// setAutocompleteOptions(predictions.map(p => ({ description: p.description, place_id: p.place_id })));
|
);
|
||||||
// } else {
|
// const handleAddressAutocompleteInputChange = async (
|
||||||
// setAutocompleteOptions([]);
|
// event: React.SyntheticEvent,
|
||||||
// }
|
// value: string,
|
||||||
// setAutocompleteLoading(false);
|
// ) => {
|
||||||
// });
|
// const test: boolean = import.meta.env.USE_LIVE_DATA;
|
||||||
// } else {
|
// console.log(test);
|
||||||
// setAutocompleteOptions([]);
|
// let data: AutocompleteDataResponseAPI[] = [];
|
||||||
// }
|
// if (value.length > 2) {
|
||||||
};
|
// if (test) {
|
||||||
|
// data = test_autocomplete.data.filter((item) => item.address.includes(value));
|
||||||
|
// // filter the data here
|
||||||
|
// setAutocompleteOptions(
|
||||||
|
// data.map((item) => ({
|
||||||
|
// description: item.address,
|
||||||
|
// place_id: item.id,
|
||||||
|
// })),
|
||||||
|
// );
|
||||||
|
// } else {
|
||||||
|
// let { data } = await axiosInstance.post<AutocompleteResponseAPI>('autocomplete-proxy/', {
|
||||||
|
// search: value,
|
||||||
|
// search_types: ['A'],
|
||||||
|
// });
|
||||||
|
// data = data.data;
|
||||||
|
// console.log(data);
|
||||||
|
// const temp = data.map((item) => ({ description: item.address, place_id: item.id }));
|
||||||
|
// console.log(temp);
|
||||||
|
// setAutocompleteOptions(temp);
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// console.log('we need more characters');
|
||||||
|
// }
|
||||||
|
|
||||||
|
// setNewProperty((prev) => ({ ...prev, address: value }));
|
||||||
|
// // if (value.length > 2 && window.google && window.google.maps && window.google.maps.places) {
|
||||||
|
// // setAutocompleteLoading(true);
|
||||||
|
// // const service = new window.google.maps.places.AutocompleteService();
|
||||||
|
// // service.getPlacePredictions({ input: value }, (predictions, status) => {
|
||||||
|
// // if (status === window.google.maps.places.PlacesServiceStatus.OK && predictions) {
|
||||||
|
// // setAutocompleteOptions(predictions.map(p => ({ description: p.description, place_id: p.place_id })));
|
||||||
|
// // } else {
|
||||||
|
// // setAutocompleteOptions([]);
|
||||||
|
// // }
|
||||||
|
// // setAutocompleteLoading(false);
|
||||||
|
// // });
|
||||||
|
// // } else {
|
||||||
|
// // setAutocompleteOptions([]);
|
||||||
|
// // }
|
||||||
|
// };
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
return () => {
|
||||||
|
debouncedFetch.cancel();
|
||||||
|
};
|
||||||
|
}, [debouncedFetch]);
|
||||||
|
|
||||||
const handleAddressAutocompleteChange = async (
|
const handleAddressAutocompleteChange = async (
|
||||||
event: React.SyntheticEvent,
|
event: React.SyntheticEvent,
|
||||||
@@ -150,7 +204,7 @@ const AddPropertyDialog: React.FC<AddPropertyDialogProps> = ({ open, onClose, on
|
|||||||
console.log('here we go', value);
|
console.log('here we go', value);
|
||||||
if (value) {
|
if (value) {
|
||||||
console.log('find the test data');
|
console.log('find the test data');
|
||||||
const test: boolean = true;
|
const test: boolean = import.meta.env.USE_LIVE_DATA;
|
||||||
if (test) {
|
if (test) {
|
||||||
const parts: string[] =
|
const parts: string[] =
|
||||||
test_property_search.data.currentMortgages[0].recordingDate.split('T');
|
test_property_search.data.currentMortgages[0].recordingDate.split('T');
|
||||||
@@ -219,6 +273,91 @@ const AddPropertyDialog: React.FC<AddPropertyDialogProps> = ({ open, onClose, on
|
|||||||
},
|
},
|
||||||
sale_info: sale_history,
|
sale_info: sale_history,
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
console.log('using live data');
|
||||||
|
let { data } = await axiosInstance.post<PropertyResponseAPI>('property-details-proxy/', {
|
||||||
|
comps: false,
|
||||||
|
id: value.place_id,
|
||||||
|
exact_match: true,
|
||||||
|
});
|
||||||
|
data = data.data;
|
||||||
|
console.log(data);
|
||||||
|
console.log(data.currentMortgages);
|
||||||
|
console.log(data.currentMortgages);
|
||||||
|
let parts: string;
|
||||||
|
let loan_amount: string;
|
||||||
|
let term: string;
|
||||||
|
if (data.currentMortgages.length > 0) {
|
||||||
|
parts = data.currentMortgages[0].recordingDate.split('T')[0];
|
||||||
|
loan_amount = data.currentMortgages[0].amount.toString();
|
||||||
|
term = data.currentMortgages[0].term;
|
||||||
|
} else {
|
||||||
|
parts = '';
|
||||||
|
loan_amount = '';
|
||||||
|
term = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
const schools: Omit<SchoolAPI, 'id' | 'created_at' | 'last_updated'>[] = data.schools.map(
|
||||||
|
(item) => {
|
||||||
|
const coordinates = extractLatLon(item.location);
|
||||||
|
return {
|
||||||
|
city: item.city,
|
||||||
|
state: item.state,
|
||||||
|
zip_code: item.zip,
|
||||||
|
latitude: coordinates?.latitude,
|
||||||
|
longitude: coordinates?.longitude,
|
||||||
|
school_type: item.type,
|
||||||
|
enrollment: item.enrollment,
|
||||||
|
grades: item.grades,
|
||||||
|
name: item.name,
|
||||||
|
parent_rating: item.parentRating,
|
||||||
|
rating: item.rating,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
);
|
||||||
|
console.log(schools);
|
||||||
|
|
||||||
|
// get the sale history
|
||||||
|
const sale_history: Omit<SaleHistoryAPI, 'id' | 'created_at' | 'last_updated'>[] =
|
||||||
|
data.saleHistory.map((item) => {
|
||||||
|
return {
|
||||||
|
seq_no: item.seqNo,
|
||||||
|
sale_date: item.saleDate,
|
||||||
|
sale_amount: item.saleAmount,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
setNewProperty({
|
||||||
|
address: data.propertyInfo.address.address,
|
||||||
|
street: data.ownerInfo.mailAddress.address,
|
||||||
|
city: data.propertyInfo.address.city,
|
||||||
|
state: data.propertyInfo.address.state,
|
||||||
|
zip_code: data.propertyInfo.address.zip,
|
||||||
|
latitude: data.propertyInfo.latitude,
|
||||||
|
longitude: data.propertyInfo.longitude,
|
||||||
|
market_value: data.estimatedValue.toString(),
|
||||||
|
loan_amount: loan_amount,
|
||||||
|
loan_term: term,
|
||||||
|
loan_start_date: parts,
|
||||||
|
description: '',
|
||||||
|
features: [],
|
||||||
|
pictures: [],
|
||||||
|
num_bedrooms: data.propertyInfo.bedrooms,
|
||||||
|
num_bathrooms: data.propertyInfo.bathrooms,
|
||||||
|
sq_ft: data.propertyInfo.buildingSquareFeet,
|
||||||
|
realestate_api_id: data.id,
|
||||||
|
views: 0,
|
||||||
|
saves: 0,
|
||||||
|
property_status: 'off_market',
|
||||||
|
schools: schools,
|
||||||
|
tax_info: {
|
||||||
|
assessed_value: data.taxInfo.assessedValue,
|
||||||
|
assessment_year: data.taxInfo.assessmentYear,
|
||||||
|
tax_amount: Number(data.taxInfo.taxAmount),
|
||||||
|
year: data.taxInfo.year,
|
||||||
|
},
|
||||||
|
sale_info: sale_history,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState, useMemo, useCallback } from 'react';
|
||||||
import {
|
import {
|
||||||
Card,
|
Card,
|
||||||
CardContent,
|
CardContent,
|
||||||
@@ -25,6 +25,8 @@ import { AutocompleteDataResponseAPI } from 'types';
|
|||||||
import { axiosInstance, axiosRealEstateApi } from '../../../../../axiosApi';
|
import { axiosInstance, axiosRealEstateApi } from '../../../../../axiosApi';
|
||||||
import { extractLatLon } from 'utils';
|
import { extractLatLon } from 'utils';
|
||||||
import { PlacePrediction } from './AddPropertyDialog';
|
import { PlacePrediction } from './AddPropertyDialog';
|
||||||
|
import { PropertyResponseAPI } from '../../../../../types';
|
||||||
|
import debounce from 'lodash/debounce';
|
||||||
|
|
||||||
interface VendorProfileCardProps {
|
interface VendorProfileCardProps {
|
||||||
vendor: VendorAPI;
|
vendor: VendorAPI;
|
||||||
@@ -32,6 +34,26 @@ interface VendorProfileCardProps {
|
|||||||
onSave: (updatedVendor: VendorAPI) => void;
|
onSave: (updatedVendor: VendorAPI) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fetchAutocompleteOptions = async (
|
||||||
|
value: string,
|
||||||
|
setAutocompleteOptions: (options: any[]) => void,
|
||||||
|
) => {
|
||||||
|
// ... your existing API call logic from handleAddressAutocompleteInputChange
|
||||||
|
try {
|
||||||
|
let { data } = await axiosInstance.post<AutocompleteResponseAPI>('autocomplete-proxy/', {
|
||||||
|
search: value,
|
||||||
|
search_types: ['A'],
|
||||||
|
});
|
||||||
|
let temp = data.data.map((item) => ({ description: item.address, place_id: item.id }));
|
||||||
|
console.log(temp);
|
||||||
|
|
||||||
|
setAutocompleteOptions(temp);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Autocomplete fetch failed:', error);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const VendorProfileCard: React.FC<VendorProfileCardProps> = ({ vendor, onUpgrade, onSave }) => {
|
const VendorProfileCard: React.FC<VendorProfileCardProps> = ({ vendor, onUpgrade, onSave }) => {
|
||||||
const [isEditing, setIsEditing] = useState(false);
|
const [isEditing, setIsEditing] = useState(false);
|
||||||
const [editedVendor, setEditedVendor] = useState<VendorAPI>(vendor);
|
const [editedVendor, setEditedVendor] = useState<VendorAPI>(vendor);
|
||||||
@@ -107,6 +129,11 @@ const VendorProfileCard: React.FC<VendorProfileCardProps> = ({ vendor, onUpgrade
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const debouncedFetch = useMemo(
|
||||||
|
() => debounce(fetchAutocompleteOptions, 200),
|
||||||
|
[], // Dependency array ensures the debounced function is created only once
|
||||||
|
);
|
||||||
|
|
||||||
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
const { name, value } = e.target;
|
const { name, value } = e.target;
|
||||||
//setNewProperty((prev) => ({ ...prev, [name]: value }));
|
//setNewProperty((prev) => ({ ...prev, [name]: value }));
|
||||||
@@ -119,58 +146,80 @@ const VendorProfileCard: React.FC<VendorProfileCardProps> = ({ vendor, onUpgrade
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleAddressAutocompleteInputChange = async (
|
const handleAddressAutocompleteInputChange = useCallback(
|
||||||
event: React.SyntheticEvent,
|
(event: React.SyntheticEvent, value: string) => {
|
||||||
value: string,
|
// 1. Update the local state immediately for a smooth input experience
|
||||||
) => {
|
setEditedVendor((prev) => ({ ...prev, address: value })); // <--- THIS IS THE CRITICAL LINE
|
||||||
const test: boolean = !import.meta.env.USE_LIVE_DATA;
|
|
||||||
let data: AutocompleteDataResponseAPI[] = [];
|
// 2. Clear options if the value is too short
|
||||||
if (value.length > 2) {
|
if (value.length < 3) {
|
||||||
if (test) {
|
setAutocompleteOptions([]);
|
||||||
data = test_autocomplete.data.filter((item) => item.address.includes(value));
|
// Important: Cancel any pending debounced calls
|
||||||
// filter the data here
|
debouncedFetch.cancel();
|
||||||
} else {
|
return;
|
||||||
const { data } = await axiosRealEstateApi.post<AutocompleteDataResponseAPI[]>(
|
|
||||||
'AutoComplete',
|
|
||||||
{
|
|
||||||
search: value,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
setAutocompleteOptions(
|
console.log('attempting the function');
|
||||||
data.map((item) => ({
|
|
||||||
description: item.address,
|
// 3. Call the debounced function, which will fire the API call
|
||||||
place_id: item.id,
|
// only after 300ms of inactivity.
|
||||||
})),
|
const result = debouncedFetch(value, setAutocompleteOptions);
|
||||||
);
|
console.log(result);
|
||||||
} else {
|
},
|
||||||
console.log('we need more characters');
|
[debouncedFetch],
|
||||||
}
|
);
|
||||||
};
|
|
||||||
|
// const handleAddressAutocompleteInputChange = async (
|
||||||
|
// event: React.SyntheticEvent,
|
||||||
|
// value: string,
|
||||||
|
// ) => {
|
||||||
|
// const test: boolean = import.meta.env.USE_LIVE_DATA;
|
||||||
|
// let data: AutocompleteDataResponseAPI[] = [];
|
||||||
|
// if (value.length > 2) {
|
||||||
|
// if (test) {
|
||||||
|
// data = test_autocomplete.data.filter((item) => item.address.includes(value));
|
||||||
|
// setAutocompleteOptions(
|
||||||
|
// data.map((item) => ({
|
||||||
|
// description: item.address,
|
||||||
|
// place_id: item.id,
|
||||||
|
// })),
|
||||||
|
// );
|
||||||
|
// // filter the data here
|
||||||
|
// } else {
|
||||||
|
// let { data } = await axiosInstance.post<AutocompleteResponseAPI>('autocomplete-proxy/', {
|
||||||
|
// search: value,
|
||||||
|
// search_types: ['A'],
|
||||||
|
// });
|
||||||
|
// data = data.data;
|
||||||
|
// const temp = data.map((item) => ({ description: item.address, place_id: item.id }));
|
||||||
|
// setAutocompleteOptions(temp);
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// console.log('we need more characters');
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
const handleAddressAutocompleteChange = async (
|
const handleAddressAutocompleteChange = async (
|
||||||
event: React.SyntheticEvent,
|
event: React.SyntheticEvent,
|
||||||
value: PlacePrediction | null,
|
value: PlacePrediction | null,
|
||||||
) => {
|
) => {
|
||||||
console.log('here we go', value);
|
let { data } = await axiosInstance.post<PropertyResponseAPI>('property-details-proxy/', {
|
||||||
if (1) {
|
comps: false,
|
||||||
const data = test_autocomplete.data.filter((item) => item.id === value.place_id);
|
id: value.place_id,
|
||||||
if (data.length > 0) {
|
exact_match: true,
|
||||||
const item = data[0];
|
});
|
||||||
const coordinates = extractLatLon(item.location);
|
data = data.data;
|
||||||
setEditedVendor((prev) => ({
|
console.log(data);
|
||||||
...prev,
|
|
||||||
address: item.address,
|
setEditedVendor((prev) => ({
|
||||||
city: item.city,
|
...prev,
|
||||||
state: item.state,
|
address: data.propertyInfo.address.address,
|
||||||
zip_code: item.zip,
|
street: data.propertyInfo.address.address,
|
||||||
latitude: Number(coordinates.latitude),
|
city: data.propertyInfo.address.city,
|
||||||
longitude: Number(coordinates.longitude),
|
state: data.propertyInfo.address.state,
|
||||||
}));
|
zip_code: data.propertyInfo.address.zip,
|
||||||
}
|
latitude: data.propertyInfo.latitude,
|
||||||
} else {
|
longitude: data.propertyInfo.longitude,
|
||||||
// use the api here
|
}));
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ const SignUp = (): ReactElement => {
|
|||||||
password2,
|
password2,
|
||||||
}: SignUpValues): Promise<void> => {
|
}: SignUpValues): Promise<void> => {
|
||||||
try {
|
try {
|
||||||
const response = await axiosInstance.post('/register/', {
|
const response = await axiosInstance.post('register/', {
|
||||||
email: email,
|
email: email,
|
||||||
first_name: first_name,
|
first_name: first_name,
|
||||||
last_name: last_name,
|
last_name: last_name,
|
||||||
@@ -62,8 +62,11 @@ const SignUp = (): ReactElement => {
|
|||||||
password: password,
|
password: password,
|
||||||
password2: password2,
|
password2: password2,
|
||||||
});
|
});
|
||||||
|
console.log(response);
|
||||||
if (response.status == 201) {
|
if (response.status == 201) {
|
||||||
navigate('/authentication/login');
|
navigate('/authentication/login');
|
||||||
|
|
||||||
|
console.log('Good response');
|
||||||
} else {
|
} else {
|
||||||
console.log(`No good: ${response}`);
|
console.log(`No good: ${response}`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -379,23 +379,23 @@ export interface AutocompleteResponseAPI {
|
|||||||
}
|
}
|
||||||
export interface AutocompleteDataResponseAPI {
|
export interface AutocompleteDataResponseAPI {
|
||||||
zip: string;
|
zip: string;
|
||||||
address: string;
|
address?: string;
|
||||||
city: string;
|
city?: string;
|
||||||
searchType: string;
|
searchType: string;
|
||||||
stateId: string;
|
stateId: string;
|
||||||
latitude: number;
|
latitude?: number;
|
||||||
county: string;
|
county?: string;
|
||||||
fips: string;
|
fips?: string;
|
||||||
title: string;
|
title: string;
|
||||||
house: string;
|
house?: string;
|
||||||
unit?: string;
|
unit?: string;
|
||||||
countyId: string;
|
countyId?: string;
|
||||||
street: string;
|
street?: string;
|
||||||
location: string;
|
location?: string;
|
||||||
id: string;
|
id?: string;
|
||||||
state: string;
|
state: string;
|
||||||
apn: string;
|
apn?: string;
|
||||||
longitude: number;
|
longitude?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PropertyResponseDataMortgageAPI {
|
export interface PropertyResponseDataMortgageAPI {
|
||||||
|
|||||||
Reference in New Issue
Block a user