⭐ If you would like to buy me a coffee, well thank you very much that is mega kind! : https://www.buymeacoffee.com/honeyvig Hire a web Developer and Designer to upgrade and boost your online presence with cutting edge Technologies

Friday, November 7, 2025

I built an AirBnB clone with structured content! Using Sanity.io and Next.js

 

0:00

hello everyone and welcome to this video which i am super excited about as we are going to

0:05

learn how to build an airbnb clone complete with a content management system for this video we're

0:12

going to be building it with next js we are going to be using xjs in order to help us build

0:18

server side rendering and static web applications with react and we are also going to be using sanity

0:26

and sanity is the content management system that i was talking about sanity is pretty cool as it's used by

0:33

all the major players such as nike or nike however you want to say it national geographic

0:40

what else conna sonos figma netlify and literally so so many more it's crazy and just quickly

0:46

for those of you who perhaps have not used a content management system before where you are in for a treat okay so quickly what do

0:54

we need to build this airbnb clone well in this airbnb clone i want to have like a main

1:00

page in which it's going to display all my properties as well as provide you with a

1:05

map so we are actually going to be using google map api for this as well i'm going to show you how to do that

1:11

in order to show multiple properties on the dashboard and then of course if we

1:17

click into each property it's going to display a lot more information about that particular

1:23

property so this is going to be fun we're going to be building a lot of schemas we're going to be doing that

1:28

in sanity io it's going to be painless i promise like this is the easiest content

1:33

management system i think i've ever used so you're in safe hands this is what the final project will

1:41

look like so there is a lot to learn i'm not gonna lie this is gonna be a long tutorial by by no means is it gonna be

1:48

hard because i'm gonna take you through everything step by step the whole way through and of course

1:56

explain concepts and things that perhaps you might not have seen before throughout i mean i am really excited

2:02

it's gonna be so much fun so please come and code along with me by the end you will have your own

2:08

airbnb clone also of course using a content management system and once you have that knowledge

2:14

you can apply the knowledge that we learn here today to build any app that you want okay

2:21

so i hope you're excited i obviously am please of course i have to ask please do

2:26

like and subscribe to my channel if you do like my content as it really does allow me to keep

2:31

creating more content for you guys okay so

2:36

what are we waiting for let's do it okay so first things first i want to

2:42

start off with making our content management system with sanity now we are doing this because

2:49

we're going to start off by building our back end first so the back end of our airbnb app which

2:55

is going to involve us making schemas and types in order to view what our database

3:02

relationships are going to look like thanks to sanity io which is going to show them for us visually and a

3:07

beautiful ui so it's really user friendly i'm going to show you show you how to

3:12

do that in part one and then in part two we're going to use that data and everything we built on the

3:18

back end in order to build out our front end okay so let's do it here we are on

3:26

sanity i o um the first thing i'm going to do is obviously sign up so i'm just going to use my

3:33

email to do that and there we go now this is free to use up

3:39

to a certain point it's perfect for projects like this and they do have a lot of

3:44

template projects that you can use to get started but as you are following me on my tutorial i'm going to show you how to

3:50

do it from scratch okay so let's go ahead and click here

3:58

now this will take us to the sanity documentation including

4:04

getting started with sanity cl i now the first thing we want to do

4:11

uh is actually install the command line interface or cli or cli as i like to call it and we can do

4:19

that by simply going to our terminal and then anywhere as we're going to be installing this globally

4:25

i'm literally just going to copy this line the dash g is for installing it globally on your

4:31

machine so i'm just going to paste that install globally

4:37

g is globally sanity command line interface and there we go we have now installed it

4:44

so now if i write sanity you'll see all the commands that

4:49

i have available to me we want to initialize so init is the command we

4:56

need we want to initialize a new sanity project so i'm just going to

5:01

clear that and write sanity in it like so it really is that simple now i

5:09

just follow the prompt so what i want to do i want to create a new project yes my project name is going to be

5:18

let's call it air let's just call it airbnb right because that's what we are

5:23

building we are building an air bnb clone enter

5:29

okay do we want to use the default data configuration i'm going to put yes

5:34

and we are creating a data set project output path this is going to

5:41

this is going to be our output part i'm okay with that what do we want to do do we want to build a movie project an e-commerce

5:48

platform no a blog no clean project with no predefined schemas

5:53

yes so that is what we are doing of course if you wanted to build a movie app or a

5:58

blog then they do have those templates for you i do suggest that you click those in your spare time but not

6:04

now because we are building an airbnb project okay so this is going to take a while

6:11

because it's actually doing a lot for us it's configuring everything it's getting the right files set up it's

6:17

literally doing all the heavy lifting for us sort of similarly to when you use create react app

6:23

and it gets all the configuration and files set up for you there too so it's very it's very similar

6:30

i'm just going to speed this up for us so look

6:35

okay so we have done that now what it's very i like the prompts that it

6:41

gives us um well we can do a few things

6:46

we can run sign to start to run our studio but i'm just going to open up the code first so i'm going to do that with a shortcut

6:52

code dot as i am using vs code ah i need to actually make sure

6:57

i am in the project first so cdf bnb don't forget to be on the project

7:03

and code dots okay so here we have everything that the

7:10

command sanity in it has created for us essentially it has provided us

7:16

with a package.json file which has all the dependencies that we are

7:21

going to need for this project as well as some script that we are going to use

7:27

we also have a schemas folder with some boilerplate essentially for

7:33

uh where we're gonna put our created document types so we're gonna put them in here and then

7:39

a sanity json file okay which we're gonna go into a little bit later okay but essentially

7:48

this is all important information for us that we're gonna need so thank you sanity for whipping

7:55

this up for us okay now if i go back to my terminal i'm just

8:02

going to clear these and run sanity start like that

8:07

and just wait a little bit well we're going to essentially start our sanity studio so once again

8:15

it's just doing its thing i'm gonna speed this up for us

8:21

okay so content studio successfully compiled i am literally just gonna take this url

8:28

go to my browser and just put it in

8:34

and i'm just gonna log in again using the same credentials as last time

8:41

and there we go here we have our sanity studio um we can see it's our sani

8:48

studio we've named this airbnb and we can see that on our left we don't have a schema does not contain

8:54

any document types yet if those if it did then those types will be listed here we're going to be adding that

9:01

throughout the project so this is essentially we're going to be doing by the end of this section we are gonna have

9:08

essentially something that looks like this okay so let's get going now the first thing i'm gonna

9:17

do is actually go into here okay so now let's have a look at our

9:23

schema.js file so if you open this up this file in the schemas folder

9:31

the schema defines our content models okay so we're gonna start

9:38

modeling out our content logically um let's not really worry about

9:43

how it's gonna be presented we just need to think about how everything's going to essentially work together and what kind

9:48

of relationships it's going to have

9:55

so i know that i want to have a property right and that property is going to have a geolocation

10:01

because we're going to be using google maps because that's what um airbnb has it has a map uh displaying

10:08

where the property is exactly by longitude and latitude you want to give the property a title so for

10:14

example my lovely london flat a price per night

10:19

how many beds it has and then of course the host which is going to be a person which can

10:25

always use also shared by a traveler because both the host and the traveler are a person so we can

10:33

use that to our advantage to make our repo just look a little bit neater and then we also want to have

10:39

reviews that are linked to a traveler okay so that's one relationship

10:46

that we're gonna have to have and of course we want images of the property itself so in a nutshell

10:53

that is what i want and that's what we're gonna build so let's get to it starting with the property

11:02

so i'm going to create a document type called property with one string field called

11:10

name and then we are also going to have a title and a

11:17

type okay so the title is that's going to be the display

11:24

name for the type uh the name is going to be i the identifier for the document type

11:30

and the type itself um but we can go into that a little bit

11:36

later on that's just all you need to know so let's get to it

11:44

so in my schemas folder i'm just going to make a new file and call it property js

11:50

and in here i'm going to export default default if i can spell that correctly

11:56

and now as we said i need a name name is a string i need a title

12:04

also as a string and i need a type as i said those are the three

12:10

things that i need and then this is going to be a document type okay so the property is going to be

12:17

a document type and then everything that we discussed is going to be

12:23

a field so field

12:29

like so and i'm going to have an array of fields okay so maybe i should just put

12:36

that as a field that's probably makes more sense okay so the first thing that we discussed is

12:42

actually giving our property a title right so once again i

12:48

am just going to i'm so just going to copy this because that's what we are going to be doing

12:53

this is not going to be a document type this time so this field well i'm going to name this field title

13:01

and i'm actually going to give the title it's going to be title as well uh not to be confusing but this is going

13:08

to be the properties title that i discussed and the type of this is going to be a string because that's all

13:13

i want to be i want it to be a string so okay let's just see let's just see

13:19

how this works for now okay i'm just gonna save this and then go into the schema

13:25

and now all i'm gonna do is import the object and document

13:31

schema okay so right down here we import

13:42

object and document schema scheme schema

13:50

and our property is a document type type document uh not that that's

13:56

important for now i just want to reiterate that and i'm going to import property from

14:04

well it's in the same folder so it's just going to be property like so so i've imported the

14:11

property and now in here

14:19

i am going to put my document type of property in here and i'm simply going

14:25

to do it like so because our boilerplate here is going to concatenate it with anything

14:30

else that we put in here so now if i click save and then

14:36

go to here well isn't that handy it's saying we're missing the type name so let's go back here

14:44

we know that this is a property and let's just give it the title of

14:50

property with a capital p so now if i go here and refresh

14:58

we have made our first document type document we've made a property with

15:04

the type of document but it doesn't really have anything here at the moment because we

15:11

haven't actually added one if i wanted to add one to our content management system now i would

15:17

just click here and it says oh create new property because we have named it a property

15:23

and ta-da i can now add a property and the only field is requesting is a

15:28

title so i can now put a lovely

15:35

learn done flat and publish and there we go we have our

15:41

first property all we really needed from it is a title so that's all that we have done we

15:48

filled it out and we published it and now we have our first property it's a london flat if we want to add a new one

15:54

well we can do just that i just simply have to click here and add something else and it will get added

16:00

here amazing but of course this is really basic we really want to build out this

16:05

property with everything that we've said so i'm just going to leave this for now and carry

16:10

on so the next thing i actually want to do so we have our title let's actually also

16:17

give it perhaps a location so this time i'm going to make this location

16:24

title location and this is going to be a geo point this time

16:32

geo point um we'll go into this type later for now i'm just going to finish

16:38

typing out everything we need for this file so once again perhaps i should just make

16:45

a few of these uh this time let's delete that and

16:50

delete this this time i'm going to actually have a property type because

16:57

you know how on um airbnb it asks you know would you rather have a bungalow or

17:02

just one room or the whole house or something so that's what property type is going to cover for us

17:09

property type and i'm actually going to make it like a radio selection where you can just pick one so the type for this

17:17

um it's not going to have a type this time i'm actually just going to say options

17:23

and be very strict about what we can choose for this

17:28

uh so i'm going to have a list like this and then the list is going to be an

17:34

array and that array is going to have a title so once

17:39

again with the title i'm just going to put house and then

17:44

value so there's our first one we've got a

17:50

house and then what else can we have well i guess we can have a flat

17:55

so that's going to go on our radio button flat uh what else a

18:02

i don't know a bed and break fast and then let's put the value

18:09

here as bed and break fast

18:15

and then let's just have maybe one one more sure why not i'm gonna have a boutique hotel because

18:22

that's quite fun boutique

18:30

and this is going to say boutique hotel okay so that's

18:36

four i think that's fine i'm happy with that and let's just say it's i want it to be radio right

18:42

so i need to say layout radio um let's just see if that's working

18:48

without giving us errors type is missing a type

18:54

okay let's go back oh yes type this is going to be a string

19:01

because the value that we choose is a string so save that refresh

19:11

okay so now you can see when we uh want to add a new property we are

19:16

asked for all these other things too so the locations latitude and longitude

19:22

altitude these are optional and then the property type which is a radio um

19:28

option okay a radio select you can only pick one okay let's

19:36

carry on hopefully you can see how uh this works once you get it it is

19:42

quite it's quite easy to get the hang of um i know it can seem intimidating at first

19:47

but as long as you stick to the rules name title type then you should be

19:55

fine so once again just as i've said it name title type

20:09

so next thing we want is um we want a main image because you know

20:15

airbnb has that one main image and then a few supporting images and this is actually going to be

20:22

a type image and then i'm going to say options

20:30

hot spots true so we've done our main image and now i

20:37

want to do the supporting images so um once again

20:42

i wish i should just really keep that i might as well just keep that

20:49

um copied at all times i'm just going to copy that for later um and what should we call this let's

20:56

just call it images title images and type well this isn't

21:01

going to be more than one image so this is type array and in that array this is how you do

21:07

arrays so array of and then let's open up our array and then

21:15

type and then i'm gonna actually create a property image so

21:22

yeah i'm gonna do that um so i'm just gonna comment this out for

21:28

now actually because we actually need to create this type

21:33

which i'll show you how to do just like we created the property type we need to create uh sorry just like we created the

21:39

property type we're going to have to create a property image type so for now i'm just commenting that out

21:46

and then once a whoops once again

21:53

okay so now we've got the images next perhaps let's do let's do price

22:00

per night because then we can derive the monthly price from that if we wish

22:07

so i think price per night is a good one to have price per night

22:12

type and this is going to be a number right so we need to actually say that

22:19

next i want to have the beds i want to know what the bed situation is before i decide to stay

22:26

out to this bmb and this is going to be a number as well as the uh let's say bedrooms

22:32

because they usually have that too they have the beds and the bedrooms separately because you know that makes

22:38

sense perhaps you have more than one bed in a bedroom because i have stayed in

22:46

places like that sure why not okay

22:51

so now that we have all that we actually need to get a slug which is going to help us out if we need

22:57

to go specifically to that property so i'm going to go into

23:03

this later i think this is something that's better off explained visually so when we use it you will see what i

23:09

mean by a slug because i mean it's not exactly the animal so type slug that is an

23:16

actual type and once again options we're gonna have options for this and we can get the uh

23:26

source for this title and then the max length of the slug

23:35

let's just put a hundred okay so we've actually like hard coded that the max length

23:40

uh for that and then um i'm also going to give this

23:46

an i d so once again id title id

23:53

and that's going to be a number okay i think that's it what else did we say um

24:01

oh yeah we need to give a description don't we because all these airbnbs have a description so

24:08

description description and this is going to be a

24:15

string okay so i'm just going to see what that looks like before carrying on

24:22

so we here we can see here we now have a main image which we can upload or drop an image to we have

24:28

somewhere to put the price for night beds bedrooms slugs so we can generate a slug

24:34

the slug is generated off the title an id and a description great now it's

24:41

time for maybe the slightly more complicated stuff even though it's not that complicated really we're gonna have

24:48

to make our own types so as you can see here i've been using like types that are sort of generic i guess

24:55

string number um slug and so on uh and we commented this out because this

25:01

uses a type that i need to make right so let's go ahead and do that i'm gonna uncomment the sound now

25:09

and this will break uh this will break right because the type property image does not exist

25:14

i'm going to make it so in my schema i'm just going to put property image

25:19

js and let's create our first type okay custom type here we go even though we did already create one

25:26

we created a document type this is to this is slightly uh different i guess because we're going to be using it in

25:32

the property type itself once again export default so

25:37

this is how this is sort of like standard and you guessed it name title type

25:43

the name of this is going to be property image as we previously decided property image

25:50

for the title and this is going to be a type of image okay because this will put it into the array the array of images

25:56

this is an image um once again we can give it fields if we want let's go let's do it

26:03

why not we can always decide we don't want it later but it's nice to have the knowledge of how to do this and

26:09

once again name title type i want each image to have a caption

26:16

so a caption and this is of course a string

26:23

and then you can also do something like this is high

26:30

lighted true i'll show you what that is later and then

26:39

uh i'm just gonna put options

26:45

hot spot true so you would have seen me use this hot

26:52

spot uh twice now i'm just going to show you the difference of having a hot spot and not having a hot spot just give me

27:00

one second let's save this and then go into the schema and i'm just going to

27:07

add property image in here as well and import it so that was of course done

27:15

automatically for me but make sure that you actually import the property image to if yours doesn't automatically uh

27:23

show up okay now so if you go into here and go to the place where you can

27:29

add images you will see i will be able to add more than one image okay so it's not like this up here we can add more than

27:35

one image because we made a property image type and we stuck it in an array that

27:41

lives on the property itself the property type so now i can

27:46

actually drag images in here let's go ahead and just use one that i have um

27:53

let me see this probably it's not a property so there we go and i can actually edit

28:00

stuff in here too i can do whatever i really want that is what the hot spot

28:05

means you would have seen that i'm using hotspot quite a lot hotspot true that allows me to do all this type of stuff so if

28:12

you want that keep the hot spot on as true and of course i mean

28:18

let's just let's just save this for now um

28:24

so if i exit out of it you will see that is saved i can also delete it if i wish so i'm going to

28:31

delete it for now because i don't want in that in my property it's a piece of fluff it's not really a property so let's move

28:37

on until we fully make our property okay so we have made our property image

28:45

type remember we had to put it in here so that it could be concatenated

28:51

with the others the next thing i want to do so let's go back to our property

28:58

is actually provide a host for this so similarly to how we made a property

29:05

image type i'm gonna have to make some custom types here too so once again

29:18

name i'm going to put a host i'm going to put title host and i'm going to put type

29:25

host which we are yet to make don't forget a comma and then perhaps while i'm here already

29:31

i'm just going to um okay let's make uh

29:36

yeah let's make some reviews too so i'm going to make an array of reviews so just move that up for us

29:44

name view title review sorry plural because it's going to be an

29:49

array isn't it type array and then array of so we need of uh open up our array

29:59

and then let's make a review type um so yeah type of review which we are

30:06

also yet to make just like the host type great so

30:15

let's make the um let's make the review first i think it'll actually be easier

30:20

and then we'll move on to the host now i'm just going to start this off again so once again export

30:25

defaults um i mean this is really good for muscle memory right because there is a

30:32

lot of repetition but it's all important name title type so the name of this

30:40

is going to be a review a singular review title review type uh this is going to be

30:47

an object so we haven't used an object type before um let's put fields that will make up our

30:55

review so i'm going to have the once again

31:00

just to make our lives easier let's have a review description

31:11

description review description and this is going to be a string um

31:20

and then let's also have the person that left the review which is going to be the traveler which we are going to have to

31:26

make uh traveler that's why i want to leave

31:31

host last because traveler and host are going to have something in common so type we're going to make a traveler

31:38

type and then i am just going to have a rating as oops rating as well

31:48

so name rating title rating and then

31:55

um yeah let's have options now so options

32:07

uh it's going to be a list and then the list of arrays an array of things

32:13

um i'm gonna have a title of five stars

32:22

and the value is gonna just have five stars like this if i could just

32:30

format everything correctly and spell five stars okay so we've got our first option i

32:36

think we'll make this a uh radio select as well so five four oops

32:44

nope four three two

32:53

one brilliant okay and now we have our layout which is

33:00

gonna be radio cool so there's our review

33:07

um let's stick it in here too so i'm just going to put the review and hopefully that will automatically

33:13

import it didn't the other one did though import

33:19

review from review let's have a look now

33:28

what's it not liking uh unknown type host unknown type traveler

33:34

well yes we know that the fields property must be an array of fields

33:40

let's go back i'm just going to comment this out for now get rid of the traveler and then get rid

33:46

of the host

33:52

so hopefully that should work now no the fields property must be an array of

33:57

fields instead so undefined on the rating so so that's quite handy

34:05

for debugging so on the review type object uh that should be a string

34:11

remember because the value is going to be used as true so save that wait for that to rebuild

34:19

and there we go so we can now add a review so we can

34:25

give a description so awesome place and a waiting cool

34:35

um here we go that's our one review but we now need to associate a uh

34:40

traveler with it right so let's get to it let's now make a uh let's start with the traveler first

34:47

traveler js once again export default name

34:55

traveler title

35:00

traveler and type so i'm just going to put capital t here

35:07

uh and the type is actually going to be a um it's going to be a reference

35:12

because i want the traveler and the host to share a type which is a person

35:20

so this is how you would do so you would write two and then i'm just gonna open up my array

35:28

um type person so obviously now we need to create a person but it's all going to

35:33

be worth it when you see how good it looks on our content management system

35:39

so there we go um okay so now we have created

35:46

our traveler let's first make our person type so once again i'm going

35:54

to go in here make a person js click enter export default

36:03

name person title person

36:11

type i'm going to make this a document type

36:18

and i'll show you the where this will show up if it's a document type

36:23

and then let's have some fields once again so fields

36:36

and what do we need to have for each person well we need each person to have a name so i'm just going

36:43

to put a name like so and this is going to be a string uh we can also give it a description if

36:50

we want something like please use um you know first

36:58

name last name format if we want we can do that

37:05

just to give like a sort of helper we also want each person to have a

37:12

slug titled slug and type

37:21

slug um we don't really want a description for this but once again we want to have options

37:30

source name and max length 100 because we don't want

37:36

it to be longer than 100 when it's generated 100 characters long

37:42

next we also want each person to have their own id so sort of like the

37:47

properties right oops name

37:53

id title i d and this is going to be the type

38:01

of number and then we also want each person to have you know an image so we

38:07

know what they look like so once again image image and this is the type image

38:16

because that exists great so we have our person we have our traveler and now let's do our

38:23

host js and then host well it's exactly the same as

38:28

traveler really apart from there is a difference only the travelers

38:34

uh are gonna have uh the ability to read reviews and the host is gonna be

38:39

attached to the property itself okay so now i'm actually going to

38:44

uncomment out the bit that says host

38:50

save that let's go to our schema and import everything we have just made so that is the traveler

38:58

the host and the person type so once again

39:07

wandy traveller

39:12

host and the person document type and i believe they should all have

39:18

capitals yes they should okay so now let's go back to

39:26

here there we go so now

39:32

the property document type and the person document type we can add a person so i can add

39:39

any kubo i can generate a slug for myself give myself an id so i'm gonna be the

39:45

first one uh add an image of myself so let's go ahead and do that now

39:52

upload um

39:58

just gonna use this headshot okay so there we are publish

40:06

there i am there i am as a little person okay so i've just created a

40:12

person i've not defined myself as a traveler or host yet but if i go into a

40:20

lovely flat i can select myself as a host okay so i am now the

40:27

host of this property great okay i am really excited about this

40:36

i believe we are now done building our back end let's actually go add some uh

40:43

properties to our database let's add some people which we can then decide if they are travelers or hosts of our

40:50

property okay let's do it

40:57

now there is actually an option to be able to change what is previewed in

41:04

here if you wish obviously i think sanity does a good job at guessing what is the best to preview

41:11

to you but if you don't like it you can override it so for example say instead of having my

41:17

image and my name i wanted to have an image and i an id so

41:23

i would use preview select and this of course is using the title name

41:30

so i am literally using my name to show me my name but if i wanted to

41:36

use my id and an image i could change this to id and then refresh this

41:46

and you'll see uh you are getting me by id so the person's id instead of

41:52

their name as an identifier so that is one thing you can do if you wish um i'm gonna leave this for you

42:01

here in case you want to use it so i'm going to upload that onto github

42:06

like i said it does a pretty good job of picking the most likely one you should

42:13

use but you know just in case you're not happy with it that's just something you can do okay so i think we

42:21

are now ready to actually start adding some data to our content management system so let's create some

42:27

properties let's create some people which we will then assign to the property as a host

42:33

or a traveler so that is going to be up to us let's do it so

42:40

in the property um i'm actually going to just delete these so

42:48

i'm just going to get rid of them delete

42:54

delete the london flat and delete this one too

43:00

oops why did i just do that i just duplicated it by mistake at least you know that's an option that

43:06

you can do i'm just going to delete that and i'm going to

43:13

delete this one too as soon as it lets me i'm just going to select it delete

43:22

okay so yes let's make our first property i'm going to call it a lovely

43:30

london flat again let's get the longitude and latitude

43:52

so this is the latitude of my flat and this is going to be the longitude

43:59

i'm going to leave the altitude this is going to be a flat as we said and now let's upload some images of the

44:05

flat so

44:12

just going to upload a main image and then i'm going to add some other properties too

44:18

so i can choose to upload or drop them in it is up to you i'm gonna do this one

44:25

so let's add that in there we can also edit the details if we wish

44:31

but i don't really want to so there's one flat

44:37

there we go let's add another one so once again i'm just going to

44:51

add a second image uh and then let's go ahead and add four let's make that be um sort of like

44:59

how many we want for each property so there's our there we go we've got

45:06

four images we've got one main image i think that's the same one but i mean it's fine for now we can always

45:13

change it if we wish let's say the price price per night for this flat is 230 i'm not going to use

45:22

um currency for this because i don't know what country you're doing it and so

45:27

i don't really want to just push wherever i am on you 230 whatever that's what the

45:34

price is uh let's say it has three beds two bedrooms let's generate a slug for it

45:41

give the idea of zero it's the first one give it a description so a lovely flat

45:47

situated in the heart of batter c

45:54

situated i hope i spot that right lovely flat surgeon how to see perfect for a mini

46:01

break and exploration of the city

46:08

the host i'm gonna add myself i am the host and then reviews well for reviews we

46:14

actually um let's just say it has no reviews for now this one okay we'll add some reviews

46:19

let's publish this now let's add some more people so i'm going to add

46:25

let's add omar um abdullah to generate a slug for him

46:34

give him id of one and so here we have omar abdullah

46:41

let's go ahead and publish him now let's go back to our property and add a review from

46:48

omar so add a review um great stay and lovely

46:56

flat five stars for me

47:08

great now ah why can't we select a host

47:14

that is strange let's go back to our review oh yes we didn't uncomment

47:21

this out so now let's go back let that rebuild

47:28

go back in here and then we add omar as the traveler from our person

47:36

list so great we have a review from omar this is looking good

47:43

um okay fantastic cool so i mean let's just make another

47:52

property while we are here let's have two properties to work with i'm gonna put a

47:59

spacious flat sorry house in hackney

48:14

give it a latitude give it a longitude say it's a house add

48:22

a main image so once again upload

48:29

house then

48:45

just add some images

48:52

for the house i'm just going to do four again don't forget we can also add a caption

48:58

as we did add that to it so i can put the pillows

49:05

the pillows you can touch i don't know there we go so we can

49:12

have captions on the images too if we want and if we want to display them in the front end that could be an

49:18

option as well um let's carry on adding some images

49:27

get a picture of the bedroom sure and then just one more

49:35

again of a couch just to show how comfy this place is so

49:41

we've got our four images now price per night let's say i don't know a thousand thirty because it's a huge

49:47

house that's probably a bit cheaper whatever five beds four bedrooms

49:52

generate a slug give an id got a description so a large

50:00

house situated or a large house in hackney

50:08

um heck me perfect for a large family

50:15

or i don't know celebrations

50:20

i hope you enjoy your stay here um and let's just say

50:27

i don't know let's say omar's the host it's a very small site we have at the moment uh and then again let's add a review i

50:34

have stadium so i say this place is lovely

50:42

of course ideally we'd have way more people in our daily race but you know i don't want you to sit here while i add

50:47

um loads of data i think this illustrates perfectly how we can add

50:54

data to our content management system so let's publish that and i think

51:01

we are now ready to start making our front end so i hope

51:08

you've enjoyed this section next we're gonna actually uh work on link it up to our front and i hope

51:14

you're excited i hope you've learned a lot in this section and if you feel like i didn't go

51:20

into something in enough detail please let me know in the description below and i will aim to answer all your

51:26

questions for you but for now let's carry on part two okay

51:34

so in part one we built our back end essentially we built our content management system

51:40

we added data we added two properties and we added two people which are interchangeably

51:45

hosts and travelers in this part we're going to build out our front end so let's do it now it's

51:53

important to actually note that for this part we actually need to keep

51:58

the back end running as that is where we're going to be getting our data from in order to populate our front

52:04

end so keep that running and then in a new tab so yeah you can do a new window if you

52:11

want but i like to keep it neat and keep a uh keep everything in one place i've just got a new tab

52:19

now in here make sure you are not in the airbnb project we have just

52:26

made um so i'm just going to go into the directory that i usually work in

52:32

the airbnb project is in there however i want to make a front end for it so i'm going to do this

52:38

with another command that command is mpx create

52:45

next app okay so similarly to create react app we can use it to essentially get started with next js

52:53

which is what we're going to be doing for this project to build our front end

52:58

so in our terminal in the directory of our choice i'm just going to create a next app and

53:05

i'm going to call it airbnb front and or you can call it whatever you want

53:12

just make sure to know that this is we're gonna be working on our front end so i'm just gonna click that and wait

53:19

for that to create a new next js app for me all configured all

53:24

nicely so i can get going once again i'm just going to speed this up and edit

53:32

now to run our app we already have some commands here but i just want to show you what this looks like so i'm going to

53:38

open it up using code dot which is a shortcut for anyone out there using

53:46

a vs coach so there we go i'm actually going to

53:52

just minimize the back end even though it is running i don't actually need it up anymore so

53:59

here is what create next app has made for us essentially we've got a

54:05

package.json file with some scripts and some dependencies as well as just some basic boilerplate

54:13

if we actually run this so npm

54:19

what were the commands again npn run dev

54:30

and then go to localhost 3000

54:36

you will see this is the boilerplate of our next js project i just want to delete all of this now so we can start

54:42

from scratch so i'm going to go into the pages

54:51

go into the index.js file and then all of this stuff that it's returning

54:57

i'm just going to get rid of it like so and then just return

55:04

nothing essentially um now we can call this home we can call it

55:10

whatever we want import styles uh i actually don't want to import any of

55:15

this so now if we look at this we have a blank canvas to start with this

55:22

is looking good it's going to make that bigger for us so we can read everything that is

55:28

happening um keep that out 100 though

55:33

okay great so for example if i was to now write

55:38

hello you will see that pop up in there

55:44

cool okay so before we get going let's actually check that we can actually get

55:50

the data in our front and right so i'm just going to delete this and i'm actually going

55:55

to create a client okay so i'm going to create a client i'm

56:00

going to call it sanity client let's do it

56:06

in the root of my project i'm actually just going to create a sanity js file and i'm going to paste just some

56:13

code that i want to share with you um i don't really feel the need to type this all out because there is a lot of

56:20

annotation and help there for you as a developer when you are doing this by yourself

56:26

so this is the code that you will need of course you will have my github so please go ahead and

56:31

take it this is essentially um what we're going to need to start off

56:37

our sanity client of course we do need to import next

56:42

sanity into our project as well so let's go ahead and do that in order

56:48

for us to be able to essentially use create client and create image url builder so i'm going to go in here

56:56

and just start a new tab and write npmi next sanity to uh import that package

57:05

the next thing we are going to have to do is get our project id which i showed

57:10

you at the beginning of this video and our data set

57:17

so we're gonna get that from the studio um and we're gonna have to create a dot env

57:23

file and notice we can store them secretly and then call them or get them

57:29

using this we're going to be going into the env file and getting our next public sanity data set and our project i

57:36

j um so i'm just going to create a file called.env for us and

57:45

let's get that and whack that in here and let's also get that and work that in here like so

57:54

i'm just gonna save this file because um this is looking good we don't need to change

57:59

anything here so now i'm just going to gravitate

58:05

actually back to our backend project and this is what the sanity file is for we need to get

58:11

the project id and the data set so i'm just going to grab that here

58:17

and put it in my front end so in the dot emv i'm just

58:23

going to paste that in here and also get the data set too

58:28

so once again let's get our

58:34

project and simply grab the data set

58:43

and put it in here and save that

58:48

great

58:55

now let's go back to our index.js file

59:00

now i'm just going to actually i mean you can keep it like this but i

59:06

personally prefer just to use um

59:13

functional expressions and then export default

59:19

you could have kept it it's just a total it's a preference thing it's just how i prefer to keep my code uh and now we actually have to

59:26

import the sanity client from our sanity.js

59:32

file so import sanity client

59:41

i can't spell today client from and then i'm going to go back one

59:49

and go into the sanity.js file great so we've imported our sanity gs our

59:55

sanity client now let's actually get to using it in order so we can get our data right so we're going to do it like this

60:03

we're going to export const get server

60:10

server side props equals async

60:17

um hopefully you guys are familiar with next js if you are not i i mean of course you

60:23

can carry along coding with me um but i do recommend that you look into next.js

60:29

in more detail because um that's just what we're using for this

60:34

tutorial so this is the uh i guess

60:39

syntax that you have to use in order to communicate with

60:54

sanity

61:00

sanity has its own query language called gro q or grok

61:07

graph relation object queries so that is exactly what we are using in order to

61:14

communicate with our database and make queries to it so our query um

61:21

essentially we're gonna be looking for the type property

61:29

so that's what we're doing and then we're gonna store so we're gonna use the sanity client await

61:37

sanity client to fetch sanity client to fetch our data so we're going to

61:43

fetch by passing through the query we're going to pass through that query we just made and save it as property

61:51

well actually let's call this properties as there's multiple of them now i'm quickly just going to write some

61:57

code if there's property let proper

62:02

t's if there's no properties by length so if there's nothing in there

62:09

then return

62:18

props properties

62:28

and just an empty array

62:41

else

62:46

return props

62:54

properties

63:00

okay and then of course we're getting the

63:06

server-side props and we're going to pass through the properties

63:11

and i'm just going to console.log out of the properties

63:18

and there we go we have our two properties okay so we've got them into

63:25

our project this is looking good let's carry on because we have a lot to

63:30

get through but we're getting the data so we've managed to sync up our back end and get the data to

63:36

appear in our front end so this is fantastic okay now

63:43

let's actually get to showing the properties uh let's actually first work on maybe

63:49

the one property itself and then work on the homepage where it shows all the properties

63:55

so i'm gonna do that by first off

64:02

i think we should

64:11

okay yeah okay fine let's in the pages i'm going to create a folder called uh property

64:21

and in the folder itself i'm going to make a file and then i'm going to put slug

64:29

js so like this and this is essentially going to represent the slug of each of our properties that we

64:35

generated in the first part um we're gonna have to actually

64:42

create a component for this so export const property

64:50

and then i'm gonna have some props

64:57

and for now i'm just going to return um well let's just return an h1

65:04

tag that's gonna have our property title but let's just see if this works now i'm just gonna use the word

65:10

title oops uh export

65:16

default property

65:24

title okay so the word title is showing up that is looking good um

65:32

we don't need to export this twice okay so we've got the title the word title

65:37

showing up but now actually let's go about getting our server slide props in order so we can use them

65:43

uh in our page so i'm going to have to use the client

65:50

for this we're going to do it the exact same way that we did before um when i export

65:57

const and then we need to once again get server side props

66:04

it's going to be an async function and then we're going to have to pass through the page

66:10

con text i'm going to show you what this does in a little bit so

66:17

okay so if you actually use the page context query slug

66:24

and i'm just gonna save this as const page slug for now and i'm gonna console log

66:30

it just so you can see that we are actually getting the page slug

66:36

okay so pleach page slug so context query slug

66:43

and then if i actually go to this page and refresh it and look in here i'm just going to

66:50

ignore that for now because it doesn't really matter i just want to make sure that we are getting the slug

66:55

and i am a lovely london flat so we're getting these slug that is looking good let's carry on

67:03

now we need to actually i'm going to delete this now because we don't need it we need to actually write our query so

67:10

just like we did before so this time i want to get the property based on the page slug

67:16

so i'm going to write const query and i'm going to use grok again so this is the uh query language

67:22

that we are using in the tutorial i'm going to use back ticks because we are actually going to have to put

67:29

in some variables in here i'm going to open up our brackets type

67:36

equals property

67:42

okay and slug current

67:48

equals page slug so that is

67:56

uh what our query is if the type is property and the the current slug is the page slug

68:03

uh and then we also actually need to get the title get the location

68:11

get the property type so i could have just copy pasted from above

68:17

property type get the main emerge get the images

68:26

get the price per night get the beds get

68:32

the bedrooms get the description

68:40

get the host but we don't just want the host okay we want everything that comes along with the host so this is how you

68:45

would do that if something is referenced get the id get the name so the arrow is

68:52

basically for anything that is referenced get the slug and get the image for the host and then

68:57

of course we also need the reviews and that is an array

69:04

um the reviews are made up of the traveler so

69:11

again we need this is referenced so we need this syntax and each traveler has an id

69:18

also a name oops just a dot there

69:23

ah a slug and an image okay cool

69:33

so i think that is it now we need to use this sanity client again so once again i'm

69:38

going to save whatever comes back as a property i'm going to await

69:44

i'm going to use the sanity client client to fetch the query but we also

69:52

need to pass through the slug the page slug

69:58

page slug like that okay so and one last thing

70:07

again if there is no property

70:13

oops if there's no property

70:20

let's return props just an empty array

70:27

and then actually maybe no props now and then not found

70:35

true

70:42

okay um else then i want to

70:52

else else i want to return

70:59

the props which are the title once again

71:06

oops which is the property title the location which is the property

71:14

location to the property objects location property type which is the property

71:21

objects property type

71:27

what else was that main image which is once again the property objects

71:34

main image the images which is property images

71:40

um price there's a lot of stuff we have on here so just bear with me then the property

71:47

objects price per night the beds

71:56

property beds bedrooms i think we're nearly done property

72:05

bed rooms description property objects

72:12

description at the host so the property objects

72:21

post and finally the reviews so the property

72:28

objects reviews okay i believe this

72:36

is it so now if i pass through

72:43

a title and let's just replace this with

72:48

title there we go we have our title showing up amazing

72:57

so we have done this let's get all the other props in so that we can work with them

73:04

so i'm just gonna uh de-structure them up here

73:11

so once again title i'm just gonna actually just copy this because i don't wanna type them all out

73:16

individually again a description and then we're just missing hosts and reviews and i believe that is

73:24

it that we need okay now let's get to using this for our app uh this next section is

73:30

basically gonna be me just styling things up i'm making things look good so let's do it and after that

73:38

we're gonna actually use the google uh maps api okay so that we can visualize where the

73:45

property is on a map so

73:50

okay so we have um i'm just gonna get rid of this and then let's put this in a container

73:58

so i'm just going to put class name container

74:06

[Music] and now i'm going to put in the title so like title like so

74:11

and then let's also make the title bold actually i'm just going to work that in here um

74:20

yeah let's just get everything in for now so we've got our title in the next thing i want to do is maybe use

74:26

an h2 tag let's also make this bold and in

74:31

here i just want to put the property [Music]

74:37

type so that's going to say it's a flat or a house

74:42

property type hosted by and then if there is a host

74:50

uh i want to get the name of the host so just like that um cool

74:59

nice next let's use an h4 tag and i'm just gonna put

75:06

bedrooms so the number of bedrooms so that is a number don't forget so that's the number of bedrooms so i'm

75:12

just going to put the word bedroom uh and then let's also put

75:18

the beds so the number of beds and beds or bed we're gonna have to make

75:24

this multiple um because we obviously want to deal prop to type not to find

75:30

property type not defined cool so obviously because we have two

75:37

bedrooms we probably want that to be an s so i'm just going to quickly make a utils

75:42

uh file in the root my project utils dot js and then i'm just going to

75:50

write a quick helper function for us to essentially turn things uh

75:57

to have an s like make things multiple by adding an s to the word so i'm gonna do so like

76:04

this uh export the cons so we can use it

76:09

const is mole to pull

76:15

s is multiple and then i'm going to pass through a value and whatever value i pass through we are going to

76:23

essentially um return so we're gonna get the value and if the value deeply

76:31

equals zero uh or

76:37

the value is larger than one so i'm gonna actually put this

76:46

in value than one um if that is

76:52

is that true question mark if it is then please return an s otherwise just return an empty string

77:02

otherwise just return an empty string okay so if the value equals zero or is

77:09

larger than one return s otherwise return an empty string now let's import this into our slug

77:17

so import is multiple from the utils

77:28

cool um and i'm literally just gonna

77:36

do this so bedroom and then i'm just gonna do is multiple and then pass through the

77:42

value of bedrooms and do it again for beds so is

77:48

mul to pull and pass through the value of beds because that is a number and

77:55

whatever that number is um it's going to return an s or not so now both should come back with s's

78:02

and they have great let's carry on what else do we need in

78:09

here well

78:18

i'm just going to do a little line so that we can carry on

78:25

i know that okay let's actually just make it look a little bit more like the

78:30

actual website itself so i know that they have some text

78:36

like this so i'm just gonna go enhanced clean

78:45

here this host is committed

78:53

two air b and b's five step

79:01

enhanced cleaning process okay so we've got one

79:08

i mean this is just me just like being pedantic i guess trying to make it look exactly like the website

79:16

what else do we have we have amenities oh i can't spell

79:23

amenities amenities for

79:30

everyday living

79:36

um the host has equipped this

79:46

place for long stairs kitchen

79:53

champ conditioner

80:00

hair dryer included i mean you could have if you wanted to

80:06

you know had an amenities section in your uh content management system so

80:12

then you can get this data up if you didn't want it to be hard coded like i am doing now that would actually make a lot of sense

80:20

so please do also consider that and house rules i think i'm just gonna i think all of them have

80:25

the same house rules maybe they don't i'm not sure but i'm obviously just gonna hard code this for this project this

80:31

place isn't suitable for pets

80:36

and the host does not allow parties or smoking so maybe it's not

80:44

hard coded but there we go okay so

80:51

this is looking good we have some um text

80:58

the next thing i want to do is perhaps add a price box uh

81:05

so i'm going to add a div let's actually just call it price

81:16

box okay after this let's do some styling because at the moment i've just been putting in you know like words and

81:22

stuff but this is going to be the first thing that we properly style and in the price box let's just have

81:29

a price per night so here i'm gonna put in my um

81:36

so i've used the pound however please feel free to use whatever you want i didn't really want to you know give it

81:43

a uh currency in the back end but you can use dollars uh polish zwarte

81:50

whatever you wish okay um now i've got the price per night i also need to get a review

81:58

in here so let actually let's just do the review amount and once again

82:07

uh let's use review uh let's use is multiple again and then

82:14

pass through the reviews view amount like

82:22

so um and then

82:29

let's just have a button here as well in the price box um so let's style i like to use divs

82:39

because then you can really style up the button how you wish class name button

82:47

and let's just write that okay so the one is to change the dates and let's just

82:53

write that if you click on the button it'll just take you to the um to the main page

83:02

so on click uh oops on click

83:09

for now i'm just going to leave it empty and not do anything ah stop on click

83:20

why is it doing this to me why is it all red okay there we go so yeah i'm just going

83:26

to leave that for now and then we'll decide what to do i just want to take it back to the main page i think

83:31

okay so let's take a break here and style up the price button review amount is not defined

83:38

oh yes okay uh const review amount is just going to be the reviews

83:47

the view arrays length um we could have just put in the review

83:53

it's length in there but i don't know i didn't okay so there's all our information of course

84:01

we have to start adding images and stuff but let's just do a lot of styling first so all of my styling i'm just gonna put

84:08

it all all of it for the whole project in one page um i think that should be fine

84:16

so i'm going to go into the styles css global css sorry i'm actually going to

84:21

delete this because we don't need it um so i'm just going to have the global css

84:28

uh shall we delete all of this yeah let's go ahead and start let's start fresh okay so the first

84:34

thing i actually want to do is um for my html

84:39

and my body uh let's just put padding zero i like to keep

84:46

padding and margin zero to start with you know just so you can really um

84:55

make everything uh custom now i'm gonna actually import

85:00

a font uh from google fonts because i don't really like these so if you don't know how to do this i'm gonna show you

85:06

how google fonts just simply go in here and i'm gonna search for a font called

85:12

notto notto sans uh jp this is the one i quite

85:18

like and i'm just gonna select all of these because i think that were quite nice um maybe and i go let's go on

85:27

so i've just got all of them i'm going to import them so i can use this in my

85:33

project i'm going to put it out to the top like so

85:43

and now that just means that all i need to do really is get the font family

85:56

okay and now let's go into our project and ta-da the new font has

86:03

been applied i think that's a lot more air b and b ish

86:09

okay cool so we've got our new font um that's going to be

86:18

global now let's go ahead and do the let's

86:24

do the price box shall we okay so the price box

86:33

um let's just give it a width that is 35 uh of its parent container and then

86:41

height so that's the container itself the height let's make it 250 pixels

86:46

and now for now i'm just going to give it a border that is one pixel solid

86:54

and um rgb this is a color that i picked out

87:02

earlier

87:08

cool and a border radius because i like border radiuses uh let's give a border radius of 12

87:16

pixels and actually let's give it a box shadow as well box

87:24

let's make the box shadow rgb

87:30

um um zero six pixels

87:37

i actually inspected the airbnb page and this is pretty much what i got

87:44

nearly as was close enough to what um what i got for

87:51

the price box so there we go we've already got a sort of like nice price box um

87:59

showing up for us let's actually style the container it is in as well um

88:06

[Music] cool let's actually align everything

88:11

center to align items

88:16

center now we need to do display flex don't we

88:22

so display flex

88:28

flex direction column and i think that should be it okay so

88:34

that is now centered now let's do the container

88:42

so i'm just going to do that above here container uh display flex

88:51

flex direction column and now i'm going to give it a

88:59

margin maybe so top 20 and to the sides 50 top and bottom 20 that is

89:06

okay so we have a little padding around the container so that is good

89:13

um that's really the only things that we have oh we could do the button as well so let's maybe do that

89:22

let's make our button 90 of its parent give it a padding

89:30

of 15 pixels a border radius of let's say 10 pixels

89:37

a color now i actually inspected the uh airbnb page for this so this is the

89:43

exact color they're going to use they're going to use a gradient too that is the color of the text

89:49

and then the gradient we're going to use is this so we need background not

89:56

background color but just background and then linear gradient

90:05

i'm gonna have 135 degrees and then rgb two five five

90:13

five six nine two at twenty percent

90:20

and then rgb 189 30

90:27

89. so there we go there is our button

90:34

so yes it is very similar to mmb yes i did inspect airbnb's page for that button

90:42

okay let's carry on

90:48

okay so we have all of that we have a price box

91:00

let's go back up here so we've got the title let's actually also put in just a

91:06

smaller review amount because that's what the website has so i'm just going to put that in there

91:12

like so and then let's put in some images so to put in the images well the

91:19

main image is going to be easy so i'm just going to make a div um and perhaps maybe

91:27

actually let's make an images section so class name equals images

91:34

section and in here let's actually i'm going to create a

91:42

image component um so let's do that uh and then in

91:49

here i'm gonna have the a div that says it's gonna have the

91:59

sub images section cool

92:06

so i have that and now i'm gonna map on once again i'm just going to make an

92:12

image component and let's actually go make it fast why

92:17

not okay so once again in the root of my project i'm

92:23

just going to make components and in here i'm going to add image

92:31

js

92:38

const image equals and then i don't know what i'm going to pass

92:44

through yet but i'm going to return

92:53

a div with the class name

93:01

now i either want this to be a main image or an image so i'm going to have an identifier that

93:07

i'm going to pass through i then identify and if that identifier

93:13

is a main image um well then just keep main

93:22

image otherwise oops otherwise it's just an image

93:29

okay otherwise it's just an image so that is what the class is gonna class

93:36

name is going to be uh and then image is just gonna be well the source of the

93:43

image which i'm gonna leave um i'm gonna leave just blank for now cool so like i said i'm gonna have to

93:51

pass through an identifier and the image itself um okay so

94:02

i think that is fine for now it's going to save this file and then go

94:09

back to the slug so like i said we need to pass through two things an identifier and

94:16

an image for it to uh attach to the image source

94:26

so the first one well we know that an identifier

94:31

for the first one we want that to be main image okay

94:38

um and then the image we want to pass through is the main image from our data

94:46

uh and for these sub images well i'm gonna have to map onto here so the

94:52

identifier for this is just gonna be an image and then let's actually map so we're

94:57

gonna get our images from our data i'm gonna map um and for each

95:05

thing i am actually going to want to have a let's have

95:12

a key and the image oops

95:21

okay wrap that round

95:31

our function so i'm going to pass through an image

95:37

okay so i'm getting the images that we have that we have okay so i'm

95:44

getting the images that we have from our data and then i'm using map to

95:49

map the image onto each one of my image components uh so that should work i'm literally

95:56

going to pass through each of those images so i'm just going to click save for now it won't work because we

96:03

still have quite a lot of things to do image is not defined and we also

96:08

have an imported image into here so import

96:14

image from components

96:20

components there we go image now

96:27

we are gonna have to use uh a url for from sanity in order to essentially

96:34

get our images to show up so i'm gonna pass through the image

96:39

and i'm actually gonna import so let's go ahead and do that import uh

96:46

url4 from sanity so

96:54

if you don't remember that is from

96:59

here that is the code that i gave you and

97:05

we're just using this we are using create image url builder

97:11

that we have imported from next sanity and we have done some configuration and

97:16

saved as url4 now in my images js i've imported it and

97:22

i'm going to use it right here and what i'm going to do is get our image

97:27

that we have passed through but wrap um url4 around it like so

97:36

let's save does not complain to all right oops

97:43

um we need to export it export default

97:49

image

97:55

so there we go we have now got our image and of course

98:02

you can do a bunch of stuff with this um if i really uh there's a lot of like

98:08

cool stuff you can do like i could do auto for matt uh yeah like

98:15

the um sonic documentation will provide you with a bunch of stuff that is quite fun for you to do

98:20

as well so if you want to do that go ahead and have a read more about this right here

98:28

so the create image url builder okay cool so we've got our main image uh

98:35

now we just need to work on the little images too so let's do that

98:44

hmm i don't know why our images or small images aren't working

98:49

let's have a look console log images and let's see console log

98:57

main image it's very strange

99:05

so those are images each image has an asset a key and a

99:11

property type and this one just has the asset and type it's because we gave this a key

99:18

we've mapped on a key but this looks exactly the same as

99:24

this was essentially what is giving us the image

99:33

very strange very strange indeed

99:39

okay well you know what i'm going to come back to this um let's i'll read up on the

99:44

documentation because that's really weird i don't understand because all i'm doing is just passing on an

99:50

image into this image component that i made and it should work the same as the

99:56

main image but for some reason it is not

100:02

okay well i'll go back to it um what else can we do maybe let's do some

100:09

styling let's style it up so let's style up the images section the main image

100:16

and the sub images section so

100:24

images section images section i'm going to use display

100:29

flex and i'm also going to use flex wrap which we don't need to do that

100:35

i'm just going to do display flex and um make the

100:42

border radius of the whole section how will this look the same let's make

100:49

it like around 10 pixels i think that should be fine and hide any overflow so overflow hidden

100:56

so you can see we already have a [Music]

101:03

you can see now we have a little rounded edge and then these have moved over here so

101:10

now let's actually maybe do the sub section so sub images section

101:20

and just make sure that they also once we have the images that they are display flex but wrap over

101:26

themselves so i'm going to do flex wrap wrap like that and also overflow hidden

101:41

call overflow hidden do we want to start the main image yes

101:49

main image

101:56

let's give it a width of 50 pixels 50 sorry so it's always 50

102:02

of the apparent component and a height of 270 pixels

102:09

and also overflow hidden

102:21

maybe that's a bit too small

102:31

or we could just make it let's make the image

102:37

yeah maybe let's shrink it down a little bit i think maybe that would be wise so

102:46

any images in the image class or even the main class

102:54

uh

103:00

main image because we don't know about the other ones yet so the image within that let's give it a width of a hundred

103:08

percent cool so that looks better i'm just making sure that we can see the whole image

103:14

based on its width okay um i think i'm now ready to carry on

103:21

obviously it's a bit annoying about these but we'll fix those later now what else do we want to do

103:28

we obviously have all our information i am actually perhaps let's actually make a div that

103:34

is a section so we can start making this look even more like the airbnb website

103:41

section and then in it first i'm gonna have a

103:47

div with the class of information for the first half of our

103:53

section which has all the writing that we did so there we go and i'm just literally

104:00

going to i think take all of this and put it in here and then of course

104:07

make sure it's formatted correctly for readability

104:16

so one more there we go so there we go and now we have a section which has

104:22

information um

104:28

let's perhaps style those up too so i'll do this up here we've got a container we also have a reusable section

104:36

and we have a class m4 mason 2.

104:45

margin 20 pixels uh let's have zero so 20 pixels on the

104:52

top then i want zero on everywhere else and then i also want

105:00

display flex but uh oh yeah and justify content

105:08

uh space between so that's what all our sections are gonna be like and then the information

105:23

well i'm just going to give it a width of 60 pixels because we have the information box that i want

105:30

appear to appear on the right

105:35

great so now i think i need to move my price box so it's in the section but not

105:42

in the information section okay cool so this is looking a lot

105:50

better and of course more and more like our airbnb site should

106:02

okay so i feel like we're done with the top part now um let's just make another

106:09

line here and right under that let's

106:16

actually start with um i'm gonna put the description

106:24

so they just script churn of the property itself

106:31

followed by a another break or line uh and then because it is literally a

106:37

line or break really sorry and then under that

106:46

um once again i'm going to have an h2 tag

106:52

because that's what the website looks like and i'm just going to use my review amount again they like their

106:58

review amounts review amount of view

107:03

and then is multiple and pass through the review amount like

107:10

so now if review amount

107:18

exists or is larger than zero in actual fact and we'll actually know

107:25

just if it exists then we want to show the following then we want to essentially get our

107:32

reviews and map so similarly like the images

107:37

we're going to map our review onto each review component that we are

107:45

about to make so there we go

107:52

we're going to map it out like so

107:59

so for each review so we're getting the reviews array we're then uh gonna get a individual

108:06

review and we're gonna get the review component that we are of course yet to make

108:15

why is this not liking that

108:22

okay um and then to each review component well let's actually

108:28

pass through the review itself key

108:38

and the actual review cool

108:45

so now let's go into components and make a review js component so similarly to

108:52

uh the image const review equals no props to pass in for now

109:00

and then just return uh something so let's just put a div there for now and let's not forget to export

109:08

default re view now how do i want my review to

109:14

look well i know that i need to pass through the review itself um and then what do i want to

109:22

return well let's actually make this a class name

109:30

review box so that's something i'm going to style up and in my review box i want to add let's put an h1

109:38

tag the review rating

109:45

let's put another h2 tag and the traveler who did it so reviews traveler

109:52

that's attached to the review and then an image so i'm going to put an image of

109:59

the traveler so let's close that off the image i want to put through we're

110:07

going to have to use a url again so let's get the review

110:15

traveler image because i know the traveler has one i'm going to use url4 to wrap around

110:23

the review traveler image so i think that's it what else can we

110:30

have from the review i'm going to console log view just so you can see

110:38

yes i know review is not defined that's because we have not imported it at the top so i'm just going to import

110:44

that import review from review

110:52

url for is not defined uh so let's do that we need to import it

110:57

don't we so we need to import from sanity or sanity file import url for

111:04

from uh let's find some oops we went back too far

111:11

sanity okay

111:18

okay let's do some more debugging so we are passing through our review we're obviously not

111:26

passing through something correctly here

111:33

okay so let's go back here

111:38

let's just try console logging the review itself

111:44

okay so we are getting the review we're getting the review rating

111:50

so let's put that back in

112:00

oops

112:07

so there's one review that says five at stars let's also perhaps try the review

112:16

traveler

112:26

hmm the review traveler does not work okay

112:35

review traveler so that's it review traveler name okay that's why

112:41

because we can't actually have an object can we so review traveler name

112:47

i thought i remembered everything correctly but i did not so we've got our rating we've got our name oh my abdullah has given us a rating now

112:54

let's get his image

113:04

and then we have his image of course it is really big but if you remember what i told you we can actually format the

113:11

image directly from here so i could do something like width 50

113:19

height 50

113:25

crop focal

113:30

point see if that has worked so that's a lot better as you can

113:37

see um nice uh of course feel free to you know like

113:46

make it look however you wish but i think for now i am fine with that image just there so this

113:54

is looking good we are getting our ratings we are getting all the information

114:01

what else is there let's have a look

114:09

okay and the last thing we are actually going to do is

114:19

so once again just going to put that on one line let's make a

114:25

line because the last thing we need to do is show the location of our property on a map so i'm just going to give a

114:32

title location and for this part i'm actually going to

114:39

need to create a map okay so we will do that in a bit

114:45

or actually should we do that now okay let's do that now so for this i am going to have to use a

114:51

google api key google maps api key so for those of you who don't

114:57

know where to get one from google maps api

115:03

this is where i got mine from you need to sign on to the google maps platform

115:08

get the maps javascript api and then you are essentially provided with

115:14

a bunch of documentation um i'm obviously not going to go into this in too much because this should probably be

115:20

like a separate tutorial of its own but however um i'll just quickly show

115:27

you how to get your api very quick lee

115:38

so you would go into here that is the url and then you would

115:45

essentially create an api key there is a bunch of other stuff but as long as you get here you

115:51

should be fine it will then take you to a credentials page you might need to do a bit of signing up but once you have

115:59

that you should get to this which will give you credentials and you can

116:04

create a new project i of course have already created a new project so this is my project for uh using

116:11

sanity and i have my api key right here so i would simply copy that api

116:17

key and then in a dot env file i'm going to put google

116:25

places ap i like so and i am just going to

116:32

paste my google's places api so that is really

116:38

it uh once again this is what the page looks like um and this

116:45

is how i got to get the token it's on the google maps platform

116:52

so make sure to get to this page and once you do have that well it is quite good because

116:58

there's a lot of um code for us

117:03

so for example i would simply react map google

117:12

map api okay so this is what we need i literally

117:18

just googled it and got my answer so i'm just gonna take this it really isn't very complicated

117:27

just go to the react google maps api package and i am going to take all of

117:34

this like so um and then in my components i'm going to

117:39

create a map js file and simply paste all that code

117:45

it really is that easy once again this is the package that you need react

117:52

google maps api so i've pasted all of that in here of

117:59

course you need your api key here so we go process env

118:04

dot google maps api key because that is what we saved it as

118:11

in here oh no we didn't google places api it's a good thing that i checked

118:19

okay great so i believe this is all we really need let's

118:25

have a closer look so we have the container

118:32

style we have the center i'm actually going to move this into the component itself

118:39

so i'm just going to put it um perhaps down here i'm also going to

118:45

rename this so let's make it make this const map

118:52

equals just to keep everything consistent and of course export default and rename this to

118:59

map 2. click save now i'm actually going to want to pass

119:05

through the location that we have from our data and the location if you remember had a latitude

119:12

and a longitude so instead of having a hard-coded lasting longitude i'm going

119:17

to use my location latitude and i'm going to use my location

119:23

longitude just just like that

119:28

okay

119:36

and i think that should be it okay

119:42

so let's click save so we've got our map now i'm going to import map from

119:49

map

119:56

and then let's use the map under location and of course let's pass through the

120:10

location click save

120:18

all right we didn't import the package whoops that is my fault so let's start a new tab make

120:26

sure it's the tab of the front end npm i and then just import that package so we

120:31

can use it

120:38

okay now i'm just going to restart this and

120:54

scroll down

121:04

now because we are using it in dev mode it can be a bit temperamental if you want to give in your payment

121:11

details i think that should clear it up but um let's just see if this is working

121:16

so we're passing through our location let's see the map okay

121:22

so let's just console.log girl console.log console.log

121:29

location

121:34

latitude um and then let's actually put something here so we know what we are looking at

121:42

so we are getting it ah there we go so we are getting our location so as you can see

121:49

a lovely flat situated in the heart of battersea and that's where it's taking us it is taking

121:54

us to battersea so we've done it we have successfully uh

122:01

got our map working we can of course change the uh container style that is

122:08

totally up to us for example i might want to put 100 pixel

122:14

100 width and i think that looks a little bit better i can of course also put a little ma

122:22

i can of course also put a little marker where i want um my location

122:29

to be all i would have to do for that is essentially uh add a marker

122:36

so instead of this here i would use marker

122:41

and then the marker actually i don't need a closing one because it's self-closing and then i would just pass

122:49

through a uh position because marker is actually also

122:58

from here right so i need to get it from there it's already like pre pre-made for us

123:04

and pre-decided that it takes a position that needs a

123:16

latitude and we're going to give it location latitude and longitude and of course

123:24

we're going to give it location longitude um and then we can of course

123:29

give it an icon too uh i'm just going to give it like the standard

123:36

icon that came with um the documentation from uh google

123:43

maps google spaces google places api cell image and the

123:50

image is going to be const image equals

123:58

oops image and then i'm going to make sure that the anchor

124:07

has google new google

124:14

maps point so once again i'm literally just getting this from the

124:21

documentation

124:26

so if we go back here and we look at markers so add a marker to your map

124:31

that's basically all i've done i've used these instructions um to do so essentially

124:39

so once again i'm literally just using the documentation and i'm just going to use this is what

124:44

i've used essentially um and i'm just going to use this url as the

124:50

image so let's copy that so that our marker can have a cool little flag like that

124:57

so of course you can personalize this it is totally up to you but if i put a

125:03

little beach flag then i should get a little

125:12

once again i don't know why like i said it is temperamental because

125:20

i'm using it in developer mode i believe as you can see it says for development purposes only but i find

125:26

that somehow if you just i'm just gonna console.log

125:33

this then that seems to work for development purposes i can't see the map

125:38

the little marker though why is that

125:45

ah and there we go we now have a little marker that is a beach flag on our property

125:52

cool okay i'm loving what this is looking like um i do want to go back to the images

125:59

but like i said i'm gonna have to do some research on that so let's move on to the main page first and

126:06

then i'll go back and tackle this okay

126:11

uh oh yeah we wanted to also link this back to the um

126:18

home page so perhaps let's do that uh i'm just going to so maybe we

126:26

don't have to use a on click maybe we can just link it

126:36

next link

126:42

so we can just use a next link uh i think i'm going to do that so i'm just going to import that

126:49

here import link from next link so instead of having on click i could just

126:56

wrap my um div my button div

127:03

in that link tag and make the edge ref go to the home page and that should um

127:10

that should work so let's have a look

127:17

and great that takes us to the home page so now let's do the home page right okay

127:23

let's do it so i just need to go back to this page right here so at the moment

127:30

we're not returning anything let's change that okay

127:36

so in here i guess if properties do exist well then we want to essentially

127:43

show a feed right so this is what we want to show if they do exist we want to

127:49

uh let's create a div with the class name of

127:55

main okay and this is going to have a it will have our feed in it so

128:03

class name let's call it a feed container

128:15

okay and in our feed container um before we do any mapping because i

128:20

want to map all the properties in here let's just put places uh to stay near

128:28

you

128:35

uh a div with the class name

128:41

of feed

128:51

properties map so this is where we're going to do some mapping and once

128:57

again so i'm going to get the uh property itself and its index and

129:05

for each property well let's actually create another div

129:13

so i'm going to map onto this and then once again i'm actually going to use the

129:20

link tag i think but let's just have a think about what's going to go in here

129:25

so i've got my div uh let's actually let's just keep it simple

129:34

includes the class name of card for now uh and the key

129:42

of property id

129:49

okay so i'm going to map each property to this um little card essentially so we've got

129:57

our opening div and then inside each of these i'm going

130:02

to get an image oops tag

130:12

so again it's self-closing and for each of these images well it needs a image and for this i'm simply going to

130:20

get the property so property main image and of course we need to use

130:28

the url4 um like so so we need to import that to

130:35

uh url4 because it's in the same place as the sanity client so let's see how that looks so

130:42

amazing we are getting the properties that is looking good maybe let's do some styling before we

130:48

carry on so we need to sell the card the feed the feed container and the main so let's do that here

130:56

uh main

131:01

feed container the feed itself and the

131:08

card okay so i'm just going to give it some like rough styling really for now

131:16

let's make the main well it's going to have to have both the feed and the maps so i'm going to put display flex uh in

131:24

there and flex direction row because i want them to appear next to each other side by side

131:32

um now let's have a look at the feed container where the feed container uh i want it to

131:39

be width uh a hundred percent

131:48

and take up the whole height of the uh windows so like so

131:54

um i'm going to give it a background color that's slightly darker than white so i'm going to use

132:02

f8f8f8 and it's giving padding 20 pixels because everyone likes a bit of padding

132:08

in their containers now the feed itself i'm just going to put display

132:14

flex uh flex wrap wrap so the anything that goes into the

132:21

feed wraps over each other and then finally the card itself

132:29

uh each card is just going to have a padding of 10 pixels so we've got the feed and on the other

132:34

side we want to have the maps so i'm just going to put well the map

132:40

with all our markers so map

132:47

once again let's start that next to the feed maybe

132:55

also give it with fifty percent and the feed container to width fifty percent two so that they are 50

133:02

50. and now let's make these card images a bit smaller so perhaps make sure that the uh

133:11

any image in the cards or card image

133:16

his max width

133:21

i don't know 100 pixels it's maybe a bit too small 200 pixels

133:32

okay so that's immediately looking like a lot better uh it would just mean that they

133:38

sort of wrap over each other i guess

133:44

you can even make them 250 pixels it is it's really up to you

133:52

i'm also going to give them a order radius of 20 pixels

134:06

cool so we've got our little places to stay next to us we can even display more

134:12

information about them too so let's go ahead and do that

134:20

so i guess we don't need the index anymore um we do however want to link the card so

134:27

i'm going to just put a link that we're going to import once again from uh next link and then

134:34

we actually need to put the reference of the um

134:41

href of the image of the property slug so i'm just gonna do this

135:01

property forward slash and then we're gonna use

135:07

the property slug current

135:15

[Music] okay that should work let's check it out

135:21

link is not defined it's because we did not import it import link how do we do it

135:29

here okay

135:37

so now if we click on one it will take us directly to the correct page and we can go

135:44

back to cool so we've done that uh let's actually also maybe show

135:51

some more information so here is the card itself um

135:57

let's also add a p tag that perhaps shows the uh reviews because we love

136:04

reviews

136:10

so i'm gonna get the property and get its review uh views sorry and their

136:18

length um so i'm just going to go that and then review and once again

136:26

is multiple and pass through whatever this is

136:32

so if that number is multiple we'll get an s review um let's also perhaps

136:40

put in the property title so property title

136:50

like so and then the price per night why not so again let's make

136:56

that an age of three tag and go property price

137:02

per night

137:12

cool so now when we look here amazing this is looking a heck of a lot better

137:19

uh and then let's just put her like it's like so awesome i mean

137:27

i'm really happy with this i think this is looking really really cool okay

137:35

perhaps we don't even need that in bold but hey whatever it is absolutely

137:42

fine so we've got our place to stay near you now finally

137:47

let's actually get all the locations of these places actually no let's make a header first

137:53

sure why not let's actually make a header um

138:00

so for this i'm going to just create a navbar oops nav bar js

138:10

now uh the navbar is something to be constant nav bar like so

138:19

and i want the navbar to well it's going to have the logo for one so i'm just going to have a div

138:29

class name nav i need div

138:37

so another damn div with the class name of logo this time

138:46

okay and of course we need to export default love

138:57

okay now what do we want to do with this nav bar hmm

139:08

in the underscore app js file now again i'm just going to change this

139:14

to const my app equals just to keep everything consistent

139:19

and here in the return instead of just returning this component like so i actually

139:27

want to return the component with all the page props but with a navbar above it meaning that

139:33

the navbar will be on every page that we have no matter what so i'm just going to import that

139:38

nav bar up here and it means that will be on our property page or our main page

139:44

just whichever really so that's going to be quite cool i'm going to import nav bar from

139:52

my components and that is really it obviously we

139:59

haven't really styled it up so maybe let's style up before we have a look at what this

140:04

looks like so let's put it at the top actually

140:12

now and then of course we also need our logo

140:24

so our nav is gonna have a position um sticky because we wanted to be at the

140:31

top the whole time um i'm also going to give it a

140:37

z index so it's always at the forefront of a hundred

140:43

let's also give it some box shadow so rgb uh same as last time

140:51

so over 12 percent um

140:57

zero six pixels 16 pixels so i think that should be okay

141:04

oops

141:10

and a padding of 30 pixels and then our logo

141:17

um i'm actually going to use a background image for this so background image

141:24

and i'm going to actually import a image so let's

141:31

create a another folder here called images and

141:40

i'm just going to use a logo that i have pre-made and put it into my images like so

141:48

and now this means that i can go into my images

141:56

and get to the airbnb logo um i'm also going to just make sure that

142:02

it's the right size so let's just say like uh 130 pixels

142:08

and then a height of 40 pixels

142:19

okay let's have a look

142:25

hmm so that's not looking great what is happening here a background size

142:32

maybe you need to give it

142:41

okay so that is looking better and you'll see if i click on any of these

142:46

that our logo is still up there because the navbar is still up there the box shading

142:53

hasn't been box shadow sorry hasn't been applied to our nav bar why is that

142:59

now we've got one zero extra there that we don't need

143:08

hmm still so nav all right dot enough because it was a class of nav

143:14

so now we have okay this is looking really good the last thing you want to do is

143:21

actually um the cluster maps so in the index.js

143:27

once again i'm actually going to have to create another component

143:34

because we're going to have to have multiple markers so we can't just you reuse this one sadly let's call this dashboard

143:41

map js uh and i am gonna copy all of this

143:47

actually into my dashboard however we're gonna have to

143:53

map out markers for however many properties we pass in essentially so just to make it

144:00

less confusing i'm gonna rename this we could have kept this the way it is uh but i think just for readability

144:08

let's rename dashboard map here and dashboard map here

144:16

cool so this time we're not passing through a location we're gonna pass through properties so multiple

144:22

properties okay uh and that means that the how are we going to

144:30

do this

144:35

so we no longer really need this i'm going to get rid of that

144:45

now we need to map on to the marker so for each uh so i'm going to go get

144:52

the properties and i am going to map

144:57

so let's make sure to do that at the end i'm going to map um

145:10

each property and its index so we probably don't even need index but

145:17

that means that for each position well if there is a property

145:25

uh and its location exists we want to get the latitude and then the same for the longitude

145:33

so just stick that in front of there you don't need that so we're going to

145:39

map onto each one each of the properties uh latitudes and longitudes okay

145:47

so now let's have a look at what this looks like we didn't import the

145:53

dash map dashboard so once again let's go here here is the map and then i'm simply

146:00

going to put the dashboard map and then we need to pass through

146:06

the properties like so properties and then we need to import it

146:14

ah which is already done for us thank you very much so now let's have a look at what this

146:19

looks like center is not defined i yes because we don't have a center anymore does it

146:26

need a center yes it does but we need to get the

146:32

average of all these properties which is uh because we can't really

146:39

do that but luckily they're all in london we can't do it easily we could but for now

146:46

i'm just going to use my center as the first locations

146:53

uh latitude and longitude okay so property

147:03

properties we're gonna go into the first one and get its location uh latitude and

147:11

we're gonna go into the first one again and get its location longitude

147:17

so now we have a center

147:24

why is it there i don't want it there

147:36

heights let's also make this 100

147:42

vh amazing so we've done it we have mapped on two of those properties like i said the

147:49

center is actually the first properties location if you really wanted to get an average

147:55

of the longitude and latitudes of each one you'd have to do that math in that component

148:01

i'm not going to do it here but if you do want to do it you need to do exactly that get

148:07

the average point of all of your properties longitudes and then the

148:12

latitudes so this is looking really cool i'm really pleased with how this has turned out

148:23

why is that appearing there i don't want it appearing there though let's fix

148:30

that i want it here um

148:37

let's just see what our map is doing let's just give a background color

148:43

of uh red for now

148:50

okay so it's there why why are you there

149:05

let's try and move it out one see if that helps no ah okay yes

149:12

and now i guess

149:18

main we'll just do

149:24

let's find me oh that's why i didn't okay ah my god i've been coding

149:33

for too long so now i can get rid of this red let's go back here i'm just going to

149:39

console.log something so it works console.log

149:46

let's just do this and then have a look here and there we

149:53

go how good is this we are getting our properties if we add a new property in our content

149:59

management system it will show up here and the little flag for it will show up on the right so the little marker

150:06

and then if we click in here we get the actual

150:12

flat or property so this is amazing we have now finished our

150:18

airbnb clone um i'm gonna finish this image problem now for sure but thank you so much for

150:26

coding with me i've really enjoyed this this has been a long one but hopefully you do have a very uh

150:34

well-rounded app complete with content management system complete with a google maps api i'm

150:41

going to put all the links to everything that we discussed in the description below as well as where to get your google maps

150:48

api uh where to get the sanity information and just in general

150:56

where to find my finished code which i'm going to tidy you up to but for now let's get to

151:04

fixing this image problem okay so what i would do is just this i would simply

151:12

change this a little bit around here um i'm not sure why this wasn't working

151:20

but this should be the best solution if you do ever get stuck by the way sanity does have a discord

151:26

channel that i'm aware of and the one time that i did ask something everyone was quite responsive

151:32

so that was good so please feel free to use that i don't have the link but i'm

151:38

sure you can find it on sanity io or i could actually find it and put in the description below

151:44

too so reminding me if it is not there but yes so this is how we would fix

151:50

that and ta-da okay so we are now officially completed

151:57

thanks so much again for watching please do share your finished products i'm gonna clean this code up a little

152:04

bit so while it will mostly be the same if i have maybe like changed some styling or

152:09

something uh then don't freak out i'll most likely just be changing the styling i do want

152:15

to keep this project as similar or exactly the same as this tutorial has

152:21

been so once again here's my finished product i hope you uh have enjoyed this

152:27

tutorial please do give me a thumbs up and a sub if you did

152:32

and i will see you again for another tutorial soon

No comments:

Post a Comment