├── 10
└── app
│ ├── common
│ ├── app-nav.component.js
│ ├── app-nav.html
│ ├── app-sidebar.component.js
│ ├── app-sidebar.controller.js
│ ├── app-sidebar.html
│ ├── app.component.js
│ ├── app.controller.js
│ ├── app.html
│ └── app.module.js
│ ├── components
│ ├── auth
│ │ ├── auth-form
│ │ │ ├── auth-form.component.js
│ │ │ ├── auth-form.controller.js
│ │ │ └── auth-form.html
│ │ ├── auth.module.js
│ │ ├── auth.service.js
│ │ ├── login
│ │ │ ├── login.component.js
│ │ │ ├── login.controller.js
│ │ │ └── login.html
│ │ └── register
│ │ │ ├── register.component.js
│ │ │ ├── register.controller.js
│ │ │ └── register.html
│ ├── components.module.js
│ └── contact
│ │ ├── contact-detail
│ │ ├── contact-detail.component.js
│ │ ├── contact-detail.controller.js
│ │ └── contact-detail.html
│ │ ├── contact-edit
│ │ ├── contact-edit.component.js
│ │ ├── contact-edit.controller.js
│ │ └── contact-edit.html
│ │ ├── contact-new
│ │ ├── contact-new.component.js
│ │ ├── contact-new.controller.js
│ │ └── contact-new.html
│ │ ├── contact-tag
│ │ ├── contact-tag.component.js
│ │ ├── contact-tag.controller.js
│ │ └── contact-tag.html
│ │ ├── contact.module.js
│ │ ├── contact.service.js
│ │ ├── contact
│ │ ├── contact.component.js
│ │ ├── contact.controller.js
│ │ └── contact.html
│ │ ├── contacts
│ │ ├── contacts.component.js
│ │ ├── contacts.controller.js
│ │ ├── contacts.filter.js
│ │ └── contacts.html
│ │ └── length-check
│ │ └── length-check.directive.js
│ ├── root.component.js
│ ├── root.html
│ └── root.module.js
├── .babelrc
├── .editorconfig
├── .gitignore
├── 00-complete
└── app
│ ├── common
│ ├── app-nav.component.js
│ ├── app-nav.html
│ ├── app-sidebar.component.js
│ ├── app-sidebar.controller.js
│ ├── app-sidebar.html
│ ├── app.component.js
│ ├── app.controller.js
│ ├── app.html
│ ├── app.module.js
│ └── app.spec.js
│ ├── components
│ ├── auth
│ │ ├── auth-form
│ │ │ ├── auth-form.component.js
│ │ │ ├── auth-form.controller.js
│ │ │ ├── auth-form.html
│ │ │ └── auth-form.spec.js
│ │ ├── auth.module.js
│ │ ├── auth.service.js
│ │ ├── auth.spec.js
│ │ ├── login
│ │ │ ├── login.component.js
│ │ │ ├── login.controller.js
│ │ │ ├── login.html
│ │ │ └── login.spec.js
│ │ └── register
│ │ │ ├── register.component.js
│ │ │ ├── register.controller.js
│ │ │ ├── register.html
│ │ │ └── register.spec.js
│ ├── components.module.js
│ └── contact
│ │ ├── contact-detail
│ │ ├── contact-detail.component.js
│ │ ├── contact-detail.controller.js
│ │ ├── contact-detail.html
│ │ └── contact-detail.spec.js
│ │ ├── contact-edit
│ │ ├── contact-edit.component.js
│ │ ├── contact-edit.controller.js
│ │ ├── contact-edit.html
│ │ └── contact-edit.spec.js
│ │ ├── contact-new
│ │ ├── contact-new.component.js
│ │ ├── contact-new.controller.js
│ │ ├── contact-new.html
│ │ └── contact-new.spec.js
│ │ ├── contact-tag
│ │ ├── contact-tag.component.js
│ │ ├── contact-tag.controller.js
│ │ ├── contact-tag.html
│ │ └── contact-tag.spec.js
│ │ ├── contact.module.js
│ │ ├── contact.service.js
│ │ ├── contact
│ │ ├── contact.component.js
│ │ ├── contact.controller.js
│ │ ├── contact.html
│ │ └── contact.spec.js
│ │ ├── contacts.spec.js
│ │ ├── contacts
│ │ ├── contacts.component.js
│ │ ├── contacts.controller.js
│ │ ├── contacts.filter.js
│ │ ├── contacts.html
│ │ └── contacts.spec.js
│ │ └── length-check
│ │ ├── length-check.directive.js
│ │ └── length-check.spec.js
│ ├── root.component.js
│ ├── root.html
│ └── root.module.js
├── 01
└── app
│ ├── common
│ └── app.module.js
│ ├── components
│ ├── auth
│ │ └── auth.module.js
│ ├── components.module.js
│ └── contact
│ │ └── contact.module.js
│ ├── root.component.js
│ ├── root.html
│ └── root.module.js
├── 02
└── app
│ ├── common
│ └── app.module.js
│ ├── components
│ ├── auth
│ │ ├── auth-form
│ │ │ ├── auth-form.component.js
│ │ │ ├── auth-form.controller.js
│ │ │ └── auth-form.html
│ │ ├── auth.module.js
│ │ ├── auth.service.js
│ │ ├── login
│ │ │ ├── login.component.js
│ │ │ ├── login.controller.js
│ │ │ └── login.html
│ │ └── register
│ │ │ ├── register.component.js
│ │ │ ├── register.controller.js
│ │ │ └── register.html
│ ├── components.module.js
│ └── contact
│ │ └── contact.module.js
│ ├── root.component.js
│ ├── root.html
│ └── root.module.js
├── 03
└── app
│ ├── common
│ ├── app-nav.component.js
│ ├── app-nav.html
│ ├── app-sidebar.component.js
│ ├── app-sidebar.controller.js
│ ├── app-sidebar.html
│ ├── app.component.js
│ ├── app.controller.js
│ ├── app.html
│ └── app.module.js
│ ├── components
│ ├── auth
│ │ ├── auth-form
│ │ │ ├── auth-form.component.js
│ │ │ ├── auth-form.controller.js
│ │ │ └── auth-form.html
│ │ ├── auth.module.js
│ │ ├── auth.service.js
│ │ ├── login
│ │ │ ├── login.component.js
│ │ │ ├── login.controller.js
│ │ │ └── login.html
│ │ └── register
│ │ │ ├── register.component.js
│ │ │ ├── register.controller.js
│ │ │ └── register.html
│ ├── components.module.js
│ └── contact
│ │ └── contact.module.js
│ ├── root.component.js
│ ├── root.html
│ └── root.module.js
├── 04
└── app
│ ├── common
│ ├── app-nav.component.js
│ ├── app-nav.html
│ ├── app-sidebar.component.js
│ ├── app-sidebar.controller.js
│ ├── app-sidebar.html
│ ├── app.component.js
│ ├── app.controller.js
│ ├── app.html
│ └── app.module.js
│ ├── components
│ ├── auth
│ │ ├── auth-form
│ │ │ ├── auth-form.component.js
│ │ │ ├── auth-form.controller.js
│ │ │ └── auth-form.html
│ │ ├── auth.module.js
│ │ ├── auth.service.js
│ │ ├── login
│ │ │ ├── login.component.js
│ │ │ ├── login.controller.js
│ │ │ └── login.html
│ │ └── register
│ │ │ ├── register.component.js
│ │ │ ├── register.controller.js
│ │ │ └── register.html
│ ├── components.module.js
│ └── contact
│ │ ├── contact-detail
│ │ ├── contact-detail.component.js
│ │ ├── contact-detail.controller.js
│ │ └── contact-detail.html
│ │ ├── contact-new
│ │ ├── contact-new.component.js
│ │ ├── contact-new.controller.js
│ │ └── contact-new.html
│ │ ├── contact.module.js
│ │ └── contact.service.js
│ ├── root.component.js
│ ├── root.html
│ └── root.module.js
├── 05
└── app
│ ├── common
│ ├── app-nav.component.js
│ ├── app-nav.html
│ ├── app-sidebar.component.js
│ ├── app-sidebar.controller.js
│ ├── app-sidebar.html
│ ├── app.component.js
│ ├── app.controller.js
│ ├── app.html
│ └── app.module.js
│ ├── components
│ ├── auth
│ │ ├── auth-form
│ │ │ ├── auth-form.component.js
│ │ │ ├── auth-form.controller.js
│ │ │ └── auth-form.html
│ │ ├── auth.module.js
│ │ ├── auth.service.js
│ │ ├── login
│ │ │ ├── login.component.js
│ │ │ ├── login.controller.js
│ │ │ └── login.html
│ │ └── register
│ │ │ ├── register.component.js
│ │ │ ├── register.controller.js
│ │ │ └── register.html
│ ├── components.module.js
│ └── contact
│ │ ├── contact-detail
│ │ ├── contact-detail.component.js
│ │ ├── contact-detail.controller.js
│ │ └── contact-detail.html
│ │ ├── contact-edit
│ │ ├── contact-edit.component.js
│ │ ├── contact-edit.controller.js
│ │ └── contact-edit.html
│ │ ├── contact-new
│ │ ├── contact-new.component.js
│ │ ├── contact-new.controller.js
│ │ └── contact-new.html
│ │ ├── contact.module.js
│ │ └── contact.service.js
│ ├── root.component.js
│ ├── root.html
│ └── root.module.js
├── 06
└── app
│ ├── common
│ ├── app-nav.component.js
│ ├── app-nav.html
│ ├── app-sidebar.component.js
│ ├── app-sidebar.controller.js
│ ├── app-sidebar.html
│ ├── app.component.js
│ ├── app.controller.js
│ ├── app.html
│ └── app.module.js
│ ├── components
│ ├── auth
│ │ ├── auth-form
│ │ │ ├── auth-form.component.js
│ │ │ ├── auth-form.controller.js
│ │ │ └── auth-form.html
│ │ ├── auth.module.js
│ │ ├── auth.service.js
│ │ ├── login
│ │ │ ├── login.component.js
│ │ │ ├── login.controller.js
│ │ │ └── login.html
│ │ └── register
│ │ │ ├── register.component.js
│ │ │ ├── register.controller.js
│ │ │ └── register.html
│ ├── components.module.js
│ └── contact
│ │ ├── contact-detail
│ │ ├── contact-detail.component.js
│ │ ├── contact-detail.controller.js
│ │ └── contact-detail.html
│ │ ├── contact-edit
│ │ ├── contact-edit.component.js
│ │ ├── contact-edit.controller.js
│ │ └── contact-edit.html
│ │ ├── contact-new
│ │ ├── contact-new.component.js
│ │ ├── contact-new.controller.js
│ │ └── contact-new.html
│ │ ├── contact-tag
│ │ ├── contact-tag.component.js
│ │ ├── contact-tag.controller.js
│ │ └── contact-tag.html
│ │ ├── contact.module.js
│ │ └── contact.service.js
│ ├── root.component.js
│ ├── root.html
│ └── root.module.js
├── 07
└── app
│ ├── common
│ ├── app-nav.component.js
│ ├── app-nav.html
│ ├── app-sidebar.component.js
│ ├── app-sidebar.controller.js
│ ├── app-sidebar.html
│ ├── app.component.js
│ ├── app.controller.js
│ ├── app.html
│ └── app.module.js
│ ├── components
│ ├── auth
│ │ ├── auth-form
│ │ │ ├── auth-form.component.js
│ │ │ ├── auth-form.controller.js
│ │ │ └── auth-form.html
│ │ ├── auth.module.js
│ │ ├── auth.service.js
│ │ ├── login
│ │ │ ├── login.component.js
│ │ │ ├── login.controller.js
│ │ │ └── login.html
│ │ └── register
│ │ │ ├── register.component.js
│ │ │ ├── register.controller.js
│ │ │ └── register.html
│ ├── components.module.js
│ └── contact
│ │ ├── contact-detail
│ │ ├── contact-detail.component.js
│ │ ├── contact-detail.controller.js
│ │ └── contact-detail.html
│ │ ├── contact-edit
│ │ ├── contact-edit.component.js
│ │ ├── contact-edit.controller.js
│ │ └── contact-edit.html
│ │ ├── contact-new
│ │ ├── contact-new.component.js
│ │ ├── contact-new.controller.js
│ │ └── contact-new.html
│ │ ├── contact-tag
│ │ ├── contact-tag.component.js
│ │ ├── contact-tag.controller.js
│ │ └── contact-tag.html
│ │ ├── contact.module.js
│ │ ├── contact.service.js
│ │ └── contacts
│ │ ├── contacts.component.js
│ │ ├── contacts.controller.js
│ │ └── contacts.html
│ ├── root.component.js
│ ├── root.html
│ └── root.module.js
├── 08
└── app
│ ├── common
│ ├── app-nav.component.js
│ ├── app-nav.html
│ ├── app-sidebar.component.js
│ ├── app-sidebar.controller.js
│ ├── app-sidebar.html
│ ├── app.component.js
│ ├── app.controller.js
│ ├── app.html
│ └── app.module.js
│ ├── components
│ ├── auth
│ │ ├── auth-form
│ │ │ ├── auth-form.component.js
│ │ │ ├── auth-form.controller.js
│ │ │ └── auth-form.html
│ │ ├── auth.module.js
│ │ ├── auth.service.js
│ │ ├── login
│ │ │ ├── login.component.js
│ │ │ ├── login.controller.js
│ │ │ └── login.html
│ │ └── register
│ │ │ ├── register.component.js
│ │ │ ├── register.controller.js
│ │ │ └── register.html
│ ├── components.module.js
│ └── contact
│ │ ├── contact-detail
│ │ ├── contact-detail.component.js
│ │ ├── contact-detail.controller.js
│ │ └── contact-detail.html
│ │ ├── contact-edit
│ │ ├── contact-edit.component.js
│ │ ├── contact-edit.controller.js
│ │ └── contact-edit.html
│ │ ├── contact-new
│ │ ├── contact-new.component.js
│ │ ├── contact-new.controller.js
│ │ └── contact-new.html
│ │ ├── contact-tag
│ │ ├── contact-tag.component.js
│ │ ├── contact-tag.controller.js
│ │ └── contact-tag.html
│ │ ├── contact.module.js
│ │ ├── contact.service.js
│ │ ├── contact
│ │ ├── contact.component.js
│ │ ├── contact.controller.js
│ │ └── contact.html
│ │ └── contacts
│ │ ├── contacts.component.js
│ │ ├── contacts.controller.js
│ │ └── contacts.html
│ ├── root.component.js
│ ├── root.html
│ └── root.module.js
├── 09
└── app
│ ├── common
│ ├── app-nav.component.js
│ ├── app-nav.html
│ ├── app-sidebar.component.js
│ ├── app-sidebar.controller.js
│ ├── app-sidebar.html
│ ├── app.component.js
│ ├── app.controller.js
│ ├── app.html
│ └── app.module.js
│ ├── components
│ ├── auth
│ │ ├── auth-form
│ │ │ ├── auth-form.component.js
│ │ │ ├── auth-form.controller.js
│ │ │ └── auth-form.html
│ │ ├── auth.module.js
│ │ ├── auth.service.js
│ │ ├── login
│ │ │ ├── login.component.js
│ │ │ ├── login.controller.js
│ │ │ └── login.html
│ │ └── register
│ │ │ ├── register.component.js
│ │ │ ├── register.controller.js
│ │ │ └── register.html
│ ├── components.module.js
│ └── contact
│ │ ├── contact-detail
│ │ ├── contact-detail.component.js
│ │ ├── contact-detail.controller.js
│ │ └── contact-detail.html
│ │ ├── contact-edit
│ │ ├── contact-edit.component.js
│ │ ├── contact-edit.controller.js
│ │ └── contact-edit.html
│ │ ├── contact-new
│ │ ├── contact-new.component.js
│ │ ├── contact-new.controller.js
│ │ └── contact-new.html
│ │ ├── contact-tag
│ │ ├── contact-tag.component.js
│ │ ├── contact-tag.controller.js
│ │ └── contact-tag.html
│ │ ├── contact.module.js
│ │ ├── contact.service.js
│ │ ├── contact
│ │ ├── contact.component.js
│ │ ├── contact.controller.js
│ │ └── contact.html
│ │ └── contacts
│ │ ├── contacts.component.js
│ │ ├── contacts.controller.js
│ │ ├── contacts.filter.js
│ │ └── contacts.html
│ ├── root.component.js
│ ├── root.html
│ └── root.module.js
├── README.md
├── gulpfile.babel.js
├── karma.conf.js
├── mocks
└── firebase.mock.js
├── package.json
└── src
├── app
├── common
│ └── app.module.js
├── components
│ ├── auth
│ │ └── auth.module.js
│ ├── components.module.js
│ └── contact
│ │ └── contact.module.js
├── root.component.js
├── root.html
└── root.module.js
├── fonts
├── MaterialIcons-Regular.eot
├── MaterialIcons-Regular.ttf
├── MaterialIcons-Regular.woff
└── MaterialIcons-Regular.woff2
├── img
├── favicon.ico
└── logo.png
├── index.html
└── sass
└── style.scss
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015"]
3 | }
4 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig helps developers define and maintain consistent
2 | # coding styles between different editors and IDEs
3 | # editorconfig.org
4 |
5 | root = true
6 |
7 | [*]
8 |
9 | # Change these settings to your own preference
10 | indent_style = space
11 | indent_size = 2
12 |
13 | # We recommend you to keep these unchanged
14 | end_of_line = lf
15 | charset = utf-8
16 | trim_trailing_whitespace = true
17 | insert_final_newline = true
18 |
19 | [*.md]
20 | trim_trailing_whitespace = false
21 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | dist
2 | node_modules
3 | .DS_Store
4 | .tmp
5 | .sass-cache
6 | *.sublime-*
7 | .jekyll-metadata
8 | .idea
9 | npm-debug.log
10 | templates.js
11 |
--------------------------------------------------------------------------------
/00-complete/app/common/app-nav.component.js:
--------------------------------------------------------------------------------
1 | var appNav = {
2 | bindings: {
3 | user: '<',
4 | onLogout: '&'
5 | },
6 | templateUrl: './app-nav.html'
7 | };
8 |
9 | angular
10 | .module('common')
11 | .component('appNav', appNav);
12 |
--------------------------------------------------------------------------------
/00-complete/app/common/app-nav.html:
--------------------------------------------------------------------------------
1 |
23 |
--------------------------------------------------------------------------------
/00-complete/app/common/app-sidebar.component.js:
--------------------------------------------------------------------------------
1 | var appSidebar = {
2 | templateUrl: './app-sidebar.html',
3 | controller: 'AppSidebarController'
4 | };
5 |
6 | angular
7 | .module('common')
8 | .component('appSidebar', appSidebar);
9 |
--------------------------------------------------------------------------------
/00-complete/app/common/app-sidebar.controller.js:
--------------------------------------------------------------------------------
1 | function AppSidebarController() {
2 | var ctrl = this;
3 | ctrl.contactTags = [{
4 | label: 'All contacts',
5 | icon: 'star',
6 | state: 'none'
7 | }, {
8 | label: 'Friends',
9 | icon: 'people',
10 | state: 'friends'
11 | }, {
12 | label: 'Family',
13 | icon: 'child_care',
14 | state: 'family'
15 | }, {
16 | label: 'Acquaintances',
17 | icon: 'accessibility',
18 | state: 'acquaintances'
19 | }, {
20 | label: 'Following',
21 | icon: 'remove_red_eye',
22 | state: 'following'
23 | }];
24 | }
25 |
26 | angular
27 | .module('common')
28 | .controller('AppSidebarController', AppSidebarController);
29 |
--------------------------------------------------------------------------------
/00-complete/app/common/app-sidebar.html:
--------------------------------------------------------------------------------
1 |
26 |
--------------------------------------------------------------------------------
/00-complete/app/common/app.component.js:
--------------------------------------------------------------------------------
1 | var app = {
2 | templateUrl: './app.html',
3 | controller: 'AppController'
4 | };
5 |
6 | angular
7 | .module('common')
8 | .component('app', app)
9 | .config(function ($stateProvider) {
10 | $stateProvider
11 | .state('app', {
12 | redirectTo: 'contacts',
13 | url: '/app',
14 | data: {
15 | requiredAuth: true
16 | },
17 | component: 'app'
18 | })
19 | });
20 |
--------------------------------------------------------------------------------
/00-complete/app/common/app.controller.js:
--------------------------------------------------------------------------------
1 | function AppController(AuthService, $state) {
2 | var ctrl = this;
3 | ctrl.user = AuthService.getUser();
4 | ctrl.logout = function () {
5 | AuthService.logout().then(function () {
6 | $state.go('auth.login');
7 | });
8 | };
9 | }
10 |
11 | angular
12 | .module('common')
13 | .controller('AppController', AppController);
14 |
--------------------------------------------------------------------------------
/00-complete/app/common/app.html:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/00-complete/app/common/app.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('common', [
3 | 'ui.router',
4 | 'angular-loading-bar'
5 | ])
6 | .run(function ($transitions, cfpLoadingBar) {
7 | $transitions.onStart({}, cfpLoadingBar.start);
8 | $transitions.onSuccess({}, cfpLoadingBar.complete);
9 | });
10 |
--------------------------------------------------------------------------------
/00-complete/app/components/auth/auth-form/auth-form.component.js:
--------------------------------------------------------------------------------
1 | var authForm = {
2 | bindings: {
3 | user: '<',
4 | button: '@',
5 | message: '@',
6 | onSubmit: '&'
7 | },
8 | templateUrl: './auth-form.html',
9 | controller: 'AuthFormController'
10 | };
11 |
12 | angular
13 | .module('components.auth')
14 | .component('authForm', authForm);
15 |
--------------------------------------------------------------------------------
/00-complete/app/components/auth/auth-form/auth-form.controller.js:
--------------------------------------------------------------------------------
1 | function AuthFormController() {
2 | var ctrl = this;
3 | ctrl.$onChanges = function (changes) {
4 | if (changes.user) {
5 | ctrl.user = angular.copy(ctrl.user);
6 | }
7 | };
8 | ctrl.submitForm = function () {
9 | ctrl.onSubmit({
10 | $event: {
11 | user: ctrl.user
12 | }
13 | });
14 | };
15 | }
16 |
17 | angular
18 | .module('components.auth')
19 | .controller('AuthFormController', AuthFormController);
20 |
--------------------------------------------------------------------------------
/00-complete/app/components/auth/auth-form/auth-form.html:
--------------------------------------------------------------------------------
1 |
27 |
--------------------------------------------------------------------------------
/00-complete/app/components/auth/auth-form/auth-form.spec.js:
--------------------------------------------------------------------------------
1 | describe('Auth', function () {
2 | beforeEach(module('components.auth'));
3 |
4 | describe('AuthFormController', function () {
5 | var $componentController,
6 | controller,
7 | mockUser = { $id: 1 },
8 | mockSubmit = angular.noop;
9 |
10 | beforeEach(inject(function ($injector) {
11 | $componentController = $injector.get('$componentController');
12 |
13 | controller = $componentController('authForm',
14 | { $scope: {} },
15 | { user: mockUser, button: '', message: '', onSubmit: mockSubmit }
16 | );
17 | }));
18 |
19 | it('should call onSelect with the correct payload', function () {
20 | var payload = { $event: { user: mockUser } };
21 |
22 | spyOn(controller, 'onSubmit');
23 | controller.submitForm();
24 | expect(controller.onSubmit).toHaveBeenCalledWith(payload);
25 | });
26 | });
27 | });
28 |
--------------------------------------------------------------------------------
/00-complete/app/components/auth/auth.service.js:
--------------------------------------------------------------------------------
1 | function AuthService($firebaseAuth) {
2 | var auth = $firebaseAuth();
3 | var authData = null;
4 | function storeAuthData(response) {
5 | authData = response;
6 | return authData;
7 | }
8 | function onSignIn(user) {
9 | authData = user;
10 | return auth.$requireSignIn();
11 | }
12 | function clearAuthData() {
13 | authData = null;
14 | }
15 | this.login = function (user) {
16 | return auth
17 | .$signInWithEmailAndPassword(user.email, user.password)
18 | .then(storeAuthData);
19 | };
20 | this.register = function (user) {
21 | return auth
22 | .$createUserWithEmailAndPassword(user.email, user.password)
23 | .then(storeAuthData);
24 | };
25 | this.logout = function () {
26 | return auth
27 | .$signOut()
28 | .then(clearAuthData);
29 | };
30 | this.requireAuthentication = function () {
31 | return auth
32 | .$waitForSignIn().then(onSignIn);
33 | };
34 | this.isAuthenticated = function () {
35 | return !!authData;
36 | };
37 | this.getUser = function () {
38 | if (authData) {
39 | return authData;
40 | }
41 | };
42 | }
43 |
44 | angular
45 | .module('components.auth')
46 | .service('AuthService', AuthService);
47 |
--------------------------------------------------------------------------------
/00-complete/app/components/auth/login/login.component.js:
--------------------------------------------------------------------------------
1 | var login = {
2 | templateUrl: './login.html',
3 | controller: 'LoginController'
4 | };
5 |
6 | angular
7 | .module('components.auth')
8 | .component('login', login)
9 | .config(function ($stateProvider, $urlRouterProvider) {
10 | $stateProvider
11 | .state('auth', {
12 | redirectTo: 'auth.login',
13 | url: '/auth',
14 | template: ''
15 | })
16 | .state('auth.login', {
17 | url: '/login',
18 | component: 'login'
19 | });
20 | $urlRouterProvider.otherwise('/auth/login');
21 | });
22 |
--------------------------------------------------------------------------------
/00-complete/app/components/auth/login/login.controller.js:
--------------------------------------------------------------------------------
1 | function LoginController(AuthService, $state) {
2 | var ctrl = this;
3 | ctrl.$onInit = function () {
4 | ctrl.error = null;
5 | ctrl.user = {
6 | email: '',
7 | password: ''
8 | };
9 | };
10 | ctrl.loginUser = function (event) {
11 | return AuthService
12 | .login(event.user)
13 | .then(function () {
14 | $state.go('app');
15 | }, function (reason) {
16 | ctrl.error = reason.message;
17 | });
18 | };
19 | }
20 |
21 | angular
22 | .module('components.auth')
23 | .controller('LoginController', LoginController);
24 |
--------------------------------------------------------------------------------
/00-complete/app/components/auth/login/login.html:
--------------------------------------------------------------------------------
1 |
10 |
15 |
--------------------------------------------------------------------------------
/00-complete/app/components/auth/register/register.component.js:
--------------------------------------------------------------------------------
1 | var register = {
2 | templateUrl: './register.html',
3 | controller: 'RegisterController'
4 | };
5 |
6 | angular
7 | .module('components.auth')
8 | .component('register', register)
9 | .config(function ($stateProvider) {
10 | $stateProvider
11 | .state('auth.register', {
12 | url: '/register',
13 | component: 'register'
14 | });
15 | });
16 |
--------------------------------------------------------------------------------
/00-complete/app/components/auth/register/register.controller.js:
--------------------------------------------------------------------------------
1 | function RegisterController(AuthService, $state) {
2 | var ctrl = this;
3 | ctrl.$onInit = function () {
4 | ctrl.error = null;
5 | ctrl.user = {
6 | email: '',
7 | password: ''
8 | };
9 | };
10 | ctrl.createUser = function (event) {
11 | return AuthService
12 | .register(event.user)
13 | .then(function () {
14 | $state.go('app');
15 | }, function (reason) {
16 | ctrl.error = reason.message;
17 | });
18 | };
19 | }
20 |
21 | angular
22 | .module('components.auth')
23 | .controller('RegisterController', RegisterController);
24 |
--------------------------------------------------------------------------------
/00-complete/app/components/auth/register/register.html:
--------------------------------------------------------------------------------
1 |
10 |
15 |
--------------------------------------------------------------------------------
/00-complete/app/components/components.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('components', [
3 | 'components.contact',
4 | 'components.auth'
5 | ]);
6 |
--------------------------------------------------------------------------------
/00-complete/app/components/contact/contact-detail/contact-detail.component.js:
--------------------------------------------------------------------------------
1 | var contactDetail = {
2 | bindings: {
3 | contact: '<',
4 | onSave: '&',
5 | onUpdate: '&',
6 | onDelete: '&'
7 | },
8 | templateUrl: './contact-detail.html',
9 | controller: 'ContactDetailController'
10 | };
11 |
12 | angular
13 | .module('components.contact')
14 | .component('contactDetail', contactDetail);
15 |
--------------------------------------------------------------------------------
/00-complete/app/components/contact/contact-detail/contact-detail.controller.js:
--------------------------------------------------------------------------------
1 | function ContactDetailController() {
2 | var ctrl = this;
3 | ctrl.$onInit = function () {
4 | ctrl.isNewContact = !ctrl.contact.$id;
5 | };
6 | ctrl.saveContact = function () {
7 | ctrl.onSave({
8 | $event: {
9 | contact: ctrl.contact
10 | }
11 | });
12 | };
13 | ctrl.updateContact = function () {
14 | ctrl.onUpdate({
15 | $event: {
16 | contact: ctrl.contact
17 | }
18 | });
19 | };
20 | ctrl.deleteContact = function () {
21 | ctrl.onDelete({
22 | $event: {
23 | contact: ctrl.contact
24 | }
25 | });
26 | };
27 | ctrl.tagChange = function (event) {
28 | ctrl.contact.tag = event.tag;
29 | ctrl.updateContact();
30 | }
31 | }
32 |
33 | angular
34 | .module('components.contact')
35 | .controller('ContactDetailController', ContactDetailController);
36 |
--------------------------------------------------------------------------------
/00-complete/app/components/contact/contact-edit/contact-edit.component.js:
--------------------------------------------------------------------------------
1 | var contactEdit = {
2 | bindings: {
3 | contact: '<'
4 | },
5 | templateUrl: './contact-edit.html',
6 | controller: 'ContactEditController'
7 | };
8 |
9 | angular
10 | .module('components.contact')
11 | .component('contactEdit', contactEdit)
12 | .config(function ($stateProvider) {
13 | $stateProvider
14 | .state('contact', {
15 | parent: 'app',
16 | url: '/contact/:id',
17 | component: 'contactEdit',
18 | resolve: {
19 | contact: function ($transition$, ContactService) {
20 | var key = $transition$.params().id;
21 | return ContactService.getContactById(key).$loaded();
22 | }
23 | }
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/00-complete/app/components/contact/contact-edit/contact-edit.controller.js:
--------------------------------------------------------------------------------
1 | function ContactEditController($state, ContactService, cfpLoadingBar, $window) {
2 | var ctrl = this;
3 | ctrl.updateContact = function (event) {
4 | cfpLoadingBar.start();
5 | return ContactService
6 | .updateContact(event.contact)
7 | .then(cfpLoadingBar.complete, cfpLoadingBar.complete);
8 | };
9 | ctrl.deleteContact = function (event) {
10 | var message = 'Delete ' + event.contact.name + ' from contacts?';
11 | if ($window.confirm(message)) {
12 | return ContactService
13 | .deleteContact(event.contact)
14 | .then(function () {
15 | $state.go('contacts');
16 | });
17 | }
18 | };
19 | }
20 |
21 | angular
22 | .module('components.contact')
23 | .controller('ContactEditController', ContactEditController);
24 |
--------------------------------------------------------------------------------
/00-complete/app/components/contact/contact-edit/contact-edit.html:
--------------------------------------------------------------------------------
1 |
5 |
6 |
--------------------------------------------------------------------------------
/00-complete/app/components/contact/contact-new/contact-new.component.js:
--------------------------------------------------------------------------------
1 | var contactNew = {
2 | templateUrl: './contact-new.html',
3 | controller: 'ContactNewController'
4 | };
5 |
6 | angular
7 | .module('components.contact')
8 | .component('contactNew', contactNew)
9 | .config(function ($stateProvider) {
10 | $stateProvider
11 | .state('new', {
12 | parent: 'app',
13 | url: '/new',
14 | component: 'contactNew'
15 | });
16 | });
17 |
--------------------------------------------------------------------------------
/00-complete/app/components/contact/contact-new/contact-new.controller.js:
--------------------------------------------------------------------------------
1 | function ContactNewController(ContactService, $state) {
2 | var ctrl = this;
3 | ctrl.$onInit = function () {
4 | ctrl.contact = {
5 | name: '',
6 | email: '',
7 | job: '',
8 | location: '',
9 | social: {
10 | facebook: '',
11 | github: '',
12 | twitter: '',
13 | linkedin: ''
14 | },
15 | tag: 'none'
16 | };
17 | };
18 | ctrl.createNewContact = function (event) {
19 | return ContactService
20 | .createNewContact(event.contact)
21 | .then(function (contact) {
22 | $state.go('contact', {
23 | id: contact.key
24 | });
25 | });
26 | };
27 | }
28 |
29 | angular
30 | .module('components.contact')
31 | .controller('ContactNewController', ContactNewController);
32 |
--------------------------------------------------------------------------------
/00-complete/app/components/contact/contact-new/contact-new.html:
--------------------------------------------------------------------------------
1 |
4 |
5 |
--------------------------------------------------------------------------------
/00-complete/app/components/contact/contact-tag/contact-tag.component.js:
--------------------------------------------------------------------------------
1 | var contactTag = {
2 | bindings: {
3 | tag: '<',
4 | onChange: '&'
5 | },
6 | templateUrl: './contact-tag.html',
7 | controller: 'ContactTagController'
8 | };
9 |
10 | angular
11 | .module('components.contact')
12 | .component('contactTag', contactTag);
13 |
--------------------------------------------------------------------------------
/00-complete/app/components/contact/contact-tag/contact-tag.controller.js:
--------------------------------------------------------------------------------
1 | function ContactTagController() {
2 | var ctrl = this;
3 | ctrl.$onInit = function () {
4 | ctrl.tags = [
5 | 'friends', 'family', 'acquaintances', 'following'
6 | ];
7 | };
8 | ctrl.$onChanges = function (changes) {
9 | if (changes.tag) {
10 | ctrl.tag = angular.copy(ctrl.tag);
11 | }
12 | };
13 | ctrl.updateTag = function (tag) {
14 | ctrl.onChange({
15 | $event: {
16 | tag: tag
17 | }
18 | });
19 | };
20 | }
21 |
22 | angular
23 | .module('components.contact')
24 | .controller('ContactTagController', ContactTagController);
25 |
--------------------------------------------------------------------------------
/00-complete/app/components/contact/contact-tag/contact-tag.html:
--------------------------------------------------------------------------------
1 |
18 |
--------------------------------------------------------------------------------
/00-complete/app/components/contact/contact-tag/contact-tag.spec.js:
--------------------------------------------------------------------------------
1 | describe('Contact', function () {
2 | beforeEach(module('components.contact'));
3 |
4 | describe('ContactController', function () {
5 | var $componentController,
6 | controller,
7 | mockTag = 'friends',
8 | mockChange = angular.noop;
9 |
10 | beforeEach(inject(function ($injector) {
11 | $componentController = $injector.get('$componentController');
12 | controller = $componentController('contactTag',
13 | { $scope: {} },
14 | { tag: mockTag, onChange: mockChange }
15 | );
16 | }));
17 |
18 | it('should bind to the correct tag', function () {
19 | var mockTag = 'football';
20 | controller.tag = mockTag;
21 | expect(controller.tag).toEqual(mockTag);
22 | });
23 |
24 | it('should call onSelect with the correct payload', function () {
25 | var tag = 'mate',
26 | payload = { $event: { tag: tag }};
27 |
28 | spyOn(controller, 'onChange');
29 | controller.updateTag(tag);
30 | expect(controller.onChange).toHaveBeenCalledWith(payload);
31 | });
32 | });
33 | });
34 |
--------------------------------------------------------------------------------
/00-complete/app/components/contact/contact.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('components.contact', [
3 | 'ui.router'
4 | ]);
5 |
--------------------------------------------------------------------------------
/00-complete/app/components/contact/contact.service.js:
--------------------------------------------------------------------------------
1 | function ContactService(AuthService, $firebaseRef, $firebaseArray, $firebaseObject) {
2 | var ref = $firebaseRef.contacts;
3 | var uid = AuthService.getUser().uid;
4 | return {
5 | createNewContact: function (contact) {
6 | return $firebaseArray(ref.child(uid)).$add(contact);
7 | },
8 | getContactById: function (id) {
9 | return $firebaseObject(ref.child(uid).child(id));
10 | },
11 | getContactList: function () {
12 | return $firebaseArray(ref.child(uid));
13 | },
14 | updateContact: function (contact) {
15 | return contact.$save();
16 | },
17 | deleteContact: function (contact) {
18 | return contact.$remove();
19 | }
20 | };
21 | }
22 |
23 | angular
24 | .module('components.contact')
25 | .factory('ContactService', ContactService);
26 |
--------------------------------------------------------------------------------
/00-complete/app/components/contact/contact/contact.component.js:
--------------------------------------------------------------------------------
1 | var contact = {
2 | bindings: {
3 | contact: '<',
4 | onSelect: '&'
5 | },
6 | templateUrl: './contact.html',
7 | controller: 'ContactController'
8 | };
9 |
10 | angular
11 | .module('components.contact')
12 | .component('contact', contact);
13 |
--------------------------------------------------------------------------------
/00-complete/app/components/contact/contact/contact.controller.js:
--------------------------------------------------------------------------------
1 | function ContactController() {
2 | var ctrl = this;
3 | ctrl.selectContact = function () {
4 | ctrl.onSelect({
5 | $event: {
6 | contactId: ctrl.contact.$id
7 | }
8 | });
9 | };
10 | }
11 |
12 | angular
13 | .module('components.contact')
14 | .controller('ContactController', ContactController);
15 |
--------------------------------------------------------------------------------
/00-complete/app/components/contact/contact/contact.html:
--------------------------------------------------------------------------------
1 |
17 |
--------------------------------------------------------------------------------
/00-complete/app/components/contact/contact/contact.spec.js:
--------------------------------------------------------------------------------
1 | describe('Contact', function () {
2 | beforeEach(module('components.contact'));
3 |
4 | describe('Controller', function () {
5 | var $componentController,
6 | controller,
7 | mockContact = { $id: 1 },
8 | mockSelect = angular.noop;
9 |
10 | beforeEach(inject(function ($injector) {
11 | $componentController = $injector.get('$componentController');
12 | controller = $componentController('contact',
13 | { $scope: {} },
14 | { contact: mockContact, onSelect: mockSelect }
15 | );
16 | }));
17 |
18 | it('should bind to the correct contact', function () {
19 | expect(controller.contact.$id).toEqual(mockContact.$id);
20 | });
21 |
22 | it('should call onSelect with the correct payload', function () {
23 | var payload = { $event: { contactId: mockContact.$id } };
24 |
25 | spyOn(controller, 'onSelect');
26 | controller.selectContact();
27 | expect(controller.onSelect).toHaveBeenCalledWith(payload);
28 | });
29 | });
30 | });
--------------------------------------------------------------------------------
/00-complete/app/components/contact/contacts/contacts.component.js:
--------------------------------------------------------------------------------
1 | var contacts = {
2 | bindings: {
3 | contacts: '<',
4 | filter: '<'
5 | },
6 | templateUrl: './contacts.html',
7 | controller: 'ContactsController'
8 | };
9 |
10 | angular
11 | .module('components.contact')
12 | .component('contacts', contacts)
13 | .config(function ($stateProvider) {
14 | $stateProvider
15 | .state('contacts', {
16 | parent: 'app',
17 | url: '/contacts?filter',
18 | component: 'contacts',
19 | params: {
20 | filter: {
21 | value: 'none'
22 | }
23 | },
24 | resolve: {
25 | contacts: function (ContactService) {
26 | return ContactService.getContactList().$loaded();
27 | },
28 | filter: function ($transition$) {
29 | return $transition$.params();
30 | }
31 | }
32 | });
33 | });
34 |
--------------------------------------------------------------------------------
/00-complete/app/components/contact/contacts/contacts.controller.js:
--------------------------------------------------------------------------------
1 | function ContactsController($filter, $state) {
2 | var ctrl = this;
3 | var contacts = ctrl.contacts;
4 |
5 | ctrl.filteredContacts = $filter('contactsFilter')(contacts, ctrl.filter);
6 |
7 | ctrl.goToContact = function (event) {
8 | $state.go('contact', {
9 | id: event.contactId
10 | });
11 | };
12 | }
13 |
14 | angular
15 | .module('components.contact')
16 | .controller('ContactsController', ContactsController);
17 |
--------------------------------------------------------------------------------
/00-complete/app/components/contact/contacts/contacts.filter.js:
--------------------------------------------------------------------------------
1 | function contactsFilter() {
2 | return function (collection, params) {
3 | return collection.filter(function (item) {
4 | return item.tag === (
5 | params.filter === 'none' ? item.tag : params.filter
6 | );
7 | });
8 | };
9 | }
10 |
11 | angular
12 | .module('components.contact')
13 | .filter('contactsFilter', contactsFilter);
14 |
--------------------------------------------------------------------------------
/00-complete/app/components/contact/contacts/contacts.html:
--------------------------------------------------------------------------------
1 |
17 |
--------------------------------------------------------------------------------
/00-complete/app/components/contact/length-check/length-check.directive.js:
--------------------------------------------------------------------------------
1 | function lengthCheck() {
2 | return {
3 | restrict: 'A',
4 | require: 'ngModel',
5 | compile: function ($element) {
6 | $element.addClass('dynamic-input');
7 | return function ($scope, $element, $attrs, $ctrl) {
8 | var dynamicClass = 'dynamic-input--no-contents';
9 | $scope.$watch(function () {
10 | return $ctrl.$viewValue;
11 | }, function (newValue) {
12 | if (newValue) {
13 | $element.removeClass(dynamicClass);
14 | } else {
15 | $element.addClass(dynamicClass);
16 | }
17 | });
18 | };
19 | }
20 | };
21 | }
22 |
23 | angular
24 | .module('components.contact')
25 | .directive('lengthCheck', lengthCheck);
26 |
--------------------------------------------------------------------------------
/00-complete/app/root.component.js:
--------------------------------------------------------------------------------
1 | var root = {
2 | templateUrl: './root.html'
3 | };
4 |
5 | angular
6 | .module('root')
7 | .component('root', root);
8 |
--------------------------------------------------------------------------------
/00-complete/app/root.html:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/00-complete/app/root.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('root', [
3 | 'common',
4 | 'components',
5 | 'templates'
6 | ]);
7 |
--------------------------------------------------------------------------------
/01/app/common/app.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('common', [
3 | 'ui.router'
4 | ]);
5 |
--------------------------------------------------------------------------------
/01/app/components/auth/auth.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('components.auth', [
3 | 'ui.router',
4 | 'firebase'
5 | ])
6 | .config(function ($firebaseRefProvider) {
7 |
8 | var config = {
9 | apiKey: "AIzaSyCsNISt3dFx7dy5AImIIk62jDDd0OLvZK0",
10 | authDomain: "contacts-manager-e486f.firebaseapp.com",
11 | databaseURL: "https://contacts-manager-e486f.firebaseio.com",
12 | storageBucket: "contacts-manager-e486f.appspot.com",
13 | };
14 |
15 | $firebaseRefProvider
16 | .registerUrl({
17 | default: config.databaseURL,
18 | contacts: config.databaseURL + '/contacts'
19 | });
20 |
21 | firebase.initializeApp(config);
22 | });
23 |
--------------------------------------------------------------------------------
/01/app/components/components.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('components', [
3 | 'components.contact',
4 | 'components.auth'
5 | ]);
6 |
--------------------------------------------------------------------------------
/01/app/components/contact/contact.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('components.contact', [
3 | 'ui.router'
4 | ]);
5 |
--------------------------------------------------------------------------------
/01/app/root.component.js:
--------------------------------------------------------------------------------
1 | var root = {
2 | templateUrl: './root.html'
3 | };
4 |
5 | angular
6 | .module('root')
7 | .component('root', root);
8 |
--------------------------------------------------------------------------------
/01/app/root.html:
--------------------------------------------------------------------------------
1 |
2 | Hello world!
3 |
4 |
--------------------------------------------------------------------------------
/01/app/root.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('root', [
3 | 'common',
4 | 'components',
5 | 'templates'
6 | ]);
7 |
--------------------------------------------------------------------------------
/02/app/common/app.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('common', [
3 | 'ui.router'
4 | ]);
5 |
--------------------------------------------------------------------------------
/02/app/components/auth/auth-form/auth-form.component.js:
--------------------------------------------------------------------------------
1 | var authForm = {
2 | bindings: {
3 | user: '<',
4 | button: '@',
5 | message: '@',
6 | onSubmit: '&'
7 | },
8 | templateUrl: './auth-form.html',
9 | controller: 'AuthFormController'
10 | };
11 |
12 | angular
13 | .module('components.auth')
14 | .component('authForm', authForm);
15 |
--------------------------------------------------------------------------------
/02/app/components/auth/auth-form/auth-form.controller.js:
--------------------------------------------------------------------------------
1 | function AuthFormController() {
2 | var ctrl = this;
3 | ctrl.$onChanges = function (changes) {
4 | if (changes.user) {
5 | ctrl.user = angular.copy(ctrl.user);
6 | }
7 | };
8 | ctrl.submitForm = function () {
9 | ctrl.onSubmit({
10 | $event: {
11 | user: ctrl.user
12 | }
13 | });
14 | };
15 | }
16 |
17 | angular
18 | .module('components.auth')
19 | .controller('AuthFormController', AuthFormController);
20 |
--------------------------------------------------------------------------------
/02/app/components/auth/auth-form/auth-form.html:
--------------------------------------------------------------------------------
1 |
27 |
--------------------------------------------------------------------------------
/02/app/components/auth/auth.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('components.auth', [
3 | 'ui.router',
4 | 'firebase'
5 | ])
6 | .config(function ($firebaseRefProvider) {
7 |
8 | var config = {
9 | apiKey: "AIzaSyCsNISt3dFx7dy5AImIIk62jDDd0OLvZK0",
10 | authDomain: "contacts-manager-e486f.firebaseapp.com",
11 | databaseURL: "https://contacts-manager-e486f.firebaseio.com",
12 | storageBucket: "contacts-manager-e486f.appspot.com",
13 | };
14 |
15 | $firebaseRefProvider
16 | .registerUrl({
17 | default: config.databaseURL,
18 | contacts: config.databaseURL + '/contacts'
19 | });
20 |
21 | firebase.initializeApp(config);
22 | });
23 |
--------------------------------------------------------------------------------
/02/app/components/auth/auth.service.js:
--------------------------------------------------------------------------------
1 | function AuthService($firebaseAuth) {
2 | var auth = $firebaseAuth();
3 | var authData = null;
4 | function storeAuthData(response) {
5 | authData = response;
6 | return authData;
7 | }
8 | this.login = function (user) {
9 | return auth
10 | .$signInWithEmailAndPassword(user.email, user.password)
11 | .then(storeAuthData);
12 | };
13 | this.register = function (user) {
14 | return auth
15 | .$createUserWithEmailAndPassword(user.email, user.password)
16 | .then(storeAuthData);
17 | };
18 | }
19 |
20 | angular
21 | .module('components.auth')
22 | .service('AuthService', AuthService);
23 |
--------------------------------------------------------------------------------
/02/app/components/auth/login/login.component.js:
--------------------------------------------------------------------------------
1 | var login = {
2 | templateUrl: './login.html',
3 | controller: 'LoginController'
4 | };
5 |
6 | angular
7 | .module('components.auth')
8 | .component('login', login)
9 | .config(function ($stateProvider, $urlRouterProvider) {
10 | $stateProvider
11 | .state('auth', {
12 | redirectTo: 'auth.login',
13 | url: '/auth',
14 | template: ''
15 | })
16 | .state('auth.login', {
17 | url: '/login',
18 | component: 'login'
19 | });
20 | $urlRouterProvider.otherwise('/auth/login');
21 | });
22 |
--------------------------------------------------------------------------------
/02/app/components/auth/login/login.controller.js:
--------------------------------------------------------------------------------
1 | function LoginController(AuthService) {
2 | var ctrl = this;
3 | ctrl.$onInit = function () {
4 | ctrl.error = null;
5 | ctrl.user = {
6 | email: '',
7 | password: ''
8 | };
9 | };
10 | ctrl.loginUser = function (event) {
11 | return AuthService
12 | .login(event.user)
13 | .then(function () {
14 | console.log('Success!');
15 | }, function (reason) {
16 | ctrl.error = reason.message;
17 | });
18 | };
19 | }
20 |
21 | angular
22 | .module('components.auth')
23 | .controller('LoginController', LoginController);
24 |
--------------------------------------------------------------------------------
/02/app/components/auth/login/login.html:
--------------------------------------------------------------------------------
1 |
10 |
15 |
--------------------------------------------------------------------------------
/02/app/components/auth/register/register.component.js:
--------------------------------------------------------------------------------
1 | var register = {
2 | templateUrl: './register.html',
3 | controller: 'RegisterController'
4 | };
5 |
6 | angular
7 | .module('components.auth')
8 | .component('register', register)
9 | .config(function ($stateProvider) {
10 | $stateProvider
11 | .state('auth.register', {
12 | url: '/register',
13 | component: 'register'
14 | });
15 | });
16 |
--------------------------------------------------------------------------------
/02/app/components/auth/register/register.controller.js:
--------------------------------------------------------------------------------
1 | function RegisterController(AuthService) {
2 | var ctrl = this;
3 | ctrl.$onInit = function () {
4 | ctrl.error = null;
5 | ctrl.user = {
6 | email: '',
7 | password: ''
8 | };
9 | };
10 | ctrl.createUser = function (event) {
11 | return AuthService
12 | .register(event.user)
13 | .then(function () {
14 | console.log('Success!');
15 | }, function (reason) {
16 | ctrl.error = reason.message;
17 | });
18 | };
19 | }
20 |
21 | angular
22 | .module('components.auth')
23 | .controller('RegisterController', RegisterController);
24 |
--------------------------------------------------------------------------------
/02/app/components/auth/register/register.html:
--------------------------------------------------------------------------------
1 |
10 |
15 |
--------------------------------------------------------------------------------
/02/app/components/components.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('components', [
3 | 'components.contact',
4 | 'components.auth'
5 | ]);
6 |
--------------------------------------------------------------------------------
/02/app/components/contact/contact.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('components.contact', [
3 | 'ui.router'
4 | ]);
5 |
--------------------------------------------------------------------------------
/02/app/root.component.js:
--------------------------------------------------------------------------------
1 | var root = {
2 | templateUrl: './root.html'
3 | };
4 |
5 | angular
6 | .module('root')
7 | .component('root', root);
8 |
--------------------------------------------------------------------------------
/02/app/root.html:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/02/app/root.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('root', [
3 | 'common',
4 | 'components',
5 | 'templates'
6 | ]);
7 |
--------------------------------------------------------------------------------
/03/app/common/app-nav.component.js:
--------------------------------------------------------------------------------
1 | var appNav = {
2 | bindings: {
3 | user: '<',
4 | onLogout: '&'
5 | },
6 | templateUrl: './app-nav.html'
7 | };
8 |
9 | angular
10 | .module('common')
11 | .component('appNav', appNav);
12 |
--------------------------------------------------------------------------------
/03/app/common/app-nav.html:
--------------------------------------------------------------------------------
1 |
23 |
--------------------------------------------------------------------------------
/03/app/common/app-sidebar.component.js:
--------------------------------------------------------------------------------
1 | var appSidebar = {
2 | templateUrl: './app-sidebar.html',
3 | controller: 'AppSidebarController'
4 | };
5 |
6 | angular
7 | .module('common')
8 | .component('appSidebar', appSidebar);
9 |
--------------------------------------------------------------------------------
/03/app/common/app-sidebar.controller.js:
--------------------------------------------------------------------------------
1 | function AppSidebarController() {
2 | var ctrl = this;
3 | ctrl.contactTags = [{
4 | label: 'All contacts',
5 | icon: 'star'
6 | }, {
7 | label: 'Friends',
8 | icon: 'people'
9 | }, {
10 | label: 'Family',
11 | icon: 'child_care'
12 | }, {
13 | label: 'Acquaintances',
14 | icon: 'accessibility'
15 | }, {
16 | label: 'Following',
17 | icon: 'remove_red_eye'
18 | }];
19 | }
20 |
21 | angular
22 | .module('common')
23 | .controller('AppSidebarController', AppSidebarController);
24 |
--------------------------------------------------------------------------------
/03/app/common/app-sidebar.html:
--------------------------------------------------------------------------------
1 |
25 |
--------------------------------------------------------------------------------
/03/app/common/app.component.js:
--------------------------------------------------------------------------------
1 | var app = {
2 | templateUrl: './app.html',
3 | controller: 'AppController'
4 | };
5 |
6 | angular
7 | .module('common')
8 | .component('app', app)
9 | .config(function ($stateProvider) {
10 | $stateProvider
11 | .state('app', {
12 | // redirectTo: 'contacts'
13 | url: '/app',
14 | data: {
15 | requiredAuth: true
16 | },
17 | component: 'app'
18 | })
19 | });
20 |
--------------------------------------------------------------------------------
/03/app/common/app.controller.js:
--------------------------------------------------------------------------------
1 | function AppController(AuthService, $state) {
2 | var ctrl = this;
3 | ctrl.user = AuthService.getUser();
4 | ctrl.logout = function () {
5 | AuthService.logout().then(function () {
6 | $state.go('auth.login');
7 | });
8 | };
9 | }
10 |
11 | angular
12 | .module('common')
13 | .controller('AppController', AppController);
14 |
--------------------------------------------------------------------------------
/03/app/common/app.html:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/03/app/common/app.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('common', [
3 | 'ui.router',
4 | 'angular-loading-bar'
5 | ])
6 | .run(function ($transitions, cfpLoadingBar) {
7 | $transitions.onStart({}, cfpLoadingBar.start);
8 | $transitions.onSuccess({}, cfpLoadingBar.complete);
9 | });
10 |
--------------------------------------------------------------------------------
/03/app/components/auth/auth-form/auth-form.component.js:
--------------------------------------------------------------------------------
1 | var authForm = {
2 | bindings: {
3 | user: '<',
4 | button: '@',
5 | message: '@',
6 | onSubmit: '&'
7 | },
8 | templateUrl: './auth-form.html',
9 | controller: 'AuthFormController'
10 | };
11 |
12 | angular
13 | .module('components.auth')
14 | .component('authForm', authForm);
15 |
--------------------------------------------------------------------------------
/03/app/components/auth/auth-form/auth-form.controller.js:
--------------------------------------------------------------------------------
1 | function AuthFormController() {
2 | var ctrl = this;
3 | ctrl.$onChanges = function (changes) {
4 | if (changes.user) {
5 | ctrl.user = angular.copy(ctrl.user);
6 | }
7 | };
8 | ctrl.submitForm = function () {
9 | ctrl.onSubmit({
10 | $event: {
11 | user: ctrl.user
12 | }
13 | });
14 | };
15 | }
16 |
17 | angular
18 | .module('components.auth')
19 | .controller('AuthFormController', AuthFormController);
20 |
--------------------------------------------------------------------------------
/03/app/components/auth/auth-form/auth-form.html:
--------------------------------------------------------------------------------
1 |
27 |
--------------------------------------------------------------------------------
/03/app/components/auth/auth.service.js:
--------------------------------------------------------------------------------
1 | function AuthService($firebaseAuth) {
2 | var auth = $firebaseAuth();
3 | var authData = null;
4 | function storeAuthData(response) {
5 | authData = response;
6 | return authData;
7 | }
8 | function onSignIn(user) {
9 | authData = user;
10 | return auth.$requireSignIn();
11 | }
12 | function clearAuthData() {
13 | authData = null;
14 | }
15 | this.login = function (user) {
16 | return auth
17 | .$signInWithEmailAndPassword(user.email, user.password)
18 | .then(storeAuthData);
19 | };
20 | this.register = function (user) {
21 | return auth
22 | .$createUserWithEmailAndPassword(user.email, user.password)
23 | .then(storeAuthData);
24 | };
25 | this.logout = function () {
26 | return auth
27 | .$signOut()
28 | .then(clearAuthData);
29 | };
30 | this.requireAuthentication = function () {
31 | return auth
32 | .$waitForSignIn().then(onSignIn);
33 | };
34 | this.isAuthenticated = function () {
35 | return !!authData;
36 | };
37 | this.getUser = function () {
38 | if (authData) {
39 | return authData;
40 | }
41 | };
42 | }
43 |
44 | angular
45 | .module('components.auth')
46 | .service('AuthService', AuthService);
47 |
--------------------------------------------------------------------------------
/03/app/components/auth/login/login.component.js:
--------------------------------------------------------------------------------
1 | var login = {
2 | templateUrl: './login.html',
3 | controller: 'LoginController'
4 | };
5 |
6 | angular
7 | .module('components.auth')
8 | .component('login', login)
9 | .config(function ($stateProvider, $urlRouterProvider) {
10 | $stateProvider
11 | .state('auth', {
12 | redirectTo: 'auth.login',
13 | url: '/auth',
14 | template: ''
15 | })
16 | .state('auth.login', {
17 | url: '/login',
18 | component: 'login'
19 | });
20 | $urlRouterProvider.otherwise('/auth/login');
21 | });
22 |
--------------------------------------------------------------------------------
/03/app/components/auth/login/login.controller.js:
--------------------------------------------------------------------------------
1 | function LoginController(AuthService, $state) {
2 | var ctrl = this;
3 | ctrl.$onInit = function () {
4 | ctrl.error = null;
5 | ctrl.user = {
6 | email: '',
7 | password: ''
8 | };
9 | };
10 | ctrl.loginUser = function (event) {
11 | return AuthService
12 | .login(event.user)
13 | .then(function () {
14 | $state.go('app');
15 | }, function (reason) {
16 | ctrl.error = reason.message;
17 | });
18 | };
19 | }
20 |
21 | angular
22 | .module('components.auth')
23 | .controller('LoginController', LoginController);
24 |
--------------------------------------------------------------------------------
/03/app/components/auth/login/login.html:
--------------------------------------------------------------------------------
1 |
10 |
15 |
--------------------------------------------------------------------------------
/03/app/components/auth/register/register.component.js:
--------------------------------------------------------------------------------
1 | var register = {
2 | templateUrl: './register.html',
3 | controller: 'RegisterController'
4 | };
5 |
6 | angular
7 | .module('components.auth')
8 | .component('register', register)
9 | .config(function ($stateProvider) {
10 | $stateProvider
11 | .state('auth.register', {
12 | url: '/register',
13 | component: 'register'
14 | });
15 | });
16 |
--------------------------------------------------------------------------------
/03/app/components/auth/register/register.controller.js:
--------------------------------------------------------------------------------
1 | function RegisterController(AuthService, $state) {
2 | var ctrl = this;
3 | ctrl.$onInit = function () {
4 | ctrl.error = null;
5 | ctrl.user = {
6 | email: '',
7 | password: ''
8 | };
9 | };
10 | ctrl.createUser = function (event) {
11 | return AuthService
12 | .register(event.user)
13 | .then(function () {
14 | $state.go('app');
15 | }, function (reason) {
16 | ctrl.error = reason.message;
17 | });
18 | };
19 | }
20 |
21 | angular
22 | .module('components.auth')
23 | .controller('RegisterController', RegisterController);
24 |
--------------------------------------------------------------------------------
/03/app/components/auth/register/register.html:
--------------------------------------------------------------------------------
1 |
10 |
15 |
--------------------------------------------------------------------------------
/03/app/components/components.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('components', [
3 | 'components.contact',
4 | 'components.auth'
5 | ]);
6 |
--------------------------------------------------------------------------------
/03/app/components/contact/contact.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('components.contact', [
3 | 'ui.router'
4 | ]);
5 |
--------------------------------------------------------------------------------
/03/app/root.component.js:
--------------------------------------------------------------------------------
1 | var root = {
2 | templateUrl: './root.html'
3 | };
4 |
5 | angular
6 | .module('root')
7 | .component('root', root);
8 |
--------------------------------------------------------------------------------
/03/app/root.html:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/03/app/root.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('root', [
3 | 'common',
4 | 'components',
5 | 'templates'
6 | ]);
7 |
--------------------------------------------------------------------------------
/04/app/common/app-nav.component.js:
--------------------------------------------------------------------------------
1 | var appNav = {
2 | bindings: {
3 | user: '<',
4 | onLogout: '&'
5 | },
6 | templateUrl: './app-nav.html'
7 | };
8 |
9 | angular
10 | .module('common')
11 | .component('appNav', appNav);
12 |
--------------------------------------------------------------------------------
/04/app/common/app-nav.html:
--------------------------------------------------------------------------------
1 |
23 |
--------------------------------------------------------------------------------
/04/app/common/app-sidebar.component.js:
--------------------------------------------------------------------------------
1 | var appSidebar = {
2 | templateUrl: './app-sidebar.html',
3 | controller: 'AppSidebarController'
4 | };
5 |
6 | angular
7 | .module('common')
8 | .component('appSidebar', appSidebar);
9 |
--------------------------------------------------------------------------------
/04/app/common/app-sidebar.controller.js:
--------------------------------------------------------------------------------
1 | function AppSidebarController() {
2 | var ctrl = this;
3 | ctrl.contactTags = [{
4 | label: 'All contacts',
5 | icon: 'star'
6 | }, {
7 | label: 'Friends',
8 | icon: 'people'
9 | }, {
10 | label: 'Family',
11 | icon: 'child_care'
12 | }, {
13 | label: 'Acquaintances',
14 | icon: 'accessibility'
15 | }, {
16 | label: 'Following',
17 | icon: 'remove_red_eye'
18 | }];
19 | }
20 |
21 | angular
22 | .module('common')
23 | .controller('AppSidebarController', AppSidebarController);
24 |
--------------------------------------------------------------------------------
/04/app/common/app-sidebar.html:
--------------------------------------------------------------------------------
1 |
25 |
--------------------------------------------------------------------------------
/04/app/common/app.component.js:
--------------------------------------------------------------------------------
1 | var app = {
2 | templateUrl: './app.html',
3 | controller: 'AppController'
4 | };
5 |
6 | angular
7 | .module('common')
8 | .component('app', app)
9 | .config(function ($stateProvider) {
10 | $stateProvider
11 | .state('app', {
12 | // redirectTo: 'contacts'
13 | url: '/app',
14 | data: {
15 | requiredAuth: true
16 | },
17 | component: 'app'
18 | })
19 | });
20 |
--------------------------------------------------------------------------------
/04/app/common/app.controller.js:
--------------------------------------------------------------------------------
1 | function AppController(AuthService, $state) {
2 | var ctrl = this;
3 | ctrl.user = AuthService.getUser();
4 | ctrl.logout = function () {
5 | AuthService.logout().then(function () {
6 | $state.go('auth.login');
7 | });
8 | };
9 | }
10 |
11 | angular
12 | .module('common')
13 | .controller('AppController', AppController);
14 |
--------------------------------------------------------------------------------
/04/app/common/app.html:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/04/app/common/app.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('common', [
3 | 'ui.router',
4 | 'angular-loading-bar'
5 | ])
6 | .run(function ($transitions, cfpLoadingBar) {
7 | $transitions.onStart({}, cfpLoadingBar.start);
8 | $transitions.onSuccess({}, cfpLoadingBar.complete);
9 | });
10 |
--------------------------------------------------------------------------------
/04/app/components/auth/auth-form/auth-form.component.js:
--------------------------------------------------------------------------------
1 | var authForm = {
2 | bindings: {
3 | user: '<',
4 | button: '@',
5 | message: '@',
6 | onSubmit: '&'
7 | },
8 | templateUrl: './auth-form.html',
9 | controller: 'AuthFormController'
10 | };
11 |
12 | angular
13 | .module('components.auth')
14 | .component('authForm', authForm);
15 |
--------------------------------------------------------------------------------
/04/app/components/auth/auth-form/auth-form.controller.js:
--------------------------------------------------------------------------------
1 | function AuthFormController() {
2 | var ctrl = this;
3 | ctrl.$onChanges = function (changes) {
4 | if (changes.user) {
5 | ctrl.user = angular.copy(ctrl.user);
6 | }
7 | };
8 | ctrl.submitForm = function () {
9 | ctrl.onSubmit({
10 | $event: {
11 | user: ctrl.user
12 | }
13 | });
14 | };
15 | }
16 |
17 | angular
18 | .module('components.auth')
19 | .controller('AuthFormController', AuthFormController);
20 |
--------------------------------------------------------------------------------
/04/app/components/auth/auth-form/auth-form.html:
--------------------------------------------------------------------------------
1 |
27 |
--------------------------------------------------------------------------------
/04/app/components/auth/auth.service.js:
--------------------------------------------------------------------------------
1 | function AuthService($firebaseAuth) {
2 | var auth = $firebaseAuth();
3 | var authData = null;
4 | function storeAuthData(response) {
5 | authData = response;
6 | return authData;
7 | }
8 | function onSignIn(user) {
9 | authData = user;
10 | return auth.$requireSignIn();
11 | }
12 | function clearAuthData() {
13 | authData = null;
14 | }
15 | this.login = function (user) {
16 | return auth
17 | .$signInWithEmailAndPassword(user.email, user.password)
18 | .then(storeAuthData);
19 | };
20 | this.register = function (user) {
21 | return auth
22 | .$createUserWithEmailAndPassword(user.email, user.password)
23 | .then(storeAuthData);
24 | };
25 | this.logout = function () {
26 | return auth
27 | .$signOut()
28 | .then(clearAuthData);
29 | };
30 | this.requireAuthentication = function () {
31 | return auth
32 | .$waitForSignIn().then(onSignIn);
33 | };
34 | this.isAuthenticated = function () {
35 | return !!authData;
36 | };
37 | this.getUser = function () {
38 | if (authData) {
39 | return authData;
40 | }
41 | };
42 | }
43 |
44 | angular
45 | .module('components.auth')
46 | .service('AuthService', AuthService);
47 |
--------------------------------------------------------------------------------
/04/app/components/auth/login/login.component.js:
--------------------------------------------------------------------------------
1 | var login = {
2 | templateUrl: './login.html',
3 | controller: 'LoginController'
4 | };
5 |
6 | angular
7 | .module('components.auth')
8 | .component('login', login)
9 | .config(function ($stateProvider, $urlRouterProvider) {
10 | $stateProvider
11 | .state('auth', {
12 | redirectTo: 'auth.login',
13 | url: '/auth',
14 | template: ''
15 | })
16 | .state('auth.login', {
17 | url: '/login',
18 | component: 'login'
19 | });
20 | $urlRouterProvider.otherwise('/auth/login');
21 | });
22 |
--------------------------------------------------------------------------------
/04/app/components/auth/login/login.controller.js:
--------------------------------------------------------------------------------
1 | function LoginController(AuthService, $state) {
2 | var ctrl = this;
3 | ctrl.$onInit = function () {
4 | ctrl.error = null;
5 | ctrl.user = {
6 | email: '',
7 | password: ''
8 | };
9 | };
10 | ctrl.loginUser = function (event) {
11 | return AuthService
12 | .login(event.user)
13 | .then(function () {
14 | $state.go('app');
15 | }, function (reason) {
16 | ctrl.error = reason.message;
17 | });
18 | };
19 | }
20 |
21 | angular
22 | .module('components.auth')
23 | .controller('LoginController', LoginController);
24 |
--------------------------------------------------------------------------------
/04/app/components/auth/login/login.html:
--------------------------------------------------------------------------------
1 |
10 |
15 |
--------------------------------------------------------------------------------
/04/app/components/auth/register/register.component.js:
--------------------------------------------------------------------------------
1 | var register = {
2 | templateUrl: './register.html',
3 | controller: 'RegisterController'
4 | };
5 |
6 | angular
7 | .module('components.auth')
8 | .component('register', register)
9 | .config(function ($stateProvider) {
10 | $stateProvider
11 | .state('auth.register', {
12 | url: '/register',
13 | component: 'register'
14 | });
15 | });
16 |
--------------------------------------------------------------------------------
/04/app/components/auth/register/register.controller.js:
--------------------------------------------------------------------------------
1 | function RegisterController(AuthService, $state) {
2 | var ctrl = this;
3 | ctrl.$onInit = function () {
4 | ctrl.error = null;
5 | ctrl.user = {
6 | email: '',
7 | password: ''
8 | };
9 | };
10 | ctrl.createUser = function (event) {
11 | return AuthService
12 | .register(event.user)
13 | .then(function () {
14 | $state.go('app');
15 | }, function (reason) {
16 | ctrl.error = reason.message;
17 | });
18 | };
19 | }
20 |
21 | angular
22 | .module('components.auth')
23 | .controller('RegisterController', RegisterController);
24 |
--------------------------------------------------------------------------------
/04/app/components/auth/register/register.html:
--------------------------------------------------------------------------------
1 |
10 |
15 |
--------------------------------------------------------------------------------
/04/app/components/components.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('components', [
3 | 'components.contact',
4 | 'components.auth'
5 | ]);
6 |
--------------------------------------------------------------------------------
/04/app/components/contact/contact-detail/contact-detail.component.js:
--------------------------------------------------------------------------------
1 | var contactDetail = {
2 | bindings: {
3 | contact: '<',
4 | onSave: '&'
5 | },
6 | templateUrl: './contact-detail.html',
7 | controller: 'ContactDetailController'
8 | };
9 |
10 | angular
11 | .module('components.contact')
12 | .component('contactDetail', contactDetail);
13 |
--------------------------------------------------------------------------------
/04/app/components/contact/contact-detail/contact-detail.controller.js:
--------------------------------------------------------------------------------
1 | function ContactDetailController() {
2 | var ctrl = this;
3 | ctrl.$onInit = function () {
4 | ctrl.isNewContact = !ctrl.contact.$id;
5 | };
6 | ctrl.saveContact = function () {
7 | ctrl.onSave({
8 | $event: {
9 | contact: ctrl.contact
10 | }
11 | });
12 | };
13 | }
14 |
15 | angular
16 | .module('components.contact')
17 | .controller('ContactDetailController', ContactDetailController);
18 |
--------------------------------------------------------------------------------
/04/app/components/contact/contact-new/contact-new.component.js:
--------------------------------------------------------------------------------
1 | var contactNew = {
2 | templateUrl: './contact-new.html',
3 | controller: 'ContactNewController'
4 | };
5 |
6 | angular
7 | .module('components.contact')
8 | .component('contactNew', contactNew)
9 | .config(function ($stateProvider) {
10 | $stateProvider
11 | .state('new', {
12 | parent: 'app',
13 | url: '/new',
14 | component: 'contactNew'
15 | });
16 | });
17 |
--------------------------------------------------------------------------------
/04/app/components/contact/contact-new/contact-new.controller.js:
--------------------------------------------------------------------------------
1 | function ContactNewController(ContactService) {
2 | var ctrl = this;
3 | ctrl.$onInit = function () {
4 | ctrl.contact = {
5 | name: '',
6 | email: '',
7 | job: '',
8 | location: '',
9 | social: {
10 | facebook: '',
11 | github: '',
12 | twitter: '',
13 | linkedin: ''
14 | },
15 | tag: 'none'
16 | };
17 | };
18 | ctrl.createNewContact = function (event) {
19 | return ContactService
20 | .createNewContact(event.contact)
21 | .then(function (contact) {
22 | // success
23 | console.log(contact);
24 | });
25 | };
26 | }
27 |
28 | angular
29 | .module('components.contact')
30 | .controller('ContactNewController', ContactNewController);
31 |
--------------------------------------------------------------------------------
/04/app/components/contact/contact-new/contact-new.html:
--------------------------------------------------------------------------------
1 |
4 |
5 |
--------------------------------------------------------------------------------
/04/app/components/contact/contact.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('components.contact', [
3 | 'ui.router'
4 | ]);
5 |
--------------------------------------------------------------------------------
/04/app/components/contact/contact.service.js:
--------------------------------------------------------------------------------
1 | function ContactService(AuthService, $firebaseRef, $firebaseArray) {
2 | var ref = $firebaseRef.contacts;
3 | var uid = AuthService.getUser().uid;
4 | return {
5 | createNewContact: function (contact) {
6 | return $firebaseArray(ref.child(uid)).$add(contact);
7 | }
8 | };
9 | }
10 |
11 | angular
12 | .module('components.contact')
13 | .factory('ContactService', ContactService);
14 |
--------------------------------------------------------------------------------
/04/app/root.component.js:
--------------------------------------------------------------------------------
1 | var root = {
2 | templateUrl: './root.html'
3 | };
4 |
5 | angular
6 | .module('root')
7 | .component('root', root);
8 |
--------------------------------------------------------------------------------
/04/app/root.html:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/04/app/root.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('root', [
3 | 'common',
4 | 'components',
5 | 'templates'
6 | ]);
7 |
--------------------------------------------------------------------------------
/05/app/common/app-nav.component.js:
--------------------------------------------------------------------------------
1 | var appNav = {
2 | bindings: {
3 | user: '<',
4 | onLogout: '&'
5 | },
6 | templateUrl: './app-nav.html'
7 | };
8 |
9 | angular
10 | .module('common')
11 | .component('appNav', appNav);
12 |
--------------------------------------------------------------------------------
/05/app/common/app-nav.html:
--------------------------------------------------------------------------------
1 |
23 |
--------------------------------------------------------------------------------
/05/app/common/app-sidebar.component.js:
--------------------------------------------------------------------------------
1 | var appSidebar = {
2 | templateUrl: './app-sidebar.html',
3 | controller: 'AppSidebarController'
4 | };
5 |
6 | angular
7 | .module('common')
8 | .component('appSidebar', appSidebar);
9 |
--------------------------------------------------------------------------------
/05/app/common/app-sidebar.controller.js:
--------------------------------------------------------------------------------
1 | function AppSidebarController() {
2 | var ctrl = this;
3 | ctrl.contactTags = [{
4 | label: 'All contacts',
5 | icon: 'star'
6 | }, {
7 | label: 'Friends',
8 | icon: 'people'
9 | }, {
10 | label: 'Family',
11 | icon: 'child_care'
12 | }, {
13 | label: 'Acquaintances',
14 | icon: 'accessibility'
15 | }, {
16 | label: 'Following',
17 | icon: 'remove_red_eye'
18 | }];
19 | }
20 |
21 | angular
22 | .module('common')
23 | .controller('AppSidebarController', AppSidebarController);
24 |
--------------------------------------------------------------------------------
/05/app/common/app-sidebar.html:
--------------------------------------------------------------------------------
1 |
25 |
--------------------------------------------------------------------------------
/05/app/common/app.component.js:
--------------------------------------------------------------------------------
1 | var app = {
2 | templateUrl: './app.html',
3 | controller: 'AppController'
4 | };
5 |
6 | angular
7 | .module('common')
8 | .component('app', app)
9 | .config(function ($stateProvider) {
10 | $stateProvider
11 | .state('app', {
12 | // redirectTo: 'contacts'
13 | url: '/app',
14 | data: {
15 | requiredAuth: true
16 | },
17 | component: 'app'
18 | })
19 | });
20 |
--------------------------------------------------------------------------------
/05/app/common/app.controller.js:
--------------------------------------------------------------------------------
1 | function AppController(AuthService, $state) {
2 | var ctrl = this;
3 | ctrl.user = AuthService.getUser();
4 | ctrl.logout = function () {
5 | AuthService.logout().then(function () {
6 | $state.go('auth.login');
7 | });
8 | };
9 | }
10 |
11 | angular
12 | .module('common')
13 | .controller('AppController', AppController);
14 |
--------------------------------------------------------------------------------
/05/app/common/app.html:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/05/app/common/app.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('common', [
3 | 'ui.router',
4 | 'angular-loading-bar'
5 | ])
6 | .run(function ($transitions, cfpLoadingBar) {
7 | $transitions.onStart({}, cfpLoadingBar.start);
8 | $transitions.onSuccess({}, cfpLoadingBar.complete);
9 | });
10 |
--------------------------------------------------------------------------------
/05/app/components/auth/auth-form/auth-form.component.js:
--------------------------------------------------------------------------------
1 | var authForm = {
2 | bindings: {
3 | user: '<',
4 | button: '@',
5 | message: '@',
6 | onSubmit: '&'
7 | },
8 | templateUrl: './auth-form.html',
9 | controller: 'AuthFormController'
10 | };
11 |
12 | angular
13 | .module('components.auth')
14 | .component('authForm', authForm);
15 |
--------------------------------------------------------------------------------
/05/app/components/auth/auth-form/auth-form.controller.js:
--------------------------------------------------------------------------------
1 | function AuthFormController() {
2 | var ctrl = this;
3 | ctrl.$onChanges = function (changes) {
4 | if (changes.user) {
5 | ctrl.user = angular.copy(ctrl.user);
6 | }
7 | };
8 | ctrl.submitForm = function () {
9 | ctrl.onSubmit({
10 | $event: {
11 | user: ctrl.user
12 | }
13 | });
14 | };
15 | }
16 |
17 | angular
18 | .module('components.auth')
19 | .controller('AuthFormController', AuthFormController);
20 |
--------------------------------------------------------------------------------
/05/app/components/auth/auth-form/auth-form.html:
--------------------------------------------------------------------------------
1 |
27 |
--------------------------------------------------------------------------------
/05/app/components/auth/auth.service.js:
--------------------------------------------------------------------------------
1 | function AuthService($firebaseAuth) {
2 | var auth = $firebaseAuth();
3 | var authData = null;
4 | function storeAuthData(response) {
5 | authData = response;
6 | return authData;
7 | }
8 | function onSignIn(user) {
9 | authData = user;
10 | return auth.$requireSignIn();
11 | }
12 | function clearAuthData() {
13 | authData = null;
14 | }
15 | this.login = function (user) {
16 | return auth
17 | .$signInWithEmailAndPassword(user.email, user.password)
18 | .then(storeAuthData);
19 | };
20 | this.register = function (user) {
21 | return auth
22 | .$createUserWithEmailAndPassword(user.email, user.password)
23 | .then(storeAuthData);
24 | };
25 | this.logout = function () {
26 | return auth
27 | .$signOut()
28 | .then(clearAuthData);
29 | };
30 | this.requireAuthentication = function () {
31 | return auth
32 | .$waitForSignIn().then(onSignIn);
33 | };
34 | this.isAuthenticated = function () {
35 | return !!authData;
36 | };
37 | this.getUser = function () {
38 | if (authData) {
39 | return authData;
40 | }
41 | };
42 | }
43 |
44 | angular
45 | .module('components.auth')
46 | .service('AuthService', AuthService);
47 |
--------------------------------------------------------------------------------
/05/app/components/auth/login/login.component.js:
--------------------------------------------------------------------------------
1 | var login = {
2 | templateUrl: './login.html',
3 | controller: 'LoginController'
4 | };
5 |
6 | angular
7 | .module('components.auth')
8 | .component('login', login)
9 | .config(function ($stateProvider, $urlRouterProvider) {
10 | $stateProvider
11 | .state('auth', {
12 | redirectTo: 'auth.login',
13 | url: '/auth',
14 | template: ''
15 | })
16 | .state('auth.login', {
17 | url: '/login',
18 | component: 'login'
19 | });
20 | $urlRouterProvider.otherwise('/auth/login');
21 | });
22 |
--------------------------------------------------------------------------------
/05/app/components/auth/login/login.controller.js:
--------------------------------------------------------------------------------
1 | function LoginController(AuthService, $state) {
2 | var ctrl = this;
3 | ctrl.$onInit = function () {
4 | ctrl.error = null;
5 | ctrl.user = {
6 | email: '',
7 | password: ''
8 | };
9 | };
10 | ctrl.loginUser = function (event) {
11 | return AuthService
12 | .login(event.user)
13 | .then(function () {
14 | $state.go('app');
15 | }, function (reason) {
16 | ctrl.error = reason.message;
17 | });
18 | };
19 | }
20 |
21 | angular
22 | .module('components.auth')
23 | .controller('LoginController', LoginController);
24 |
--------------------------------------------------------------------------------
/05/app/components/auth/login/login.html:
--------------------------------------------------------------------------------
1 |
10 |
15 |
--------------------------------------------------------------------------------
/05/app/components/auth/register/register.component.js:
--------------------------------------------------------------------------------
1 | var register = {
2 | templateUrl: './register.html',
3 | controller: 'RegisterController'
4 | };
5 |
6 | angular
7 | .module('components.auth')
8 | .component('register', register)
9 | .config(function ($stateProvider) {
10 | $stateProvider
11 | .state('auth.register', {
12 | url: '/register',
13 | component: 'register'
14 | });
15 | });
16 |
--------------------------------------------------------------------------------
/05/app/components/auth/register/register.controller.js:
--------------------------------------------------------------------------------
1 | function RegisterController(AuthService, $state) {
2 | var ctrl = this;
3 | ctrl.$onInit = function () {
4 | ctrl.error = null;
5 | ctrl.user = {
6 | email: '',
7 | password: ''
8 | };
9 | };
10 | ctrl.createUser = function (event) {
11 | return AuthService
12 | .register(event.user)
13 | .then(function () {
14 | $state.go('app');
15 | }, function (reason) {
16 | ctrl.error = reason.message;
17 | });
18 | };
19 | }
20 |
21 | angular
22 | .module('components.auth')
23 | .controller('RegisterController', RegisterController);
24 |
--------------------------------------------------------------------------------
/05/app/components/auth/register/register.html:
--------------------------------------------------------------------------------
1 |
10 |
15 |
--------------------------------------------------------------------------------
/05/app/components/components.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('components', [
3 | 'components.contact',
4 | 'components.auth'
5 | ]);
6 |
--------------------------------------------------------------------------------
/05/app/components/contact/contact-detail/contact-detail.component.js:
--------------------------------------------------------------------------------
1 | var contactDetail = {
2 | bindings: {
3 | contact: '<',
4 | onSave: '&',
5 | onUpdate: '&',
6 | onDelete: '&'
7 | },
8 | templateUrl: './contact-detail.html',
9 | controller: 'ContactDetailController'
10 | };
11 |
12 | angular
13 | .module('components.contact')
14 | .component('contactDetail', contactDetail);
15 |
--------------------------------------------------------------------------------
/05/app/components/contact/contact-detail/contact-detail.controller.js:
--------------------------------------------------------------------------------
1 | function ContactDetailController() {
2 | var ctrl = this;
3 | ctrl.$onInit = function () {
4 | ctrl.isNewContact = !ctrl.contact.$id;
5 | };
6 | ctrl.saveContact = function () {
7 | ctrl.onSave({
8 | $event: {
9 | contact: ctrl.contact
10 | }
11 | });
12 | };
13 | ctrl.updateContact = function () {
14 | ctrl.onUpdate({
15 | $event: {
16 | contact: ctrl.contact
17 | }
18 | });
19 | };
20 | ctrl.deleteContact = function () {
21 | ctrl.onDelete({
22 | $event: {
23 | contact: ctrl.contact
24 | }
25 | });
26 | };
27 | }
28 |
29 | angular
30 | .module('components.contact')
31 | .controller('ContactDetailController', ContactDetailController);
32 |
--------------------------------------------------------------------------------
/05/app/components/contact/contact-edit/contact-edit.component.js:
--------------------------------------------------------------------------------
1 | var contactEdit = {
2 | bindings: {
3 | contact: '<'
4 | },
5 | templateUrl: './contact-edit.html',
6 | controller: 'ContactEditController'
7 | };
8 |
9 | angular
10 | .module('components.contact')
11 | .component('contactEdit', contactEdit)
12 | .config(function ($stateProvider) {
13 | $stateProvider
14 | .state('contact', {
15 | parent: 'app',
16 | url: '/contact/:id',
17 | component: 'contactEdit',
18 | resolve: {
19 | contact: function ($transition$, ContactService) {
20 | var key = $transition$.params().id;
21 | return ContactService.getContactById(key).$loaded();
22 | }
23 | }
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/05/app/components/contact/contact-edit/contact-edit.controller.js:
--------------------------------------------------------------------------------
1 | function ContactEditController($state, ContactService, cfpLoadingBar, $window) {
2 | var ctrl = this;
3 | ctrl.updateContact = function (event) {
4 | cfpLoadingBar.start();
5 | return ContactService
6 | .updateContact(event.contact)
7 | .then(cfpLoadingBar.complete, cfpLoadingBar.complete);
8 | };
9 | ctrl.deleteContact = function (event) {
10 | var message = 'Delete ' + event.contact.name + ' from contacts?';
11 | if ($window.confirm(message)) {
12 | return ContactService
13 | .deleteContact(event.contact)
14 | .then(function () {
15 | $state.go('contacts');
16 | });
17 | }
18 | };
19 | }
20 |
21 | angular
22 | .module('components.contact')
23 | .controller('ContactEditController', ContactEditController);
24 |
--------------------------------------------------------------------------------
/05/app/components/contact/contact-edit/contact-edit.html:
--------------------------------------------------------------------------------
1 |
5 |
6 |
--------------------------------------------------------------------------------
/05/app/components/contact/contact-new/contact-new.component.js:
--------------------------------------------------------------------------------
1 | var contactNew = {
2 | templateUrl: './contact-new.html',
3 | controller: 'ContactNewController'
4 | };
5 |
6 | angular
7 | .module('components.contact')
8 | .component('contactNew', contactNew)
9 | .config(function ($stateProvider) {
10 | $stateProvider
11 | .state('new', {
12 | parent: 'app',
13 | url: '/new',
14 | component: 'contactNew'
15 | });
16 | });
17 |
--------------------------------------------------------------------------------
/05/app/components/contact/contact-new/contact-new.controller.js:
--------------------------------------------------------------------------------
1 | function ContactNewController(ContactService, $state) {
2 | var ctrl = this;
3 | ctrl.$onInit = function () {
4 | ctrl.contact = {
5 | name: '',
6 | email: '',
7 | job: '',
8 | location: '',
9 | social: {
10 | facebook: '',
11 | github: '',
12 | twitter: '',
13 | linkedin: ''
14 | },
15 | tag: 'none'
16 | };
17 | };
18 | ctrl.createNewContact = function (event) {
19 | return ContactService
20 | .createNewContact(event.contact)
21 | .then(function (contact) {
22 | $state.go('contact', {
23 | id: contact.key
24 | });
25 | });
26 | };
27 | }
28 |
29 | angular
30 | .module('components.contact')
31 | .controller('ContactNewController', ContactNewController);
32 |
--------------------------------------------------------------------------------
/05/app/components/contact/contact-new/contact-new.html:
--------------------------------------------------------------------------------
1 |
4 |
5 |
--------------------------------------------------------------------------------
/05/app/components/contact/contact.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('components.contact', [
3 | 'ui.router'
4 | ]);
5 |
--------------------------------------------------------------------------------
/05/app/components/contact/contact.service.js:
--------------------------------------------------------------------------------
1 | function ContactService(AuthService, $firebaseRef, $firebaseArray, $firebaseObject) {
2 | var ref = $firebaseRef.contacts;
3 | var uid = AuthService.getUser().uid;
4 | return {
5 | createNewContact: function (contact) {
6 | return $firebaseArray(ref.child(uid)).$add(contact);
7 | },
8 | getContactById: function (id) {
9 | return $firebaseObject(ref.child(uid).child(id));
10 | },
11 | updateContact: function (contact) {
12 | return contact.$save();
13 | },
14 | deleteContact: function (contact) {
15 | return contact.$remove();
16 | }
17 | };
18 | }
19 |
20 | angular
21 | .module('components.contact')
22 | .factory('ContactService', ContactService);
23 |
--------------------------------------------------------------------------------
/05/app/root.component.js:
--------------------------------------------------------------------------------
1 | var root = {
2 | templateUrl: './root.html'
3 | };
4 |
5 | angular
6 | .module('root')
7 | .component('root', root);
8 |
--------------------------------------------------------------------------------
/05/app/root.html:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/05/app/root.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('root', [
3 | 'common',
4 | 'components',
5 | 'templates'
6 | ]);
7 |
--------------------------------------------------------------------------------
/06/app/common/app-nav.component.js:
--------------------------------------------------------------------------------
1 | var appNav = {
2 | bindings: {
3 | user: '<',
4 | onLogout: '&'
5 | },
6 | templateUrl: './app-nav.html'
7 | };
8 |
9 | angular
10 | .module('common')
11 | .component('appNav', appNav);
12 |
--------------------------------------------------------------------------------
/06/app/common/app-nav.html:
--------------------------------------------------------------------------------
1 |
23 |
--------------------------------------------------------------------------------
/06/app/common/app-sidebar.component.js:
--------------------------------------------------------------------------------
1 | var appSidebar = {
2 | templateUrl: './app-sidebar.html',
3 | controller: 'AppSidebarController'
4 | };
5 |
6 | angular
7 | .module('common')
8 | .component('appSidebar', appSidebar);
9 |
--------------------------------------------------------------------------------
/06/app/common/app-sidebar.controller.js:
--------------------------------------------------------------------------------
1 | function AppSidebarController() {
2 | var ctrl = this;
3 | ctrl.contactTags = [{
4 | label: 'All contacts',
5 | icon: 'star'
6 | }, {
7 | label: 'Friends',
8 | icon: 'people'
9 | }, {
10 | label: 'Family',
11 | icon: 'child_care'
12 | }, {
13 | label: 'Acquaintances',
14 | icon: 'accessibility'
15 | }, {
16 | label: 'Following',
17 | icon: 'remove_red_eye'
18 | }];
19 | }
20 |
21 | angular
22 | .module('common')
23 | .controller('AppSidebarController', AppSidebarController);
24 |
--------------------------------------------------------------------------------
/06/app/common/app-sidebar.html:
--------------------------------------------------------------------------------
1 |
25 |
--------------------------------------------------------------------------------
/06/app/common/app.component.js:
--------------------------------------------------------------------------------
1 | var app = {
2 | templateUrl: './app.html',
3 | controller: 'AppController'
4 | };
5 |
6 | angular
7 | .module('common')
8 | .component('app', app)
9 | .config(function ($stateProvider) {
10 | $stateProvider
11 | .state('app', {
12 | // redirectTo: 'contacts'
13 | url: '/app',
14 | data: {
15 | requiredAuth: true
16 | },
17 | component: 'app'
18 | })
19 | });
20 |
--------------------------------------------------------------------------------
/06/app/common/app.controller.js:
--------------------------------------------------------------------------------
1 | function AppController(AuthService, $state) {
2 | var ctrl = this;
3 | ctrl.user = AuthService.getUser();
4 | ctrl.logout = function () {
5 | AuthService.logout().then(function () {
6 | $state.go('auth.login');
7 | });
8 | };
9 | }
10 |
11 | angular
12 | .module('common')
13 | .controller('AppController', AppController);
14 |
--------------------------------------------------------------------------------
/06/app/common/app.html:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/06/app/common/app.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('common', [
3 | 'ui.router',
4 | 'angular-loading-bar'
5 | ])
6 | .run(function ($transitions, cfpLoadingBar) {
7 | $transitions.onStart({}, cfpLoadingBar.start);
8 | $transitions.onSuccess({}, cfpLoadingBar.complete);
9 | });
10 |
--------------------------------------------------------------------------------
/06/app/components/auth/auth-form/auth-form.component.js:
--------------------------------------------------------------------------------
1 | var authForm = {
2 | bindings: {
3 | user: '<',
4 | button: '@',
5 | message: '@',
6 | onSubmit: '&'
7 | },
8 | templateUrl: './auth-form.html',
9 | controller: 'AuthFormController'
10 | };
11 |
12 | angular
13 | .module('components.auth')
14 | .component('authForm', authForm);
15 |
--------------------------------------------------------------------------------
/06/app/components/auth/auth-form/auth-form.controller.js:
--------------------------------------------------------------------------------
1 | function AuthFormController() {
2 | var ctrl = this;
3 | ctrl.$onChanges = function (changes) {
4 | if (changes.user) {
5 | ctrl.user = angular.copy(ctrl.user);
6 | }
7 | };
8 | ctrl.submitForm = function () {
9 | ctrl.onSubmit({
10 | $event: {
11 | user: ctrl.user
12 | }
13 | });
14 | };
15 | }
16 |
17 | angular
18 | .module('components.auth')
19 | .controller('AuthFormController', AuthFormController);
20 |
--------------------------------------------------------------------------------
/06/app/components/auth/auth-form/auth-form.html:
--------------------------------------------------------------------------------
1 |
27 |
--------------------------------------------------------------------------------
/06/app/components/auth/auth.service.js:
--------------------------------------------------------------------------------
1 | function AuthService($firebaseAuth) {
2 | var auth = $firebaseAuth();
3 | var authData = null;
4 | function storeAuthData(response) {
5 | authData = response;
6 | return authData;
7 | }
8 | function onSignIn(user) {
9 | authData = user;
10 | return auth.$requireSignIn();
11 | }
12 | function clearAuthData() {
13 | authData = null;
14 | }
15 | this.login = function (user) {
16 | return auth
17 | .$signInWithEmailAndPassword(user.email, user.password)
18 | .then(storeAuthData);
19 | };
20 | this.register = function (user) {
21 | return auth
22 | .$createUserWithEmailAndPassword(user.email, user.password)
23 | .then(storeAuthData);
24 | };
25 | this.logout = function () {
26 | return auth
27 | .$signOut()
28 | .then(clearAuthData);
29 | };
30 | this.requireAuthentication = function () {
31 | return auth
32 | .$waitForSignIn().then(onSignIn);
33 | };
34 | this.isAuthenticated = function () {
35 | return !!authData;
36 | };
37 | this.getUser = function () {
38 | if (authData) {
39 | return authData;
40 | }
41 | };
42 | }
43 |
44 | angular
45 | .module('components.auth')
46 | .service('AuthService', AuthService);
47 |
--------------------------------------------------------------------------------
/06/app/components/auth/login/login.component.js:
--------------------------------------------------------------------------------
1 | var login = {
2 | templateUrl: './login.html',
3 | controller: 'LoginController'
4 | };
5 |
6 | angular
7 | .module('components.auth')
8 | .component('login', login)
9 | .config(function ($stateProvider, $urlRouterProvider) {
10 | $stateProvider
11 | .state('auth', {
12 | redirectTo: 'auth.login',
13 | url: '/auth',
14 | template: ''
15 | })
16 | .state('auth.login', {
17 | url: '/login',
18 | component: 'login'
19 | });
20 | $urlRouterProvider.otherwise('/auth/login');
21 | });
22 |
--------------------------------------------------------------------------------
/06/app/components/auth/login/login.controller.js:
--------------------------------------------------------------------------------
1 | function LoginController(AuthService, $state) {
2 | var ctrl = this;
3 | ctrl.$onInit = function () {
4 | ctrl.error = null;
5 | ctrl.user = {
6 | email: '',
7 | password: ''
8 | };
9 | };
10 | ctrl.loginUser = function (event) {
11 | return AuthService
12 | .login(event.user)
13 | .then(function () {
14 | $state.go('app');
15 | }, function (reason) {
16 | ctrl.error = reason.message;
17 | });
18 | };
19 | }
20 |
21 | angular
22 | .module('components.auth')
23 | .controller('LoginController', LoginController);
24 |
--------------------------------------------------------------------------------
/06/app/components/auth/login/login.html:
--------------------------------------------------------------------------------
1 |
10 |
15 |
--------------------------------------------------------------------------------
/06/app/components/auth/register/register.component.js:
--------------------------------------------------------------------------------
1 | var register = {
2 | templateUrl: './register.html',
3 | controller: 'RegisterController'
4 | };
5 |
6 | angular
7 | .module('components.auth')
8 | .component('register', register)
9 | .config(function ($stateProvider) {
10 | $stateProvider
11 | .state('auth.register', {
12 | url: '/register',
13 | component: 'register'
14 | });
15 | });
16 |
--------------------------------------------------------------------------------
/06/app/components/auth/register/register.controller.js:
--------------------------------------------------------------------------------
1 | function RegisterController(AuthService, $state) {
2 | var ctrl = this;
3 | ctrl.$onInit = function () {
4 | ctrl.error = null;
5 | ctrl.user = {
6 | email: '',
7 | password: ''
8 | };
9 | };
10 | ctrl.createUser = function (event) {
11 | return AuthService
12 | .register(event.user)
13 | .then(function () {
14 | $state.go('app');
15 | }, function (reason) {
16 | ctrl.error = reason.message;
17 | });
18 | };
19 | }
20 |
21 | angular
22 | .module('components.auth')
23 | .controller('RegisterController', RegisterController);
24 |
--------------------------------------------------------------------------------
/06/app/components/auth/register/register.html:
--------------------------------------------------------------------------------
1 |
10 |
15 |
--------------------------------------------------------------------------------
/06/app/components/components.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('components', [
3 | 'components.contact',
4 | 'components.auth'
5 | ]);
6 |
--------------------------------------------------------------------------------
/06/app/components/contact/contact-detail/contact-detail.component.js:
--------------------------------------------------------------------------------
1 | var contactDetail = {
2 | bindings: {
3 | contact: '<',
4 | onSave: '&',
5 | onUpdate: '&',
6 | onDelete: '&'
7 | },
8 | templateUrl: './contact-detail.html',
9 | controller: 'ContactDetailController'
10 | };
11 |
12 | angular
13 | .module('components.contact')
14 | .component('contactDetail', contactDetail);
15 |
--------------------------------------------------------------------------------
/06/app/components/contact/contact-detail/contact-detail.controller.js:
--------------------------------------------------------------------------------
1 | function ContactDetailController() {
2 | var ctrl = this;
3 | ctrl.$onInit = function () {
4 | ctrl.isNewContact = !ctrl.contact.$id;
5 | };
6 | ctrl.saveContact = function () {
7 | ctrl.onSave({
8 | $event: {
9 | contact: ctrl.contact
10 | }
11 | });
12 | };
13 | ctrl.updateContact = function () {
14 | ctrl.onUpdate({
15 | $event: {
16 | contact: ctrl.contact
17 | }
18 | });
19 | };
20 | ctrl.deleteContact = function () {
21 | ctrl.onDelete({
22 | $event: {
23 | contact: ctrl.contact
24 | }
25 | });
26 | };
27 | ctrl.tagChange = function (event) {
28 | ctrl.contact.tag = event.tag;
29 | ctrl.updateContact();
30 | }
31 | }
32 |
33 | angular
34 | .module('components.contact')
35 | .controller('ContactDetailController', ContactDetailController);
36 |
--------------------------------------------------------------------------------
/06/app/components/contact/contact-edit/contact-edit.component.js:
--------------------------------------------------------------------------------
1 | var contactEdit = {
2 | bindings: {
3 | contact: '<'
4 | },
5 | templateUrl: './contact-edit.html',
6 | controller: 'ContactEditController'
7 | };
8 |
9 | angular
10 | .module('components.contact')
11 | .component('contactEdit', contactEdit)
12 | .config(function ($stateProvider) {
13 | $stateProvider
14 | .state('contact', {
15 | parent: 'app',
16 | url: '/contact/:id',
17 | component: 'contactEdit',
18 | resolve: {
19 | contact: function ($transition$, ContactService) {
20 | var key = $transition$.params().id;
21 | return ContactService.getContactById(key).$loaded();
22 | }
23 | }
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/06/app/components/contact/contact-edit/contact-edit.controller.js:
--------------------------------------------------------------------------------
1 | function ContactEditController($state, ContactService, cfpLoadingBar, $window) {
2 | var ctrl = this;
3 | ctrl.updateContact = function (event) {
4 | cfpLoadingBar.start();
5 | return ContactService
6 | .updateContact(event.contact)
7 | .then(cfpLoadingBar.complete, cfpLoadingBar.complete);
8 | };
9 | ctrl.deleteContact = function (event) {
10 | var message = 'Delete ' + event.contact.name + ' from contacts?';
11 | if ($window.confirm(message)) {
12 | return ContactService
13 | .deleteContact(event.contact)
14 | .then(function () {
15 | $state.go('contacts');
16 | });
17 | }
18 | };
19 | }
20 |
21 | angular
22 | .module('components.contact')
23 | .controller('ContactEditController', ContactEditController);
24 |
--------------------------------------------------------------------------------
/06/app/components/contact/contact-edit/contact-edit.html:
--------------------------------------------------------------------------------
1 |
5 |
6 |
--------------------------------------------------------------------------------
/06/app/components/contact/contact-new/contact-new.component.js:
--------------------------------------------------------------------------------
1 | var contactNew = {
2 | templateUrl: './contact-new.html',
3 | controller: 'ContactNewController'
4 | };
5 |
6 | angular
7 | .module('components.contact')
8 | .component('contactNew', contactNew)
9 | .config(function ($stateProvider) {
10 | $stateProvider
11 | .state('new', {
12 | parent: 'app',
13 | url: '/new',
14 | component: 'contactNew'
15 | });
16 | });
17 |
--------------------------------------------------------------------------------
/06/app/components/contact/contact-new/contact-new.controller.js:
--------------------------------------------------------------------------------
1 | function ContactNewController(ContactService, $state) {
2 | var ctrl = this;
3 | ctrl.$onInit = function () {
4 | ctrl.contact = {
5 | name: '',
6 | email: '',
7 | job: '',
8 | location: '',
9 | social: {
10 | facebook: '',
11 | github: '',
12 | twitter: '',
13 | linkedin: ''
14 | },
15 | tag: 'none'
16 | };
17 | };
18 | ctrl.createNewContact = function (event) {
19 | return ContactService
20 | .createNewContact(event.contact)
21 | .then(function (contact) {
22 | $state.go('contact', {
23 | id: contact.key
24 | });
25 | });
26 | };
27 | }
28 |
29 | angular
30 | .module('components.contact')
31 | .controller('ContactNewController', ContactNewController);
32 |
--------------------------------------------------------------------------------
/06/app/components/contact/contact-new/contact-new.html:
--------------------------------------------------------------------------------
1 |
4 |
5 |
--------------------------------------------------------------------------------
/06/app/components/contact/contact-tag/contact-tag.component.js:
--------------------------------------------------------------------------------
1 | var contactTag = {
2 | bindings: {
3 | tag: '<',
4 | onChange: '&'
5 | },
6 | templateUrl: './contact-tag.html',
7 | controller: 'ContactTagController'
8 | };
9 |
10 | angular
11 | .module('components.contact')
12 | .component('contactTag', contactTag);
13 |
--------------------------------------------------------------------------------
/06/app/components/contact/contact-tag/contact-tag.controller.js:
--------------------------------------------------------------------------------
1 | function ContactTagController() {
2 | var ctrl = this;
3 | ctrl.$onInit = function () {
4 | ctrl.tags = [
5 | 'friends', 'family', 'acquaintances', 'following'
6 | ];
7 | };
8 | ctrl.$onChanges = function (changes) {
9 | if (changes.tag) {
10 | ctrl.tag = angular.copy(ctrl.tag);
11 | }
12 | };
13 | ctrl.updateTag = function (tag) {
14 | ctrl.onChange({
15 | $event: {
16 | tag: tag
17 | }
18 | });
19 | };
20 | }
21 |
22 | angular
23 | .module('components.contact')
24 | .controller('ContactTagController', ContactTagController);
25 |
--------------------------------------------------------------------------------
/06/app/components/contact/contact-tag/contact-tag.html:
--------------------------------------------------------------------------------
1 |
18 |
--------------------------------------------------------------------------------
/06/app/components/contact/contact.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('components.contact', [
3 | 'ui.router'
4 | ]);
5 |
--------------------------------------------------------------------------------
/06/app/components/contact/contact.service.js:
--------------------------------------------------------------------------------
1 | function ContactService(AuthService, $firebaseRef, $firebaseArray, $firebaseObject) {
2 | var ref = $firebaseRef.contacts;
3 | var uid = AuthService.getUser().uid;
4 | return {
5 | createNewContact: function (contact) {
6 | return $firebaseArray(ref.child(uid)).$add(contact);
7 | },
8 | getContactById: function (id) {
9 | return $firebaseObject(ref.child(uid).child(id));
10 | },
11 | updateContact: function (contact) {
12 | return contact.$save();
13 | },
14 | deleteContact: function (contact) {
15 | return contact.$remove();
16 | }
17 | };
18 | }
19 |
20 | angular
21 | .module('components.contact')
22 | .factory('ContactService', ContactService);
23 |
--------------------------------------------------------------------------------
/06/app/root.component.js:
--------------------------------------------------------------------------------
1 | var root = {
2 | templateUrl: './root.html'
3 | };
4 |
5 | angular
6 | .module('root')
7 | .component('root', root);
8 |
--------------------------------------------------------------------------------
/06/app/root.html:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/06/app/root.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('root', [
3 | 'common',
4 | 'components',
5 | 'templates'
6 | ]);
7 |
--------------------------------------------------------------------------------
/07/app/common/app-nav.component.js:
--------------------------------------------------------------------------------
1 | var appNav = {
2 | bindings: {
3 | user: '<',
4 | onLogout: '&'
5 | },
6 | templateUrl: './app-nav.html'
7 | };
8 |
9 | angular
10 | .module('common')
11 | .component('appNav', appNav);
12 |
--------------------------------------------------------------------------------
/07/app/common/app-nav.html:
--------------------------------------------------------------------------------
1 |
23 |
--------------------------------------------------------------------------------
/07/app/common/app-sidebar.component.js:
--------------------------------------------------------------------------------
1 | var appSidebar = {
2 | templateUrl: './app-sidebar.html',
3 | controller: 'AppSidebarController'
4 | };
5 |
6 | angular
7 | .module('common')
8 | .component('appSidebar', appSidebar);
9 |
--------------------------------------------------------------------------------
/07/app/common/app-sidebar.controller.js:
--------------------------------------------------------------------------------
1 | function AppSidebarController() {
2 | var ctrl = this;
3 | ctrl.contactTags = [{
4 | label: 'All contacts',
5 | icon: 'star'
6 | }, {
7 | label: 'Friends',
8 | icon: 'people'
9 | }, {
10 | label: 'Family',
11 | icon: 'child_care'
12 | }, {
13 | label: 'Acquaintances',
14 | icon: 'accessibility'
15 | }, {
16 | label: 'Following',
17 | icon: 'remove_red_eye'
18 | }];
19 | }
20 |
21 | angular
22 | .module('common')
23 | .controller('AppSidebarController', AppSidebarController);
24 |
--------------------------------------------------------------------------------
/07/app/common/app-sidebar.html:
--------------------------------------------------------------------------------
1 |
25 |
--------------------------------------------------------------------------------
/07/app/common/app.component.js:
--------------------------------------------------------------------------------
1 | var app = {
2 | templateUrl: './app.html',
3 | controller: 'AppController'
4 | };
5 |
6 | angular
7 | .module('common')
8 | .component('app', app)
9 | .config(function ($stateProvider) {
10 | $stateProvider
11 | .state('app', {
12 | redirectTo: 'contacts',
13 | url: '/app',
14 | data: {
15 | requiredAuth: true
16 | },
17 | component: 'app'
18 | })
19 | });
20 |
--------------------------------------------------------------------------------
/07/app/common/app.controller.js:
--------------------------------------------------------------------------------
1 | function AppController(AuthService, $state) {
2 | var ctrl = this;
3 | ctrl.user = AuthService.getUser();
4 | ctrl.logout = function () {
5 | AuthService.logout().then(function () {
6 | $state.go('auth.login');
7 | });
8 | };
9 | }
10 |
11 | angular
12 | .module('common')
13 | .controller('AppController', AppController);
14 |
--------------------------------------------------------------------------------
/07/app/common/app.html:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/07/app/common/app.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('common', [
3 | 'ui.router',
4 | 'angular-loading-bar'
5 | ])
6 | .run(function ($transitions, cfpLoadingBar) {
7 | $transitions.onStart({}, cfpLoadingBar.start);
8 | $transitions.onSuccess({}, cfpLoadingBar.complete);
9 | });
10 |
--------------------------------------------------------------------------------
/07/app/components/auth/auth-form/auth-form.component.js:
--------------------------------------------------------------------------------
1 | var authForm = {
2 | bindings: {
3 | user: '<',
4 | button: '@',
5 | message: '@',
6 | onSubmit: '&'
7 | },
8 | templateUrl: './auth-form.html',
9 | controller: 'AuthFormController'
10 | };
11 |
12 | angular
13 | .module('components.auth')
14 | .component('authForm', authForm);
15 |
--------------------------------------------------------------------------------
/07/app/components/auth/auth-form/auth-form.controller.js:
--------------------------------------------------------------------------------
1 | function AuthFormController() {
2 | var ctrl = this;
3 | ctrl.$onChanges = function (changes) {
4 | if (changes.user) {
5 | ctrl.user = angular.copy(ctrl.user);
6 | }
7 | };
8 | ctrl.submitForm = function () {
9 | ctrl.onSubmit({
10 | $event: {
11 | user: ctrl.user
12 | }
13 | });
14 | };
15 | }
16 |
17 | angular
18 | .module('components.auth')
19 | .controller('AuthFormController', AuthFormController);
20 |
--------------------------------------------------------------------------------
/07/app/components/auth/auth-form/auth-form.html:
--------------------------------------------------------------------------------
1 |
27 |
--------------------------------------------------------------------------------
/07/app/components/auth/auth.service.js:
--------------------------------------------------------------------------------
1 | function AuthService($firebaseAuth) {
2 | var auth = $firebaseAuth();
3 | var authData = null;
4 | function storeAuthData(response) {
5 | authData = response;
6 | return authData;
7 | }
8 | function onSignIn(user) {
9 | authData = user;
10 | return auth.$requireSignIn();
11 | }
12 | function clearAuthData() {
13 | authData = null;
14 | }
15 | this.login = function (user) {
16 | return auth
17 | .$signInWithEmailAndPassword(user.email, user.password)
18 | .then(storeAuthData);
19 | };
20 | this.register = function (user) {
21 | return auth
22 | .$createUserWithEmailAndPassword(user.email, user.password)
23 | .then(storeAuthData);
24 | };
25 | this.logout = function () {
26 | return auth
27 | .$signOut()
28 | .then(clearAuthData);
29 | };
30 | this.requireAuthentication = function () {
31 | return auth
32 | .$waitForSignIn().then(onSignIn);
33 | };
34 | this.isAuthenticated = function () {
35 | return !!authData;
36 | };
37 | this.getUser = function () {
38 | if (authData) {
39 | return authData;
40 | }
41 | };
42 | }
43 |
44 | angular
45 | .module('components.auth')
46 | .service('AuthService', AuthService);
47 |
--------------------------------------------------------------------------------
/07/app/components/auth/login/login.component.js:
--------------------------------------------------------------------------------
1 | var login = {
2 | templateUrl: './login.html',
3 | controller: 'LoginController'
4 | };
5 |
6 | angular
7 | .module('components.auth')
8 | .component('login', login)
9 | .config(function ($stateProvider, $urlRouterProvider) {
10 | $stateProvider
11 | .state('auth', {
12 | redirectTo: 'auth.login',
13 | url: '/auth',
14 | template: ''
15 | })
16 | .state('auth.login', {
17 | url: '/login',
18 | component: 'login'
19 | });
20 | $urlRouterProvider.otherwise('/auth/login');
21 | });
22 |
--------------------------------------------------------------------------------
/07/app/components/auth/login/login.controller.js:
--------------------------------------------------------------------------------
1 | function LoginController(AuthService, $state) {
2 | var ctrl = this;
3 | ctrl.$onInit = function () {
4 | ctrl.error = null;
5 | ctrl.user = {
6 | email: '',
7 | password: ''
8 | };
9 | };
10 | ctrl.loginUser = function (event) {
11 | return AuthService
12 | .login(event.user)
13 | .then(function () {
14 | $state.go('app');
15 | }, function (reason) {
16 | ctrl.error = reason.message;
17 | });
18 | };
19 | }
20 |
21 | angular
22 | .module('components.auth')
23 | .controller('LoginController', LoginController);
24 |
--------------------------------------------------------------------------------
/07/app/components/auth/login/login.html:
--------------------------------------------------------------------------------
1 |
10 |
15 |
--------------------------------------------------------------------------------
/07/app/components/auth/register/register.component.js:
--------------------------------------------------------------------------------
1 | var register = {
2 | templateUrl: './register.html',
3 | controller: 'RegisterController'
4 | };
5 |
6 | angular
7 | .module('components.auth')
8 | .component('register', register)
9 | .config(function ($stateProvider) {
10 | $stateProvider
11 | .state('auth.register', {
12 | url: '/register',
13 | component: 'register'
14 | });
15 | });
16 |
--------------------------------------------------------------------------------
/07/app/components/auth/register/register.controller.js:
--------------------------------------------------------------------------------
1 | function RegisterController(AuthService, $state) {
2 | var ctrl = this;
3 | ctrl.$onInit = function () {
4 | ctrl.error = null;
5 | ctrl.user = {
6 | email: '',
7 | password: ''
8 | };
9 | };
10 | ctrl.createUser = function (event) {
11 | return AuthService
12 | .register(event.user)
13 | .then(function () {
14 | $state.go('app');
15 | }, function (reason) {
16 | ctrl.error = reason.message;
17 | });
18 | };
19 | }
20 |
21 | angular
22 | .module('components.auth')
23 | .controller('RegisterController', RegisterController);
24 |
--------------------------------------------------------------------------------
/07/app/components/auth/register/register.html:
--------------------------------------------------------------------------------
1 |
10 |
15 |
--------------------------------------------------------------------------------
/07/app/components/components.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('components', [
3 | 'components.contact',
4 | 'components.auth'
5 | ]);
6 |
--------------------------------------------------------------------------------
/07/app/components/contact/contact-detail/contact-detail.component.js:
--------------------------------------------------------------------------------
1 | var contactDetail = {
2 | bindings: {
3 | contact: '<',
4 | onSave: '&',
5 | onUpdate: '&',
6 | onDelete: '&'
7 | },
8 | templateUrl: './contact-detail.html',
9 | controller: 'ContactDetailController'
10 | };
11 |
12 | angular
13 | .module('components.contact')
14 | .component('contactDetail', contactDetail);
15 |
--------------------------------------------------------------------------------
/07/app/components/contact/contact-detail/contact-detail.controller.js:
--------------------------------------------------------------------------------
1 | function ContactDetailController() {
2 | var ctrl = this;
3 | ctrl.$onInit = function () {
4 | ctrl.isNewContact = !ctrl.contact.$id;
5 | };
6 | ctrl.saveContact = function () {
7 | ctrl.onSave({
8 | $event: {
9 | contact: ctrl.contact
10 | }
11 | });
12 | };
13 | ctrl.updateContact = function () {
14 | ctrl.onUpdate({
15 | $event: {
16 | contact: ctrl.contact
17 | }
18 | });
19 | };
20 | ctrl.deleteContact = function () {
21 | ctrl.onDelete({
22 | $event: {
23 | contact: ctrl.contact
24 | }
25 | });
26 | };
27 | ctrl.tagChange = function (event) {
28 | ctrl.contact.tag = event.tag;
29 | ctrl.updateContact();
30 | }
31 | }
32 |
33 | angular
34 | .module('components.contact')
35 | .controller('ContactDetailController', ContactDetailController);
36 |
--------------------------------------------------------------------------------
/07/app/components/contact/contact-edit/contact-edit.component.js:
--------------------------------------------------------------------------------
1 | var contactEdit = {
2 | bindings: {
3 | contact: '<'
4 | },
5 | templateUrl: './contact-edit.html',
6 | controller: 'ContactEditController'
7 | };
8 |
9 | angular
10 | .module('components.contact')
11 | .component('contactEdit', contactEdit)
12 | .config(function ($stateProvider) {
13 | $stateProvider
14 | .state('contact', {
15 | parent: 'app',
16 | url: '/contact/:id',
17 | component: 'contactEdit',
18 | resolve: {
19 | contact: function ($transition$, ContactService) {
20 | var key = $transition$.params().id;
21 | return ContactService.getContactById(key).$loaded();
22 | }
23 | }
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/07/app/components/contact/contact-edit/contact-edit.controller.js:
--------------------------------------------------------------------------------
1 | function ContactEditController($state, ContactService, cfpLoadingBar, $window) {
2 | var ctrl = this;
3 | ctrl.updateContact = function (event) {
4 | cfpLoadingBar.start();
5 | return ContactService
6 | .updateContact(event.contact)
7 | .then(cfpLoadingBar.complete, cfpLoadingBar.complete);
8 | };
9 | ctrl.deleteContact = function (event) {
10 | var message = 'Delete ' + event.contact.name + ' from contacts?';
11 | if ($window.confirm(message)) {
12 | return ContactService
13 | .deleteContact(event.contact)
14 | .then(function () {
15 | $state.go('contacts');
16 | });
17 | }
18 | };
19 | }
20 |
21 | angular
22 | .module('components.contact')
23 | .controller('ContactEditController', ContactEditController);
24 |
--------------------------------------------------------------------------------
/07/app/components/contact/contact-edit/contact-edit.html:
--------------------------------------------------------------------------------
1 |
5 |
6 |
--------------------------------------------------------------------------------
/07/app/components/contact/contact-new/contact-new.component.js:
--------------------------------------------------------------------------------
1 | var contactNew = {
2 | templateUrl: './contact-new.html',
3 | controller: 'ContactNewController'
4 | };
5 |
6 | angular
7 | .module('components.contact')
8 | .component('contactNew', contactNew)
9 | .config(function ($stateProvider) {
10 | $stateProvider
11 | .state('new', {
12 | parent: 'app',
13 | url: '/new',
14 | component: 'contactNew'
15 | });
16 | });
17 |
--------------------------------------------------------------------------------
/07/app/components/contact/contact-new/contact-new.controller.js:
--------------------------------------------------------------------------------
1 | function ContactNewController(ContactService, $state) {
2 | var ctrl = this;
3 | ctrl.$onInit = function () {
4 | ctrl.contact = {
5 | name: '',
6 | email: '',
7 | job: '',
8 | location: '',
9 | social: {
10 | facebook: '',
11 | github: '',
12 | twitter: '',
13 | linkedin: ''
14 | },
15 | tag: 'none'
16 | };
17 | };
18 | ctrl.createNewContact = function (event) {
19 | return ContactService
20 | .createNewContact(event.contact)
21 | .then(function (contact) {
22 | $state.go('contact', {
23 | id: contact.key
24 | });
25 | });
26 | };
27 | }
28 |
29 | angular
30 | .module('components.contact')
31 | .controller('ContactNewController', ContactNewController);
32 |
--------------------------------------------------------------------------------
/07/app/components/contact/contact-new/contact-new.html:
--------------------------------------------------------------------------------
1 |
4 |
5 |
--------------------------------------------------------------------------------
/07/app/components/contact/contact-tag/contact-tag.component.js:
--------------------------------------------------------------------------------
1 | var contactTag = {
2 | bindings: {
3 | tag: '<',
4 | onChange: '&'
5 | },
6 | templateUrl: './contact-tag.html',
7 | controller: 'ContactTagController'
8 | };
9 |
10 | angular
11 | .module('components.contact')
12 | .component('contactTag', contactTag);
13 |
--------------------------------------------------------------------------------
/07/app/components/contact/contact-tag/contact-tag.controller.js:
--------------------------------------------------------------------------------
1 | function ContactTagController() {
2 | var ctrl = this;
3 | ctrl.$onInit = function () {
4 | ctrl.tags = [
5 | 'friends', 'family', 'acquaintances', 'following'
6 | ];
7 | };
8 | ctrl.$onChanges = function (changes) {
9 | if (changes.tag) {
10 | ctrl.tag = angular.copy(ctrl.tag);
11 | }
12 | };
13 | ctrl.updateTag = function (tag) {
14 | ctrl.onChange({
15 | $event: {
16 | tag: tag
17 | }
18 | });
19 | };
20 | }
21 |
22 | angular
23 | .module('components.contact')
24 | .controller('ContactTagController', ContactTagController);
25 |
--------------------------------------------------------------------------------
/07/app/components/contact/contact-tag/contact-tag.html:
--------------------------------------------------------------------------------
1 |
18 |
--------------------------------------------------------------------------------
/07/app/components/contact/contact.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('components.contact', [
3 | 'ui.router'
4 | ]);
5 |
--------------------------------------------------------------------------------
/07/app/components/contact/contact.service.js:
--------------------------------------------------------------------------------
1 | function ContactService(AuthService, $firebaseRef, $firebaseArray, $firebaseObject) {
2 | var ref = $firebaseRef.contacts;
3 | var uid = AuthService.getUser().uid;
4 | return {
5 | createNewContact: function (contact) {
6 | return $firebaseArray(ref.child(uid)).$add(contact);
7 | },
8 | getContactById: function (id) {
9 | return $firebaseObject(ref.child(uid).child(id));
10 | },
11 | getContactList: function () {
12 | return $firebaseArray(ref.child(uid));
13 | },
14 | updateContact: function (contact) {
15 | return contact.$save();
16 | },
17 | deleteContact: function (contact) {
18 | return contact.$remove();
19 | }
20 | };
21 | }
22 |
23 | angular
24 | .module('components.contact')
25 | .factory('ContactService', ContactService);
26 |
--------------------------------------------------------------------------------
/07/app/components/contact/contacts/contacts.component.js:
--------------------------------------------------------------------------------
1 | var contacts = {
2 | bindings: {
3 | contacts: '<'
4 | },
5 | templateUrl: './contacts.html',
6 | controller: 'ContactsController'
7 | };
8 |
9 | angular
10 | .module('components.contact')
11 | .component('contacts', contacts)
12 | .config(function ($stateProvider) {
13 | $stateProvider
14 | .state('contacts', {
15 | parent: 'app',
16 | url: '/contacts',
17 | component: 'contacts',
18 | resolve: {
19 | contacts: function (ContactService) {
20 | return ContactService.getContactList().$loaded();
21 | }
22 | }
23 | });
24 | });
25 |
--------------------------------------------------------------------------------
/07/app/components/contact/contacts/contacts.controller.js:
--------------------------------------------------------------------------------
1 | function ContactsController() {
2 | var ctrl = this;
3 | ctrl.goToContact = function (event) {
4 | // $state.go('contact', { id: event.contactId })
5 | };
6 | }
7 |
8 | angular
9 | .module('components.contact')
10 | .controller('ContactsController', ContactsController);
11 |
--------------------------------------------------------------------------------
/07/app/components/contact/contacts/contacts.html:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/07/app/root.component.js:
--------------------------------------------------------------------------------
1 | var root = {
2 | templateUrl: './root.html'
3 | };
4 |
5 | angular
6 | .module('root')
7 | .component('root', root);
8 |
--------------------------------------------------------------------------------
/07/app/root.html:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/07/app/root.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('root', [
3 | 'common',
4 | 'components',
5 | 'templates'
6 | ]);
7 |
--------------------------------------------------------------------------------
/08/app/common/app-nav.component.js:
--------------------------------------------------------------------------------
1 | var appNav = {
2 | bindings: {
3 | user: '<',
4 | onLogout: '&'
5 | },
6 | templateUrl: './app-nav.html'
7 | };
8 |
9 | angular
10 | .module('common')
11 | .component('appNav', appNav);
12 |
--------------------------------------------------------------------------------
/08/app/common/app-nav.html:
--------------------------------------------------------------------------------
1 |
23 |
--------------------------------------------------------------------------------
/08/app/common/app-sidebar.component.js:
--------------------------------------------------------------------------------
1 | var appSidebar = {
2 | templateUrl: './app-sidebar.html',
3 | controller: 'AppSidebarController'
4 | };
5 |
6 | angular
7 | .module('common')
8 | .component('appSidebar', appSidebar);
9 |
--------------------------------------------------------------------------------
/08/app/common/app-sidebar.controller.js:
--------------------------------------------------------------------------------
1 | function AppSidebarController() {
2 | var ctrl = this;
3 | ctrl.contactTags = [{
4 | label: 'All contacts',
5 | icon: 'star'
6 | }, {
7 | label: 'Friends',
8 | icon: 'people'
9 | }, {
10 | label: 'Family',
11 | icon: 'child_care'
12 | }, {
13 | label: 'Acquaintances',
14 | icon: 'accessibility'
15 | }, {
16 | label: 'Following',
17 | icon: 'remove_red_eye'
18 | }];
19 | }
20 |
21 | angular
22 | .module('common')
23 | .controller('AppSidebarController', AppSidebarController);
24 |
--------------------------------------------------------------------------------
/08/app/common/app-sidebar.html:
--------------------------------------------------------------------------------
1 |
25 |
--------------------------------------------------------------------------------
/08/app/common/app.component.js:
--------------------------------------------------------------------------------
1 | var app = {
2 | templateUrl: './app.html',
3 | controller: 'AppController'
4 | };
5 |
6 | angular
7 | .module('common')
8 | .component('app', app)
9 | .config(function ($stateProvider) {
10 | $stateProvider
11 | .state('app', {
12 | redirectTo: 'contacts',
13 | url: '/app',
14 | data: {
15 | requiredAuth: true
16 | },
17 | component: 'app'
18 | })
19 | });
20 |
--------------------------------------------------------------------------------
/08/app/common/app.controller.js:
--------------------------------------------------------------------------------
1 | function AppController(AuthService, $state) {
2 | var ctrl = this;
3 | ctrl.user = AuthService.getUser();
4 | ctrl.logout = function () {
5 | AuthService.logout().then(function () {
6 | $state.go('auth.login');
7 | });
8 | };
9 | }
10 |
11 | angular
12 | .module('common')
13 | .controller('AppController', AppController);
14 |
--------------------------------------------------------------------------------
/08/app/common/app.html:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/08/app/common/app.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('common', [
3 | 'ui.router',
4 | 'angular-loading-bar'
5 | ])
6 | .run(function ($transitions, cfpLoadingBar) {
7 | $transitions.onStart({}, cfpLoadingBar.start);
8 | $transitions.onSuccess({}, cfpLoadingBar.complete);
9 | });
10 |
--------------------------------------------------------------------------------
/08/app/components/auth/auth-form/auth-form.component.js:
--------------------------------------------------------------------------------
1 | var authForm = {
2 | bindings: {
3 | user: '<',
4 | button: '@',
5 | message: '@',
6 | onSubmit: '&'
7 | },
8 | templateUrl: './auth-form.html',
9 | controller: 'AuthFormController'
10 | };
11 |
12 | angular
13 | .module('components.auth')
14 | .component('authForm', authForm);
15 |
--------------------------------------------------------------------------------
/08/app/components/auth/auth-form/auth-form.controller.js:
--------------------------------------------------------------------------------
1 | function AuthFormController() {
2 | var ctrl = this;
3 | ctrl.$onChanges = function (changes) {
4 | if (changes.user) {
5 | ctrl.user = angular.copy(ctrl.user);
6 | }
7 | };
8 | ctrl.submitForm = function () {
9 | ctrl.onSubmit({
10 | $event: {
11 | user: ctrl.user
12 | }
13 | });
14 | };
15 | }
16 |
17 | angular
18 | .module('components.auth')
19 | .controller('AuthFormController', AuthFormController);
20 |
--------------------------------------------------------------------------------
/08/app/components/auth/auth-form/auth-form.html:
--------------------------------------------------------------------------------
1 |
27 |
--------------------------------------------------------------------------------
/08/app/components/auth/auth.service.js:
--------------------------------------------------------------------------------
1 | function AuthService($firebaseAuth) {
2 | var auth = $firebaseAuth();
3 | var authData = null;
4 | function storeAuthData(response) {
5 | authData = response;
6 | return authData;
7 | }
8 | function onSignIn(user) {
9 | authData = user;
10 | return auth.$requireSignIn();
11 | }
12 | function clearAuthData() {
13 | authData = null;
14 | }
15 | this.login = function (user) {
16 | return auth
17 | .$signInWithEmailAndPassword(user.email, user.password)
18 | .then(storeAuthData);
19 | };
20 | this.register = function (user) {
21 | return auth
22 | .$createUserWithEmailAndPassword(user.email, user.password)
23 | .then(storeAuthData);
24 | };
25 | this.logout = function () {
26 | return auth
27 | .$signOut()
28 | .then(clearAuthData);
29 | };
30 | this.requireAuthentication = function () {
31 | return auth
32 | .$waitForSignIn().then(onSignIn);
33 | };
34 | this.isAuthenticated = function () {
35 | return !!authData;
36 | };
37 | this.getUser = function () {
38 | if (authData) {
39 | return authData;
40 | }
41 | };
42 | }
43 |
44 | angular
45 | .module('components.auth')
46 | .service('AuthService', AuthService);
47 |
--------------------------------------------------------------------------------
/08/app/components/auth/login/login.component.js:
--------------------------------------------------------------------------------
1 | var login = {
2 | templateUrl: './login.html',
3 | controller: 'LoginController'
4 | };
5 |
6 | angular
7 | .module('components.auth')
8 | .component('login', login)
9 | .config(function ($stateProvider, $urlRouterProvider) {
10 | $stateProvider
11 | .state('auth', {
12 | redirectTo: 'auth.login',
13 | url: '/auth',
14 | template: ''
15 | })
16 | .state('auth.login', {
17 | url: '/login',
18 | component: 'login'
19 | });
20 | $urlRouterProvider.otherwise('/auth/login');
21 | });
22 |
--------------------------------------------------------------------------------
/08/app/components/auth/login/login.controller.js:
--------------------------------------------------------------------------------
1 | function LoginController(AuthService, $state) {
2 | var ctrl = this;
3 | ctrl.$onInit = function () {
4 | ctrl.error = null;
5 | ctrl.user = {
6 | email: '',
7 | password: ''
8 | };
9 | };
10 | ctrl.loginUser = function (event) {
11 | return AuthService
12 | .login(event.user)
13 | .then(function () {
14 | $state.go('app');
15 | }, function (reason) {
16 | ctrl.error = reason.message;
17 | });
18 | };
19 | }
20 |
21 | angular
22 | .module('components.auth')
23 | .controller('LoginController', LoginController);
24 |
--------------------------------------------------------------------------------
/08/app/components/auth/login/login.html:
--------------------------------------------------------------------------------
1 |
10 |
15 |
--------------------------------------------------------------------------------
/08/app/components/auth/register/register.component.js:
--------------------------------------------------------------------------------
1 | var register = {
2 | templateUrl: './register.html',
3 | controller: 'RegisterController'
4 | };
5 |
6 | angular
7 | .module('components.auth')
8 | .component('register', register)
9 | .config(function ($stateProvider) {
10 | $stateProvider
11 | .state('auth.register', {
12 | url: '/register',
13 | component: 'register'
14 | });
15 | });
16 |
--------------------------------------------------------------------------------
/08/app/components/auth/register/register.controller.js:
--------------------------------------------------------------------------------
1 | function RegisterController(AuthService, $state) {
2 | var ctrl = this;
3 | ctrl.$onInit = function () {
4 | ctrl.error = null;
5 | ctrl.user = {
6 | email: '',
7 | password: ''
8 | };
9 | };
10 | ctrl.createUser = function (event) {
11 | return AuthService
12 | .register(event.user)
13 | .then(function () {
14 | $state.go('app');
15 | }, function (reason) {
16 | ctrl.error = reason.message;
17 | });
18 | };
19 | }
20 |
21 | angular
22 | .module('components.auth')
23 | .controller('RegisterController', RegisterController);
24 |
--------------------------------------------------------------------------------
/08/app/components/auth/register/register.html:
--------------------------------------------------------------------------------
1 |
10 |
15 |
--------------------------------------------------------------------------------
/08/app/components/components.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('components', [
3 | 'components.contact',
4 | 'components.auth'
5 | ]);
6 |
--------------------------------------------------------------------------------
/08/app/components/contact/contact-detail/contact-detail.component.js:
--------------------------------------------------------------------------------
1 | var contactDetail = {
2 | bindings: {
3 | contact: '<',
4 | onSave: '&',
5 | onUpdate: '&',
6 | onDelete: '&'
7 | },
8 | templateUrl: './contact-detail.html',
9 | controller: 'ContactDetailController'
10 | };
11 |
12 | angular
13 | .module('components.contact')
14 | .component('contactDetail', contactDetail);
15 |
--------------------------------------------------------------------------------
/08/app/components/contact/contact-detail/contact-detail.controller.js:
--------------------------------------------------------------------------------
1 | function ContactDetailController() {
2 | var ctrl = this;
3 | ctrl.$onInit = function () {
4 | ctrl.isNewContact = !ctrl.contact.$id;
5 | };
6 | ctrl.saveContact = function () {
7 | ctrl.onSave({
8 | $event: {
9 | contact: ctrl.contact
10 | }
11 | });
12 | };
13 | ctrl.updateContact = function () {
14 | ctrl.onUpdate({
15 | $event: {
16 | contact: ctrl.contact
17 | }
18 | });
19 | };
20 | ctrl.deleteContact = function () {
21 | ctrl.onDelete({
22 | $event: {
23 | contact: ctrl.contact
24 | }
25 | });
26 | };
27 | ctrl.tagChange = function (event) {
28 | ctrl.contact.tag = event.tag;
29 | ctrl.updateContact();
30 | }
31 | }
32 |
33 | angular
34 | .module('components.contact')
35 | .controller('ContactDetailController', ContactDetailController);
36 |
--------------------------------------------------------------------------------
/08/app/components/contact/contact-edit/contact-edit.component.js:
--------------------------------------------------------------------------------
1 | var contactEdit = {
2 | bindings: {
3 | contact: '<'
4 | },
5 | templateUrl: './contact-edit.html',
6 | controller: 'ContactEditController'
7 | };
8 |
9 | angular
10 | .module('components.contact')
11 | .component('contactEdit', contactEdit)
12 | .config(function ($stateProvider) {
13 | $stateProvider
14 | .state('contact', {
15 | parent: 'app',
16 | url: '/contact/:id',
17 | component: 'contactEdit',
18 | resolve: {
19 | contact: function ($transition$, ContactService) {
20 | var key = $transition$.params().id;
21 | return ContactService.getContactById(key).$loaded();
22 | }
23 | }
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/08/app/components/contact/contact-edit/contact-edit.controller.js:
--------------------------------------------------------------------------------
1 | function ContactEditController($state, ContactService, cfpLoadingBar, $window) {
2 | var ctrl = this;
3 | ctrl.updateContact = function (event) {
4 | cfpLoadingBar.start();
5 | return ContactService
6 | .updateContact(event.contact)
7 | .then(cfpLoadingBar.complete, cfpLoadingBar.complete);
8 | };
9 | ctrl.deleteContact = function (event) {
10 | var message = 'Delete ' + event.contact.name + ' from contacts?';
11 | if ($window.confirm(message)) {
12 | return ContactService
13 | .deleteContact(event.contact)
14 | .then(function () {
15 | $state.go('contacts');
16 | });
17 | }
18 | };
19 | }
20 |
21 | angular
22 | .module('components.contact')
23 | .controller('ContactEditController', ContactEditController);
24 |
--------------------------------------------------------------------------------
/08/app/components/contact/contact-edit/contact-edit.html:
--------------------------------------------------------------------------------
1 |
5 |
6 |
--------------------------------------------------------------------------------
/08/app/components/contact/contact-new/contact-new.component.js:
--------------------------------------------------------------------------------
1 | var contactNew = {
2 | templateUrl: './contact-new.html',
3 | controller: 'ContactNewController'
4 | };
5 |
6 | angular
7 | .module('components.contact')
8 | .component('contactNew', contactNew)
9 | .config(function ($stateProvider) {
10 | $stateProvider
11 | .state('new', {
12 | parent: 'app',
13 | url: '/new',
14 | component: 'contactNew'
15 | });
16 | });
17 |
--------------------------------------------------------------------------------
/08/app/components/contact/contact-new/contact-new.controller.js:
--------------------------------------------------------------------------------
1 | function ContactNewController(ContactService, $state) {
2 | var ctrl = this;
3 | ctrl.$onInit = function () {
4 | ctrl.contact = {
5 | name: '',
6 | email: '',
7 | job: '',
8 | location: '',
9 | social: {
10 | facebook: '',
11 | github: '',
12 | twitter: '',
13 | linkedin: ''
14 | },
15 | tag: 'none'
16 | };
17 | };
18 | ctrl.createNewContact = function (event) {
19 | return ContactService
20 | .createNewContact(event.contact)
21 | .then(function (contact) {
22 | $state.go('contact', {
23 | id: contact.key
24 | });
25 | });
26 | };
27 | }
28 |
29 | angular
30 | .module('components.contact')
31 | .controller('ContactNewController', ContactNewController);
32 |
--------------------------------------------------------------------------------
/08/app/components/contact/contact-new/contact-new.html:
--------------------------------------------------------------------------------
1 |
4 |
5 |
--------------------------------------------------------------------------------
/08/app/components/contact/contact-tag/contact-tag.component.js:
--------------------------------------------------------------------------------
1 | var contactTag = {
2 | bindings: {
3 | tag: '<',
4 | onChange: '&'
5 | },
6 | templateUrl: './contact-tag.html',
7 | controller: 'ContactTagController'
8 | };
9 |
10 | angular
11 | .module('components.contact')
12 | .component('contactTag', contactTag);
13 |
--------------------------------------------------------------------------------
/08/app/components/contact/contact-tag/contact-tag.controller.js:
--------------------------------------------------------------------------------
1 | function ContactTagController() {
2 | var ctrl = this;
3 | ctrl.$onInit = function () {
4 | ctrl.tags = [
5 | 'friends', 'family', 'acquaintances', 'following'
6 | ];
7 | };
8 | ctrl.$onChanges = function (changes) {
9 | if (changes.tag) {
10 | ctrl.tag = angular.copy(ctrl.tag);
11 | }
12 | };
13 | ctrl.updateTag = function (tag) {
14 | ctrl.onChange({
15 | $event: {
16 | tag: tag
17 | }
18 | });
19 | };
20 | }
21 |
22 | angular
23 | .module('components.contact')
24 | .controller('ContactTagController', ContactTagController);
25 |
--------------------------------------------------------------------------------
/08/app/components/contact/contact-tag/contact-tag.html:
--------------------------------------------------------------------------------
1 |
18 |
--------------------------------------------------------------------------------
/08/app/components/contact/contact.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('components.contact', [
3 | 'ui.router'
4 | ]);
5 |
--------------------------------------------------------------------------------
/08/app/components/contact/contact.service.js:
--------------------------------------------------------------------------------
1 | function ContactService(AuthService, $firebaseRef, $firebaseArray, $firebaseObject) {
2 | var ref = $firebaseRef.contacts;
3 | var uid = AuthService.getUser().uid;
4 | return {
5 | createNewContact: function (contact) {
6 | return $firebaseArray(ref.child(uid)).$add(contact);
7 | },
8 | getContactById: function (id) {
9 | return $firebaseObject(ref.child(uid).child(id));
10 | },
11 | getContactList: function () {
12 | return $firebaseArray(ref.child(uid));
13 | },
14 | updateContact: function (contact) {
15 | return contact.$save();
16 | },
17 | deleteContact: function (contact) {
18 | return contact.$remove();
19 | }
20 | };
21 | }
22 |
23 | angular
24 | .module('components.contact')
25 | .factory('ContactService', ContactService);
26 |
--------------------------------------------------------------------------------
/08/app/components/contact/contact/contact.component.js:
--------------------------------------------------------------------------------
1 | var contact = {
2 | bindings: {
3 | contact: '<',
4 | onSelect: '&'
5 | },
6 | templateUrl: './contact.html',
7 | controller: 'ContactController'
8 | };
9 |
10 | angular
11 | .module('components.contact')
12 | .component('contact', contact);
13 |
--------------------------------------------------------------------------------
/08/app/components/contact/contact/contact.controller.js:
--------------------------------------------------------------------------------
1 | function ContactController() {
2 | var ctrl = this;
3 | ctrl.selectContact = function () {
4 | ctrl.onSelect({
5 | $event: {
6 | contactId: ctrl.contact.$id
7 | }
8 | });
9 | };
10 | }
11 |
12 | angular
13 | .module('components.contact')
14 | .controller('ContactController', ContactController);
15 |
--------------------------------------------------------------------------------
/08/app/components/contact/contact/contact.html:
--------------------------------------------------------------------------------
1 |
17 |
--------------------------------------------------------------------------------
/08/app/components/contact/contacts/contacts.component.js:
--------------------------------------------------------------------------------
1 | var contacts = {
2 | bindings: {
3 | contacts: '<'
4 | },
5 | templateUrl: './contacts.html',
6 | controller: 'ContactsController'
7 | };
8 |
9 | angular
10 | .module('components.contact')
11 | .component('contacts', contacts)
12 | .config(function ($stateProvider) {
13 | $stateProvider
14 | .state('contacts', {
15 | parent: 'app',
16 | url: '/contacts',
17 | component: 'contacts',
18 | resolve: {
19 | contacts: function (ContactService) {
20 | return ContactService.getContactList().$loaded();
21 | }
22 | }
23 | });
24 | });
25 |
--------------------------------------------------------------------------------
/08/app/components/contact/contacts/contacts.controller.js:
--------------------------------------------------------------------------------
1 | function ContactsController($state) {
2 | var ctrl = this;
3 | ctrl.goToContact = function (event) {
4 | $state.go('contact', {
5 | id: event.contactId
6 | });
7 | };
8 | }
9 |
10 | angular
11 | .module('components.contact')
12 | .controller('ContactsController', ContactsController);
13 |
--------------------------------------------------------------------------------
/08/app/components/contact/contacts/contacts.html:
--------------------------------------------------------------------------------
1 |
17 |
--------------------------------------------------------------------------------
/08/app/root.component.js:
--------------------------------------------------------------------------------
1 | var root = {
2 | templateUrl: './root.html'
3 | };
4 |
5 | angular
6 | .module('root')
7 | .component('root', root);
8 |
--------------------------------------------------------------------------------
/08/app/root.html:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/08/app/root.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('root', [
3 | 'common',
4 | 'components',
5 | 'templates'
6 | ]);
7 |
--------------------------------------------------------------------------------
/09/app/common/app-nav.component.js:
--------------------------------------------------------------------------------
1 | var appNav = {
2 | bindings: {
3 | user: '<',
4 | onLogout: '&'
5 | },
6 | templateUrl: './app-nav.html'
7 | };
8 |
9 | angular
10 | .module('common')
11 | .component('appNav', appNav);
12 |
--------------------------------------------------------------------------------
/09/app/common/app-nav.html:
--------------------------------------------------------------------------------
1 |
23 |
--------------------------------------------------------------------------------
/09/app/common/app-sidebar.component.js:
--------------------------------------------------------------------------------
1 | var appSidebar = {
2 | templateUrl: './app-sidebar.html',
3 | controller: 'AppSidebarController'
4 | };
5 |
6 | angular
7 | .module('common')
8 | .component('appSidebar', appSidebar);
9 |
--------------------------------------------------------------------------------
/09/app/common/app-sidebar.controller.js:
--------------------------------------------------------------------------------
1 | function AppSidebarController() {
2 | var ctrl = this;
3 | ctrl.contactTags = [{
4 | label: 'All contacts',
5 | icon: 'star',
6 | state: 'none'
7 | }, {
8 | label: 'Friends',
9 | icon: 'people',
10 | state: 'friends'
11 | }, {
12 | label: 'Family',
13 | icon: 'child_care',
14 | state: 'family'
15 | }, {
16 | label: 'Acquaintances',
17 | icon: 'accessibility',
18 | state: 'acquaintances'
19 | }, {
20 | label: 'Following',
21 | icon: 'remove_red_eye',
22 | state: 'following'
23 | }];
24 | }
25 |
26 | angular
27 | .module('common')
28 | .controller('AppSidebarController', AppSidebarController);
29 |
--------------------------------------------------------------------------------
/09/app/common/app-sidebar.html:
--------------------------------------------------------------------------------
1 |
26 |
--------------------------------------------------------------------------------
/09/app/common/app.component.js:
--------------------------------------------------------------------------------
1 | var app = {
2 | templateUrl: './app.html',
3 | controller: 'AppController'
4 | };
5 |
6 | angular
7 | .module('common')
8 | .component('app', app)
9 | .config(function ($stateProvider) {
10 | $stateProvider
11 | .state('app', {
12 | redirectTo: 'contacts',
13 | url: '/app',
14 | data: {
15 | requiredAuth: true
16 | },
17 | component: 'app'
18 | })
19 | });
20 |
--------------------------------------------------------------------------------
/09/app/common/app.controller.js:
--------------------------------------------------------------------------------
1 | function AppController(AuthService, $state) {
2 | var ctrl = this;
3 | ctrl.user = AuthService.getUser();
4 | ctrl.logout = function () {
5 | AuthService.logout().then(function () {
6 | $state.go('auth.login');
7 | });
8 | };
9 | }
10 |
11 | angular
12 | .module('common')
13 | .controller('AppController', AppController);
14 |
--------------------------------------------------------------------------------
/09/app/common/app.html:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/09/app/common/app.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('common', [
3 | 'ui.router',
4 | 'angular-loading-bar'
5 | ])
6 | .run(function ($transitions, cfpLoadingBar) {
7 | $transitions.onStart({}, cfpLoadingBar.start);
8 | $transitions.onSuccess({}, cfpLoadingBar.complete);
9 | });
10 |
--------------------------------------------------------------------------------
/09/app/components/auth/auth-form/auth-form.component.js:
--------------------------------------------------------------------------------
1 | var authForm = {
2 | bindings: {
3 | user: '<',
4 | button: '@',
5 | message: '@',
6 | onSubmit: '&'
7 | },
8 | templateUrl: './auth-form.html',
9 | controller: 'AuthFormController'
10 | };
11 |
12 | angular
13 | .module('components.auth')
14 | .component('authForm', authForm);
15 |
--------------------------------------------------------------------------------
/09/app/components/auth/auth-form/auth-form.controller.js:
--------------------------------------------------------------------------------
1 | function AuthFormController() {
2 | var ctrl = this;
3 | ctrl.$onChanges = function (changes) {
4 | if (changes.user) {
5 | ctrl.user = angular.copy(ctrl.user);
6 | }
7 | };
8 | ctrl.submitForm = function () {
9 | ctrl.onSubmit({
10 | $event: {
11 | user: ctrl.user
12 | }
13 | });
14 | };
15 | }
16 |
17 | angular
18 | .module('components.auth')
19 | .controller('AuthFormController', AuthFormController);
20 |
--------------------------------------------------------------------------------
/09/app/components/auth/auth-form/auth-form.html:
--------------------------------------------------------------------------------
1 |
27 |
--------------------------------------------------------------------------------
/09/app/components/auth/auth.service.js:
--------------------------------------------------------------------------------
1 | function AuthService($firebaseAuth) {
2 | var auth = $firebaseAuth();
3 | var authData = null;
4 | function storeAuthData(response) {
5 | authData = response;
6 | return authData;
7 | }
8 | function onSignIn(user) {
9 | authData = user;
10 | return auth.$requireSignIn();
11 | }
12 | function clearAuthData() {
13 | authData = null;
14 | }
15 | this.login = function (user) {
16 | return auth
17 | .$signInWithEmailAndPassword(user.email, user.password)
18 | .then(storeAuthData);
19 | };
20 | this.register = function (user) {
21 | return auth
22 | .$createUserWithEmailAndPassword(user.email, user.password)
23 | .then(storeAuthData);
24 | };
25 | this.logout = function () {
26 | return auth
27 | .$signOut()
28 | .then(clearAuthData);
29 | };
30 | this.requireAuthentication = function () {
31 | return auth
32 | .$waitForSignIn().then(onSignIn);
33 | };
34 | this.isAuthenticated = function () {
35 | return !!authData;
36 | };
37 | this.getUser = function () {
38 | if (authData) {
39 | return authData;
40 | }
41 | };
42 | }
43 |
44 | angular
45 | .module('components.auth')
46 | .service('AuthService', AuthService);
47 |
--------------------------------------------------------------------------------
/09/app/components/auth/login/login.component.js:
--------------------------------------------------------------------------------
1 | var login = {
2 | templateUrl: './login.html',
3 | controller: 'LoginController'
4 | };
5 |
6 | angular
7 | .module('components.auth')
8 | .component('login', login)
9 | .config(function ($stateProvider, $urlRouterProvider) {
10 | $stateProvider
11 | .state('auth', {
12 | redirectTo: 'auth.login',
13 | url: '/auth',
14 | template: ''
15 | })
16 | .state('auth.login', {
17 | url: '/login',
18 | component: 'login'
19 | });
20 | $urlRouterProvider.otherwise('/auth/login');
21 | });
22 |
--------------------------------------------------------------------------------
/09/app/components/auth/login/login.controller.js:
--------------------------------------------------------------------------------
1 | function LoginController(AuthService, $state) {
2 | var ctrl = this;
3 | ctrl.$onInit = function () {
4 | ctrl.error = null;
5 | ctrl.user = {
6 | email: '',
7 | password: ''
8 | };
9 | };
10 | ctrl.loginUser = function (event) {
11 | return AuthService
12 | .login(event.user)
13 | .then(function () {
14 | $state.go('app');
15 | }, function (reason) {
16 | ctrl.error = reason.message;
17 | });
18 | };
19 | }
20 |
21 | angular
22 | .module('components.auth')
23 | .controller('LoginController', LoginController);
24 |
--------------------------------------------------------------------------------
/09/app/components/auth/login/login.html:
--------------------------------------------------------------------------------
1 |
10 |
15 |
--------------------------------------------------------------------------------
/09/app/components/auth/register/register.component.js:
--------------------------------------------------------------------------------
1 | var register = {
2 | templateUrl: './register.html',
3 | controller: 'RegisterController'
4 | };
5 |
6 | angular
7 | .module('components.auth')
8 | .component('register', register)
9 | .config(function ($stateProvider) {
10 | $stateProvider
11 | .state('auth.register', {
12 | url: '/register',
13 | component: 'register'
14 | });
15 | });
16 |
--------------------------------------------------------------------------------
/09/app/components/auth/register/register.controller.js:
--------------------------------------------------------------------------------
1 | function RegisterController(AuthService, $state) {
2 | var ctrl = this;
3 | ctrl.$onInit = function () {
4 | ctrl.error = null;
5 | ctrl.user = {
6 | email: '',
7 | password: ''
8 | };
9 | };
10 | ctrl.createUser = function (event) {
11 | return AuthService
12 | .register(event.user)
13 | .then(function () {
14 | $state.go('app');
15 | }, function (reason) {
16 | ctrl.error = reason.message;
17 | });
18 | };
19 | }
20 |
21 | angular
22 | .module('components.auth')
23 | .controller('RegisterController', RegisterController);
24 |
--------------------------------------------------------------------------------
/09/app/components/auth/register/register.html:
--------------------------------------------------------------------------------
1 |
10 |
15 |
--------------------------------------------------------------------------------
/09/app/components/components.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('components', [
3 | 'components.contact',
4 | 'components.auth'
5 | ]);
6 |
--------------------------------------------------------------------------------
/09/app/components/contact/contact-detail/contact-detail.component.js:
--------------------------------------------------------------------------------
1 | var contactDetail = {
2 | bindings: {
3 | contact: '<',
4 | onSave: '&',
5 | onUpdate: '&',
6 | onDelete: '&'
7 | },
8 | templateUrl: './contact-detail.html',
9 | controller: 'ContactDetailController'
10 | };
11 |
12 | angular
13 | .module('components.contact')
14 | .component('contactDetail', contactDetail);
15 |
--------------------------------------------------------------------------------
/09/app/components/contact/contact-detail/contact-detail.controller.js:
--------------------------------------------------------------------------------
1 | function ContactDetailController() {
2 | var ctrl = this;
3 | ctrl.$onInit = function () {
4 | ctrl.isNewContact = !ctrl.contact.$id;
5 | };
6 | ctrl.saveContact = function () {
7 | ctrl.onSave({
8 | $event: {
9 | contact: ctrl.contact
10 | }
11 | });
12 | };
13 | ctrl.updateContact = function () {
14 | ctrl.onUpdate({
15 | $event: {
16 | contact: ctrl.contact
17 | }
18 | });
19 | };
20 | ctrl.deleteContact = function () {
21 | ctrl.onDelete({
22 | $event: {
23 | contact: ctrl.contact
24 | }
25 | });
26 | };
27 | ctrl.tagChange = function (event) {
28 | ctrl.contact.tag = event.tag;
29 | ctrl.updateContact();
30 | }
31 | }
32 |
33 | angular
34 | .module('components.contact')
35 | .controller('ContactDetailController', ContactDetailController);
36 |
--------------------------------------------------------------------------------
/09/app/components/contact/contact-edit/contact-edit.component.js:
--------------------------------------------------------------------------------
1 | var contactEdit = {
2 | bindings: {
3 | contact: '<'
4 | },
5 | templateUrl: './contact-edit.html',
6 | controller: 'ContactEditController'
7 | };
8 |
9 | angular
10 | .module('components.contact')
11 | .component('contactEdit', contactEdit)
12 | .config(function ($stateProvider) {
13 | $stateProvider
14 | .state('contact', {
15 | parent: 'app',
16 | url: '/contact/:id',
17 | component: 'contactEdit',
18 | resolve: {
19 | contact: function ($transition$, ContactService) {
20 | var key = $transition$.params().id;
21 | return ContactService.getContactById(key).$loaded();
22 | }
23 | }
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/09/app/components/contact/contact-edit/contact-edit.controller.js:
--------------------------------------------------------------------------------
1 | function ContactEditController($state, ContactService, cfpLoadingBar, $window) {
2 | var ctrl = this;
3 | ctrl.updateContact = function (event) {
4 | cfpLoadingBar.start();
5 | return ContactService
6 | .updateContact(event.contact)
7 | .then(cfpLoadingBar.complete, cfpLoadingBar.complete);
8 | };
9 | ctrl.deleteContact = function (event) {
10 | var message = 'Delete ' + event.contact.name + ' from contacts?';
11 | if ($window.confirm(message)) {
12 | return ContactService
13 | .deleteContact(event.contact)
14 | .then(function () {
15 | $state.go('contacts');
16 | });
17 | }
18 | };
19 | }
20 |
21 | angular
22 | .module('components.contact')
23 | .controller('ContactEditController', ContactEditController);
24 |
--------------------------------------------------------------------------------
/09/app/components/contact/contact-edit/contact-edit.html:
--------------------------------------------------------------------------------
1 |
5 |
6 |
--------------------------------------------------------------------------------
/09/app/components/contact/contact-new/contact-new.component.js:
--------------------------------------------------------------------------------
1 | var contactNew = {
2 | templateUrl: './contact-new.html',
3 | controller: 'ContactNewController'
4 | };
5 |
6 | angular
7 | .module('components.contact')
8 | .component('contactNew', contactNew)
9 | .config(function ($stateProvider) {
10 | $stateProvider
11 | .state('new', {
12 | parent: 'app',
13 | url: '/new',
14 | component: 'contactNew'
15 | });
16 | });
17 |
--------------------------------------------------------------------------------
/09/app/components/contact/contact-new/contact-new.controller.js:
--------------------------------------------------------------------------------
1 | function ContactNewController(ContactService, $state) {
2 | var ctrl = this;
3 | ctrl.$onInit = function () {
4 | ctrl.contact = {
5 | name: '',
6 | email: '',
7 | job: '',
8 | location: '',
9 | social: {
10 | facebook: '',
11 | github: '',
12 | twitter: '',
13 | linkedin: ''
14 | },
15 | tag: 'none'
16 | };
17 | };
18 | ctrl.createNewContact = function (event) {
19 | return ContactService
20 | .createNewContact(event.contact)
21 | .then(function (contact) {
22 | $state.go('contact', {
23 | id: contact.key
24 | });
25 | });
26 | };
27 | }
28 |
29 | angular
30 | .module('components.contact')
31 | .controller('ContactNewController', ContactNewController);
32 |
--------------------------------------------------------------------------------
/09/app/components/contact/contact-new/contact-new.html:
--------------------------------------------------------------------------------
1 |
4 |
5 |
--------------------------------------------------------------------------------
/09/app/components/contact/contact-tag/contact-tag.component.js:
--------------------------------------------------------------------------------
1 | var contactTag = {
2 | bindings: {
3 | tag: '<',
4 | onChange: '&'
5 | },
6 | templateUrl: './contact-tag.html',
7 | controller: 'ContactTagController'
8 | };
9 |
10 | angular
11 | .module('components.contact')
12 | .component('contactTag', contactTag);
13 |
--------------------------------------------------------------------------------
/09/app/components/contact/contact-tag/contact-tag.controller.js:
--------------------------------------------------------------------------------
1 | function ContactTagController() {
2 | var ctrl = this;
3 | ctrl.$onInit = function () {
4 | ctrl.tags = [
5 | 'friends', 'family', 'acquaintances', 'following'
6 | ];
7 | };
8 | ctrl.$onChanges = function (changes) {
9 | if (changes.tag) {
10 | ctrl.tag = angular.copy(ctrl.tag);
11 | }
12 | };
13 | ctrl.updateTag = function (tag) {
14 | ctrl.onChange({
15 | $event: {
16 | tag: tag
17 | }
18 | });
19 | };
20 | }
21 |
22 | angular
23 | .module('components.contact')
24 | .controller('ContactTagController', ContactTagController);
25 |
--------------------------------------------------------------------------------
/09/app/components/contact/contact-tag/contact-tag.html:
--------------------------------------------------------------------------------
1 |
18 |
--------------------------------------------------------------------------------
/09/app/components/contact/contact.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('components.contact', [
3 | 'ui.router'
4 | ]);
5 |
--------------------------------------------------------------------------------
/09/app/components/contact/contact.service.js:
--------------------------------------------------------------------------------
1 | function ContactService(AuthService, $firebaseRef, $firebaseArray, $firebaseObject) {
2 | var ref = $firebaseRef.contacts;
3 | var uid = AuthService.getUser().uid;
4 | return {
5 | createNewContact: function (contact) {
6 | return $firebaseArray(ref.child(uid)).$add(contact);
7 | },
8 | getContactById: function (id) {
9 | return $firebaseObject(ref.child(uid).child(id));
10 | },
11 | getContactList: function () {
12 | return $firebaseArray(ref.child(uid));
13 | },
14 | updateContact: function (contact) {
15 | return contact.$save();
16 | },
17 | deleteContact: function (contact) {
18 | return contact.$remove();
19 | }
20 | };
21 | }
22 |
23 | angular
24 | .module('components.contact')
25 | .factory('ContactService', ContactService);
26 |
--------------------------------------------------------------------------------
/09/app/components/contact/contact/contact.component.js:
--------------------------------------------------------------------------------
1 | var contact = {
2 | bindings: {
3 | contact: '<',
4 | onSelect: '&'
5 | },
6 | templateUrl: './contact.html',
7 | controller: 'ContactController'
8 | };
9 |
10 | angular
11 | .module('components.contact')
12 | .component('contact', contact);
13 |
--------------------------------------------------------------------------------
/09/app/components/contact/contact/contact.controller.js:
--------------------------------------------------------------------------------
1 | function ContactController() {
2 | var ctrl = this;
3 | ctrl.selectContact = function () {
4 | ctrl.onSelect({
5 | $event: {
6 | contactId: ctrl.contact.$id
7 | }
8 | });
9 | };
10 | }
11 |
12 | angular
13 | .module('components.contact')
14 | .controller('ContactController', ContactController);
15 |
--------------------------------------------------------------------------------
/09/app/components/contact/contact/contact.html:
--------------------------------------------------------------------------------
1 |
17 |
--------------------------------------------------------------------------------
/09/app/components/contact/contacts/contacts.component.js:
--------------------------------------------------------------------------------
1 | var contacts = {
2 | bindings: {
3 | contacts: '<',
4 | filter: '<'
5 | },
6 | templateUrl: './contacts.html',
7 | controller: 'ContactsController'
8 | };
9 |
10 | angular
11 | .module('components.contact')
12 | .component('contacts', contacts)
13 | .config(function ($stateProvider) {
14 | $stateProvider
15 | .state('contacts', {
16 | parent: 'app',
17 | url: '/contacts?filter',
18 | component: 'contacts',
19 | params: {
20 | filter: {
21 | value: 'none'
22 | }
23 | },
24 | resolve: {
25 | contacts: function (ContactService) {
26 | return ContactService.getContactList().$loaded();
27 | },
28 | filter: function ($transition$) {
29 | return $transition$.params();
30 | }
31 | }
32 | });
33 | });
34 |
--------------------------------------------------------------------------------
/09/app/components/contact/contacts/contacts.controller.js:
--------------------------------------------------------------------------------
1 | function ContactsController($filter, $state) {
2 | var ctrl = this;
3 | var contacts = ctrl.contacts;
4 |
5 | ctrl.filteredContacts = $filter('contactsFilter')(contacts, ctrl.filter);
6 |
7 | ctrl.goToContact = function (event) {
8 | $state.go('contact', {
9 | id: event.contactId
10 | });
11 | };
12 | }
13 |
14 | angular
15 | .module('components.contact')
16 | .controller('ContactsController', ContactsController);
17 |
--------------------------------------------------------------------------------
/09/app/components/contact/contacts/contacts.filter.js:
--------------------------------------------------------------------------------
1 | function contactsFilter() {
2 | return function (collection, params) {
3 | return collection.filter(function (item) {
4 | return item.tag === (
5 | params.filter === 'none' ? item.tag : params.filter
6 | );
7 | });
8 | };
9 | }
10 |
11 | angular
12 | .module('components.contact')
13 | .filter('contactsFilter', contactsFilter);
14 |
--------------------------------------------------------------------------------
/09/app/components/contact/contacts/contacts.html:
--------------------------------------------------------------------------------
1 |
17 |
--------------------------------------------------------------------------------
/09/app/root.component.js:
--------------------------------------------------------------------------------
1 | var root = {
2 | templateUrl: './root.html'
3 | };
4 |
5 | angular
6 | .module('root')
7 | .component('root', root);
8 |
--------------------------------------------------------------------------------
/09/app/root.html:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/09/app/root.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('root', [
3 | 'common',
4 | 'components',
5 | 'templates'
6 | ]);
7 |
--------------------------------------------------------------------------------
/10/app/common/app-nav.component.js:
--------------------------------------------------------------------------------
1 | var appNav = {
2 | bindings: {
3 | user: '<',
4 | onLogout: '&'
5 | },
6 | templateUrl: './app-nav.html'
7 | };
8 |
9 | angular
10 | .module('common')
11 | .component('appNav', appNav);
12 |
--------------------------------------------------------------------------------
/10/app/common/app-nav.html:
--------------------------------------------------------------------------------
1 |
23 |
--------------------------------------------------------------------------------
/10/app/common/app-sidebar.component.js:
--------------------------------------------------------------------------------
1 | var appSidebar = {
2 | templateUrl: './app-sidebar.html',
3 | controller: 'AppSidebarController'
4 | };
5 |
6 | angular
7 | .module('common')
8 | .component('appSidebar', appSidebar);
9 |
--------------------------------------------------------------------------------
/10/app/common/app-sidebar.controller.js:
--------------------------------------------------------------------------------
1 | function AppSidebarController() {
2 | var ctrl = this;
3 | ctrl.contactTags = [{
4 | label: 'All contacts',
5 | icon: 'star',
6 | state: 'none'
7 | }, {
8 | label: 'Friends',
9 | icon: 'people',
10 | state: 'friends'
11 | }, {
12 | label: 'Family',
13 | icon: 'child_care',
14 | state: 'family'
15 | }, {
16 | label: 'Acquaintances',
17 | icon: 'accessibility',
18 | state: 'acquaintances'
19 | }, {
20 | label: 'Following',
21 | icon: 'remove_red_eye',
22 | state: 'following'
23 | }];
24 | }
25 |
26 | angular
27 | .module('common')
28 | .controller('AppSidebarController', AppSidebarController);
29 |
--------------------------------------------------------------------------------
/10/app/common/app-sidebar.html:
--------------------------------------------------------------------------------
1 |
26 |
--------------------------------------------------------------------------------
/10/app/common/app.component.js:
--------------------------------------------------------------------------------
1 | var app = {
2 | templateUrl: './app.html',
3 | controller: 'AppController'
4 | };
5 |
6 | angular
7 | .module('common')
8 | .component('app', app)
9 | .config(function ($stateProvider) {
10 | $stateProvider
11 | .state('app', {
12 | redirectTo: 'contacts',
13 | url: '/app',
14 | data: {
15 | requiredAuth: true
16 | },
17 | component: 'app'
18 | })
19 | });
20 |
--------------------------------------------------------------------------------
/10/app/common/app.controller.js:
--------------------------------------------------------------------------------
1 | function AppController(AuthService, $state) {
2 | var ctrl = this;
3 | ctrl.user = AuthService.getUser();
4 | ctrl.logout = function () {
5 | AuthService.logout().then(function () {
6 | $state.go('auth.login');
7 | });
8 | };
9 | }
10 |
11 | angular
12 | .module('common')
13 | .controller('AppController', AppController);
14 |
--------------------------------------------------------------------------------
/10/app/common/app.html:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/10/app/common/app.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('common', [
3 | 'ui.router',
4 | 'angular-loading-bar'
5 | ])
6 | .run(function ($transitions, cfpLoadingBar) {
7 | $transitions.onStart({}, cfpLoadingBar.start);
8 | $transitions.onSuccess({}, cfpLoadingBar.complete);
9 | });
10 |
--------------------------------------------------------------------------------
/10/app/components/auth/auth-form/auth-form.component.js:
--------------------------------------------------------------------------------
1 | var authForm = {
2 | bindings: {
3 | user: '<',
4 | button: '@',
5 | message: '@',
6 | onSubmit: '&'
7 | },
8 | templateUrl: './auth-form.html',
9 | controller: 'AuthFormController'
10 | };
11 |
12 | angular
13 | .module('components.auth')
14 | .component('authForm', authForm);
15 |
--------------------------------------------------------------------------------
/10/app/components/auth/auth-form/auth-form.controller.js:
--------------------------------------------------------------------------------
1 | function AuthFormController() {
2 | var ctrl = this;
3 | ctrl.$onChanges = function (changes) {
4 | if (changes.user) {
5 | ctrl.user = angular.copy(ctrl.user);
6 | }
7 | };
8 | ctrl.submitForm = function () {
9 | ctrl.onSubmit({
10 | $event: {
11 | user: ctrl.user
12 | }
13 | });
14 | };
15 | }
16 |
17 | angular
18 | .module('components.auth')
19 | .controller('AuthFormController', AuthFormController);
20 |
--------------------------------------------------------------------------------
/10/app/components/auth/auth-form/auth-form.html:
--------------------------------------------------------------------------------
1 |
27 |
--------------------------------------------------------------------------------
/10/app/components/auth/auth.service.js:
--------------------------------------------------------------------------------
1 | function AuthService($firebaseAuth) {
2 | var auth = $firebaseAuth();
3 | var authData = null;
4 | function storeAuthData(response) {
5 | authData = response;
6 | return authData;
7 | }
8 | function onSignIn(user) {
9 | authData = user;
10 | return auth.$requireSignIn();
11 | }
12 | function clearAuthData() {
13 | authData = null;
14 | }
15 | this.login = function (user) {
16 | return auth
17 | .$signInWithEmailAndPassword(user.email, user.password)
18 | .then(storeAuthData);
19 | };
20 | this.register = function (user) {
21 | return auth
22 | .$createUserWithEmailAndPassword(user.email, user.password)
23 | .then(storeAuthData);
24 | };
25 | this.logout = function () {
26 | return auth
27 | .$signOut()
28 | .then(clearAuthData);
29 | };
30 | this.requireAuthentication = function () {
31 | return auth
32 | .$waitForSignIn().then(onSignIn);
33 | };
34 | this.isAuthenticated = function () {
35 | return !!authData;
36 | };
37 | this.getUser = function () {
38 | if (authData) {
39 | return authData;
40 | }
41 | };
42 | }
43 |
44 | angular
45 | .module('components.auth')
46 | .service('AuthService', AuthService);
47 |
--------------------------------------------------------------------------------
/10/app/components/auth/login/login.component.js:
--------------------------------------------------------------------------------
1 | var login = {
2 | templateUrl: './login.html',
3 | controller: 'LoginController'
4 | };
5 |
6 | angular
7 | .module('components.auth')
8 | .component('login', login)
9 | .config(function ($stateProvider, $urlRouterProvider) {
10 | $stateProvider
11 | .state('auth', {
12 | redirectTo: 'auth.login',
13 | url: '/auth',
14 | template: ''
15 | })
16 | .state('auth.login', {
17 | url: '/login',
18 | component: 'login'
19 | });
20 | $urlRouterProvider.otherwise('/auth/login');
21 | });
22 |
--------------------------------------------------------------------------------
/10/app/components/auth/login/login.controller.js:
--------------------------------------------------------------------------------
1 | function LoginController(AuthService, $state) {
2 | var ctrl = this;
3 | ctrl.$onInit = function () {
4 | ctrl.error = null;
5 | ctrl.user = {
6 | email: '',
7 | password: ''
8 | };
9 | };
10 | ctrl.loginUser = function (event) {
11 | return AuthService
12 | .login(event.user)
13 | .then(function () {
14 | $state.go('app');
15 | }, function (reason) {
16 | ctrl.error = reason.message;
17 | });
18 | };
19 | }
20 |
21 | angular
22 | .module('components.auth')
23 | .controller('LoginController', LoginController);
24 |
--------------------------------------------------------------------------------
/10/app/components/auth/login/login.html:
--------------------------------------------------------------------------------
1 |
10 |
15 |
--------------------------------------------------------------------------------
/10/app/components/auth/register/register.component.js:
--------------------------------------------------------------------------------
1 | var register = {
2 | templateUrl: './register.html',
3 | controller: 'RegisterController'
4 | };
5 |
6 | angular
7 | .module('components.auth')
8 | .component('register', register)
9 | .config(function ($stateProvider) {
10 | $stateProvider
11 | .state('auth.register', {
12 | url: '/register',
13 | component: 'register'
14 | });
15 | });
16 |
--------------------------------------------------------------------------------
/10/app/components/auth/register/register.controller.js:
--------------------------------------------------------------------------------
1 | function RegisterController(AuthService, $state) {
2 | var ctrl = this;
3 | ctrl.$onInit = function () {
4 | ctrl.error = null;
5 | ctrl.user = {
6 | email: '',
7 | password: ''
8 | };
9 | };
10 | ctrl.createUser = function (event) {
11 | return AuthService
12 | .register(event.user)
13 | .then(function () {
14 | $state.go('app');
15 | }, function (reason) {
16 | ctrl.error = reason.message;
17 | });
18 | };
19 | }
20 |
21 | angular
22 | .module('components.auth')
23 | .controller('RegisterController', RegisterController);
24 |
--------------------------------------------------------------------------------
/10/app/components/auth/register/register.html:
--------------------------------------------------------------------------------
1 |
10 |
15 |
--------------------------------------------------------------------------------
/10/app/components/components.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('components', [
3 | 'components.contact',
4 | 'components.auth'
5 | ]);
6 |
--------------------------------------------------------------------------------
/10/app/components/contact/contact-detail/contact-detail.component.js:
--------------------------------------------------------------------------------
1 | var contactDetail = {
2 | bindings: {
3 | contact: '<',
4 | onSave: '&',
5 | onUpdate: '&',
6 | onDelete: '&'
7 | },
8 | templateUrl: './contact-detail.html',
9 | controller: 'ContactDetailController'
10 | };
11 |
12 | angular
13 | .module('components.contact')
14 | .component('contactDetail', contactDetail);
15 |
--------------------------------------------------------------------------------
/10/app/components/contact/contact-detail/contact-detail.controller.js:
--------------------------------------------------------------------------------
1 | function ContactDetailController() {
2 | var ctrl = this;
3 | ctrl.$onInit = function () {
4 | ctrl.isNewContact = !ctrl.contact.$id;
5 | };
6 | ctrl.saveContact = function () {
7 | ctrl.onSave({
8 | $event: {
9 | contact: ctrl.contact
10 | }
11 | });
12 | };
13 | ctrl.updateContact = function () {
14 | ctrl.onUpdate({
15 | $event: {
16 | contact: ctrl.contact
17 | }
18 | });
19 | };
20 | ctrl.deleteContact = function () {
21 | ctrl.onDelete({
22 | $event: {
23 | contact: ctrl.contact
24 | }
25 | });
26 | };
27 | ctrl.tagChange = function (event) {
28 | ctrl.contact.tag = event.tag;
29 | ctrl.updateContact();
30 | }
31 | }
32 |
33 | angular
34 | .module('components.contact')
35 | .controller('ContactDetailController', ContactDetailController);
36 |
--------------------------------------------------------------------------------
/10/app/components/contact/contact-edit/contact-edit.component.js:
--------------------------------------------------------------------------------
1 | var contactEdit = {
2 | bindings: {
3 | contact: '<'
4 | },
5 | templateUrl: './contact-edit.html',
6 | controller: 'ContactEditController'
7 | };
8 |
9 | angular
10 | .module('components.contact')
11 | .component('contactEdit', contactEdit)
12 | .config(function ($stateProvider) {
13 | $stateProvider
14 | .state('contact', {
15 | parent: 'app',
16 | url: '/contact/:id',
17 | component: 'contactEdit',
18 | resolve: {
19 | contact: function ($transition$, ContactService) {
20 | var key = $transition$.params().id;
21 | return ContactService.getContactById(key).$loaded();
22 | }
23 | }
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/10/app/components/contact/contact-edit/contact-edit.controller.js:
--------------------------------------------------------------------------------
1 | function ContactEditController($state, ContactService, cfpLoadingBar, $window) {
2 | var ctrl = this;
3 | ctrl.updateContact = function (event) {
4 | cfpLoadingBar.start();
5 | return ContactService
6 | .updateContact(event.contact)
7 | .then(cfpLoadingBar.complete, cfpLoadingBar.complete);
8 | };
9 | ctrl.deleteContact = function (event) {
10 | var message = 'Delete ' + event.contact.name + ' from contacts?';
11 | if ($window.confirm(message)) {
12 | return ContactService
13 | .deleteContact(event.contact)
14 | .then(function () {
15 | $state.go('contacts');
16 | });
17 | }
18 | };
19 | }
20 |
21 | angular
22 | .module('components.contact')
23 | .controller('ContactEditController', ContactEditController);
24 |
--------------------------------------------------------------------------------
/10/app/components/contact/contact-edit/contact-edit.html:
--------------------------------------------------------------------------------
1 |
5 |
6 |
--------------------------------------------------------------------------------
/10/app/components/contact/contact-new/contact-new.component.js:
--------------------------------------------------------------------------------
1 | var contactNew = {
2 | templateUrl: './contact-new.html',
3 | controller: 'ContactNewController'
4 | };
5 |
6 | angular
7 | .module('components.contact')
8 | .component('contactNew', contactNew)
9 | .config(function ($stateProvider) {
10 | $stateProvider
11 | .state('new', {
12 | parent: 'app',
13 | url: '/new',
14 | component: 'contactNew'
15 | });
16 | });
17 |
--------------------------------------------------------------------------------
/10/app/components/contact/contact-new/contact-new.controller.js:
--------------------------------------------------------------------------------
1 | function ContactNewController(ContactService, $state) {
2 | var ctrl = this;
3 | ctrl.$onInit = function () {
4 | ctrl.contact = {
5 | name: '',
6 | email: '',
7 | job: '',
8 | location: '',
9 | social: {
10 | facebook: '',
11 | github: '',
12 | twitter: '',
13 | linkedin: ''
14 | },
15 | tag: 'none'
16 | };
17 | };
18 | ctrl.createNewContact = function (event) {
19 | return ContactService
20 | .createNewContact(event.contact)
21 | .then(function (contact) {
22 | $state.go('contact', {
23 | id: contact.key
24 | });
25 | });
26 | };
27 | }
28 |
29 | angular
30 | .module('components.contact')
31 | .controller('ContactNewController', ContactNewController);
32 |
--------------------------------------------------------------------------------
/10/app/components/contact/contact-new/contact-new.html:
--------------------------------------------------------------------------------
1 |
4 |
5 |
--------------------------------------------------------------------------------
/10/app/components/contact/contact-tag/contact-tag.component.js:
--------------------------------------------------------------------------------
1 | var contactTag = {
2 | bindings: {
3 | tag: '<',
4 | onChange: '&'
5 | },
6 | templateUrl: './contact-tag.html',
7 | controller: 'ContactTagController'
8 | };
9 |
10 | angular
11 | .module('components.contact')
12 | .component('contactTag', contactTag);
13 |
--------------------------------------------------------------------------------
/10/app/components/contact/contact-tag/contact-tag.controller.js:
--------------------------------------------------------------------------------
1 | function ContactTagController() {
2 | var ctrl = this;
3 | ctrl.$onInit = function () {
4 | ctrl.tags = [
5 | 'friends', 'family', 'acquaintances', 'following'
6 | ];
7 | };
8 | ctrl.$onChanges = function (changes) {
9 | if (changes.tag) {
10 | ctrl.tag = angular.copy(ctrl.tag);
11 | }
12 | };
13 | ctrl.updateTag = function (tag) {
14 | ctrl.onChange({
15 | $event: {
16 | tag: tag
17 | }
18 | });
19 | };
20 | }
21 |
22 | angular
23 | .module('components.contact')
24 | .controller('ContactTagController', ContactTagController);
25 |
--------------------------------------------------------------------------------
/10/app/components/contact/contact-tag/contact-tag.html:
--------------------------------------------------------------------------------
1 |
18 |
--------------------------------------------------------------------------------
/10/app/components/contact/contact.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('components.contact', [
3 | 'ui.router'
4 | ]);
5 |
--------------------------------------------------------------------------------
/10/app/components/contact/contact.service.js:
--------------------------------------------------------------------------------
1 | function ContactService(AuthService, $firebaseRef, $firebaseArray, $firebaseObject) {
2 | var ref = $firebaseRef.contacts;
3 | var uid = AuthService.getUser().uid;
4 | return {
5 | createNewContact: function (contact) {
6 | return $firebaseArray(ref.child(uid)).$add(contact);
7 | },
8 | getContactById: function (id) {
9 | return $firebaseObject(ref.child(uid).child(id));
10 | },
11 | getContactList: function () {
12 | return $firebaseArray(ref.child(uid));
13 | },
14 | updateContact: function (contact) {
15 | return contact.$save();
16 | },
17 | deleteContact: function (contact) {
18 | return contact.$remove();
19 | }
20 | };
21 | }
22 |
23 | angular
24 | .module('components.contact')
25 | .factory('ContactService', ContactService);
26 |
--------------------------------------------------------------------------------
/10/app/components/contact/contact/contact.component.js:
--------------------------------------------------------------------------------
1 | var contact = {
2 | bindings: {
3 | contact: '<',
4 | onSelect: '&'
5 | },
6 | templateUrl: './contact.html',
7 | controller: 'ContactController'
8 | };
9 |
10 | angular
11 | .module('components.contact')
12 | .component('contact', contact);
13 |
--------------------------------------------------------------------------------
/10/app/components/contact/contact/contact.controller.js:
--------------------------------------------------------------------------------
1 | function ContactController() {
2 | var ctrl = this;
3 | ctrl.selectContact = function () {
4 | ctrl.onSelect({
5 | $event: {
6 | contactId: ctrl.contact.$id
7 | }
8 | });
9 | };
10 | }
11 |
12 | angular
13 | .module('components.contact')
14 | .controller('ContactController', ContactController);
15 |
--------------------------------------------------------------------------------
/10/app/components/contact/contact/contact.html:
--------------------------------------------------------------------------------
1 |
17 |
--------------------------------------------------------------------------------
/10/app/components/contact/contacts/contacts.component.js:
--------------------------------------------------------------------------------
1 | var contacts = {
2 | bindings: {
3 | contacts: '<',
4 | filter: '<'
5 | },
6 | templateUrl: './contacts.html',
7 | controller: 'ContactsController'
8 | };
9 |
10 | angular
11 | .module('components.contact')
12 | .component('contacts', contacts)
13 | .config(function ($stateProvider) {
14 | $stateProvider
15 | .state('contacts', {
16 | parent: 'app',
17 | url: '/contacts?filter',
18 | component: 'contacts',
19 | params: {
20 | filter: {
21 | value: 'none'
22 | }
23 | },
24 | resolve: {
25 | contacts: function (ContactService) {
26 | return ContactService.getContactList().$loaded();
27 | },
28 | filter: function ($transition$) {
29 | return $transition$.params();
30 | }
31 | }
32 | });
33 | });
34 |
--------------------------------------------------------------------------------
/10/app/components/contact/contacts/contacts.controller.js:
--------------------------------------------------------------------------------
1 | function ContactsController($filter, $state) {
2 | var ctrl = this;
3 | var contacts = ctrl.contacts;
4 |
5 | ctrl.filteredContacts = $filter('contactsFilter')(contacts, ctrl.filter);
6 |
7 | ctrl.goToContact = function (event) {
8 | $state.go('contact', {
9 | id: event.contactId
10 | });
11 | };
12 | }
13 |
14 | angular
15 | .module('components.contact')
16 | .controller('ContactsController', ContactsController);
17 |
--------------------------------------------------------------------------------
/10/app/components/contact/contacts/contacts.filter.js:
--------------------------------------------------------------------------------
1 | function contactsFilter() {
2 | return function (collection, params) {
3 | return collection.filter(function (item) {
4 | return item.tag === (
5 | params.filter === 'none' ? item.tag : params.filter
6 | );
7 | });
8 | };
9 | }
10 |
11 | angular
12 | .module('components.contact')
13 | .filter('contactsFilter', contactsFilter);
14 |
--------------------------------------------------------------------------------
/10/app/components/contact/contacts/contacts.html:
--------------------------------------------------------------------------------
1 |
17 |
--------------------------------------------------------------------------------
/10/app/components/contact/length-check/length-check.directive.js:
--------------------------------------------------------------------------------
1 | function lengthCheck() {
2 | return {
3 | restrict: 'A',
4 | require: 'ngModel',
5 | compile: function ($element) {
6 | $element.addClass('dynamic-input');
7 | return function ($scope, $element, $attrs, $ctrl) {
8 | var dynamicClass = 'dynamic-input--no-contents';
9 | $scope.$watch(function () {
10 | return $ctrl.$viewValue;
11 | }, function (newValue) {
12 | if (newValue) {
13 | $element.removeClass(dynamicClass);
14 | } else {
15 | $element.addClass(dynamicClass);
16 | }
17 | });
18 | };
19 | }
20 | };
21 | }
22 |
23 | angular
24 | .module('components.contact')
25 | .directive('lengthCheck', lengthCheck);
26 |
--------------------------------------------------------------------------------
/10/app/root.component.js:
--------------------------------------------------------------------------------
1 | var root = {
2 | templateUrl: './root.html'
3 | };
4 |
5 | angular
6 | .module('root')
7 | .component('root', root);
8 |
--------------------------------------------------------------------------------
/10/app/root.html:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/10/app/root.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('root', [
3 | 'common',
4 | 'components',
5 | 'templates'
6 | ]);
7 |
--------------------------------------------------------------------------------
/src/app/common/app.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('common', [
3 | 'ui.router'
4 | ]);
5 |
--------------------------------------------------------------------------------
/src/app/components/auth/auth.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('components.auth', [
3 | 'ui.router',
4 | 'firebase'
5 | ]);
6 |
--------------------------------------------------------------------------------
/src/app/components/components.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('components', [
3 | 'components.contact',
4 | 'components.auth'
5 | ]);
6 |
--------------------------------------------------------------------------------
/src/app/components/contact/contact.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('components.contact', [
3 | 'ui.router'
4 | ]);
5 |
--------------------------------------------------------------------------------
/src/app/root.component.js:
--------------------------------------------------------------------------------
1 | var root = {
2 | templateUrl: './root.html'
3 | };
4 |
5 | angular
6 | .module('root')
7 | .component('root', root);
8 |
--------------------------------------------------------------------------------
/src/app/root.html:
--------------------------------------------------------------------------------
1 |
2 | Hello world!
3 |
4 |
--------------------------------------------------------------------------------
/src/app/root.module.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('root', [
3 | 'common',
4 | 'components',
5 | 'templates'
6 | ]);
7 |
--------------------------------------------------------------------------------
/src/fonts/MaterialIcons-Regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ultimatecourses/ultimate-angular-master-seed/a72b7ddfa3bbbb2ac30934d14e57ab8a6f049331/src/fonts/MaterialIcons-Regular.eot
--------------------------------------------------------------------------------
/src/fonts/MaterialIcons-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ultimatecourses/ultimate-angular-master-seed/a72b7ddfa3bbbb2ac30934d14e57ab8a6f049331/src/fonts/MaterialIcons-Regular.ttf
--------------------------------------------------------------------------------
/src/fonts/MaterialIcons-Regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ultimatecourses/ultimate-angular-master-seed/a72b7ddfa3bbbb2ac30934d14e57ab8a6f049331/src/fonts/MaterialIcons-Regular.woff
--------------------------------------------------------------------------------
/src/fonts/MaterialIcons-Regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ultimatecourses/ultimate-angular-master-seed/a72b7ddfa3bbbb2ac30934d14e57ab8a6f049331/src/fonts/MaterialIcons-Regular.woff2
--------------------------------------------------------------------------------
/src/img/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ultimatecourses/ultimate-angular-master-seed/a72b7ddfa3bbbb2ac30934d14e57ab8a6f049331/src/img/favicon.ico
--------------------------------------------------------------------------------
/src/img/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ultimatecourses/ultimate-angular-master-seed/a72b7ddfa3bbbb2ac30934d14e57ab8a6f049331/src/img/logo.png
--------------------------------------------------------------------------------
/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Contacts Manager
6 |
7 |
8 |
9 |
10 |
11 | Loading...
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------