In previous lessons, we covered all the basics one full-stack app can have. Now is the time for you to implement all these features one more time.
The app needs to have users (signup, login, and logout functionality) and full CRUD on at least one of the models, but that one model can't be just users (you can have CRUD on users as well, but that can't be the only one). So let's summarize the requirements:
- Models: User, Room, Reviews
- Routes: auth, rooms, reviews, users (optional, in case you want to add CRUD on users as well)
- Views: all the necessary pages so the users can auth themselves and do the CRUD. For easier navigation through your files and consistent naming please organize all the pages into folders (ex. auth-views, room-views, comment-views, ...)
Once more, let's use our friend IronLauncher
and create a new app:
$ ironlauncher rooms-app
$ cd rooms-app
$ npm run dev
Our app will have users, and they will use email
and password
to authenticate themselves. They will also have to input their full name when signing in. In addition to this way, please feel free to use any of the social strategies (this is a bonus feature).
So your user schema should look somewhat like this:
const userSchema = new Schema(
{
email: String,
password: String,
fullName: String,
// slack login - optional
slackID: String,
// google login - optional
googleID: String
},
{
timestamps: true
}
);
Now create all the routes and views needed to have users successfully signup/login/logout. For auth, you can use passport.js
and its local strategy or the sessions & cookies
setup.
💡 Make sure you install all the packages:
For passport.js
: bcrypt, passport, passport-local,
For sessions & cookies
: bcryptjs, express-session, connect-mongo.
And if you have social login
: passport-google-oauth and/or passport-slack.
Hint: You have already everything set up in the previous lessons + class examples, be resourceful 🥳.
Great, we have users so let's start adding some more functionality to our app. Our rooms will have following schema:
const roomSchema = new Schema({
name: { type: String },
description: { type: String },
imageUrl: { type: String },
owner: { type: Schema.Types.ObjectId, ref: "User" },
reviews: [] // we will update this field a bit later when we create review model
});
Our users can:
- create new rooms only when logged in
- edit and delete the rooms only if they created them (if they are the owners)
- see the list of the rooms even though they are not logged in
Please proceed to create all the routes and files necessary to display forms and see the results after the submission.
Great, you already have a fully functioning CRUD app with users but we will go one more step: let's create reviews section for each room.
The review schema can look like this:
const reviewSchema = new Schema({
user: { type: Schema.Types.ObjectId, ref: "User" },
comment: { type: String, maxlength: 200 }
});
Now we can go ahead and update reviews
property in the roomSchema:
// ...
reviews: [{ type: Schema.Types.ObjectId, ref: "Review" }];
// ...
Our users can:
- when logged in, make reviews for all the rooms but the ones they created
- when logged in, edit and/or delete their comments (optional)
- when logged out, see the rooms and all the comments
Happy coding! ❤️