turash/bugulma/frontend/components/map/HistoricalMarkers.tsx
Damir Mukimov 6347f42e20
Consolidate repositories: Remove nested frontend .git and merge into main repository
- Remove nested git repository from bugulma/frontend/.git
- Add all frontend files to main repository tracking
- Convert from separate frontend/backend repos to unified monorepo
- Preserve all frontend code and development history as tracked files
- Eliminate nested repository complexity for simpler development workflow

This creates a proper monorepo structure with frontend and backend
coexisting in the same repository for easier development and deployment.
2025-11-25 06:02:57 +01:00

94 lines
2.5 KiB
TypeScript

import { LatLngTuple } from 'leaflet';
import React, { useCallback } from 'react';
import { Marker, Popup } from 'react-leaflet';
import { useMapActions } from '@/contexts/MapContexts.tsx';
import { HistoricalLandmark } from '@/types.ts';
import { getCachedHistoricalIcon } from '@/utils/map/iconCache.ts';
interface HistoricalMarkersProps {
landmarks: HistoricalLandmark[];
selectedLandmark: HistoricalLandmark | null;
hoveredLandmarkId: string | null;
}
/**
* Individual historical marker component memoized to prevent unnecessary re-renders
*/
const HistoricalMarker = React.memo<{
landmark: HistoricalLandmark;
isSelected: boolean;
isHovered: boolean;
onSelect: (landmark: HistoricalLandmark) => void;
onHover: (landmarkId: string | null) => void;
}>(({ landmark, isSelected, isHovered, onSelect, onHover }) => {
const position: LatLngTuple = [landmark.location.lat, landmark.location.lng];
const icon = getCachedHistoricalIcon(landmark.id, landmark, isSelected, isHovered);
const handleClick = useCallback(() => {
onSelect(landmark);
}, [landmark, onSelect]);
const handleMouseOver = useCallback(() => {
onHover(landmark.id);
}, [landmark.id, onHover]);
const handleMouseOut = useCallback(() => {
onHover(null);
}, [onHover]);
if (!landmark.location) return null;
return (
<Marker
position={position}
icon={icon}
eventHandlers={{
click: handleClick,
mouseover: handleMouseOver,
mouseout: handleMouseOut,
}}
>
<Popup>
<div>
<h3 className="text-base font-semibold">{landmark.name}</h3>
<p className="text-sm text-muted-foreground">{landmark.period}</p>
</div>
</Popup>
</Marker>
);
});
HistoricalMarker.displayName = 'HistoricalMarker';
const HistoricalMarkers: React.FC<HistoricalMarkersProps> = ({
landmarks,
selectedLandmark,
hoveredLandmarkId,
}) => {
const { handleSelectLandmark, setHoveredLandmarkId } = useMapActions();
return (
<>
{landmarks.map((landmark) => {
if (!landmark.location) return null;
const isSelected = selectedLandmark?.id === landmark.id;
const isHovered = hoveredLandmarkId === landmark.id;
return (
<HistoricalMarker
key={landmark.id}
landmark={landmark}
isSelected={isSelected}
isHovered={isHovered}
onSelect={handleSelectLandmark}
onHover={setHoveredLandmarkId}
/>
);
})}
</>
);
};
export default React.memo(HistoricalMarkers);