65 lines
2.6 KiB
TypeScript
65 lines
2.6 KiB
TypeScript
import { useMemo } from 'react'
|
|
import { createPortal } from 'react-dom'
|
|
import { MdOpenInNew } from 'react-icons/md'
|
|
import { buildGoogleMapsUrl, type MapProject } from '../data/mapProjects'
|
|
import { useLang } from '../i18n/lang'
|
|
import { MapViewport } from './MapViewport'
|
|
import { POPUP_PRIMARY_CLASS, ProjectPopupCard } from './ProjectPopupCard'
|
|
import { useMapLibre } from './useMapLibre'
|
|
import { useProjectMarkers } from './useProjectMarkers'
|
|
|
|
export type ProjectsMapSingleProps = {
|
|
/** همان پروژهی شیت — یا محل جایگزین ساختهشده با createPlaceholderProject */
|
|
location: MapProject
|
|
/** تصاویر پروژه — همان آرایهٔ صفحهٔ جزئیات (تصویر شاخص + گالری) */
|
|
images?: string[]
|
|
/** ارتفاع/فاصلهها از بیرون — مثل «h-80» */
|
|
className?: string
|
|
}
|
|
|
|
/**
|
|
* نمای «تکپروژه» — یک سنجاق دقیق روی مختصات همان پروژه و پاپآپی که فقط با
|
|
* کلیک کاربر باز میشود. تنها اکشن کارت، مشاهدهٔ آدرس پروژه در نشان است.
|
|
* جابهجایی نقشه به محدودهٔ همین پروژه بسته شده تا به بیرون نرود.
|
|
*/
|
|
export function ProjectsMapSingle({ location, images = [], className = '' }: ProjectsMapSingleProps) {
|
|
const { t } = useLang()
|
|
const projects = useMemo(() => [location], [location])
|
|
// بدون maxBounds — زوماوت آزاد تا دید کشوری (همرفتار با نقشهٔ صفحهٔ پروژهها)
|
|
const { containerRef, map, status, retry } = useMapLibre({
|
|
center: [location.lng, location.lat],
|
|
zoom: 15,
|
|
minZoom: 5,
|
|
})
|
|
const { popupHost, activeProject, closePopup } = useProjectMarkers(map, projects)
|
|
|
|
return (
|
|
<MapViewport
|
|
containerRef={containerRef}
|
|
map={map}
|
|
status={status}
|
|
onRetry={retry}
|
|
label={t('mapAria')}
|
|
className={className}
|
|
>
|
|
{popupHost &&
|
|
activeProject &&
|
|
createPortal(
|
|
<ProjectPopupCard project={activeProject} images={images} hideImageWhenEmpty onClose={closePopup}>
|
|
{/* منطق دکمهٔ آدرس دستنخورده است — تنها اکشن این کارت */}
|
|
<a
|
|
href={buildGoogleMapsUrl(activeProject)}
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
className={POPUP_PRIMARY_CLASS}
|
|
>
|
|
{t('viewAddress')}
|
|
<MdOpenInNew className="h-4 w-4" aria-hidden="true" />
|
|
</a>
|
|
</ProjectPopupCard>,
|
|
popupHost,
|
|
)}
|
|
</MapViewport>
|
|
)
|
|
}
|