وڪيپيڊيا:مشق پٽي
| وڪيپيڊيا جي هن ريتخاني واري صفحي تي ڀليڪار۔ ريتخانا اهي صفحا آهن جتي وڪيپيڊيا جي صفحن ۾ ترميم ڪرڻ جي عمل سان تجربا ڪرڻ لاءِ جاءِ مهيا ڪئي ويندي آهي. هن ريتخاني کي ترميم ڪرڻ لاءِ هتي ڪلڪ ڪريو يا هن صفحي جي مٿان موجود "ترميم" ٽيب تي ڪلڪ ڪريو۔ پوءِ پنهنجون تبديليون ڪريو ۽ مڪمل ٿيڻ تي "صفحو سانڍيو" بٽڻ تي ڪلڪ ڪريو۔ توهان "پيش نگاه" تي ڪلڪ ڪري محفوظ ڪرڻ کان اڳ ڏيک ڏسي سگهو ٿا. جيڪڏهن توهان صاف ريتخاني ۾ ترميم شروع ڪرڻ لاءِ هتي ڪلڪ ڪريو. هڪ خودڪار عمل هن صفحي کي باقاعدي صاف ڪندو رهي ٿو، ۽ ڪيترائي ٻيا استعمال ڪندڙ پڻ هن ريتخاني کي پنهنجن تجربن لاءِ استعمال ڪندا آهن، تنهنڪري هتي رکيل ڪا به شيءِ مستقل طور تي محفوظ نه رهندي۔ وزيوئل ايڊيٽر کي آزمائڻ لاءِ، واپرائيندڙ:ريتخانو يا mw:VisualEditor:Test تي وڃو۔ مهرباني ڪري ڪاپي رائيٽ ٿيل، توهين آميز يا هتڪ انگيز مواد ريتخاني ۾ شامل نه ڪريو۔ جيڪڏهن توهان رجسٽرڊ آهيو ۽ لاگ اِن آهيو، ته توهان پنهنجو ذاتي ريتخانو هتي ڳولي يا ٺاهي سگهو ٿا۔ مستقبل ۾ پنهنجي ذاتي ريتخاني تائين آساني سان پهچڻ لاءِ، صفحي جي بلڪل مٿان (توهان جي نالي جي ڀرسان) موجود "ريتخانو" لنڪ تي ڪلڪ ڪريو۔
| وڪيپيڊيا:مشق_پٽي |
مڪمل 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 تي ختم ٿئي ٿو)، تنهنڪري مون ترجمو ۽ درستگي صرف موجود حصي تائين ڪئي آهي.