Okay.
Our next task is to take a look at the register to allow users to register a new account with our application.
So let's head back to VS code, and we'll start off in the schemas folder inside lib.
And we'll just create a new file and call it Register schema dot ts.
So we can take advantage of Zod validation.
And I'll export const register schema and set it equal to Z which we get from Zod dot objects, open
parentheses curly brackets.
And we're effectively going to have the same properties inside here.
We don't need to take any additional information from the user, so we might as well keep it simple.
And we'll have the email which is going to be a type of string and email.
And then we'll specify the password and we'll use that dot string.
And we can also use a regular expression inside here.
So if we do want to match what we're doing on the API.
On the client side we can do, and inside our register we will do that.
We don't need to check it on the login, because if they get the password wrong then it's just a wrong
password.
It doesn't matter if it's a complex password or a weak password.
We don't need to check for that, but we can check for that on the register component.
So let's use a regular expression for this.
So what do we put inside here then for a complex password.
Well I don't know.
I'm not an expert on regular expressions, but I know a place where I can find regular expressions to
help me out with this.
And I'm just going to look for regexp and or it's regex lib, I think is the one that I typically use
for this kind of thing.
So regular expression library regex lib I'll click on this.
And then inside here we can search for regular expressions for certain tasks.
So I want one that's going to match a complex password.
So I'm just going to search inside here.
And one of these is suitable for what we need lots of different options for different types of complex
passwords.
The one that I'm looking for specifically is created for equivalent to what Microsoft uses as their
complex passwords.
So it's in here somewhere and I'll keep going down.
And this one at the bottom.
In my case this regular expression match can be used for validating a strong password, etc..
And this expression follows the above four norms specified by Microsoft for a strong password.
So one small case letter, one capital letter, one digit, one special character, and the length should
be between 6 and 10 characters.
So we can just use this regular expression as it is.
And this will validate a complex password for us.
So I'll copy this into my clipboard.
I'll head back to VS code and just above our export here I'll say const password validation equals and
we can use a new reg exp.
Open parentheses.
And I'll just paste this in on the second line.
But we need to put this inside of two forward slashes.
And then we put our regular expression inside here.
And that should be fine.
So we've got our opening forward slash followed by the regular expression inside here you can see some
logic inside here.
This checks to make sure there's at least one digit.
This makes sure there's at least one lowercase.
Let's make sure there's at least one uppercase.
And this makes sure that one of them is a special character.
And somewhere in this regular expression at the beginning, we check to make sure it's between 6 and
10 characters.
So it's not a regular expression course, thankfully, and this will do the job that we need it to do.
So inside our reg x as a parameter.
We can pass in the password validation at a comma, open curly brackets, and then we can give this
a message.
And we'll just define because we're not able to check just on a single a regular expression what specific
mistake they've made here.
But we'll just describe what the password should be.
So I'll say password must contain one alpha, one number one special and b 6 to 10 characters.
And I should specify lowercase alpha and one upper case.
Character.
And I'll change alpha to character to be a bit more accurate about what this is actually doing.
So that will suffice for our message there and describe what it is they need to input for this.
And then we can go and create our register component.
So back to the File Explorer.
Inside our account feature we will create a new file.
And this will be for a register form TSX.
And we'll just add the boilerplate inside here.
And I'll just go back to the register schema actually because we also need to export the type that we're
going to be using for this.
So I'll say export type and call it register schema equals.
And we'll use infer so that Zod can infer the type that we're using here.
And we'll use type of and register schema.
Great.
And let's go back to our register form.
And at the top here we'll use the export we made earlier in our account API.
So I'll have the function inside square brackets to register user, and I'll set this equal to the use
register mutation and just reformat things inside here.
And we'll use the use form again.
So I'll use the use form hook and we'll give it a type of register schema.
And inside here we'll specify the mode is untouched.
And the resolver will use these odd resolver and pass in the register schema.
And then inside the curly brackets where we're using the use form we'll bring in the register.
The handle submits the form states and we'll use the errors.
And we'll also just bring in the is valid.
So we can make sure the form is valid before we enable the button to allow them to submit the form and
below this will just add an Onsubmit method.
So we'll say const Onsubmit equals async and data and use the register schema as it's type open curly
brackets and we will say await register user and pass in the data.
And the login form is going to be pretty much the same as the register form with just a few small changes.
So I'm going to go to the login form, and I'm going to copy this container in its entirety and paste
that into the register form to save us a bit of time.
We're not doing anything different with the register in terms of what we're taking from the user, so
I'll just copy that in its entirety and I'll add all the missing imports and see how we're getting on
after that.
So let's see what changes we need to make inside here.
The container can stay the same.
We just need to change the sign in to register.
The component is a form.
We're using the same handle submit function, so let's move down.
This can also stay the same because we're going to take in the same information the email address and
the password for the user.
And we can use in the button.
And let's get the is loading in as well.
We'll use the version from the form this time just to demonstrate that it's pretty much the same thing
that we get.
And I'll use both the is valid and the is loading to disable the button if either of those conditions
is true, so either is loading or not is valid, and the button will be disabled.
And we'll change the text inside here to register.
And instead of don't have an account this can be already have an account.
And we'll send them to the login.
And Will use sign in here as the text for that link.
And we just need to go back to our roots.
And it's getting quite busy at the top here.
Let's close the others down and I'll open up the routes.
And I'll just copy the login form down and change this to register.
And specify register form.
As the components.
So let's just take a look at how we're doing so far.
And if we go back to our form or go back to our application and click on register, then what we should
have is the button disabled at the moment.
And if I start typing test at test and click out, then I get an invalid email until I make it valid.
I've got the password message there as well, and this shouldn't go away until I have a complex password
in place, and if I remove a couple of characters or make it not complex, then I'm going to fail the
validation.
So great.
That's what we're looking for so far.
But we need to think about what are we getting back from this, and how do we want to inform the user
about what's happened?
Was it successful because this registering alone is not going to log them in.
And even though technically what I do here should work, it's not great from a user experience point
of view.
If they don't know if this was successful until they actually do go to the sign in and then they try
and log in.
So let's give the user some notification as well.
And we'll also redirect them to the login component so that after they have registered they get notified
the registration was successful.
And then they're taken to the place where they can actually log in with that new account as well.
So let's head back to our accounts API to finish this bit off.
And inside our register we're also going to use the on query inquiry started function so that we can
do something after that query is fulfilled.
So below the query we'll use async and on query started once again open parentheses.
We don't need any arguments.
So just an underscore for that.
And we only need the query fulfilled in this case.
And we'll add a try catch block inside here.
And if we get an error we'll just console.log the error.
And in the try block we'll use await and query fulfilled.
Following this we'll make use of our toaster.
So we'll bring in the toast and say toast success.
And we'll say registration successful.
You can now sign in exclamation mark.
And below this will make use of our router which we get from.
Or we've already got to inside this component.
And we'll use router navigates.
navigate and we will send them to forward slash log in and that should be good enough.
So if we go back to our browser, let's just refresh the page and I'll add a new email.
I'll say jane@test.com and capital P a dollar dollar w o r d is a complex password, the one that I
use for the other accounts.
I'll click register.
We see loading and then we get registration successful.
You can now sign in and I'm on my login page.
And I should be able to log in with jane@test.com with the password.
And everything should work as expected, which it does.
Marvelous.
But what we also need to consider, because we looked at the happy path there with registration, we
didn't account for the fact that the user could try and use an email address that's already taken,
and we want to take a look at how we handle those kind of errors from our API, and we'll take a look
at that next.