<!DOCTYPE html>
<html>
<head>
  <title>App</title>
  <base href=".">
  <script src="https://code.angularjs.org/tools/traceur-runtime.js"></script>
  <script src="https://code.angularjs.org/tools/system.js"></script>
  <script src="https://code.angularjs.org/tools/typescript.js"></script>
  <script src="config.js"></script>
  <script src="https://code.angularjs.org/2.0.0-alpha.53/angular2.js"></script>
  <script src="https://code.angularjs.org/2.0.0-alpha.53/router.dev.js"></script>
  <script src="https://npmcdn.com/@reactivex/rxjs@5.0.0-alpha.14/dist/global/Rx.js"></script>
  <script>
      System.import('./bootstrap.ts').then(null, console.error.bind(console));
  </script>

</head>

<body>
  <app></app>
</body>

</html>
// app.ts
import {Component} from 'angular2/core';
import {RouteConfig, ROUTER_DIRECTIVES, Router} from 'angular2/router';
import {Home} from './home.ts';
import {Login} from './login.ts';

@Component({
  selector: 'app',
  directives: [ROUTER_DIRECTIVES]
  template: `
    <h1>Hello world</h1>

    <router-outlet></router-outlet>
  `
})
@RouteConfig([
    { path: '/', redirectTo: ['Login'] },
    { path: '/home', as: 'Home', component: Home },
    { path: '/login', as: 'Login', component: Login }
])
export class App {
  constructor() {}
}
System.config({
  //use typescript for compilation
  transpiler: 'typescript',
  //typescript compiler options
  typescriptOptions: {
    emitDecoratorMetadata: true
  }
});
//main entry point
import {bootstrap} from 'angular2/platform/browser';
import {provide} from 'angular2/core';
import {ROUTER_PROVIDERS, LocationStrategy, HashLocationStrategy} from 'angular2/router';
import {App} from './app.ts';
import {Authentication} from './authentication.ts';

bootstrap(App, [
  ROUTER_PROVIDERS,
  provide(LocationStrategy, {useClass: HashLocationStrategy}),
  Authentication
]);
// login.ts
import {Component} from 'angular2/core';
import {FORM_DIRECTIVES, FormBuilder, Validators, ControlGroup, NgIf} from 'angular2/common';
import {Router} from 'angular2/router';
import {Authentication} from './authentication.ts';

@Component({
  selector: 'login',
  directives: [ FORM_DIRECTIVES, NgIf ],
  template: `
    <form [ngFormModel]="form" (submit)="$event.preventDefault(); onSubmit(form.value)">
      <div *ngIf="error">Check your password</div>
      <div>
        <label for="username">Username</label>
        <input type="text" ngControl="username">
      </div>
      <div>
        <label for="password">Password</label>
        <input type="password" ngControl="password">
      </div>
      <div class="form-group">
        <button type="submit" [disabled]="!form.valid">Login</button>
      </div>
    </form>
  `
})

export class Login {
  form: ControlGroup;
  error: boolean = false;
  constructor(fb: FormBuilder, public auth: Authentication, public router: Router) {
    this.form = fb.group({
      username:  ['', Validators.required],
      password:  ['', Validators.required]
    });
  }

  onSubmit(value: any) {
    this.auth.login(value.username, value.password)
      .subscribe(
        (token: any) => { this.router.navigate(['../Home']); },
        () => { this.error = true; }
      );
  }
}
// home.ts
import {Component} from 'angular2/core';
import {Router, CanActivate} from 'angular2/router';
import {Authentication} from './authentication.ts';
import {isLoggedin}  from './is-loggedin.ts';

@Component({
  selector: 'home',
  directives: [],
  template: `
    <h2>I am logged in</h2>
    <a href="#" (click)="onLogout()">Logout</a>
  `
})

@CanActivate(() => isLoggedin())
export class Home {
  constructor(public auth: Authentication, public router: Router) {}

  onLogout() {
    this.auth.logout()
      .subscribe(
        () => this.router.navigate(['../Login']),
      );
  }
}
// authentication.ts
import {Injectable} from 'angular2/core';

@Injectable()
export class Authentication {
  token: string;

  constructor() {
    this.token = localStorage.getItem('token');
  }

  login(username: String, password: String) {
    /*
     * If we had a login api, we would have done something like this

    return this.http.post('/auth/login', JSON.stringify({
        username: username,
        password: password
      }), {
        headers: new Headers({
          'Content-Type': 'application/json'
        })
      })
      .map((res : any) => {
        let data = res.json();
        this.token = data.token;
        localStorage.setItem('token', this.token);
      });

      for the purpose of this cookbook, we will juste simulate that
    */
    if (username === 'test' && password === 'test') {
      this.token = 'token';
      localStorage.setItem('token', this.token);
      return Rx.Observable.of('token');
    }

    return Rx.Observable.throw('authentication failure');
  }

  logout() {
    /*
     * If we had a login api, we would have done something like this

    return this.http.get(this.config.serverUrl + '/auth/logout', {
      headers: new Headers({
        'x-security-token': this.token
      })
    })
    .map((res : any) => {
      this.token = undefined;
      localStorage.removeItem('token');
    });
     */

    this.token = undefined;
    localStorage.removeItem('token');

    return Rx.Observable.of(true);
  }
}
export function isLoggedin() {
  return !!localStorage.getItem('token');
}