مواد ڏانھن هلو

وڪيپيڊيا:مشق پٽي

کليل ڄاڻ چيڪلي، وڪيپيڊيا مان

مڪمل ZimMap.jsx جزو


// React، Leaflet ۽ UI icons درآمد ڪيا ويا آهن import React, { useState, useEffect, useRef, useCallback } from 'react'; import {

 MapContainer,
 TileLayer,
 Marker,
 Popup,
 Circle,
 LayersControl,
 ZoomControl,
 useMapEvents,
 useMap

} from 'react-leaflet'; import L from 'leaflet'; import 'leaflet/dist/leaflet.css'; import { Search, Filter, Navigation, MapPin } from 'lucide-react';

// ڊفالٽ مارڪرن لاءِ درستگي delete L.Icon.Default.prototype._getIconUrl; L.Icon.Default.mergeOptions({

 iconRetinaUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-icon-2x.png',
 iconUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-icon.png',
 shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-shadow.png',

});

// نقشي جي واقعن لاءِ ڪسٽم hook function MapEvents({ onMapClick, onMoveEnd }) {

 useMapEvents({
   click: onMapClick,
   moveend: onMoveEnd,
 });
 return null;

}

// جڳھ جي سڃاڻپ لاءِ ڪسٽم hook function LocationMarker({ userLocation, setUserLocation }) {

 const map = useMap();
 const [position, setPosition] = useState(null);
 const markerRef = useRef(null);
 useEffect(() => {
   map.locate({ setView: true, maxZoom: 16 });
 }, [map]);
 useMapEvents({
   locationfound(e) {
     setPosition(e.latlng);
     setUserLocation(e.latlng);
     map.flyTo(e.latlng, map.getZoom());
   },
   locationerror(e) {
     console.error('Location error:', e.message);
     // جيڪڏهن جڳھ موجود نه هجي ته ڊفالٽ طور Harare
     const hararePosition = L.latLng(-17.825166, 31.03351);
     setPosition(hararePosition);
     setUserLocation(hararePosition);
   },
 });
 return position === null ? null : (
   <Marker
     position={position}
     ref={markerRef}
     icon={L.divIcon({
       html: `
             <svg class="w-6 h-6 text-white" fill="currentColor" viewBox="0 0 20 20">
               <path fill-rule="evenodd" d="M5.05 4.05a7 7 0 119.9 9.9L10 18.9l-4.95-4.95a7 7 0 010-9.9zM10 11a2 2 0 100-4 2 2 0 000 4z" clip-rule="evenodd" />
             </svg>
       `,
       className: 'user-location-marker',
       iconSize: [40, 40],
       iconAnchor: [20, 40]
     })}
   >
     <Popup>توهان هتي آهيو</Popup>
   </Marker>
 );

}

// ڪسٽم marker جزو const CustomMarker = ({ listing, onClick }) => {

 const markerRef = useRef(null);
 const icon = L.divIcon({
   html: `
         <svg class="w-5 h-5 text-white" fill="currentColor" viewBox="0 0 20 20">
           ${listing.category === 'Cars' ? '<path d="M8 16.5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zM15 16.5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0z" /><path d="M3 4a1 1 0 00-1 1v10a1 1 0 001 1h1.05a2.5 2.5 0 014.9 0H10a1 1 0 001-1v-1h4v1a1 1 0 001 1h1.05a2.5 2.5 0 014.9 0H21a1 1 0 001-1V5a1 1 0 00-1-1H3zM14 7h4v3h-4V7z" />' :
           listing.category === 'Property' ? '<path d="M10.707 2.293a1 1 0 00-1.414 0l-7 7a1 1 0 001.414 1.414L4 10.414V17a1 1 0 001 1h2a1 1 0 001-1v-2a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 001 1h2a1 1 0 001-1v-6.586l.293.293a1 1 0 001.414-1.414l-7-7z" />' :
           '<path fill-rule="evenodd" d="M5.05 4.05a7 7 0 119.9 9.9L10 18.9l-4.95-4.95a7 7 0 010-9.9zM10 11a2 2 0 100-4 2 2 0 000 4z" clip-rule="evenodd" />'}
         </svg>
       ${listing.isBoosted ? `
           <svg class="w-3 h-3 text-white" fill="currentColor" viewBox="0 0 20 20">
             <path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" />
           </svg>
       ` : }
   `,
   className: 'custom-listing-marker',
   iconSize: [40, 40],
   iconAnchor: [20, 40]
 });
 return (
   <Marker
     position={[listing.location.coordinates[1], listing.location.coordinates[0]]}
     icon={icon}
     ref={markerRef}
     eventHandlers={{
       click: () => onClick(listing),
       mouseover: () => markerRef.current.openPopup(),
       mouseout: () => markerRef.current.closePopup()
     }}
   >
     <Popup>

{listing.title}

{listing.category}

${listing.price.toLocaleString()}

{listing.location.city}

         <button 
            onClick={() => onClick(listing)}
           className="mt-3 w-full py-2 bg-gradient-to-r from-purple-600 to-purple-700 text-white rounded-lg"
         >
           تفصيل ڏسو
         </button>
     </Popup>
   </Marker>
 );

};

// مکيه ZimMap جزو const ZimMap = ({ listings = [], onListingClick }) => {

 const [userLocation, setUserLocation] = useState(null);
 const [radius, setRadius] = useState(10000); // ڊفالٽ 10 ڪلوميٽر
 const [filteredListings, setFilteredListings] = useState([]);
 const [mapCenter, setMapCenter] = useState([-17.825166, 31.03351]); // Harare
 const [isLocating, setIsLocating] = useState(false);
 const mapRef = useRef(null);
 // زمبابوي جون حدون
 const zimBounds = L.latLngBounds(
   L.latLng(-22.0, 25.0),
   L.latLng(-15.0, 34.0)
 );
 // ٻن coordinates جي وچ ۾ فاصلو ڳڻڻ
 const calculateDistance = (lat1, lon1, lat2, lon2) => {
   const R = 6371000;
   const φ1 = lat1 * Math.PI / 180;
   const φ2 = lat2 * Math.PI / 180;
   const Δφ = (lat2 - lat1) * Math.PI / 180;
   const Δλ = (lon2 - lon1) * Math.PI / 180;
   const a = Math.sin(Δφ / 2) * Math.sin(Δφ / 2) +
             Math.cos(φ1) * Math.cos(φ2) *
             Math.sin(Δλ / 2) * Math.sin(Δλ / 2);
   return R * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
 };
 // radius موجب listings فلٽر ڪرڻ
 useEffect(() => {
   if (!userLocation || listings.length === 0) {
     setFilteredListings(listings);
     return;
   }
   const filtered = listings.filter(listing => {
     const distance = calculateDistance(
       userLocation.lat,
       userLocation.lng,
       listing.location.coordinates[1],
       listing.location.coordinates[0]
     );
     return distance <= radius;
   });
   setFilteredListings(filtered);
 }, [listings, userLocation, radius]);
 const handleRadiusChange = (newRadius) => {
   setRadius(newRadius);
 };
 const locateUser = () => {
   setIsLocating(true);
   if (mapRef.current) {
     mapRef.current.locate({ setView: true, maxZoom: 14 });
   }
   setTimeout(() => setIsLocating(false), 1000);
 };
 const resetView = () => {
   if (mapRef.current) {
     mapRef.current.flyTo(mapCenter, 12);
   }
 };
 return (
           <Filter className="w-5 h-5 text-purple-400" />

Radius Filter

             توهان کان فاصلو
             
               {(radius / 1000).toFixed(1)} ڪلوميٽر
             
           {[5000, 10000, 25000].map((r) => (
             <button key={r} onClick={() => handleRadiusChange(r)}>
               {r === 5000 ? '5 ڪلوميٽر' : r === 10000 ? '10 ڪلوميٽر' : '25 ڪلوميٽر'}
             </button>
           ))}
               {filteredListings.length} اشتهار ڏيکاريا پيا وڃن
               {(radius / 1000).toFixed(0)} ڪلوميٽر اندر
           <button onClick={locateUser} disabled={isLocating} title="منهنجي جڳھ ڳوليو">
             <Navigation className={`w-5 h-5 ${isLocating ? 'animate-spin' : }`} />
           </button>
           <button onClick={resetView} title="نقشو ٻيهر مرڪز تي آڻيو">
             <MapPin className="w-5 h-5" />
           </button>
     {/* هتي MapContainer، TileLayer، Markers ۽ Circle جو باقي ڪوڊ شامل ٿيندو */}
 );

};

export default ZimMap;

نوٽ: توهان جو آخري ڪوڊ اڌ ۾ ڪٽيل آهي (className="h-fu تي ختم ٿئي ٿو)، تنهنڪري مون ترجمو ۽ درستگي صرف موجود حصي تائين ڪئي آهي.