Finalizing the Shipping Form Component
Hey there, welcome back to the course. In this video we are going to place this shopping cart and calculate it and basically finish off the entire component shipping address.
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

Let's go ahead and do this by going into visual studio code and going into InfoHelp.scss and we're going to do our order summary style in here as well, we're going to say that it has a width of 200 pixels. Now what's going to happen is it's going to give us a width of 200 pixels.

So we have this right here, and it has the width.

large

Now there's a problem and it's that one our title is not there for some reason, and two these are all in their own line, we want taxes and shipping for example, we want the zero to be over here. We also want the 7.96 to be over there right. You get the point, we want it to look like our design, not like this right here, we also want total to be green. Okay, let's start off by making the total green, we already made a case for that right here, all we have to do is add that into the total one.

So let's go to orderSummary.js and on this total here, let's paste info-title-green here.

orderSummary.js

<InfoTitle className='order-summary__total info-title-green' title='Total' value='$8.02'/>

Now go into Chrome and you'll see that it's green, if you remove the page... it's not green. Okay so what we need to do is go back to InfoHelp.scss and we need to do this. The reason it's not working is because we're trying to say green and then append this onto it to the title. What we need to do is just reference it directly by saying .info-title__title like that.

Or we could even dig a bit deeper and do this. So basically what I did was I just wrapped info-title with info-title Green.

.info-title-green{
  .info-title {
    &__title {
      font-weight: 600;
      color: #00CB79;
    }
  }
}

Now it's basically this but with info-title green around it, minus value. Let's see if that works.

large

Okay now if you didn't get that because it's kind of a weird way I did that with my arrow keys and stuff, just type that in to get that to work. How this is working is it saying okay info-title__green, it's just that since it's wrapped around this it's going to allow us to apply different styles to this tag. Basically, it's like and if statement if it has input title green, then apply the styles too not just these ones.

Let's go ahead and let's say on each of these info titles that they have a display of grid and a grid template rows of start to end 1fr let's then say that they have grid template columns. We'll say start to Middle to end, and 1fr 1fr, then what we'll do is say that this one belongs on grid column start to end and grid row s/e so copy those two and paste them in the &__value and grid column is middle to end.

InfoHelp.scss

.info-title {
  display: grid;
  grid-template-rows: [s] 1fr [e];
  grid-template-columns: [s] 1fr [m] 1fr [e];
  &__title {
    grid-column: s/m;
    grid-row: s/e;
    font-size: 14px;
  }
  &__value {
    grid-column: m/e;
    grid-row: s/e;
    color: #00CB79;
    font-weight: 600;
    font-size: 18px;
  }
}

So let me explain this, we have grid column s/m and grid column m/e right there. Right now we understand the concept of columns and rows right. We want it all to be on the same row so we're saying s/e on both rows. Let's go ahead and take a look in Chrome and see what this looks like.

large

Okay, you'll see everything is kind of coming together. So next step is to basically look at the design and see how wide this is because I want to make it perfect. We need this to be 240 pixels wide, ours is not 240 pixels wide, we also need this to have a gap so we'll put that in as well.

Let's go into visual studio code and let's say that the width of our order down here is 240 pixels. And then the next thing I want to do is I want to look at Chrome and see what that look's like, okay it looks better.

large

We need to make each one of these title things 240 pixels because it doesn't extend all the way over here. Let's inspect the element and see if it does because maybe it does right, see it actually does.

large

Basically we just need to set justify self on these prices here, these values, to end so that they'll go to that end like in our design here okay. So that should be pretty simple but we don't want to do it directly in the title, I mean it wouldn't matter since we're only using it here.

But the optimal thing would be to use it in order summary right because it's specific to order summary so we could just go to order summary and we could say anything with the info-title right of &__value, let's say justify-self is end, and let's see what that does.

Okay, so I just set it info-title, value, justify-self, and in order summary. So by default, it's not going to contain that, it's not going to do that, but if it happens to be in the order summary component then we're going to have them go to the right there.

Now in every case, we're using it in this app, it's always going to do that. So it wouldn't matter if you put this in here right, in value right here if we said justify self end. But the concept I'm trying to teach you here is the whole reason we use components is reusability.

I want you to know that you should apply specific styles to specific themes only in specific other components right. It's the exact same idea as saying that this is called shipping address rather than login, we want to have custom values every now and then, and that goes for styling too.

So let's go ahead and put in a grid-gap here, let's go to our design. Looks like it needs to be about 10 pixels, so let's go into our code, and let's say that the order summary has a grid row gap of 10 pixels and see what that looks like.

InfoHelp.scss

.order-summary {
  width: 240px;
  grid-row-gap: 10px;

  .info-title {
    &__value {
      justify-self: end;
    }
  }
}

I didn't note a difference and that's because we don't have it set as a grid so what we need to do is say that this is a display of grid and we have a grid template rows of repeat auto fit and, I don't know how tall are these, let's just say 1fr and then we'll just adjust them as needed so we can not be flipping around too much. Okay, let's see what this looks like, sweet that looks a lot better.

large

Let's make the height specific so the grid gap isn't any more than 10 pixels. So we don't really have a way to determine the height specifically but we can look at things like, alright this is 24 pixels high right, and it goes up here. So that's 24 + 86, that's like what... what was this again? I can't remember, 46 + 84, that's like 132. And we'll just rounded up because with this it's like 19 pixels so let's just make it 150.

Let's go into our code and let's say that this order summary also has a height of 150 pixels. Now let's go to our app and see what it looks like. Alright, it looks even taller.

large

Let's give it a title because that's really bothering me. We need to get this title up here so let's go into our application code and let's go into orderSummary.js, and it's because we're never really passing a title in, so that's not going to work so let's say title is equal to Order Summary.

orderSummary.js

<div className={`${className} order-summary`}>
  <UnderlinedTitle className='order-summary__title' title='Order Summary'/>
  <InfoTitle className='order-summary__subtotal' title={`${amtStickers} stickers`} value={`$${subtotal}`}/>
  <InfoTitle className='order-summary__tax-shipping' title='Taxes & Shipping' value={`$${tax}`}/>
  <InfoTitle className='order-summary__total info-title-green' title='Total' value={`$${subtotal + tax}`}/>
</div>

Alright let's take a look and see what this looks like, this says Order Summary that looks good.

large

Okay, one more thing we need to do to finish off the styles, actually two more things we still need to make this look a little different, and then we need to move it over to the right side. So what we need to do is we need to go into our code and we need to say, in InfoHelp.scss we want to make these each 30 pixels and then the last one we want to make 46 pixels because if you remember the last one that's 46 pixels it's the total. Remember back in the design it is 46 pixels, oh I guess they are all 46 pixels, it still worked though because they're all tiny.

Let's say that these are all 19, so these are all 20 pixels. But then this is bigger, so this is... oh the width is 46 pixels. Wow. You probably noticed that the whole time probably wondering what I was doing in case of 24. That's where I got the four from when I was reading 40 when I thought it was 44. I was probably right 24 first and then I switched to the width so I thought it was 44.

Anyway back to the coding 24, 24, grid-gap of 5 pixels. Basically what I'm seeing here is that we're gonna have to align these in the center, these titles. So let's go into our code and let's go to the title here and let's say align-self is center, as a matter of fact let's say align-items is center. Now you're probably wondering what the heck, and why my brain is working the way it is, but basically now these are centered.

large

The reason this is good is because we can see that this has a 5 Pixel gap and this has 10 pixel gap, because it's centered that's why they're different because the price is bigger and the title is smaller. This has 29 pixels, and this is 10 pixels so basically we need to say that each of these are 24 pixels high and the last one is about triple that or double, we can guess around what it is.

So let's just say order summary has 24 pixels 24 pixels and then the first one is the title I believe. Let's just say like 40 pixels and 46 pixels at the end, let's see what that looks like.

.order-summary {
  width: 240px;
  height: 150px;

  display: grid;
  grid-template-rows: 40px 24px 24px 46px;
  grid-row-gap: 10px;

  .info-title {
    &__value {
      justify-self: end;
    }
  }
}

It looks pretty good we're getting there, let's just adjust it a bit. Let's say like 30 pixels, and like 24 pixels, the grid-gap like 7 pixels. It doesn't have to be exactly like the design it can be a little different, okay see that looks good, let's make the grade gap 5 pixels.

large

Okay, that actually is accurate because it's supposed to be five between these, so that looks good. What we need to do is set order summary, well we need to move this over here. So let's go into vs code, and finally say in our order summary here, well in our shipping.scss we need to take at the bottom here we need to say name-s and that's it. Then grid column is basically we want to put it at the end so let's just say 1/-1 and then we'll say justified self is end, that way we can put it basically anywhere on the grid, we're saying it's on column one to one right. But if we say end it's going to be the very end right.

shipping.scss

&__order-summary {
  grid-row: name-s;
  grid-column: 1/-1;
  justify-self: end;
}

If this is one and this is negative one and we're saying end it's going to be all the way over here to the right. So grid row obviously we want it to start at the name but we don't want it to end at the name end because that's only 64 pixels so we're just saying name start. Alright let's check it out and it looks the same, great let's reload the page, that's always a good one.

Alright, it's not changed, so what we need to do is check our orderSummary.js, okay we're taking in a className, let's check our shipping.js shipping form. What, oh it's in the shipping form of course, let's go into shipping form. Oh my gosh, I have a shipping form summary, let's call it order-summary, there we go. Okay, you'll see it messed it up.

large

Okay, let's go back to the VS Code and un-mess it up, let's go into shipping.scss, we have order-summary. We're seeing that it belongs on grid row start and column 1/-1. The reason it's kind of messing it up saying 1/-1, I assume that's the problem here. Let's try this, let's say it starts at use this address, so let's say that it starts on column use this address and I think that's it.

shipping.scss

&__order-summary {
  grid-row: name-s;
  grid-column: use-this-address-e/-1;
  justify-self: end;
}

Let's go look at it again because that's the columns. Alright, use this address end, let's try this out. Alright, you'll see it looks good, this looks very very very very similar to our design, it's probably the closest form we've gotten so far.

large

A lot of preparation just to make that order summary component, but now we can use that order summary component anywhere in our app even though we're only going to use it in one more place, it's still kind of a cool concept. So it's commit our code, and then in that in the next video we will calculate it.

Or we can do that now because it's going to be super quick. So let's go into orderSummary.js and what we'll do is import all of our items so we'll say import connect from react redux. Now that we have access to this we can have access to our store so we can a function map state to props, it takes in state and it returns just the cart products, so we want to stay constant our product equal state.user we're pulling it out of a user and then we're just going return cart products.

orderSummary.js

function mapStateToProps(state) {
  const { cartProducts } = state.user;
  return { cartProducts }
}

Now what we can do is we can calculate this. We just recently calculated this but let's do it again, or maybe that was the video that vs code corrupted, I tried to calculate it, I don't even know. Let's to do it again, let's say let subtotal is equal to zero and then let's say this.props.cartProducts.map say cartProduct arrow function, and then we'll just say subtotal plus equals cartProduct.quantity times cartProduct.product.price.

const { className } = this.props;
let subtotal = 0;
this.props.cartProducts.map(cartProduct => {
  subtotal += cartProduct.quantity * cartProduct.product.price;
})

So we're taking the quantity of the product and we'll times it by the price of the product. Okay, now we're going to do is we're just going to go down to here and we're going to use back ticks okay here and in braces because we still need this dollar sign and we didn't include it as a part of our info title because it's just an info title, I want to be able to use this for anything else.

So before we go on let's just copy this value and let's put it in to each one of these values okay. Now let's go on with the value here, and let's put in a dollar sign with some braces and let's say subtotal okay. Now what we can do is we can put in the tax which is kind of by default always be 16. So I guess we didn't need to put in the braces for all of these, we actually didn't need to, but it's whatever.

Now in the future if we refactor it will be easier. So that's all set up, let's go ahead and check this in the browser after we use connect, I noticed we didn't use connect. So let's say OrderSummary equal to connect, mapStateToProps, no actions, order summary.

OrderSummary = connect(mapStateToProps)(OrderSummary);

Okay, cool let's check it out. Let's login, let's go shop, let's open up all, let's add a few things. We've got 4 items, let's hit check out. Alright 11.94, proceed to check out 11.94 with taxes & shipping 16 cents, total we didn't change that. Total needs to be, yeah this needs string interpellation, let's say dollar sign, brackets, put another dollar sign there and let's just say subtotal and basically we want to plus the tax.

So what we'll do is we use these brackets we might as well make this a variable and say tax and then we'll go up here. So get that in it's tax and subtotal it's kind of confusing with the dollar sign next that but whatever. And we'll say let subtotal and also say let taxes equal to .16 default flat tax rate of 16 cents. And then we'll say subtotal plus tax, and that will generate or tax which is going to be whatever our subtotal is plus 16 cents.

Okay let's go ahead and let's go back to Chrome and see what it looks like. Alright, it looks like it's pretty good. It's 16 cents for our total, let's hit back, login, let's go to shop, let's add some products into this cart, let's hit check out. Alright so we got like 4 5 6 7 products right, proceed to check out and that's good.

large

Now one more thing I didn't think of this whole time is 4 stickers, we've got to change that. It's super easy, we can do that really quick. Let's go to VS code where it says 4 stickers, again let's use string interpolation and instead of putting 4 let's put ${}, this prompts our current products.length, alright that's how you do that let's go check it out in the browser.

Alright, 0 stickers for 0 dollars. Let's go back, let's login, go to shop, let's put some in the cart, check out. Alright, so it should say five stickers, let's hit proceed, and it says 4 stickers. Okay, now the reason it's saying 4 is because we have four cart products.

We're saying cart products.length when what we really need to do is calculate it. So let's get rid of this, let's say amount stickers, we'll go up here and we'll say let amount stickers equal 0 and then in our map state here we'll just say amount stickers plus equals cart product.quantity.

That will give us the amount of stickers we have because it's gonna say oh there's two in this cart product, there's one here and then it will add them. So put that into amount stickers here and we should be good.

orderSummary.js

class OrderSummary extends Component {
    render() {
        const { className } = this.props;
        let subtotal = 0;
        let tax = 0.16;
        let amtStickers = 0;
        this.props.cartProducts.map(cartProduct => {
            subtotal += cartProduct.quantity * cartProduct.product.price;
            amtStickers += cartProduct.quantity;
        })
        return (
            <div className={`${className} order-summary`}>
                <UnderlinedTitle className='order-summary__title' title='Order Summary'/>
                <InfoTitle className='order-summary__subtotal' title={`${amtStickers} stickers`} value={`$${subtotal}`}/>
                <InfoTitle className='order-summary__tax-shipping' title='Taxes & Shipping' value={`$${tax}`}/>
                <InfoTitle className='order-summary__total info-title-green' title='Total' value={`$${subtotal + tax}`}/>
            </div>
        )
    }
}

Let's check it out in the browser, let's go back, let's hit login, let's go to shop, let's go to all, let's add a couple in here, let's go to check out, and let's hit proceed to check out. You'll see it says five stickers now. Okay so that's all good, we've go autofill working and all that junk, and we're good to go.

large

So in the next video what we're going to do is we are going to whip together the payment form, and you can already see that we have a good portion of it put together because we did a lot of it already. So let's go ahead and let's commit our code and then hop into that.

Terminal

git status
git add .
git commit -m "finished shipping form component and sub components"

I'll see you in the next video.

Resources