Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Map feature #40

Open
wants to merge 18 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ ALGOLIA_INDEX_NAME=esika
ALGOLIA_APP_ID=6208GZDBB0
ALGOLIA_ADMIN_KEY=46b4e5cfcc4f05a43293f9345744414e
ALGOLIA_SEARCH_KEY=e4251a0982ea2328fbe0f223e9e89740
MAPBOX_ACCESS_TOKEN=pk.eyJ1Ijoiam9uYXRoemloaW5kdWxhIiwiYSI6ImNreW4wZXBwbTNsd2EydW4wamJ1aTdidHgifQ.zVkgrvMk02fZiJFaV_jkDQ
MAPBOX_CUSTOM_STYLE_URL=mapbox://styles/jonathzihindula/ckynaitbt8tyh14qpylblnbwp
27,377 changes: 27,361 additions & 16 deletions package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-image-file-resizer": "^0.4.7",
"react-map-gl": "^6.1.18",
"react-phone-input-2": "^2.14.0",
"react-router": "^5.2.0",
"react-router-dom": "^5.2.0",
Expand Down
27 changes: 27 additions & 0 deletions src/app/modules/__modules__/MapBox/MapBoxMarker/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { ReactElement } from 'react';
import { Marker } from 'react-map-gl';
import LocationVector from 'app/modules/__modules__/_vectors/LocationVector';

interface IMarkerProps {
latitude: number;
longitude: number;
showPopUp: () => void;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you change this prop name to onClick as it reflects that action that has to be performed?

}

const MapBoxMarker = ({
latitude,
longitude,
showPopUp,
}: IMarkerProps): ReactElement => {
return (
<Marker
latitude={latitude}
longitude={longitude}
onClick={showPopUp}
>
<LocationVector className="text-red-600 h-10 w-10 animate-bounce cursor-pointer" />
</Marker>
);
};

export default MapBoxMarker;
35 changes: 35 additions & 0 deletions src/app/modules/__modules__/MapBox/MapBoxPopUp/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { ReactElement } from 'react';
import { Popup } from 'react-map-gl';
import { IProperty } from 'app/modules/@Types';

interface IPopUpProps {
property: IProperty | null;
latitude: number;
longitude: number;
closePopUp: () => void;
}

const MapBoxPopUp = ({
property,
latitude,
longitude,
closePopUp,
}: IPopUpProps): ReactElement => {
return (
<Popup
key={property?.propertyId}
latitude={latitude}
longitude={longitude}
onClose={closePopUp}
>
<div>
<p className="w-40 font-extrabold">{property?.title}</p>
<p className="overflow-hidden break-words w-40 text-xs">
{property?.description}
</p>
</div>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need to wrap the children inside the div as you have a parent component Popup.

You can remove that div or just make use of React Fragment.

</Popup>
);
};

export default MapBoxPopUp;
87 changes: 87 additions & 0 deletions src/app/modules/__modules__/MapBox/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import ReactMapGL, { NavigationControl } from 'react-map-gl';
import { ReactElement, SetStateAction, useState } from 'react';
import keys from 'app/modules/utils/configs/keys';
import ShowWidget from 'app/modules/__modules__/ShowWidget';
import { IProperty } from 'app/modules/@Types';
import MapBoxMarker from './MapBoxMarker/index';
import MapBoxPopUp from './MapBoxPopUp/index';
import CloseVector from '../_vectors/closeVector';

interface ICoordinates {
longitude: number;
latitude: number;
zoom: number;
}

interface Props {
property: IProperty | null;
isLoading: boolean;
closeMap: () => void;
}

const MapBox = ({
property,
isLoading,
closeMap,
}: Props): ReactElement => {
const [lng] = useState(32.58252);
const [lat] = useState(0.347596);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's better to merge the two in one state.

const [displayPupUp, setDisplayPopUp] = useState(true);

const [viewport, setViewport] = useState<ICoordinates>({
longitude: lng,
latitude: lat,
zoom: 12,
});

const showPopUp = () => {
setDisplayPopUp(true);
};
const closePopUp = () => {
setDisplayPopUp(false);
};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you only create one function that toggles the popup?


return (
<div className="mt-4 mx-auto">
<ShowWidget
condition={!isLoading}
fallback={
<div className="w-full h-full mt-3 sm:mt-0 bg-gray-200 animate-pulse" />
}
>
<ReactMapGL
{...viewport}
mapStyle={keys.MAPBOX_CUSTOM_STYLE_URL}
mapboxApiAccessToken={keys.MAPBOX_ACCESS_TOKEN}
width="100%"
height="50vh"
onViewportChange={(
viewport: SetStateAction<ICoordinates>,
): void => {
setViewport(viewport);
}}
>
<NavigationControl className="right-4 top-4" />
<div onClick={closeMap} aria-hidden>
<CloseVector className="text-black bg-white shadow-xl rounded-lg mt-4 ml-4 cursor-pointer" />
</div>
<MapBoxMarker
latitude={lat}
longitude={lng}
showPopUp={showPopUp}
/>
{displayPupUp && (
<MapBoxPopUp
property={property}
latitude={lat}
longitude={lng}
closePopUp={closePopUp}
/>
)}
</ReactMapGL>
</ShowWidget>
</div>
);
};

export default MapBox;
42 changes: 42 additions & 0 deletions src/app/modules/__modules__/MapButton/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React, { ReactElement } from 'react';
import useResponsive from 'app/modules/Hooks/useResponsive';

interface IProps {
onClick?: (event?: React.MouseEvent<HTMLButtonElement>) => void;
}

const defaultProps: IProps = {
onClick: () => null,
};

const MapButton = ({ onClick }: IProps): ReactElement => {
const [isMobile] = useResponsive();
if (!isMobile) {
return (
<>
<button
type="button"
className="w-[80%] p-1 bg-brand-bold text-sm text-white rounded-lg px-3 py-2 mt-3 "
onClick={onClick}
>
Voir sur map
</button>
</>
);
}
return (
<>
<button
type="button"
className="w-full p-3 bg-brand-bold text-white rounded-lg md:mx-auto md:px-16 mt-4 "
onClick={onClick}
>
Voir sur map
</button>
</>
);
};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is nice but you don't need to create a component for this button as there are no extra kinds of stuff that you are handling.

There is also no need of making use of useResponsive hook.

You can handle responsiveness with just tailwind.


MapButton.defaultProps = defaultProps;

export default MapButton;
27 changes: 27 additions & 0 deletions src/app/modules/__modules__/_vectors/closeVector.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from 'react';
import {
defaultVectorProps,
classNameInterface,
} from 'app/modules/@Types';

const CloseVector = ({ className }: classNameInterface) => {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
className={className}
width="53.7"
height="53.7"
viewBox="0 0 53.7 53.7"
>
<path
opacity="1"
fill="%23666E6E"
d="M35.6 34.4L28 26.8l7.6-7.6c.2-.2.2-.5 0-.7l-.5-.5c-.2-.2-.5-.2-.7 0l-7.6 7.6-7.5-7.6c-.2-.2-.5-.2-.7 0l-.6.6c-.2.2-.2.5 0 .7l7.6 7.6-7.6 7.5c-.2.2-.2.5 0 .7l.5.5c.2.2.5.2.7 0l7.6-7.6 7.6 7.6c.2.2.5.2.7 0l.5-.5c.2-.2.2-.5 0-.7z"
/>
</svg>
);
};

CloseVector.defaultVectorProps = defaultVectorProps;

export default CloseVector;
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,27 @@ import ShowWidget from 'app/modules/__modules__/ShowWidget';
import { IAgent, IObject, IProperty } from 'app/modules/@Types';
import ProfileImage from 'app/modules/__modules__/ProfileImage';
import PropertySpecs from 'app/modules/__modules__/PropertySpecs';
import MapButton from '../../../__modules__/MapButton/index';

interface Props {
agent: IAgent | null;
property: IProperty | null;
loading: boolean;
isLoading: boolean;
openMap: () => void;
showMapButton: boolean;
}

const PropertyDetailsDesktop = ({
agent,
property,
isLoading,
loading,
openMap,
showMapButton,
}: Props) => {
return (
<div className="pt-8 pb-5 flex justify-between">
<div className="pt-8 pb-10 flex justify-between">
<div className="w-[65%] h-24 border-b pb-3 border-gray-300 flex justify-between">
<div className="block w-[80%]">
<ShowWidget
Expand Down Expand Up @@ -70,7 +75,7 @@ const PropertyDetailsDesktop = ({
</p>
</ShowWidget>
</div>
<div className="pt-2 flex justify-center items-center">
<div className="pt-2 flex flex-col justify-center items-center">
<ShowWidget
condition={!isLoading}
fallback={
Expand All @@ -83,6 +88,7 @@ const PropertyDetailsDesktop = ({
>
Contacter l&apos;agent
</button>
{showMapButton && <MapButton onClick={openMap} />}
</ShowWidget>
</div>
</div>
Expand Down
28 changes: 27 additions & 1 deletion src/app/modules/_noAuth/Property/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,22 @@ import useResponsive from 'app/modules/Hooks/useResponsive';
import SearchContainer from 'app/modules/__modules__/SearchContainer';
import Header from 'app/modules/__modules__/Header';
import { useSearch } from 'app/modules/Contexts/SearchContext';
import MapBox from 'app/modules/__modules__/MapBox';
import RelatedProperties from './RelatedProperties';
import PropertyCarousel from './PropertyCarousel';
import PropertyDetails from './PropertyDetails';
import PropertyAgent from './PropertyAgent';
import PropertyImages from './PropertyImages';
import PropertyDetailsDesktop from './PropertyDetailsDesktop';
import MapButton from '../../__modules__/MapButton/index';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can ignore /index


const PropertyContainer = () => {
const [property, setProperty] = useState<IProperty | null>(null);
const [isLoading, setIsLoading] = useState<boolean>(true);
const [agent, setAgent] = useState<IAgent | null>(null);
const [readMore, setReadMore] = useState(false);
const [openMap, setOpenMap] = useState(false);
const [showMapButton, setShowMapButtom] = useState(true);

const [isMobile] = useResponsive();

Expand Down Expand Up @@ -113,6 +117,16 @@ const PropertyContainer = () => {
setReadMore(!readMore);
};

const openMapBox = () => {
setOpenMap(true);
setShowMapButtom(false);
};

const closeMapBox = () => {
setOpenMap(false);
setShowMapButtom(true);
};

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make use of one toggle function here too.

return (
<div className="container mx-auto px-0 md:px-8 no-scrollbars">
{isMobile ? (
Expand All @@ -133,6 +147,15 @@ const PropertyContainer = () => {
/>
</>
)}
{openMap && (
<>
<MapBox
property={property}
isLoading={isLoading}
closeMap={closeMapBox}
/>
</>
)}

{isMobile ? (
<>
Expand All @@ -158,6 +181,8 @@ const PropertyContainer = () => {
isLoading={isLoading}
property={property}
agent={agent}
openMap={openMapBox}
showMapButton={showMapButton}
/>
)}

Expand Down Expand Up @@ -196,7 +221,7 @@ const PropertyContainer = () => {
</ShowWidget>
</div>
{isMobile && (
<div className="mx-4 my-5 md:container md:mx-auto md:px-56 flex justify-center items-center">
<div className="mx-4 my-5 md:container md:mx-auto md:px-56 flex flex-col justify-center items-center">
<ShowWidget
condition={!isLoading}
fallback={
Expand All @@ -209,6 +234,7 @@ const PropertyContainer = () => {
>
Contacter l&apos;agent
</button>
{showMapButton && <MapButton onClick={openMapBox} />}
</ShowWidget>
</div>
)}
Expand Down
7 changes: 7 additions & 0 deletions src/app/modules/utils/configs/keys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ type kType = {
ALGOLIA_API_KEY: valueType;
ALGOLIA_APP_ID: valueType;
JWT_SECRET_KEY: valueType;
MAPBOX_ACCESS_TOKEN: string;
MAPBOX_CUSTOM_STYLE_URL: valueType | string;
USER_ROLE_KEY: string;
AGENT_ROLE_KEY: string;
GUEST_ROLE_KEY: string;
Expand All @@ -22,6 +24,11 @@ const keys: kType = {
ALGOLIA_INDEX_NAME: process.env.ALGOLIA_INDEX_NAME,
JWT_SECRET_KEY: process.env.JWT_SECRET_KEY,
USER_ROLE_KEY: process.env.USER_ROLE_KEY || 'KF094msdkdE8RL',
MAPBOX_ACCESS_TOKEN:
'pk.eyJ1Ijoiam9uYXRoemloaW5kdWxhIiwiYSI6ImNreW4wZXBwbTNsd2EydW4wamJ1aTdidHgifQ.zVkgrvMk02fZiJFaV_jkDQ',
MAPBOX_CUSTOM_STYLE_URL:
process.env.MAPBOX_CUSTOM_STYLE_URL ||
'mapbox://styles/jonathzihindula/ckynaitbt8tyh14qpylblnbwp',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Read these keys from .env file.

AGENT_ROLE_KEY: 'oPer849zcvDJS',
GUEST_ROLE_KEY: 'EGsdg4ma48LT',
};
Expand Down