Skip to content

Commit

Permalink
done map
Browse files Browse the repository at this point in the history
  • Loading branch information
mgmman committed Oct 31, 2024
1 parent 981a751 commit fa6da5c
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 17 deletions.
23 changes: 19 additions & 4 deletions src/Pages/main-page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ import { OffersList } from '../components/offer/offers-list.tsx';
import { Layout } from '../components/layout.tsx';
import { Helmet } from 'react-helmet-async';
import { Nullable } from 'vitest';
import { Map } from '../components/map/map.tsx';

interface MainPageProps {
offers: Offer[];
}

export function MainPage({ offers }: MainPageProps): React.JSX.Element {
const [activeOfferId, setActiveOfferId] = useState<Nullable<string>>('');
const [activeOffer, setActiveOffer] = useState<Nullable<Offer>>(null);
return (
<Layout showFooter>
<main className="page__main page__main--index">
Expand Down Expand Up @@ -87,13 +88,27 @@ export function MainPage({ offers }: MainPageProps): React.JSX.Element {
</form>
<OffersList
offers={offers}
onActiveOfferChange={(offerId: Nullable<string>) =>
setActiveOfferId(offerId)
onActiveOfferChange={(offer: Nullable<Offer>) =>
setActiveOffer(offer)
}

Check failure on line 93 in src/Pages/main-page.tsx

View workflow job for this annotation

GitHub Actions / Check

Unexpected newline before '}'
/>
</section>
<div className="cities__right-section">
<section className="cities__map map"></section>
<Map
city={offers[0].city}
points={offers.map((x) => ({
location: x.location,
id: x.id,
}))}
selectedPoint={
activeOffer
? {
location: activeOffer?.location,

Check failure on line 106 in src/Pages/main-page.tsx

View workflow job for this annotation

GitHub Actions / Check

Expected indentation of 22 spaces but found 24
id: activeOffer?.id,

Check failure on line 107 in src/Pages/main-page.tsx

View workflow job for this annotation

GitHub Actions / Check

Expected indentation of 22 spaces but found 24
}

Check failure on line 108 in src/Pages/main-page.tsx

View workflow job for this annotation

GitHub Actions / Check

Expected indentation of 20 spaces but found 22
: undefined
}
/>
</div>
</div>
</div>
Expand Down
57 changes: 57 additions & 0 deletions src/components/map/map.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { useRef, useEffect } from 'react';
import { Icon, Marker, layerGroup } from 'leaflet';
import 'leaflet/dist/leaflet.css';
import { useMap } from './use-map.ts';
import { City } from '../../dataTypes/city.ts';
import { Point } from '../../dataTypes/point.ts';

interface MapProps {
city: City;
points: Point[];
selectedPoint: Point | undefined;
}

const defaultCustomIcon = new Icon({
iconUrl: 'public/img/pin.svg',
iconSize: [40, 40],
iconAnchor: [20, 40],
});

const currentCustomIcon = new Icon({
iconUrl: 'public/img/pin-active.svg',
iconSize: [40, 40],
iconAnchor: [20, 40],
});

export function Map(props: MapProps): JSX.Element {
const { city, points, selectedPoint } = props;

const mapRef = useRef(null);
const map = useMap(mapRef, city);

useEffect(() => {
if (map) {
const markerLayer = layerGroup().addTo(map);
points.forEach((point) => {
const marker = new Marker({
lat: point.location.latitude,
lng: point.location.longitude,
});

marker
.setIcon(
selectedPoint !== undefined && point.id === selectedPoint.id
? currentCustomIcon
: defaultCustomIcon,
)
.addTo(markerLayer);
});

return () => {
map.removeLayer(markerLayer);
};
}
}, [map, points, selectedPoint]);

return <section className="cities__map map" ref={mapRef}></section>;
}
38 changes: 38 additions & 0 deletions src/components/map/use-map.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { useEffect, useState, MutableRefObject, useRef } from 'react';
import { Map, TileLayer } from 'leaflet';
import { City } from '../../dataTypes/city.ts';

export function useMap(
mapRef: MutableRefObject<HTMLElement | null>,
city: City,
): Map | null {
const [map, setMap] = useState<Map | null>(null);
const isRenderedRef = useRef<boolean>(false);

useEffect(() => {
if (mapRef.current !== null && !isRenderedRef.current) {
const instance = new Map(mapRef.current, {
center: {
lat: city.location.latitude,
lng: city.location.longitude,
},
zoom: 10,
});

const layer = new TileLayer(
'https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png',
{
attribution:
'&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors &copy; <a href="https://carto.com/attributions">CARTO</a>',
},
);

instance.addLayer(layer);

setMap(instance);
isRenderedRef.current = true;
}
}, [mapRef, city]);

return map;
}
8 changes: 4 additions & 4 deletions src/components/offer/offers-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ import { Nullable } from 'vitest';

interface OffersListProps {
offers: Offer[];
onActiveOfferChange?: (offerId: Nullable<string>) => void;
onActiveOfferChange?: (offer: Nullable<Offer>) => void;
}

export function OffersList({
offers,
onActiveOfferChange,
}: OffersListProps): React.JSX.Element {
const handleActiveOfferChange = (id: Nullable<string>): void => {
onActiveOfferChange?.(id);
const handleActiveOfferChange = (offer: Nullable<Offer>): void => {
onActiveOfferChange?.(offer);
};
return (
<div className="cities__places-list places__list tabs__content">
Expand All @@ -25,7 +25,7 @@ export function OffersList({
type={offer.type}
image={offer.previewImage}
title={offer.title}
onMouseEnter={() => handleActiveOfferChange(offer.id)}
onMouseEnter={() => handleActiveOfferChange(offer)}
onMouseLeave={() => handleActiveOfferChange(null)}
isFavorite={offer.isFavorite}
isPremium={offer.isPremium}
Expand Down
6 changes: 6 additions & 0 deletions src/dataTypes/point.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { Location } from './location.ts';

export type Point = {
location: Location;
id: string;
};
18 changes: 9 additions & 9 deletions src/mocks/offers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ export const offerMocks: Offer[] = [
},
},
location: {
latitude: 52.35514938496378,
longitude: 4.673877537499948,
latitude: 52.3909553943508,
longitude: 4.85309666406198,
zoom: 8,
},
isFavorite: false,
Expand All @@ -39,8 +39,8 @@ export const offerMocks: Offer[] = [
},
},
location: {
latitude: 52.35514938496378,
longitude: 4.673877537499948,
latitude: 52.3609553943508,
longitude: 4.85309666406198,
zoom: 8,
},
isFavorite: false,
Expand All @@ -62,8 +62,8 @@ export const offerMocks: Offer[] = [
},
},
location: {
latitude: 52.35514938496378,
longitude: 4.673877537499948,
latitude: 52.3909553943508,
longitude: 4.929309666406198,
zoom: 8,
},
isFavorite: true,
Expand All @@ -77,16 +77,16 @@ export const offerMocks: Offer[] = [
type: RoomType.Apartment,
price: 88,
city: {
name: 'Cologne',
name: 'Amsterdam',
location: {
latitude: 52.35514938496378,
longitude: 4.673877537499948,
zoom: 8,
},
},
location: {
latitude: 52.35514938496378,
longitude: 4.673877537499948,
latitude: 52.3809553943508,
longitude: 4.939309666406198,
zoom: 8,
},
isFavorite: true,
Expand Down

0 comments on commit fa6da5c

Please sign in to comment.