Welcome back.
It's time to create a 'sign in' form. Maybe even a 'Registration' form because for new users, you wanna
register them.
So let's work on that.
We first, want to perhaps create a 'sign in' and a 'registration' component. So let's do that.
I'm going to create a new folder, call it 'SignIn' and this folder will have a new file called 'signIn'
dot
'js'.
And again using our best friend, copy and paste, we can use that and call this 'Signin'.
And we don't have any css for it. And no props yet. Within here
we definitely want to have a 'Signin' form. And luckily for us because we're using 'tachyons', well, if we
search 'tachyons' form, they should have, oh! looks like they have a sign in form just for us so we can use.
All right this looks awesome.
We can just copy and paste this code,
and again because we have 'tachyons' the classes will be automatically applied.
So let's do that. Fix indentation a bit.
Let's save. And you see here that the syntax is wrong.
Well that's because with JSX, we could have gotten away in, when we
let me make this smaller. In html,
we didn't necessarily have to close the input boxes. But here with JSX, we have to make sure that the
input tags are closed off.
So now our case, we have three inputs, I believe. So we can save that and there's still something off. Let's see,
what else we had.
And we have one more 'input' in here.
All right.
You see the highlighting is fixed.
Let's just make sure this works by adding this 'signin' component to our app
dot js.
And then finally, we can just put it at the top for now, to make sure that it works.
Let's see what happens.
It's compiled successfully, going back and all right, we got the form.
It doesn't look too bad, but there are definitely a few things off. We don't want this bottom stuff and
we need everything centered.
Well, one thing, I want, I want this to kind of have a card underneath it.
So if I go back to 'tachyons' and I do 'tachyons' cards,
it's like a product card.
All right.
I like the look of this product card but I just like the boundaries of it.
I don't need to copy the contents. So I'm going to just copy this 'article' tag, and add it
in here.
Close off the 'article' tag,
and let's see how that looks.
All right, we got the boundary box at least, but everything's kind of pushed off.
Again we're going to start removing some things that we don't need.
We don't need the 'forgot your password',
we don't need the 'Remember Me'.
Let's save, go back to that.
And again we want to make sure that this is centered, and we actually want to change the classes here,
to,
again I did command control,
command control 'g' to have all these multiple cursors and I'll just say 'className' and we actually want
to remove this 'center' over here, we already have it up here.
All right things are starting to look a little bit better.
I want to make a bit of a shadow around the border, so again maybe change the 'border radius' to three
and change some of these values, I'm gonna add my favorite shadow, and I don't think I need this.
Let's see how that looks.
All right that's better look at that border that's looking very nice.
And maybe we want this a little bit bigger and this should say 'register' instead of 'sign up' because
well, we want to ideally have another form for a registry.
So we'll say 'Register' here, and then for a 'sign In' we'll say, 'f1', save that, go back.
All right.
That doesn't look too bad, actually.
And if I type things here, everything looks good.
Perfect.
So we have the 'sign in' form. This 'Sign In' form,
well, we don't want it to show this, when this app is active.
Ideally we have a 'Sign In' form and once a user signs in, then they're able to access the homepage.
So let's do that.
It sounds like we need a bit of state.
If I go to app dot js, and this is a problem that is very common in maps and there are libraries that you can
use, but for us, I want to build this from scratch.
So we have a better understanding of how things work. We can create a route state, and the route keeps
track of where we are on the page.
In our case, we want it to start on 'signin'.
So when the app, initially loads and the constructor gets run, 'signin' or 'route' should be 'signin'.
So now that we have this 'signin',
well it sounds like a conditional statement right.
We can just say that, if, and I can do an if statement here because we're inside of a return statement.
But because these are just, this is just JSX, we can wrap things in curly brackets.
And now it's a javascript expression.
So we'll say, we'll wrap this in curly brackets,
And we want the navigation there no matter what.
If 'this' dot 'state' dot 'route' equals
'signin'.
If that's true, then I want you to return the 'signin' component. Otherwise you can return,
the 'Logo' component.
Let's just change the spacing here, just so it looks a little bit better. Let's save,
and see if that works.
There you go, added that. We see that, we get an error here saying, well, json ajax elements must be wrapped in
an enclosing tag. Remember because we're returning multiple elements here,
that doesn't work.
We need to wrap them.
Yeah that error message is a little bit tricky.
But, you get used to it after a while, so we want to wrap this, in a
'div'. Let's save. Let's go back.
All right.
Let's look at the console,
no errors but still showing 'signin'. So let's check to make sure that we did this right.
If 'this' dot 'state' dot 'route' equals 'signin'.
And as you can see, I spelled that wrong.
And that's why (it) wasn't working.
If I save.
There you go.
We get our 'Sign In'.
And if I change this to something else,
well in that case, we get our homescreen.
Amazing.
Just simple conditionals in javascript, and we have our self-direct (?).
Let's expand on this. Let's do sign in.
And now, if the user signs in,
while we want to direct them to the homepage. So let's create a function on 'signin' and this prop will
have, we'll call it 'onRouteChange'.
So when route changes, it's going to be 'this' dot 'onRouteChange'.
And let's write that function.
We can say, 'onRouteChange' using arrow functions.
Let's think about this, for now we can just save 'this' dot 'setState' to 'home'. Doesn't mean much but
it changes, the 'signin' route to 'home'.
So let's get that working. I'm going to save.
Oh! got to wrap this in curly brackets because it's an object.
Yeah.
And now if we go into the 'signin' component, we can say, for this 'input', we can just have an 'onClick' event handler.
So let me, add this on a new space, just so you can see a better.
Make this bigger a bit, there you go, will do an 'onClick' and 'onClick' this 'signin' will receive the 'onRouteChange'
event handler, and we'll just say 'onRouteChange', will save. Let's go back, going to click 'Sign In' and it's working.
All right, we also want to click 'onSignOut'
and it should take us to the 'Sign In' page.
So again we have the 'onRouteChange',
but this time on the click of the sign out which is the 'Navigation' over here, we want it to go to route.
So how can we do that?
We'll let's go to the 'Navigation' component and we want to say on the 'p' tag that there's going to be an 'onClick'
and the 'onclick' event, which we haven't written yet, but we do have the 'onRouteChange'.
So based on that, I can pass that in as a prop and going back to the app dot js,
we can pass in to 'Navigation' 'onRouteChange', 'this' dot 'onRouteChange'.
But, there's an issue here, because once I 'Sign In' and I click 'Sign Out' while nothing happenes. We're never
changing the route to 'signin'.
Ideally when we click, we change the route to 'Sign In', so that this statement over here evaluates to
true and we get the sign in form.
So it sounds like instead of us just statically entering home to 'onRouteChange', we need to dynamically
say that our route
is going to be where we give it.
We need to change 'onRouteChange' and 'signin',
and 'onRouteChange' and 'Navigation'.
So let's go to 'Signin' first and say that 'onRouteChange' 'home'.
Now, we don't want to actually run this function. The way we have it now is that, we're going to run this
function when it gets rendered.
But that's not what you want, we want it to run whenever 'onClick' happens and then 'onClick' will call
this function.
So the way we do that is, we can do an arrow function. And this arrow function will just have an 'onRoute
Change' 'home'.
So it's just a function that's going to get called. Here we're just defining the function.
Let's do the same thing in 'Navigation' as well.
In 'Navigation' 'onRouteChange', will now pass a parameter, but instead of 'home', it will say 'signin'. Let's see
if that works.
Going to 'Sign In' and 'Sign Out'. 'Sign In' and 'Sign Out', awesome.
We're not going to worry too much about getting an error because we haven't entered anything.
For now we want to make sure that the routes work.
All right.
Let's also build out the register for a new user.
We want them to have a register.
Maybe it's also asked for the name, of the user.
And just to keep things simple, we will just add a new folder in 'components'.
And this is going to be, 'register' and this is going to be very similar to 'sign in'.
So we'll, we'll have a bit of a code duplication. But again we're just building it fairly fast so it should
be fine for now.
So copying this from 'Signin', we can just copy everything from 'Signin' and go to 'Register'.
And now change the 'Signin' to 'Register' and the 'Register' maybe we'll add a number field.
Maybe that field will have at the top just the name. And we'll say 'for' 'name', 'type' 'text' and 'name' will be
just 'name'. 'id' we'll just say 'name'. We actually don't need these properties they just came with the form
that I copy and pasted from 'tachyons'.
But, it does the job for now, it should be good.
And we don't need the 'Register' link at the bottom.
Let's save.
And if we go back to the 'Signin', we also don't really want this to be an anchor tag.
We want to do a route change, so we can just maybe do a 'p' tag
and this 'p' tag will have the 'onClick' event as well.
And on click, it will say that from 'signin' we want to go to 'register'.
Perfect.
And then finally, if you go to app dot js, we wanna import this component,
'Register' and 'Register'.
And 'Register' is defined but never used, because we need to add it to our render.
Now this is a little bit tricky because we kind of have to do a few more conditional checks. Will move
this a little bit around just to have cleaner code.
I'm going to say, if 'state' dot 'route' is 'home', in that case, I want you to render our homescreen
and otherwise,
I'm gonna have another expression, so I'm wrapping it in curly brackets.
And this other expression, we'll have another ternary, that will say 'this' dot 'state' dot 'route' equals
'signin', if it's signed in then we'll return the 'Signin' form,
otherwise, we will return the 'Register' form.
And I know there's better ways to do it.
We could have just pulled this out over here or done it and the return statement.
But for now, we want this to get working so we can test that out.
We have 'Sign In'.
If I click 'Register', I go to register but we need to change the title so we can actually see that that.
Let's do that one more time.
Let's go back to 'Register' and we'll change the title to 'Register'.
Let's go back, we are on 'Sign in'.
If I click 'Register', I go to 'Register' and if I click 'Sign in', I'm finally in. And let's finally also change
the input 'type' 'submit' or the 'value' to 'Register'.
Let's save that again.
Go back, 'Register', clicks on 'Register'.
I don't know if you also noticed that we're not getting the cursor when we click on 'Register', so let's
fix that.
We'll go to 'signin' and we'll say that on this 'p' tag,
we will say, that it's a 'pointer'
class.
There you go. Whoo! All right.
So we're getting our form, which is good.
The last thing that I want to fix is the 'Sign Out'.
I want to be able to have 'Sign Out' only when I'm at home, and maybe when I'm on the 'Sign In' or 'Register',
I have the two navigation tabs over here.
That's fairly easy to do.
We can go back to 'Navigation' and in 'Navigation', we can say that,
if 'isSignedIn', a variable, that we don't have yet, but we can create one.
I just want you to think about how we want to design this. So, if it's signed in, the user, in that case
we want to display
this, right?
Otherwise, we can display, and I'm showing you how to do this without the ternary, the way that we did
it in the app
dot js.
I just want to show you both ways.
If the user isn't signed in then perhaps we should have two navigations, one that says
'Sign In' and another one that says 'Register'.
And over here, I see that we're turning this entire thing
instead of what I should have been doing, is returning the individual.
So, here I'll say 'return',
wrap this in a bracket.
And we have the first return and then if it's signed in, then we'll do 'return'.
Let's save that, Oop! I made another mistake here.
We don't need that to 'nav' things.
We actually just want the middle 'p' tag
and here, just add the two links.
So the 'Sign In' and 'Register'. So we can remove this, because it was giving me and error because I was returning
more than one thing.
All right.
Looks good.
We want to make sure that the 'onRouteChange',
if we click on 'Sign In', they all go to 'home', if we click on 'Register' again, it will also go to 'home'.
If I click 'Sign Out', I'll go to 'Sign In'.
And then finally 'isSignedIn' doesn't exist yet,
so it looks like we need to add a new state, and we'll call this one 'isSignedIn' and
to start off, it's going to be false. And there's something that we can easily do
in the 'onRouteChange'. 'onRouteChange' we can perhaps add another if statement, and we'll say if 'route'
equals 'signout'.
So for trying to sign out.
well then we should 'setState' of 'isSignedIn' to false because we're signing out.
Else if
'route' equals 'home', well in that case, we wanna 'setState' of 'isSignedIn' to true.
And you might be thinking, do we wanna not authenticate and make sure that they have access to getting
home? and that's something that we are not going to worry about for now, we just want to get it working.
So if the 'route' is 'signout' then 'isSignedIn' will be false.
If the 'route' is 'home' then well they're obviously signed it.
So it's going to be true.
And no matter what, we still want to change the 'route'. Let's see if this actually works.
I go back, I click on 'Register', oop! I'm going to 'home' instead of going to 'Register' page.
So I made a mistake here, if I go into 'Navigation',
obviously if I click on register, we want to go to the 'register' and if I click on 'Sign In', we want to
go to 'signin'. Llet's save that, let's try that again.
'Sign In', nothing happens because we're already here.
Sign, 'Register',
nice,
'Sign In', 'Register', 'Sign In', 'Register'
Perfect. Try click on 'Register' here,
I go to 'Register', if I click 'Register', I'm at 'home', and oop! we see tha, we need this change to 'Sign Out' and
that is on the 'home' page, so we can go back to app dot
js
And it's a simple fix.
We can go back here.
We want to actually pass the prop here of 'isSignedIn' to be 'this' dot 'state'
dot 'signin'. Oop! that's not it, 'isSignedIn'. Let's save. So if we go back here, we see that uh! it's not
working.
And that's because again this is why it's so tricky with javascript, I made 'false' into a string.
So when it checks, 'isSignedIn' over here false, technically is true in javascript because it's a string,
so it exists.
If I go to here, and I do 'Boolean'
false, will say that it's true.
So let's go back to that.
I'm going to say, isSignedIn', this should be false, a boolean.
So now let's see if that works.
It's going to register. If I click 'Register', it's home if I click 'Sign out', I am signing out.
But see how this isn't changed.
Because I made another mistake here.
When we click 'sign out' over here, we ideally want to go and say 'signout'
and when we sign out,
we sign out properly.
All right. We got ourselves a nice working app.
There's a few cleanup materials that we can do here, such as removing the 'console'.
We're also using 'this' dot 'state' a lot, where we can use destructuring.
So I can just have 'isSignedIn', 'imageUrl', 'route' and 'box' destructured.
So now I can make things a little bit cleaner.
By removing 'this' dot 'state' everywhere,
there you go.
Oh! and I have to add 'const' here.
All right.
Perfect, this looks pretty good.
'OnButtonSubmit', 'onInputChange',
Everything is looking nice.
We have our 'calculateFaceLocation'.
There's obviously a few things that we can improve upon, but for now we have a working app that does
exactly what we need to.
It does face recognition and it works nicely.
I also want to see the console, make sure that we don't get any errors. And we see that we have two things
here.
One is invalid DOM property for.
Did you mean htmlFor?, it gives us a nice error that says at Signin dot js, and that is because again
we're using JSX and 'for' is a javascript word.
So even though in html you can use 'for' for 'labels' to attach them to input, in JSX we have to do a 'htmlFor', so
we can do 'htmlFor', 'htmlFor',
save that, and we'll have to do that and the 'Register' as well.
And that works.
But when I click 'Sign In', I get, the form submission canceled because the form is not connected, and that
is because with HTML,
remember when we worked on forms, it automatically if there is an input or a button when there is an
'onSubmit' event, where there's 'type' submit, you will automatically try and send those forms.
If I actually change this to a 'div',
and I save that, if we go back to 'Register' and I click 'Register', I don't get that error anymore. Again,
because in future videos when we create the backend, we won't be necessarily sending a form,
we're going to be sending it through JSON, which is more dynamic.
We can customize things a little bit better.
We can just not worry about html forms, so that we have full customization with JSON. So we can do the
same here as well.
And again, signing again, no errors.
Everything works as intended.
If the form part was confusing make sure you check out the HTTP, JSON and AJAX section. Like I said before,
forms automatically submit or tried to submit things for us, we're not submitting anything yet.
We're going to create our own server, where we're going to be able to sign in our own users and register
our own new users.
There's a few things that we can clean up and we don't need to worry about, because we have a working
app. And now I want to start diving into creating a server, so that we can actually sign in people and
sign out and have a server that this website interacts with.
I'll see you in that one by. Buh-bye