Angular 2+ Exercise
- Generate a project using:
ng new ng-rolodex
- When prompted, "Would you like to add Angular routing?", pick yes
- When prompted, "Which Stylesheet format would you like to use?", pick SCSS
- Change into dir:
cd ng-rolodex
- Install all appropriate docker-based files
- Install the
knex
,bookshelf
, andpg
dependencies using npm - Setup
knexfile.js
withknex init
- Setup the appropriate
knex.js
andbookshelf.js
files - Create 2 migrations,
Users
andContacts
refer to schemas - Create the
User
andContact
Bookshelf model files - Install the
express
andbody-parser
dependency using npm - Setup an express server in
server.js
- Set up express middleware for
body-parser
- Add router middleware for
/api
to use the/api/index.js
module /api/index.js
will require and use the two modules,./contacts
,./users
- Implement the routes defined in routes
The default view for this application should be a login page that has a username input (and password input once full authentication is setup) and a "Login" button that sends the credentials to the server. The login page itself should be on the route "/login" but the "/" route should redirect to the login page if the user is not logged in.
The login form should have full validation of all input fields. A successful login should redirect to the home page, while an unsuccessful login, should show the login error on the login page.
There should be a page header that's viewable on each page. This header should be dynamic based on whether the user is logged in or not.
When not logged in, the header should only display the name of the application on the top left.
When logged in, along with the name of the application, a button to create a new contact, view all contacts, to view the users profile, and a logout button should be displayed.
The "/" route should display just a search bar that allows the user to search for a contact and a search button to execute the search against the backend server.
After inputting a few characters, and clicking the "Search" button, the view should be updated with a list of contacts that match the given character set.
For example,
With Input "jas", and clicking the "Search" button:
There should be a list of contacts in alphabetical order -
Jason Sewell
Jason Statham
Jason Voorhees
Each one of the contacts should be a link that takes the user to the contact page for that contact. The Contact page should display all known information on that contact.
For mvp, it's sufficient for a user to login with just a username, if the username exists, store the user's user_id
in localStorage
.
The user can logout. On logout, delete the user_id
value from localStorage
and redirect the user back to the login route /login
.
A user must be loggedIn
in order to create a new Contact
.
When the user is not logged in, the only page that should be available to them is the Login page.
Create a login-guard.service.ts
file in /src/app/services
and implement a canActivate
method that checks to see if the user is logged in or not. Return true if the user is logged and return false if the user is not. This login-guard should be placed all routes that require a user to be logged in to function properly. The routes needed to be protected are: '/', '/contacts', '/profile', '/contacts/new', and '/contacts/:id'.
The /contacts
route will list all contacts for the logged in user.
The all contacts should links to the appropriate /contact/:id
route.
The /contact/:id
route will show the contact's name at the top along with any additional contact information given when the contact was created/edited.
The /profile
route should show all the user's current information and allows the user to edit their own information.
Property | Type | Options |
---|---|---|
id (PK) | number | not null, unique |
username | string | not null, unique |
name | string | nullable |
string | nullable | |
address | string | nullable |
created_at | TS w/ TZ | not null |
updated_at | TS w/ TZ | not null |
Property | Type | Options |
---|---|---|
id (PK) | number | not null, unique |
name | string | not null |
address | string | nullable |
mobile | string | nullable |
work | string | nullable |
home | string | nullable |
string | nullable | |
string | nullable | |
string | nullable | |
github | string | nullable |
created_at | TS w/ TZ | not null |
updated_at | TS w/ TZ | not null |
associations
Foreign Key | Name | Relation |
---|---|---|
created_by | creator | belongs to Users |
module source file | route | action |
---|---|---|
api/users/index.js | GET /api/profile?user=:id | Respond with current user's profile |
api/users/index.js | PUT /api/users?user=:id | Edit current user account information |
api/users/auth.js | POST /api/login | Logs a user in |
api/users/auth.js | POST /api/logout | Logs a user out |
api/users/auth.js | POST /api/register | Registers a new user with the application |
api/contacts/index.js | GET /api/contacts?user=:id | Respond with all contacts for the logged in user |
api/contacts/index.js | GET /api/contacts/search/:term?user=:id | Respond with all contacts that match the search term for this user |
api/contacts/index.js | POST /api/contacts | Create and respond with a new contact |
api/contacts/index.js | GET /api/contacts/:id | Respond with the contact that matches this id |
api/contacts/index.js | PUT /api/contacts/:id | Update and respond with the updated contact |
api/contacts/index.js | DELETE /api/contacts/:id | Delete the contact that matches the given id, respond with Status 200 OK |
Please note that the following routes will change once a full authentication system is in place.
GET /api/profile?user=:id
=> GET /api/profile
PUT /api/users?user=:id
=> PUT /api/users
GET /api/contacts?user=:id
=> GET /api/contacts
GET /api/contacts/search/:term?user=:id
=> GET /api/contacts/search/:term
Additionally the body contents of the following route will need to be modified to not send the current user's id with the body. This information should be pulled off the session at this point.
PUT /api/users
POST /api/contacts
- Debounce search input
- Autofocus inputs between component reloads
- Separate
/contacts
items alphabetically - add supertest
- enable real auth
- styles
- Use observables for session handling
- Debounce search input using observables