- Read Tutorial
- Watch Guide Video
For this, we're gonna pretty much mimic what we did with the about page so this should be a pretty quick guide. And I want you to perform the same type of task that we did last time where I'm gonna walk through what I want the end goal to be. I want you to pause the video and then I want you to try to implement it yourself and then watch the way I did it and watch my solution.
So what I'd like here is exactly what we have with the about page where I have a photo on the left-hand side and then I have the content on the right-hand side so this is gonna be reinforcement learning for you. The only key differences are I want a different photo so you can get practice in pulling in a different image.
I'm just gonna pull in the same image we used for the auth page because no one except you will ever see that page. And then on the right-hand side I want a list of contact information items and to make it look a little bit better than just plain text I also want you to add some icons as well.
So go research through Font Awesome and then search for icons related to say a phone number or an address or city or email address, anything like that. Now I'm gonna add the caveat, if you do not wanna put your personal information out there or if you are under 18 years old, just put some placeholder content.
Don't go and put your personal phone number or anything like that on there if you do not want the rest of the world to know about it because when we deploy this, this is gonna go live on the web so make sure that you keep your privacy intact. So good luck in building that out and I'm going to let you go and we'll come back and we'll build the solution.
So the solution that I'm personally going to build out is going to be very similar to what we already have with the about page. So much so that I'm gonna start off by simply copying over everything from the about page right into the contact page. So if I come over now to the contact page, you'll see it's identical.
But we're not quite done, first I wanna switch out the image and I'm going to use the image that we have for that auth page and so here I'm going to call it contactPagePicture
and that's what we're gonna be calling down in the background size. And now instead of static/assets/images/bio, this is going to point to auth and then also to login.
contact.js
import React from "react"; import contactPagePicture from "../../../static/assets/images/auth/login.jpg"; export default function() { return ( <div className="content-page-wrapper"> <div className="left-column" style={{ background: "url(" + contactPagePicture + ") no-repeat", backgroundSize: "cover", backgroundPosition: "center" }} />
Now one thing I want you to notice here, it's one of the main things I want you to notice about this guide is that when you import an image and you store it inside of a module like we're doing right here, you can name it anything that you want. So if you were to open up the auth component, right here we called it loginImg even though the image itself was called login.jpg. Here we're calling it contactPagePicture so you can call it anything you want.
This is exactly like when you import a module that was exported as default. You can call it anything you would like. So hit save and let's just verify this is working and yes, we have our image, our layout's there, everything looks good.
So the majority of the rest of our time is simply going to be spent in building out those bullet points for our address, phone, contact information and then integrating the icons.
So let's switch into the content itself and make sure you're not changing your about page since they look so similar. And so I'm going to get rid of all of this content and I'm gonna start building out the structure so this is really where I wanted you to spend the majority of your time was building out a correct structure where you could center all those items in that right column, but then also integrate icons with text, customize their look and feel and their layout.
So first thing I'm gonna do here is I'm gonna create a series of divs and you may think that I'm going overkill with as many divs as I'm about to create, but hopefully, by the end you'll see that you can really not ever have too many divs, assuming that you're organizing them properly. The more divs you have, the better chance you have at being able to go in and select the correct item and you're gonna have more control over the styles that you have.
So the first div I'm gonna have is going to have a className of contact-bullet-points
and that's gonna be the first div, all of our contact items are gonna be inside of this one. Now after that one I'm going to have a bullet point group, this kind of follows along with what we did with our form.
So inside of there I'm gonna have a div with a class name of bullet-point-group
and that's gonna contain the icon and the text and because of that inside of bullet point group we're going to have a class of icon and a class of text. So div, class name equals icon and then we're gonna have the same thing div, class name equals text.
And so for this first one let's make this first one for the phone number so I'll say 555-555-5555 and add some placeholder content there. And now let's just first, before we actually try to bring in the icons, we can save that till the end. I'm just gonna put a little greater than symbol there just to be a placeholder for what we're looking for.
contact.js
import React from "react"; import contactPagePicture from "../../../static/assets/images/auth/login.jpg"; export default function() { return ( <div className="content-page-wrapper"> <div className="left-column" style={{ background: "url(" + contactPagePicture + ") no-repeat", backgroundSize: "cover", backgroundPosition: "center" }} /> <div className="right-column"> <div className="contact-bullet-points"> <div className="bullet-point-group"> <div className="icon">></div> <div className="text">555-555-5555</div> </div> </div> </div> </div> ); }
So if you hit save and come back here, you can see that our content's there centered inside of that element, but it's definitely not what we're looking for yet.
So let's continue building this out or let's build these styles now. Inside of our right column we can go and start defining these inside of our layouts file. So go inside of right column and we'll go with contact-bullet-points. And the very first rule we're gonna have, this is gonna display: grid and we'll have grid-template-columns and for this one they're all just gonna be stacked on top of each other so it's gonna be 1fr for all of those and then we're gonna have some grid-gap and for this we'll go with 21 pixels, that'll be the first one.
Now we need to go a little bit deeper, we need to go into the bullet point group so now we're gonna grab the bullet point group and we're gonna select and define the styles in here. First one is gonna be flex so I want these items by default to be right next to each other. Even though they're divs, they usually would just stack on top of each other like we saw, but I want them to be right next to each other so flex does that by default and then I want to align-items: center so that is going to align them vertically.
layouts.scss
.bullet-point-group { display: flex; align-items: center; }
So now that we have that we can hit save and there we go, that's working nicely.
We're getting closer to the type of layout that we're wanting. So now we have to select our icon and then our text. So for our placeholder icon, for that we're gonna say I want the font-size to be pretty big, I want this to be 2em and then I want the color to be teal and then for our text class, this one the font-size is gonna be a little bit smaller. Let's go 1.5em, but I want it to be nice and heavy so I'll go with a font-weight of 900 and then let's add some margin to the left of 21 pixels.
.bullet-point-group { display: flex; align-items: center; .icon { font-size: 2em; color: $teal; } .text { font-size: 1.5em; font-weight: 900;; margin-left: 21px; } }
Hit save and there we go, that is looking really nice.
Let's go now and I think it's time for us to grab our icons. So I'm gonna open up our dedicated icons directory. Doesn't it feel better not having this in the app file anymore? And we're gonna add three icons. Now we could go to Font Awesome, go through the process, but we've done that quite a few times for each one of these elements throughout the course.
I already did that so I will show the ones that I picked out because you might've picked some different ones. So the very first one was faPhone, then faEnvelope and then lastly, faMapMarkedAlt, there we go. Okay, now we can take each one of these, I'm gonna copy this and add them to our list in the library. Hit save and Prettier will format it for us.
icons.js
import { faTrash, faSignOutAlt, faEdit, faSpinner, faPlusCircle, faPhone, faEnvelope, faMapMarkedAlt } from "@fortawesome/free-solid-svg-icons"; import { library } from "@fortawesome/fontawesome-svg-core"; const Icons = () => { return library.add( faTrash, faSignOutAlt, faEdit, faSpinner, faPlusCircle, faPhone, faEnvelope, faMapMarkedAlt ); };
Now we can actually call these, make sure that you import FontAwesomeIcon at the top so I'm going to say FontAwesomeIcon and we will now that we have that, I'm gonna copy it, say I want to import FontAwesomeIcon and this is a module, it's not exported as default so make sure you wrap it in curly brackets and that's from fortawesome/react-fontawesome.
contact.js
import React from "react"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import contactPagePicture from "../../../static/assets/images/auth/login.jpg";
Feel free to reference any of the other components and that's actually what I did when I was testing this out because this one is really not my favorite naming structure. I know I've talked about it before, but calling something that's usually Font Awesome, Fort Awesome is just gonna lead to confusion and it's gonna make it very hard to memorize what's being called.
Okay, so I have our FontAwesomeIcon that is imported and now let's actually call the type of icon that we want. So this first one is going to be the phone, close that component off, hit save and let's test it out.
<div className="icon"> <FontAwesomeIcon icon="phone" /> </div>
There we go, that looks really nice, I like that.
Okay, so now that we have that, we now just need to populate the rest of our icons. So if you click on bullet point group, you can copy this down and then we're gonna do that one more time so I'm going with three. You can go with as many or as few of these as you would like. So the next one is gonna be the envelope so this is where I'm gonna be placing the spot for an email so jordan@example.com.
And then lastly here for the phone, or instead of phone make sure you put map-marker-alt. If you're using the same icon as me and here I'll just go with say Lehi, Utah.
So if you don't feel like you want to put your full address which I wouldn't recommend. I don't really see any scenario where you should ever put your actual home address in a spot where it's publicly available, but one thing that if you're trying to get a job, recruiters do like to know the general area that you live so maybe placing the city or something like that, that could be a good idea.
So if you hit save and now come back here, you can see almost everything's working.
It looks like I have a... I probably have something... Oh, you know what, I think this is map-marked and let me see if that is also... Yes, okay, yeah, it's map-marked, not map-marker.
<div className="right-column"> <div className="contact-bullet-points"> <div className="bullet-point-group"> <div className="icon"> <FontAwesomeIcon icon="phone" /> </div> <div className="text">555-555-5555</div> </div> <div className="bullet-point-group"> <div className="icon"> <FontAwesomeIcon icon="envelope" /> </div> <div className="text">jordan@example.com</div> </div> <div className="bullet-point-group"> <div className="icon"> <FontAwesomeIcon icon="map-marked-alt" /> </div> <div className="text">Lehi, UT</div> </div> </div> </div>
Okay, come back and that's working, that looks really good, I like this for a contact page.
I like the contact page to be nice and simple. Make sure all of these details, whatever you do choose to give, are up to date and a recruiter will have no problem getting a hold of you.
So great job. We have now completed all the styles for our contact page, for our about page and I think in the next guide we should go out and we should create that portfolio detail page so that when a user clicks on one of these portfolio items, they'll be taken to that page.