add: order tracking page
This commit is contained in:
@@ -20,6 +20,7 @@ interface CustomMapProps {
|
||||
onPositionSelect?: (position: [number, number]) => void;
|
||||
onZoomChange?: (zoom: number) => void;
|
||||
onClick?: (event: L.LeafletMouseEvent) => void;
|
||||
markerActive?: boolean
|
||||
}
|
||||
|
||||
// Component to handle map events and position updates
|
||||
@@ -27,7 +28,7 @@ function MapEvents({
|
||||
onZoomChange,
|
||||
onClick,
|
||||
center,
|
||||
setMapRef
|
||||
setMapRef,
|
||||
}: Pick<CustomMapProps, 'onZoomChange' | 'onClick'> & {
|
||||
center: [number, number];
|
||||
setMapRef: (map: L.Map) => void;
|
||||
@@ -84,6 +85,7 @@ const CustomMap: React.FC<CustomMapProps> = ({
|
||||
onPositionSelect,
|
||||
onZoomChange,
|
||||
onClick,
|
||||
markerActive = true
|
||||
}) => {
|
||||
const [selectedPosition, setSelectedPosition] = useState<[number, number] | null>(null);
|
||||
const [mapInstance, setMapInstance] = useState<L.Map | null>(null);
|
||||
@@ -120,7 +122,9 @@ const CustomMap: React.FC<CustomMapProps> = ({
|
||||
|
||||
const handleMapClick = (e: L.LeafletMouseEvent) => {
|
||||
const newPosition: [number, number] = [e.latlng.lat, e.latlng.lng];
|
||||
setSelectedPosition(newPosition);
|
||||
if (markerActive) {
|
||||
setSelectedPosition(newPosition);
|
||||
}
|
||||
onPositionSelect?.(newPosition);
|
||||
onClick?.(e);
|
||||
};
|
||||
@@ -146,7 +150,7 @@ const CustomMap: React.FC<CustomMapProps> = ({
|
||||
// Iran's bounding box coordinates (roughly)
|
||||
const viewbox = '44.0,25.0,63.0,40.0'; // [min lon, min lat, max lon, max lat]
|
||||
const response = await fetch(
|
||||
`https://nominatim.openstreetmap.org/search?` +
|
||||
`https://nominatim.openstreetmap.org/search?` +
|
||||
`format=json&` +
|
||||
`q=${encodeURIComponent(value)}&` +
|
||||
`countrycodes=ir&` + // Prioritize Iran
|
||||
@@ -155,11 +159,11 @@ const CustomMap: React.FC<CustomMapProps> = ({
|
||||
`limit=10&` + // Limit results to 10
|
||||
`namedetails=1&` + // Get native names
|
||||
`accept-language=fa` // Request Persian results
|
||||
, {
|
||||
headers: {
|
||||
'Accept-Language': 'fa,en;q=0.9' // Prefer Persian, fallback to English
|
||||
}
|
||||
});
|
||||
, {
|
||||
headers: {
|
||||
'Accept-Language': 'fa,en;q=0.9' // Prefer Persian, fallback to English
|
||||
}
|
||||
});
|
||||
interface SearchResult {
|
||||
place_id: string;
|
||||
display_name: string;
|
||||
@@ -179,8 +183,8 @@ const CustomMap: React.FC<CustomMapProps> = ({
|
||||
title: /* item.namedetails?.['name:fa'] ||
|
||||
item.namedetails?.name ||
|
||||
item.namedetails?.['alt_name:fa'] ||
|
||||
item.namedetails?.alt_name || */
|
||||
item.display_name,
|
||||
item.namedetails?.alt_name || */
|
||||
item.display_name,
|
||||
position: [parseFloat(item.lat), parseFloat(item.lon)] as [number, number]
|
||||
})));
|
||||
} catch (error) {
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import { motion } from 'framer-motion'
|
||||
import React from 'react'
|
||||
|
||||
type Props = {
|
||||
percentage: number | string
|
||||
}
|
||||
|
||||
function AnimatedBar({ percentage }: Props) {
|
||||
return (
|
||||
<span className='relative w-full h-1 place-self-center bg-border rounded-full'>
|
||||
<motion.span
|
||||
animate={{ width: [0, `${percentage}%`] }}
|
||||
className='absolute top-0 left-0 w-[10%] h-1 bg-primary rounded-full'
|
||||
>
|
||||
</motion.span>
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
export default AnimatedBar
|
||||
Reference in New Issue
Block a user