From b803a67f067b1423350a59c2d221172e771d2aa1 Mon Sep 17 00:00:00 2001 From: mhossain2 Date: Wed, 29 May 2024 23:07:01 +0600 Subject: [PATCH 01/11] feat: added maps pin component --- components/shared/map/Pin.tsx | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 components/shared/map/Pin.tsx diff --git a/components/shared/map/Pin.tsx b/components/shared/map/Pin.tsx new file mode 100644 index 0000000..ec10acc --- /dev/null +++ b/components/shared/map/Pin.tsx @@ -0,0 +1,26 @@ +import { IListing } from "@/types"; +import Link from "next/link"; +import { Marker, Popup } from "react-leaflet"; + +interface PinProps { + item: IListing; +} + +function Pin({ item } : PinProps) { + return ( + + +
+ +
+ {item.title} + {item.roomCount} bedroom + ৳ {item.price}k +
+
+
+
+ ); +} + +export default Pin; From 1dd0c9aa75ee7d24de06de43a79bd4d2febd4be0 Mon Sep 17 00:00:00 2001 From: mhossain2 Date: Wed, 29 May 2024 23:07:26 +0600 Subject: [PATCH 02/11] chore: added lat long types in listing --- types/Listing.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/types/Listing.ts b/types/Listing.ts index e9dc966..90ec633 100644 --- a/types/Listing.ts +++ b/types/Listing.ts @@ -12,4 +12,6 @@ export interface IListing { price: number; location: string; isSaved: boolean; + latitude: number; + longitude: number; } From edcef242c1cdb17373e4a9495a9f8e95e147e019 Mon Sep 17 00:00:00 2001 From: mhossain2 Date: Wed, 29 May 2024 23:07:55 +0600 Subject: [PATCH 03/11] feat: added maps in single listing page --- components/shared/map/Map.tsx | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 components/shared/map/Map.tsx diff --git a/components/shared/map/Map.tsx b/components/shared/map/Map.tsx new file mode 100644 index 0000000..5b1bc66 --- /dev/null +++ b/components/shared/map/Map.tsx @@ -0,0 +1,35 @@ +import { MapContainer, TileLayer, MapContainerProps } from 'react-leaflet'; + +import "leaflet/dist/leaflet.css"; +import "leaflet-defaulticon-compatibility/dist/leaflet-defaulticon-compatibility.css"; +import "leaflet-defaulticon-compatibility"; + +import Pin from './Pin'; +import { IListing } from '@/types'; + +interface MapsProps { + items: IListing[]; +} + +const Map: React.FC = ({ items }) => { + const mapProps: MapContainerProps = { + center: [23.8041, 90.4152], + zoom: 7, + scrollWheelZoom: false, + className: "w-full h-full rounded-lg" + }; + + return ( + + + {items.map(item => ( + + ))} + + ); +} + +export default Map; From e915dfa76d87041af96ef5637a20cf43ae400c2d Mon Sep 17 00:00:00 2001 From: mhossain2 Date: Wed, 29 May 2024 23:08:38 +0600 Subject: [PATCH 04/11] fix: fixed listing props error --- app/listings/[listingId]/Listing.tsx | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/app/listings/[listingId]/Listing.tsx b/app/listings/[listingId]/Listing.tsx index a6cf382..93e70f8 100644 --- a/app/listings/[listingId]/Listing.tsx +++ b/app/listings/[listingId]/Listing.tsx @@ -33,6 +33,8 @@ const ListingClient: React.FC = ({ price: 150, location: '', isSaved: false, + latitude: 0, + longitude: 0, }; const { data, isFetching } = useGetSinglePropertyQuery(id); @@ -76,13 +78,7 @@ const ListingClient: React.FC = ({ From c613416e42324c00044277275b8b7b9981b74481 Mon Sep 17 00:00:00 2001 From: mhossain2 Date: Wed, 29 May 2024 23:09:23 +0600 Subject: [PATCH 05/11] feat: updated listing info props and data showing in UI --- components/shared/listings/ListingInfo.tsx | 44 ++++++++++------------ 1 file changed, 19 insertions(+), 25 deletions(-) diff --git a/components/shared/listings/ListingInfo.tsx b/components/shared/listings/ListingInfo.tsx index 4e88802..1ddef61 100644 --- a/components/shared/listings/ListingInfo.tsx +++ b/components/shared/listings/ListingInfo.tsx @@ -1,7 +1,6 @@ 'use client'; import { useDispatch } from "react-redux"; -import { IconType } from "react-icons"; import { FaBed, FaBath, FaKitchenSet, FaCar, FaWifi } from "react-icons/fa6"; import { MdAllInbox, MdOutlineBalcony, MdElevator } from "react-icons/md"; import { IoLocation } from "react-icons/io5"; @@ -13,19 +12,11 @@ import { IFeature } from "@/types/Feature"; import RoomFeature from "../RoomFeature"; import { Card, CardHeader, CardTitle, CardDescription, CardFooter, CardContent } from "@/components/ui/card"; import { ModalKey, setModal } from '@/redux/features/modals/modalSlice'; +import Map from "../map/Map"; +import { IListing } from "@/types"; interface ListingInfoProps { - description?: string; - guestCount?: number; - roomCount?: number; - bathroomCount?: number; - category?: { - icon: IconType, - label: string; - description: string; - } | undefined - locationValue?: string; - img: string; + listing: IListing; } const newListings = [ @@ -41,6 +32,8 @@ const newListings = [ price: 15, location: 'Uttara, Dhaka', isSaved: false, + latitude: 23.873751, + longitude: 90.396454, }, { id: 2, @@ -54,6 +47,8 @@ const newListings = [ price: 23, location: 'Mirpur 10, Dhaka', isSaved: false, + latitude: 23.8069, + longitude: 90.3687, }, { id: 3, @@ -67,6 +62,8 @@ const newListings = [ price: 10, location: 'Chakbazar, Chattogram', isSaved: false, + latitude: 22.3518, + longitude: 91.8331, }, ] @@ -103,31 +100,24 @@ export const features: IFeature[] = [ }, ] -const ListingInfo: React.FC = ({ - description = '', - guestCount = 1, - roomCount = 1, - bathroomCount = 1, - category, - img -}) => { +const ListingInfo: React.FC = ({ listing }) => { const dispatch = useDispatch(); return (
-

BDT 80 Thousand

+

BDT {listing.price} Thousand

-

Sector 3, Uttara, Dhaka

+

{listing.location}

- 3 Beds + {listing.roomCount} Beds
- 4 Baths + {listing.bathroomCount} Baths
@@ -212,7 +202,7 @@ const ListingInfo: React.FC = ({
- BDT 80K Month + BDT {listing.price}k Month Hosted by stuRENT @@ -222,6 +212,10 @@ const ListingInfo: React.FC = ({ +
+

Location in Map

+ +
); From 3b6dd39782d2e221952468d1080280e27e46aa6b Mon Sep 17 00:00:00 2001 From: mhossain2 Date: Wed, 29 May 2024 23:09:43 +0600 Subject: [PATCH 06/11] refactor: updated listing mock data --- test-data/listings.ts | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/test-data/listings.ts b/test-data/listings.ts index 3c6f388..84dfbb1 100644 --- a/test-data/listings.ts +++ b/test-data/listings.ts @@ -13,6 +13,8 @@ export const listings: IListing[] = [ price: 15, location: 'Uttara, Dhaka', isSaved: false, + latitude: 23.873751, + longitude: 90.396454, }, { id: 2, @@ -26,6 +28,8 @@ export const listings: IListing[] = [ price: 30, location: 'Mirpur 10, Dhaka', isSaved: false, + latitude: 23.8069, + longitude: 90.3687, }, { id: 3, @@ -39,6 +43,8 @@ export const listings: IListing[] = [ price: 12, location: 'Chakbazar, Chattogram', isSaved: false, + latitude: 22.3518, + longitude: 91.8331, }, { id: 4, @@ -52,6 +58,8 @@ export const listings: IListing[] = [ price: 15, location: 'Uttara, Dhaka', isSaved: false, + latitude: 23.873751, + longitude: 90.396454, }, { id: 5, @@ -65,6 +73,8 @@ export const listings: IListing[] = [ price: 30, location: 'Mirpur 10, Dhaka', isSaved: false, + latitude: 23.8069, + longitude: 90.3687, }, { id: 6, @@ -78,6 +88,8 @@ export const listings: IListing[] = [ price: 10, location: 'Chakbazar, Chattogram', isSaved: false, + latitude: 22.3518, + longitude: 91.8331, }, { id: 7, @@ -91,6 +103,9 @@ export const listings: IListing[] = [ price: 10, location: 'Uttara, Dhaka', isSaved: false, + latitude: 23.873751, + longitude: 90.396454, + }, { id: 8, @@ -104,6 +119,8 @@ export const listings: IListing[] = [ price: 31, location: 'Mirpur 10, Dhaka', isSaved: false, + latitude: 23.8069, + longitude: 90.3687, }, { id: 9, @@ -117,6 +134,8 @@ export const listings: IListing[] = [ price: 13, location: 'Chakbazar, Chattogram', isSaved: false, + latitude: 22.3518, + longitude: 91.8331, }, { id: 10, @@ -130,6 +149,8 @@ export const listings: IListing[] = [ price: 10, location: 'Uttara, Dhaka', isSaved: false, + latitude: 23.873751, + longitude: 90.396454, }, { id: 11, @@ -143,6 +164,8 @@ export const listings: IListing[] = [ price: 20, location: 'Mirpur 10, Dhaka', isSaved: false, + latitude: 23.8069, + longitude: 90.3687, }, { id: 12, @@ -162,6 +185,8 @@ export const listings: IListing[] = [ price: 16, location: 'Chakbazar, Chattogram', isSaved: false, + latitude: 22.3518, + longitude: 91.8331, }, ] From 801f7c39f289dcf8d0b91bb6f00b72ae68334990 Mon Sep 17 00:00:00 2001 From: mhossain2 Date: Wed, 29 May 2024 23:10:14 +0600 Subject: [PATCH 07/11] package: added necessary packages for implementing maps --- package-lock.json | 82 +++++++++++++++++++++++++++++++++++++++++++++-- package.json | 6 ++++ 2 files changed, 86 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5f7558f..d30779f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,11 +23,16 @@ "@radix-ui/react-tooltip": "^1.0.7", "@react-oauth/google": "^0.12.1", "@reduxjs/toolkit": "^2.1.0", + "@types/leaflet": "^1.9.12", + "@types/react-leaflet": "^3.0.0", "class-variance-authority": "^0.7.0", "classnames": "^2.5.1", "clsx": "^2.1.0", "cmdk": "^1.0.0", "date-fns": "^3.1.0", + "leaflet": "^1.9.4", + "leaflet-defaulticon-compatibility": "^0.1.2", + "leaflet-geosearch": "^4.0.0", "lucide-react": "^0.303.0", "next": "14.0.4", "next-themes": "^0.2.1", @@ -38,6 +43,7 @@ "react-dom": "^18", "react-hook-form": "^7.49.2", "react-icons": "^4.12.0", + "react-leaflet": "^4.2.1", "react-photoswipe-gallery": "^3.0.1", "react-redux": "^9.1.0", "react-toastify": "^10.0.1", @@ -566,6 +572,15 @@ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.1.tgz", "integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==" }, + "node_modules/@googlemaps/js-api-loader": { + "version": "1.16.6", + "resolved": "https://registry.npmjs.org/@googlemaps/js-api-loader/-/js-api-loader-1.16.6.tgz", + "integrity": "sha512-V8p5W9DbPQx74jWUmyYJOerhiB4C+MHekaO0ZRmc6lrOYrvY7+syLhzOWpp55kqSPeNb+qbC2h8i69aLIX6krQ==", + "optional": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + } + }, "node_modules/@hookform/devtools": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/@hookform/devtools/-/devtools-4.3.1.tgz", @@ -1787,6 +1802,16 @@ "@babel/runtime": "^7.13.10" } }, + "node_modules/@react-leaflet/core": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@react-leaflet/core/-/core-2.1.0.tgz", + "integrity": "sha512-Qk7Pfu8BSarKGqILj4x7bCSZ1pjuAPZ+qmRwH5S7mDS91VSbVVsJSrW4qA+GPrro8t69gFYVMWb1Zc4yFmPiVg==", + "peerDependencies": { + "leaflet": "^1.9.0", + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, "node_modules/@react-oauth/google": { "version": "0.12.1", "resolved": "https://registry.npmjs.org/@react-oauth/google/-/google-0.12.1.tgz", @@ -1843,12 +1868,25 @@ "eslint": "^8.0.0" } }, + "node_modules/@types/geojson": { + "version": "7946.0.14", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.14.tgz", + "integrity": "sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==" + }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, + "node_modules/@types/leaflet": { + "version": "1.9.12", + "resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.9.12.tgz", + "integrity": "sha512-BK7XS+NyRI291HIo0HCfE18Lp8oA30H1gpi1tf0mF3TgiCEzanQjOqNZ4x126SXzzi2oNSZhZ5axJp1k0iM6jg==", + "dependencies": { + "@types/geojson": "*" + } + }, "node_modules/@types/lodash": { "version": "4.17.0", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.0.tgz", @@ -1896,6 +1934,15 @@ "@types/react": "*" } }, + "node_modules/@types/react-leaflet": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/react-leaflet/-/react-leaflet-3.0.0.tgz", + "integrity": "sha512-p8R9mVKbCDDqOdW+M6GyJJuFn6q+IgDFYavFiOIvaWHuOe5kIHZEtCy1pfM43JIA6JiB3D/aDoby7C51eO+XSg==", + "deprecated": "This is a stub types definition. react-leaflet provides its own type definitions, so you do not need this installed.", + "dependencies": { + "react-leaflet": "*" + } + }, "node_modules/@types/scheduler": { "version": "0.16.8", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", @@ -2882,8 +2929,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, - "peer": true + "devOptional": true }, "node_modules/fast-glob": { "version": "3.3.2", @@ -3420,6 +3466,25 @@ "json-buffer": "3.0.1" } }, + "node_modules/leaflet": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz", + "integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==" + }, + "node_modules/leaflet-defaulticon-compatibility": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/leaflet-defaulticon-compatibility/-/leaflet-defaulticon-compatibility-0.1.2.tgz", + "integrity": "sha512-IrKagWxkTwzxUkFIumy/Zmo3ksjuAu3zEadtOuJcKzuXaD76Gwvg2Z1mLyx7y52ykOzM8rAH5ChBs4DnfdGa6Q==" + }, + "node_modules/leaflet-geosearch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/leaflet-geosearch/-/leaflet-geosearch-4.0.0.tgz", + "integrity": "sha512-a92VNY9gxyv3oyEDqIWoCNoBllajWRYejztzOSNmpLRtzpA6JtGgy/wwl9tsB8+6Eek1fe+L6+W0MDEOaidbXA==", + "optionalDependencies": { + "@googlemaps/js-api-loader": "^1.16.6", + "leaflet": "^1.6.0" + } + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -4194,6 +4259,19 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "node_modules/react-leaflet": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/react-leaflet/-/react-leaflet-4.2.1.tgz", + "integrity": "sha512-p9chkvhcKrWn/H/1FFeVSqLdReGwn2qmiobOQGO3BifX+/vV/39qhY8dGqbdcPh1e6jxh/QHriLXr7a4eLFK4Q==", + "dependencies": { + "@react-leaflet/core": "^2.1.0" + }, + "peerDependencies": { + "leaflet": "^1.9.0", + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, "node_modules/react-photoswipe-gallery": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/react-photoswipe-gallery/-/react-photoswipe-gallery-3.0.1.tgz", diff --git a/package.json b/package.json index 360d2c3..a5674ae 100644 --- a/package.json +++ b/package.json @@ -24,11 +24,16 @@ "@radix-ui/react-tooltip": "^1.0.7", "@react-oauth/google": "^0.12.1", "@reduxjs/toolkit": "^2.1.0", + "@types/leaflet": "^1.9.12", + "@types/react-leaflet": "^3.0.0", "class-variance-authority": "^0.7.0", "classnames": "^2.5.1", "clsx": "^2.1.0", "cmdk": "^1.0.0", "date-fns": "^3.1.0", + "leaflet": "^1.9.4", + "leaflet-defaulticon-compatibility": "^0.1.2", + "leaflet-geosearch": "^4.0.0", "lucide-react": "^0.303.0", "next": "14.0.4", "next-themes": "^0.2.1", @@ -39,6 +44,7 @@ "react-dom": "^18", "react-hook-form": "^7.49.2", "react-icons": "^4.12.0", + "react-leaflet": "^4.2.1", "react-photoswipe-gallery": "^3.0.1", "react-redux": "^9.1.0", "react-toastify": "^10.0.1", From 3bd370bc19ddb987aed3727046282d3fb97ccf7a Mon Sep 17 00:00:00 2001 From: mhossain2 Date: Wed, 29 May 2024 23:23:00 +0600 Subject: [PATCH 08/11] styles: updated map styles --- components/shared/map/Map.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/shared/map/Map.tsx b/components/shared/map/Map.tsx index 5b1bc66..90a6680 100644 --- a/components/shared/map/Map.tsx +++ b/components/shared/map/Map.tsx @@ -16,7 +16,7 @@ const Map: React.FC = ({ items }) => { center: [23.8041, 90.4152], zoom: 7, scrollWheelZoom: false, - className: "w-full h-full rounded-lg" + className: "w-full h-full rounded-lg z-10" }; return ( From 59066e1cf2478ed4585a432349d4061c46475f76 Mon Sep 17 00:00:00 2001 From: mhossain2 Date: Wed, 29 May 2024 23:23:54 +0600 Subject: [PATCH 09/11] styles: removed max width and added full width --- app/listings/[listingId]/Listing.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/listings/[listingId]/Listing.tsx b/app/listings/[listingId]/Listing.tsx index 93e70f8..54ca371 100644 --- a/app/listings/[listingId]/Listing.tsx +++ b/app/listings/[listingId]/Listing.tsx @@ -40,7 +40,7 @@ const ListingClient: React.FC = ({ return ( -
+
From a4ec86b103372f09361956ff37f640b0df5b402f Mon Sep 17 00:00:00 2001 From: mhossain2 Date: Wed, 29 May 2024 23:24:18 +0600 Subject: [PATCH 10/11] styles: updated header z-index --- components/layout/header/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/layout/header/index.tsx b/components/layout/header/index.tsx index 8c10e8a..97362a1 100644 --- a/components/layout/header/index.tsx +++ b/components/layout/header/index.tsx @@ -51,7 +51,7 @@ const Header = () => { }, []) return ( -
+
Date: Wed, 29 May 2024 23:25:15 +0600 Subject: [PATCH 11/11] styles: updated listing info width and make maps responsive --- components/shared/listings/ListingInfo.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/components/shared/listings/ListingInfo.tsx b/components/shared/listings/ListingInfo.tsx index 1ddef61..27c9360 100644 --- a/components/shared/listings/ListingInfo.tsx +++ b/components/shared/listings/ListingInfo.tsx @@ -103,8 +103,8 @@ export const features: IFeature[] = [ const ListingInfo: React.FC = ({ listing }) => { const dispatch = useDispatch(); return ( -
-
+
+

BDT {listing.price} Thousand

@@ -199,7 +199,7 @@ const ListingInfo: React.FC = ({ listing }) => {
-
+
BDT {listing.price}k Month @@ -212,7 +212,7 @@ const ListingInfo: React.FC = ({ listing }) => { -
+

Location in Map