Skip to content

Commit 2a1c2a7

Browse files
authored
Merge pull request #272 from zigzagdev/feat/insert-result-mapping-into-page
feat: insert component into Result Page
2 parents d29c7e8 + 22502b6 commit 2a1c2a7

2 files changed

Lines changed: 55 additions & 30 deletions

File tree

Lines changed: 51 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
import { MapContainer, TileLayer, CircleMarker, Tooltip } from "react-leaflet";
1+
import { MapContainer, TileLayer, CircleMarker, Tooltip, useMap } from "react-leaflet";
22
import { useNavigate } from "react-router-dom";
33
import type { WorldHeritageVm } from "../../../../domain/types.ts";
44
import "leaflet/dist/leaflet.css";
5+
import { useEffect } from "react";
6+
import type { LatLngBoundsExpression } from "leaflet";
57

68
type Props = {
79
items: WorldHeritageVm[];
@@ -18,6 +20,23 @@ const getColor = (category: string): string => CATEGORY_COLOR[category] ?? "#636
1820
const isValidCoordinate = (lat: number | null, lng: number | null): lat is number =>
1921
lat !== null && lng !== null && lat !== 0 && lng !== 0;
2022

23+
function FitBounds({ items }: { items: WorldHeritageVm[] }) {
24+
const map = useMap();
25+
26+
useEffect(() => {
27+
if (items.length === 0) return;
28+
29+
const bounds: LatLngBoundsExpression = items.map((item) => [
30+
item.latitude as number,
31+
item.longitude as number,
32+
]);
33+
34+
map.fitBounds(bounds, { padding: [40, 40] });
35+
}, [items, map]);
36+
37+
return null;
38+
}
39+
2140
export function SearchResultMapComponent({ items }: Props) {
2241
const navigate = useNavigate();
2342

@@ -28,33 +47,36 @@ export function SearchResultMapComponent({ items }: Props) {
2847
}
2948

3049
return (
31-
<MapContainer
32-
center={[20, 0]}
33-
zoom={2}
34-
style={{ height: "360px", width: "100%" }}
35-
scrollWheelZoom={false}
36-
>
37-
<TileLayer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" />
38-
{validItems.map((item) => (
39-
<CircleMarker
40-
key={item.id}
41-
center={[item.latitude as number, item.longitude as number]}
42-
radius={7}
43-
pathOptions={{
44-
color: getColor(item.category),
45-
fillColor: getColor(item.category),
46-
fillOpacity: 0.8,
47-
}}
48-
eventHandlers={{
49-
click: () => navigate(`/heritages/${item.id}`),
50-
}}
51-
>
52-
<Tooltip>
53-
<div className="text-xs font-semibold">{item.name}</div>
54-
<div className="text-xs text-zinc-500">{item.category}</div>
55-
</Tooltip>
56-
</CircleMarker>
57-
))}
58-
</MapContainer>
50+
<div className={"my-8"}>
51+
<MapContainer
52+
center={[20, 0]}
53+
zoom={2}
54+
style={{ height: "360px", width: "100%" }}
55+
scrollWheelZoom={false}
56+
>
57+
<TileLayer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" />
58+
<FitBounds items={validItems} />
59+
{validItems.map((item) => (
60+
<CircleMarker
61+
key={item.id}
62+
center={[item.latitude as number, item.longitude as number]}
63+
radius={7}
64+
pathOptions={{
65+
color: getColor(item.category),
66+
fillColor: getColor(item.category),
67+
fillOpacity: 0.8,
68+
}}
69+
eventHandlers={{
70+
click: () => navigate(`/heritages/${item.id}`),
71+
}}
72+
>
73+
<Tooltip>
74+
<div className="text-xs font-semibold">{item.name}</div>
75+
<div className="text-xs text-zinc-500">{item.category}</div>
76+
</Tooltip>
77+
</CircleMarker>
78+
))}
79+
</MapContainer>
80+
</div>
5981
);
6082
}

client/src/app/features/search/components/SearchResultsPage.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type { WorldHeritageVm } from "../../../../domain/types";
33
import { HeritageCard } from "@features/top/cards/HeritageCard";
44
import { Pagination } from "@features/top/components/Pagination.tsx";
55
import { BreadcrumbList } from "@shared/components/BreadcrumbList.tsx";
6+
import { SearchResultMapComponent } from "@features/search/components/SearchResultMapComponent.tsx";
67

78
type SearchResultsPagination = {
89
current_page: number;
@@ -13,7 +14,7 @@ type SearchResultsPagination = {
1314

1415
export type SearchResultsPageProps = {
1516
header?: ReactNode;
16-
items: ReadonlyArray<WorldHeritageVm>;
17+
items: WorldHeritageVm[];
1718
pagination: SearchResultsPagination | null;
1819
rangeText: string;
1920
onClickItem?: (id: number) => void;
@@ -109,6 +110,8 @@ export default function SearchResultsPage({
109110
<div className="pt-8">
110111
<BreadcrumbList />
111112

113+
<SearchResultMapComponent items={items} />
114+
112115
{items.length === 0 ? (
113116
<div className="py-20 text-center">
114117
<p className="text-sm text-zinc-600">No sites found.</p>

0 commit comments

Comments
 (0)