So let's work on the orders screen now and output more than just this boring text.
Now just as with the cart screen and the products overview screen, I want a more complex order item and
therefore I'll create a separate order item component in the components folder and there in a shop folder.
As always, it's up to you whether you also do that
but since this will be not a super small component, I prefer having it in a separate file.
So I'll import React from React here and unsurprisingly of course import a bunch of things from React
Native and that would be the view, the text, stylesheet since we'll certainly set up some styles as well
and also a button because I also want to be able to expand an order so that we don't always see all the
items that are part of the order but that we can view them if we wish to. Now with that, we can create our
order item constant here, so that will be the component itself which receives props and then in the end
will have its body here and return some jsx code and we need a styles object here with Stylesheet.create
like this and also export order item as a default.
Now how should an order item look like?
Now as always, it's up to you but I'll work with a view here and my idea is that I always show like the
total amount of that order and the date and then a show details button which we can press to view the
individual items that are part of the order and for these items, I'll actually use the cart item component
here because I want to render the exact same items as I display in a cart.
So I will actually import cart item from the cart item component and reuse that component here.
Now back to that jsx code though,
so we have a wrapping view around our entire order object, our entire order entry here.
Now in there, I want to have a first row and therefore I'll use another view so that we can style
this appropriately which should hold some text that displays our total, so the sum of that order let's
say and another text where I show the date and this should be in the same row with space in between them.
Below them as I mentioned should be a button which we can press to show the details which then shows
all the items that are part of that order. Now
with that set up, of course it's clear that the amount here should be received with the help of props.
So there I expect to get an amount prop and I will call to fixed 2 to output the appropriate amount
of decimal places. Now for the date,
I want to output props date here so that we have a date we can output. For the styling, overall here
I want to have an order item style assignment so that we can style the whole order and then there, we
need like let's say styles summary so that we can style this row
and regarding the text here, this should have a style of let's say total amount, as always these style identifiers
are up to you,
here I want to have a date style.
The button also should get its own color which I'll get from the colors constant, therefore this import
needs to be added and there,
I'll use my primary color. Okay,
so that's it for now,
I'll come back to the details in a second,
now let's apply some styling here so that we can see something. For the order item itself,
I'll again reuse that cart look which I already have in the product item, so I'll copy all these settings
here from the product item and move them over to the order item
so that a shadow is applied, a background color, a border radius, all of that should be applied.
In addition, I'll add a margin of 20 in all directions so that each order item has some spacing around it.
Inside of the order item, I also want to have a padding of 10 so that the content in there doesn't sit
directly on the edges of the surrounding border and so on. Now for the summary which is this view that
holds the two text pieces, there
the styling should actually be that we have a flex direction of the row of course because items should
be sitting next to each other. Justify content should be space between
and besides that, align items should be center, so that on the cross axis which here is the vertical
axis, items are centered.
I also want to ensure that we take the full available width here to distribute the text. Now for
total amount which is the styling applied to this first text piece which outputs the amount, there
as always you can style it however you want but I'll set a font family of open sans bold to use that bold
version of my font and give it a font size of 16 let's say and then for the date which is my style I
applied to that date text here, there I
in the end also want to use a font size of 16 but font family will just be open sans, without the
bold version
and in addition, we can also reuse that dark grayish color here. Now with this, let's give it a try and
let's use that order item in the orders screen.
So in there, we first of all need to import order item from
and then of course go to the components folder, there to the shop folder and then import order item from
that order item file
and here instead of rendering that text, we now render that order item here as a self closing tag
and of course, we need to configure this.
This requires us to pass in the amount and the date and later also the detail items,
so the items in the order
but that will come in a second step.
So for now here, we need to pass in the amount and that of course is simply itemData.item which
is a single order,
don't forget we're looping through all orders here which is an array of orders,
so that's a single order
and in there, the amount if we have a look at our order model is stored in a total amount field, date
is then stored in the date field.
So here we access the total amount field and for the date prop which we also need to pass in, we can
access itemData.item.date. If we now save this and we have a look at that,
let's add some content here, order this and then go to our orders screen and we get this error.
Now this refers to objects not being valid as React should and shows us that in the end, it's the
state object it's having a problem with and that makes sense because date in our order when we create
it here in our Redux store is a date Javascript object.
Now we can't output this as text like that. To output it,
we can go to our model though here, which is in the end the blueprint we use for creating the orders
and in the order model, we can do something we haven't done before, we can add a method to this model
or to be precise, a getter which is a default Javascript feature of modern Javascript.
So here, we can use the get keyword and then any name of your choice like readable date which is
like a function but not a function you call like a function but which you access like a property in the
end which returns a calculated value and there I want to return this date, so the date object which is
stored for this object but then we can call to locale date string which is a built-in Javascript method
we can use on date objects to convert this object to a human readable date. There we pass in the language
for which we want to optimize it like this for example and now we can configure this with a second
argument which is a Javascript object. There you can define how the year should be configured and attached
you find the detailed docs for this method if you want to learn all about it and for example, we can set
the year to numeric, the month to long, the day to numeric,
the hour to two digits and the minute also to two digits.
Now we have that readable date property which we can access on any order item and there for now in the
orders screen, instead of passing in the data object like this, I access readable date which is now this
new getter property we added and now what you'll see is that if I again place this order here by clicking
order now and I now go to my orders, now you see the total amount and this cleanly formatted date and
now if I do the same on Android and I place an order here and I go to my orders screen, you see the same
there. Now there I just want to tweak that button a little bit, in general also on iOS, it shouldn't be as
broad, not as wide here. So in the order item component where I have this button, in the end what we can
do is on this view here, we can add align items center to center the content along the cross axis which
is left to right and therefore now if I try this again and I place this order and I go to orders, you see
this is now not pressable there and it's even clearer on Android if we reload it there
and I place this order real quick here, go to the orders screen, now we have this button. Now of course
the goal is that when we press this button, this order expands here. What you'll note on Android by the
way is that this date isn't displayed correctly,
so that's another thing we need to fix.
Now the reason for that not being displayed correctly is how React Native works internally, which Javascript
engine it uses internally and the one it uses for Android there or on Android platforms does simply
not support this nice to locale date string method I'm using here.
The engine used on iOS does but on Android,
that's not the case, which is of course inconvenient and not that great.
So what can we do on Android to fix this?
The solution is to install a separate library which is called moment.js, we installed with npm install
--save moment.
This is a third-party library that will work on both platforms
which makes formatting dates also super simple.
So let's wait for this installation to complete.
Now with that installed, you import everything as moment from moments and from the library you just installed
and now you can use it in this file here.
Now we can comment out this down here and instead return moment, executed like a function and pass in
this.date,
so the date object we want to format and call format. Now format takes a string where you can configure
how to format this and attached, you also find a link to the official docs where you can learn all
about the possibilities you have there.
Now here, one example, one way of formatting this, let's say a long month
which you do with 4 capital Ms, then the o to have a nicely formatted date in that month, day
in month output, a year represented by four digits and then an hour always represented with two digits
and the minutes and
now if we save this and we give this a try, start on iOS, add this here to the cart, go to the cart
and order this and now go to orders,
this looks good.
And now if we give this a try on Android as well, we order that
and then here we go to orders, this now also looks nice there.
Now that's a little fix, now let's work on the button and give it some spacing as well
besides shrinking its size and that can be done by going to the summary here which is the style apply
to the view which holds the two text pieces, there we can simply add a margin to the bottom of let's
say 15 so that we have some spacing between that summary row which is this text row at the top and the
button below it. So I'll add this to my cart here, order this, then go back here, go to orders,
now this looks good.
Now let's make sure the show details
button does something as well.