Coach App in VueJS with Authentication & Vuex
In this post we are going to create a fairly large VueJS app with authentication.
This project have been inspired by this awesome Udemy course by Maximillian.
To start with this project get the basic boiler plate of a VueJS app from this file.
After extracting the zip file, open the folder in terminal. Then do npm i to install all the dependencies.
Next, we will create a pages folder inside the src folder. And inside it create a coaches and requests folder. We will create different files in it and also a router.js file in the root directory.
In the router.js file, we will add different routes which will call different component. Also, notice the nested route which we have created.
Next, in the main.js file we will add our router and App file.
Now, we will create a components folder and inside it TheHeader.vue file. This file will have a basic template of header with router-link.
Next, we will add the styles in TheHeader.vue file.
Next, we will add TheHeader component in App.vue file.
Now, we will add a basic template in CoachRegistration.vue file.
And a basic template in ContactCoach.vue file.
And a basic template in RequestsReceived.vue file.
Next, in the CoachesList.vue file also, we will have a basic template.
Now, in http://localhost:8080/coaches we will see a nice header and other basic components.
Now, we will introduce Vuex in our app for global state management. It is like Redux in ReactJS. So, create a store folder inside src and inside it modules folder.
Inside the modules folder create coaches and requests folder. Inside the coaches folder, we will create different files related to vuex. Also, we will have a index.js file in the modules folder.
In the index.js of the coaches folder, we will include all mutations, actions and getters.
Next, in the root index.js file we will create a store and call the coachesModule. Notice, this concept is also similar to store in Redux.
Back in the index.js of the coaches, we will have a namespace and also a state containing our coaches array.
In the mutation.js file, we will export an empty object.
In the actions.js file, we will export an empty object.
In the getters.js file we will get the state of coaches and check whether coach state is there, through two functions.
Back in our main.js file, we will add the store.
Now, in the CoachesList.vue file we will add a basic template which will get all our coaches and also use the hasCoaches using computed properties. We are using the coaches array to show all coach name now.
We are now seeing the two coaches name and the buttons in localhost.
Next, we will have a CoachItem.vue file in which we will get the id, firstName, rate and areas as props.
We will also have a fullName, coachContactLink, coachDetailsLink in the computed properties.
We will also add the styles in CoachItem.vue file.
Next, in the CoachesList.vue file, we will call the CoachItem component and pass different props.
Back in http://localhost:8080/coaches we will see all Coaches.
In the CoachesList.vue file also, we will add some styles.
Back in http://localhost:8080/coaches we will see much better styles.
Now, we will create an ui folder inside components folder. And three files in it. In the BaseCard.vue file, we will add a template and some styles.
We will add the BaseCard in the main.js file.
Now, we will wrap most of the html in CoachesList.vue with base-card component.
Now, we have nice card wrapping our coaches in http://localhost:8080/coaches
Now, we will create the BaseButton.vue file with the basic template and script.
Also, we will add the styles in BaseButton.vue file.
Now, we will include the BaseButton in main.js file.
Now, we will use the base-button for our buttons in CoachesList.vue file.
Also, we will include them in the CoachItem.vue file.
Now, we have nice looking buttons in http://localhost:8080/coaches
Now, we will create a BaseBadge.vue file, in which we will get some props and will have some styles.
Now, we will also include the BaseBadge in the main.js file.
Now, we will use the base-badge in the CoachItem.vue file.
Now, our styles will look even better in http://localhost:8080/coaches
Now, we will add template and script in the CoachDetail.vue file. Here, we have a router-view which will include the router.
Next, we have also added some computed properties in the CoachDetail.vue file.
We also need to make the props as true in router.js file.
Now, our coach details page will show all the details.
Next, we will update the CoachFilter.vue file, which will have three checkboxes. And they will call the setFilter function. This function will also emit the change-filter text.
We will also add styles for the CoachFilter.vue file.
In the CoachesList.vue file we will add the coach-filter component. We will also get the change-filter emitter and call the setFilters(). We have also added the computer properties of isCoach and filteredCoaches.
Next, we will create a CoachForm.vue file and add the template data in it.
We will also add some more checkboxes in CoachForm.vue file.
Next, we will add the code in script for CoachForm.vue file. Here, we will linking all the fields and also adding code for submitting the form.
Next, we will add some styles for the CoachForm.vue file.
Now, in the CoachRegistration.vue file, will add the CoachForm component.
Now, when we goto http://localhost:8080/register we will see the nice form and on clicking on Register, we will get the output.
Now, in the mutation.js file we will add the registerCoach function, which will push the payload in the coaches array.
Now, in the actions.js file we will create the registerCoach function, which will take the coachData and commit it.
Now, from the CoachRegistration.vue file we will dispatch this data to the registerCoach function.
Now, in the index.js of the store we will get a state and a getters returning the userId.
Also in the actions.js file we will add the id.
Now, in the getters.js file we will also have an isCoach function which will get the coaches and userId. And it will return true if it finds the userId.
Now, if we add a coach we will get it in http://localhost:8080/coaches
Now, we will create a new form in ContactCoach.vue file. Here, we are also dispatching this data to the contactCoach.
We will also add some styles in the ContactCoach.vue file.
Now, we will create the vuex files in requests folder and in the index.js file add all the different files.
In the mutations.js file we will create an addRequest function which will add the payload to requests state.
Next, in the getters.js file we will have a requests and a hasRequests function.
In the actions.js file we will have a contactCoach function, which will add our payload.
Now, we will add our requestsModule in the root index.js file.
Now, we will create the RequestItem.vue file in which we will add template, script and styles.
In the RequestsReceived.vue file we will use the RequestItem component and have the receivedRequests and hasRequests computed properties.
Now, we can contact a coach and send a request.
We can see the received requests.
We forgot to add params in our ContactCoach.vue file. So, we will do the same.
Next, we will create the getters.js for the requests. Here, we have the requests and hasRequests functions.
Next, we will add a Realtime database from firebase in our project. You will get a unique url for the same.
Now, we will update our actions.js file to do a fetch call to the firebase url and take the data in PUT call.
Now, back in localhost register as a coach.
The data is saved in the firebase database.
Now, in the mutations.js for the coaches we will add a setCoaches method.
Next, in the actions.js file for the coaches we will add the loadCoaches method. Here, we are doing a GET API call and storing the data in the responseData. And then committing it to the coaches array.
Now, in our CoachesList.vue file, we will have the loadCoaches() called when the component will be created through the created() lifecycle method.
Also, it will be called when we click on the Refresh button.
Next, we will create a BaseSpinner.vue file for the spinner component. Here, we have some div and styles for the spinner.
Next, in the CoachesList.vue file we will show this base-spinner if the isLoading is true.
Next, we will include the BaseSpinner component in our main.js file.
In the CoachesList.vue file we will show the getters when isLoading is false.
Next, in CoachesList.vue file we show the Register as Coach button, if isCoach and isLoading is false. Also, the coach-item will be shown if hasCoaches is true.
Next, we will create the BaseDialog.vue file where we will create a basic template with some styles.
Now, we will include the BaseDialog in the main.js file.
In the CoachesList.vue file, we will show this base-dialog in case of and error.
Now, we will make an error in the actions.js file.
Now, in http://localhost:8080/coaches we will get the error pop-up.
Now, in the actions.js for requests, we will add a contactCoach function. This will take the email and message and make an POST call to requests in firebase.
Once, we submit a request to contact an Coach, it will be saved in the database.
Now, in the actions.js for requests, we will add a fetchRequests function. It will get all the data for requests from the databse and save it in the requests array.
Now, in the mutations.js file we will add the setRequests function to set the payload as requests.
Now, in RequestsReceived.vue file we will call the method loadRequests() in the created lifecycle.Here, we are getting all the data from the store through fetchRequests.
In the RequestsReceived.vue file we will show the dialog for error. Will also add the base-spinner.
Now, in http://localhost:8080/requests we will see the requests.
We will also create a NotFound.vue file where, we will show the Page not found.
Now, go to any non-existing page and we will see this component.
Now, we will add authentication in our project by first going to the Realtime Database and then going to the Rules tab.
Next, we will add the rules for the coaches and the requests.
Now, without login if we click on Requests we will get an error.
Now, we will create an auth folder in pages. And inside it UserAuth.vue file. Here, we have a basic form to take email and password.
Next, in the script in UserAuth.vue file we have data and different computed property to show different label on the button.
We will also add the methods of submitForm, switchAuthMode and handleError in UserAuth.vue file.
Now, we will add the required styles in UserAuth.vue file.
Now, we will add a new route for our UserAuth in the router.js file.
Now, when we will goto http://localhost:8080/auth we will see our auth screen.
Now, we will add Authentication in our firebase console. Here, click on Get started button.
Next, click on the Sign-in method in the screen.
Click on the Add new provider and then the Email/Password button.
Next, enable the Email/Password and click on Save button.
Now, in the next screen we will see the Email /Password been enabled.
Now, we will create an auth folder in the modules. And add the files required for vuex. Here, in the index.js file we have again added the different files.
Now, we will add our authModule in the root index.js file.
In the getters.js fo auth, we will add the userId and token function.
Back in firebase console click on Settings icon and then Project settings.
Now, we will get our Web API Key in the next screen.
Now, in the actions.js of the auth we will add the POST with fetch in signup(). We also need to give the api keys here.
Next, in the mutations.js of the auth we will have the setUser function.
Back in the actions.js of the auth we will add the login(). Here, again in a fetch we need to give the api keys.
Next, in actions.js of the coaches we will use the token in registerCoach().
Next, in fetchRequests of actions.js of requests we will use the token.
Now, go to http://localhost:8080/auth and we can login.
Next, in getters.js file in auth we will add isAuthenticated().
Next, in CoachesList.vue file we will add a redirect for Login and also isLoggedIn() in computed.
Now, in the TheHeader.vue file we will have isLoggedIn() and call the isAuthenticated.
We will also add the Logout button to call the logout function in TheHeader.vue file.
In the actions.js file in auth we will add the logout().
In the UserAuth.vue file we will have a path to go to coaches after sucessfully login.
We will change the redirectUrl and replace it in UserAuth.vue file.
Now, in router.js file we will use the meta in different paths. Also, beforeEach on router which will take to coaches route if not authenticated.
We will now remove the tokenExpiration from the mutations.js of the auth.
Next, in the getters.js of the auth we will have the didAutoLogout function.
Also, in the mutations.js of auth, we will add the didAutoLogout in the setUser and we will also have a setAutoLogout().
Now, we will add the didAutoLogout in the index.js file of the auth.
Next, in actions.js of auth, we will add the login and logout function.
Now, in the actions.js file we will add the auth function. Here, we will goto different url depending on the login or signup using fetch.
We are also getting the expirationDate and setting it in the localStorage.
We will also add the tryLogin, logout and autoLogout function in the actions.js file.
In the App.vue file we will add the didAutoLogout() in the computed. In the created lifecycle we are calling the tryLogin. Also, we are watching for the didAutoLogout().
Our app is done, but we will also deploy it in firebase. So, click on Hosting in firebase console.
It will ask us to install firebase tools. If we have not done the same, we need to install it globally.
It will give us the command next. Just click on the Next button.
Next, click on Continue to the console.
Now, from the terminal give the command firebase login and it will give a pop-up to login.
After that give the firebase init command and here select the Hosting function.
Next, we need to select the mentioned options in the screenshot below. Choose the correct project which you have created.
Next, run the command npm run build from the terminal.
Next, give the command firebase deploy to deploy our code to firebase.
Our code got deployed sucessfully and all functionalities working fine. You can find the code for the same in this github repo.