├── 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 |
2 |
3 |
4 | 11 |
12 | {{ ::$ctrl.user.email }} 13 | 14 | 15 | power_settings_new 16 | Logout 17 | 18 | 19 |
20 |
21 |
22 |
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 |
2 | 3 | 4 |
5 |
6 |
7 |
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 |
2 | 10 | 18 |
19 | 22 |
23 |
24 | {{ $ctrl.message }} 25 |
26 |
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 |
2 |

Login

3 | 8 | 9 |
10 |
11 | 12 | Don't have an account? Create one here. 13 | 14 |
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 |
2 |

Register

3 | 8 | 9 |
10 |
11 | 12 | Already have an account? Login here. 13 | 14 |
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 |
2 | 5 | 17 |
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 |
2 | 6 |
7 | {{ ::$ctrl.contact.name }} 8 | 9 | {{ ::$ctrl.contact.tag }} 10 | 11 |
12 | 15 |
16 |
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 |
2 | 10 |
13 | face 14 | There's no one here... 15 |
16 |
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 |
2 |
3 |
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 |
2 | 10 | 18 |
19 | 22 |
23 |
24 | {{ $ctrl.message }} 25 |
26 |
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 |
2 |

Login

3 | 8 | 9 |
10 |
11 | 12 | Don't have an account? Create one here. 13 | 14 |
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 |
2 |

Register

3 | 8 | 9 |
10 |
11 | 12 | Already have an account? Login here. 13 | 14 |
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 |
2 |
3 |
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 |
2 |
3 |
4 | 11 |
12 | {{ ::$ctrl.user.email }} 13 | 14 | 15 | power_settings_new 16 | Logout 17 | 18 | 19 |
20 |
21 |
22 |
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 |
2 | 3 | 4 |
5 |
6 |
7 |
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 |
2 | 10 | 18 |
19 | 22 |
23 |
24 | {{ $ctrl.message }} 25 |
26 |
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 |
2 |

Login

3 | 8 | 9 |
10 |
11 | 12 | Don't have an account? Create one here. 13 | 14 |
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 |
2 |

Register

3 | 8 | 9 |
10 |
11 | 12 | Already have an account? Login here. 13 | 14 |
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 |
2 |
3 |
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 |
2 |
3 |
4 | 11 |
12 | {{ ::$ctrl.user.email }} 13 | 14 | 15 | power_settings_new 16 | Logout 17 | 18 | 19 |
20 |
21 |
22 |
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 |
2 | 3 | 4 |
5 |
6 |
7 |
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 |
2 | 10 | 18 |
19 | 22 |
23 |
24 | {{ $ctrl.message }} 25 |
26 |
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 |
2 |

Login

3 | 8 | 9 |
10 |
11 | 12 | Don't have an account? Create one here. 13 | 14 |
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 |
2 |

Register

3 | 8 | 9 |
10 |
11 | 12 | Already have an account? Login here. 13 | 14 |
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 |
2 |
3 |
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 |
2 |
3 |
4 | 11 |
12 | {{ ::$ctrl.user.email }} 13 | 14 | 15 | power_settings_new 16 | Logout 17 | 18 | 19 |
20 |
21 |
22 |
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 |
2 | 3 | 4 |
5 |
6 |
7 |
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 |
2 | 10 | 18 |
19 | 22 |
23 |
24 | {{ $ctrl.message }} 25 |
26 |
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 |
2 |

Login

3 | 8 | 9 |
10 |
11 | 12 | Don't have an account? Create one here. 13 | 14 |
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 |
2 |

Register

3 | 8 | 9 |
10 |
11 | 12 | Already have an account? Login here. 13 | 14 |
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 |
2 |
3 |
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 |
2 |
3 |
4 | 11 |
12 | {{ ::$ctrl.user.email }} 13 | 14 | 15 | power_settings_new 16 | Logout 17 | 18 | 19 |
20 |
21 |
22 |
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 |
2 | 3 | 4 |
5 |
6 |
7 |
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 |
2 | 10 | 18 |
19 | 22 |
23 |
24 | {{ $ctrl.message }} 25 |
26 |
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 |
2 |

Login

3 | 8 | 9 |
10 |
11 | 12 | Don't have an account? Create one here. 13 | 14 |
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 |
2 |

Register

3 | 8 | 9 |
10 |
11 | 12 | Already have an account? Login here. 13 | 14 |
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 |
2 | 5 | 17 |
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 |
2 |
3 |
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 |
2 |
3 |
4 | 11 |
12 | {{ ::$ctrl.user.email }} 13 | 14 | 15 | power_settings_new 16 | Logout 17 | 18 | 19 |
20 |
21 |
22 |
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 |
2 | 3 | 4 |
5 |
6 |
7 |
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 |
2 | 10 | 18 |
19 | 22 |
23 |
24 | {{ $ctrl.message }} 25 |
26 |
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 |
2 |

Login

3 | 8 | 9 |
10 |
11 | 12 | Don't have an account? Create one here. 13 | 14 |
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 |
2 |

Register

3 | 8 | 9 |
10 |
11 | 12 | Already have an account? Login here. 13 | 14 |
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 |
2 | 5 | 17 |
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 |
2 | 7 |
10 | face 11 | There's no one here... 12 |
13 |
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 |
2 |
3 |
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 |
2 |
3 |
4 | 11 |
12 | {{ ::$ctrl.user.email }} 13 | 14 | 15 | power_settings_new 16 | Logout 17 | 18 | 19 |
20 |
21 |
22 |
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 |
2 | 3 | 4 |
5 |
6 |
7 |
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 |
2 | 10 | 18 |
19 | 22 |
23 |
24 | {{ $ctrl.message }} 25 |
26 |
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 |
2 |

Login

3 | 8 | 9 |
10 |
11 | 12 | Don't have an account? Create one here. 13 | 14 |
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 |
2 |

Register

3 | 8 | 9 |
10 |
11 | 12 | Already have an account? Login here. 13 | 14 |
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 |
2 | 5 | 17 |
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 |
2 | 6 |
7 | {{ ::$ctrl.contact.name }} 8 | 9 | {{ ::$ctrl.contact.tag }} 10 | 11 |
12 | 15 |
16 |
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 |
2 | 10 |
13 | face 14 | There's no one here... 15 |
16 |
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 |
2 |
3 |
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 |
2 |
3 |
4 | 11 |
12 | {{ ::$ctrl.user.email }} 13 | 14 | 15 | power_settings_new 16 | Logout 17 | 18 | 19 |
20 |
21 |
22 |
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 |
2 | 3 | 4 |
5 |
6 |
7 |
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 |
2 | 10 | 18 |
19 | 22 |
23 |
24 | {{ $ctrl.message }} 25 |
26 |
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 |
2 |

Login

3 | 8 | 9 |
10 |
11 | 12 | Don't have an account? Create one here. 13 | 14 |
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 |
2 |

Register

3 | 8 | 9 |
10 |
11 | 12 | Already have an account? Login here. 13 | 14 |
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 |
2 | 5 | 17 |
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 |
2 | 6 |
7 | {{ ::$ctrl.contact.name }} 8 | 9 | {{ ::$ctrl.contact.tag }} 10 | 11 |
12 | 15 |
16 |
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 |
2 | 10 |
13 | face 14 | There's no one here... 15 |
16 |
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 |
2 |
3 |
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 |
2 |
3 |
4 | 11 |
12 | {{ ::$ctrl.user.email }} 13 | 14 | 15 | power_settings_new 16 | Logout 17 | 18 | 19 |
20 |
21 |
22 |
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 |
2 | 3 | 4 |
5 |
6 |
7 |
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 |
2 | 10 | 18 |
19 | 22 |
23 |
24 | {{ $ctrl.message }} 25 |
26 |
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 |
2 |

Login

3 | 8 | 9 |
10 |
11 | 12 | Don't have an account? Create one here. 13 | 14 |
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 |
2 |

Register

3 | 8 | 9 |
10 |
11 | 12 | Already have an account? Login here. 13 | 14 |
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 |
2 | 5 | 17 |
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 |
2 | 6 |
7 | {{ ::$ctrl.contact.name }} 8 | 9 | {{ ::$ctrl.contact.tag }} 10 | 11 |
12 | 15 |
16 |
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 |
2 | 10 |
13 | face 14 | There's no one here... 15 |
16 |
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 |
2 |
3 |
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 | --------------------------------------------------------------------------------