Enhanced map with search, auto-redirect to searched locations, and interactive property markers

This commit is contained in:
2026-01-07 23:16:21 +05:30
parent 8c45659363
commit 4ac0bb0b41

View File

@@ -10,6 +10,8 @@ import {
Dimensions,
Animated,
ActivityIndicator,
TextInput,
TouchableOpacity,
} from 'react-native';
import MapView from 'react-native-map-clustering';
@@ -18,7 +20,7 @@ import Geolocation from '@react-native-community/geolocation';
const { width } = Dimensions.get('window');
/* ---------------- DEFAULT REGION (MUST EXIST) ---------------- */
/* ---------------- DEFAULT REGION ---------------- */
const DEFAULT_REGION: Region = {
latitude: 25.48131,
@@ -61,14 +63,15 @@ const PriceMarker = ({ item, onPress, selected }: any) => {
/* ---------------- MAIN SCREEN ---------------- */
const MapScreen: React.FC = () => {
const MapScreen = () => {
const mapRef = useRef<MapView>(null);
const [region, setRegion] = useState<Region>(DEFAULT_REGION);
const [mapType, setMapType] = useState<MapType>('standard');
const [properties, setProperties] = useState<any[]>([]);
const [selectedItem, setSelectedItem] = useState<any>(null);
const [loading, setLoading] = useState(true);
const [loading, setLoading] = useState(false);
const [searchText, setSearchText] = useState('');
const popupAnim = useRef(new Animated.Value(0)).current;
@@ -76,7 +79,6 @@ const MapScreen: React.FC = () => {
useEffect(() => {
requestLocation();
fetchProperties();
}, []);
useEffect(() => {
@@ -112,11 +114,14 @@ const MapScreen: React.FC = () => {
});
};
/* ---------------- API CALL ---------------- */
/* ---------------- SEARCH API ---------------- */
const fetchProperties = async (locationName: string) => {
if (!locationName) return;
const fetchProperties = async () => {
try {
setLoading(true);
setSelectedItem(null);
const response = await fetch(
'http://64.227.108.180:5000/property-search',
@@ -124,7 +129,7 @@ const MapScreen: React.FC = () => {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
location: 'Teliarganj',
location: locationName,
radius: 500,
}),
}
@@ -132,18 +137,23 @@ const MapScreen: React.FC = () => {
const json = await response.json();
if (json?.success && json?.location?.coordinates) {
setProperties(json.properties || []);
const apiRegion = {
if (
json?.success &&
json?.location?.coordinates?.lat &&
json?.location?.coordinates?.lng
) {
const newRegion = {
latitude: json.location.coordinates.lat,
longitude: json.location.coordinates.lng,
latitudeDelta: 0.02,
longitudeDelta: 0.02,
};
setRegion(apiRegion);
mapRef.current?.animateToRegion(apiRegion, 1000);
setProperties(json.properties || []);
setRegion(newRegion);
// ✅ MOVE MAP TO SEARCH LOCATION
mapRef.current?.animateToRegion(newRegion, 1000);
}
} catch (error) {
console.log('API Error:', error);
@@ -161,10 +171,29 @@ const MapScreen: React.FC = () => {
return (
<View style={styles.container}>
{/* -------- SEARCH BAR -------- */}
<View style={styles.searchContainer}>
<TextInput
value={searchText}
onChangeText={setSearchText}
placeholder="Search area, locality..."
style={styles.searchInput}
returnKeyType="search"
onSubmitEditing={() => fetchProperties(searchText)}
/>
<TouchableOpacity
style={styles.searchButton}
onPress={() => fetchProperties(searchText)}
>
<Text style={styles.searchText}>Search</Text>
</TouchableOpacity>
</View>
{/* -------- MAP -------- */}
<MapView
ref={mapRef}
style={StyleSheet.absoluteFillObject}
region={region} // ✅ REQUIRED
region={region}
onRegionChangeComplete={(r) => {
if (!r?.longitudeDelta) return;
setRegion(r);
@@ -193,7 +222,7 @@ const MapScreen: React.FC = () => {
</View>
)}
{/* -------- ZILLOW STYLE POPUP -------- */}
{/* -------- BOTTOM POPUP -------- */}
{selectedItem && (
<Animated.View
style={[
@@ -237,6 +266,33 @@ const MapScreen: React.FC = () => {
const styles = StyleSheet.create({
container: { flex: 1 },
searchContainer: {
position: 'absolute',
top: 40,
left: 16,
right: 16,
zIndex: 10,
flexDirection: 'row',
backgroundColor: '#fff',
borderRadius: 8,
elevation: 6,
},
searchInput: {
flex: 1,
padding: 12,
},
searchButton: {
paddingHorizontal: 16,
justifyContent: 'center',
backgroundColor: '#8B0000',
borderTopRightRadius: 8,
borderBottomRightRadius: 8,
},
searchText: {
color: '#fff',
fontWeight: '600',
},
pin: {
backgroundColor: '#8B0000',
paddingHorizontal: 12,