diff --git a/angular-tour-of-heroes/src/app/app-routing.module.ts b/angular-tour-of-heroes/src/app/app-routing.module.ts new file mode 100644 index 0000000..83a06b9 --- /dev/null +++ b/angular-tour-of-heroes/src/app/app-routing.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; +import { HeroesComponent } from './heroes/heroes.component'; +import { DashboardComponent } from './dashboard/dashboard.component'; +import { HeroDetailComponent } from './hero-detail/hero-detail.component'; + +const routes: Routes = [ + { path: '', redirectTo: '/dashboard', pathMatch: 'full'}, + { path: 'dashboard', component: DashboardComponent }, + { path: 'detail/:id', component: HeroDetailComponent }, + { path: 'heroes', component: HeroesComponent } +]; + +@NgModule({ + imports: [ RouterModule.forRoot(routes) ], + exports: [ RouterModule ] +}) + +export class AppRoutingModule { } diff --git a/angular-tour-of-heroes/src/app/app.component.css b/angular-tour-of-heroes/src/app/app.component.css index e69de29..c62f266 100644 --- a/angular-tour-of-heroes/src/app/app.component.css +++ b/angular-tour-of-heroes/src/app/app.component.css @@ -0,0 +1,28 @@ +/* AppComponent's private CSS styles */ +h1 { + font-size: 1.2em; + margin-bottom: 0; +} +h2 { + font-size: 2em; + margin-top: 0; + padding-top: 0; +} +nav a { + padding: 5px 10px; + text-decoration: none; + margin-top: 10px; + display: inline-block; + background-color: #eee; + border-radius: 4px; +} +nav a:visited, a:link { + color: #334953; +} +nav a:hover { + color: #039be5; + background-color: #cfd8dc; +} +nav a.active { + color: #039be5; +} diff --git a/angular-tour-of-heroes/src/app/app.component.html b/angular-tour-of-heroes/src/app/app.component.html index cb45ac4..49c7d17 100644 --- a/angular-tour-of-heroes/src/app/app.component.html +++ b/angular-tour-of-heroes/src/app/app.component.html @@ -1,3 +1,7 @@

{{title}}

- + + diff --git a/angular-tour-of-heroes/src/app/app.module.ts b/angular-tour-of-heroes/src/app/app.module.ts index 14166af..80b1c06 100644 --- a/angular-tour-of-heroes/src/app/app.module.ts +++ b/angular-tour-of-heroes/src/app/app.module.ts @@ -6,17 +6,21 @@ import { AppComponent } from './app.component'; import { HeroesComponent } from './heroes/heroes.component'; import { HeroDetailComponent } from './hero-detail/hero-detail.component'; import { MessagesComponent } from './messages/messages.component'; +import { AppRoutingModule } from './app-routing.module'; +import { DashboardComponent } from './dashboard/dashboard.component'; @NgModule({ declarations: [ AppComponent, HeroesComponent, HeroDetailComponent, - MessagesComponent + MessagesComponent, + DashboardComponent ], imports: [ BrowserModule, - FormsModule + FormsModule, + AppRoutingModule ], providers: [], bootstrap: [AppComponent] diff --git a/angular-tour-of-heroes/src/app/dashboard/dashboard.component.css b/angular-tour-of-heroes/src/app/dashboard/dashboard.component.css new file mode 100644 index 0000000..4b7ec1c --- /dev/null +++ b/angular-tour-of-heroes/src/app/dashboard/dashboard.component.css @@ -0,0 +1,63 @@ +/* DashboardComponent's private CSS styles */ +[class*='col-'] { + float: left; + padding-right: 20px; + padding-bottom: 20px; +} +[class*='col-']:last-of-type { + padding-right: 0; +} +a { + text-decoration: none; +} +*, *:after, *:before { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +h3 { + text-align: center; + margin-bottom: 0; +} +h4 { + position: relative; +} +.grid { + margin: 0; +} +.col-1-4 { + width: 25%; +} +.module { + padding: 20px; + text-align: center; + color: #eee; + max-height: 120px; + min-width: 120px; + background-color: #3f525c; + border-radius: 2px; +} +.module:hover { + background-color: #eee; + cursor: pointer; + color: #607d8b; +} +.grid-pad { + padding: 10px 0; +} +.grid-pad > [class*='col-']:last-of-type { + padding-right: 20px; +} +@media (max-width: 600px) { + .module { + font-size: 10px; + max-height: 75px; } +} +@media (max-width: 1024px) { + .grid { + margin: 0; + } + .module { + min-width: 60px; + } +} diff --git a/angular-tour-of-heroes/src/app/dashboard/dashboard.component.html b/angular-tour-of-heroes/src/app/dashboard/dashboard.component.html new file mode 100644 index 0000000..9827aff --- /dev/null +++ b/angular-tour-of-heroes/src/app/dashboard/dashboard.component.html @@ -0,0 +1,9 @@ +

Top Heroes

+
+ +
+

{{hero.name}}

+
+
+
diff --git a/angular-tour-of-heroes/src/app/dashboard/dashboard.component.spec.ts b/angular-tour-of-heroes/src/app/dashboard/dashboard.component.spec.ts new file mode 100644 index 0000000..9c996c3 --- /dev/null +++ b/angular-tour-of-heroes/src/app/dashboard/dashboard.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { DashboardComponent } from './dashboard.component'; + +describe('DashboardComponent', () => { + let component: DashboardComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ DashboardComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(DashboardComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/angular-tour-of-heroes/src/app/dashboard/dashboard.component.ts b/angular-tour-of-heroes/src/app/dashboard/dashboard.component.ts new file mode 100644 index 0000000..c559ccd --- /dev/null +++ b/angular-tour-of-heroes/src/app/dashboard/dashboard.component.ts @@ -0,0 +1,23 @@ +import { Component, OnInit } from '@angular/core'; +import { Hero } from '../hero'; +import { HeroService } from '../hero.service'; + +@Component({ + selector: 'app-dashboard', + templateUrl: './dashboard.component.html', + styleUrls: [ './dashboard.component.css' ] +}) +export class DashboardComponent implements OnInit { + heroes: Hero[] = []; + + constructor(private heroService: HeroService) { } + + ngOnInit() { + this.getHeroes(); + } + + getHeroes(): void { + this.heroService.getHeroes() + .subscribe(heroes => this.heroes = heroes.slice(1, 5)); + } +} diff --git a/angular-tour-of-heroes/src/app/hero-detail/hero-detail.component.css b/angular-tour-of-heroes/src/app/hero-detail/hero-detail.component.css index e69de29..3981760 100644 --- a/angular-tour-of-heroes/src/app/hero-detail/hero-detail.component.css +++ b/angular-tour-of-heroes/src/app/hero-detail/hero-detail.component.css @@ -0,0 +1,31 @@ +/* HeroDetailComponent's private CSS styles */ +label { + display: inline-block; + width: 3em; + margin: .5em 0; + color: #607D8B; + font-weight: bold; +} +input { + height: 2em; + font-size: 1em; + padding-left: .4em; +} +button { + margin-top: 20px; + font-family: Arial; + background-color: #eee; + border: none; + padding: 5px 10px; + border-radius: 4px; + cursor: pointer; + cursor: hand; +} +button:hover { + background-color: #cfd8dc; +} +button:disabled { + background-color: #eee; + color: #ccc; + cursor: auto; +} diff --git a/angular-tour-of-heroes/src/app/hero-detail/hero-detail.component.html b/angular-tour-of-heroes/src/app/hero-detail/hero-detail.component.html index 072489d..78cba67 100644 --- a/angular-tour-of-heroes/src/app/hero-detail/hero-detail.component.html +++ b/angular-tour-of-heroes/src/app/hero-detail/hero-detail.component.html @@ -9,4 +9,7 @@ + + + diff --git a/angular-tour-of-heroes/src/app/hero-detail/hero-detail.component.ts b/angular-tour-of-heroes/src/app/hero-detail/hero-detail.component.ts index 948cd11..b7124a9 100644 --- a/angular-tour-of-heroes/src/app/hero-detail/hero-detail.component.ts +++ b/angular-tour-of-heroes/src/app/hero-detail/hero-detail.component.ts @@ -1,5 +1,9 @@ import { Component, OnInit, Input } from '@angular/core'; import { Hero } from '../hero'; +import { ActivatedRoute } from '@angular/router'; +import { Location } from '@angular/common'; + +import { HeroService } from '../hero.service'; @Component({ selector: 'app-hero-detail', @@ -8,9 +12,25 @@ import { Hero } from '../hero'; }) export class HeroDetailComponent implements OnInit { @Input() hero: Hero; - constructor() { } - ngOnInit() { + constructor( + private route: ActivatedRoute, + private heroService: HeroService, + private location: Location + ) { } + + ngOnInit(): void { + this.getHero(); + } + + getHero(): void { + const id = +this.route.snapshot.paramMap.get('id'); + this.heroService.getHero(id) + .subscribe(hero => this.hero = hero); + } + + goBack(): void { + this.location.back(); } } diff --git a/angular-tour-of-heroes/src/app/hero.service.ts b/angular-tour-of-heroes/src/app/hero.service.ts index 5f1649e..20fc51c 100644 --- a/angular-tour-of-heroes/src/app/hero.service.ts +++ b/angular-tour-of-heroes/src/app/hero.service.ts @@ -16,4 +16,10 @@ export class HeroService { this.messageService.add('HeroService: fetched heroes.') return of(HEROES); } + + getHero(id: number): Observable { + // TODO: send the message _after_ fetching the hero + this.messageService.add(`HeroService: fetched hero id=${id}`); + return of(HEROES.find(hero => hero.id === id)); + } } diff --git a/angular-tour-of-heroes/src/app/heroes/heroes.component.css b/angular-tour-of-heroes/src/app/heroes/heroes.component.css index 9759a42..94a91be 100644 --- a/angular-tour-of-heroes/src/app/heroes/heroes.component.css +++ b/angular-tour-of-heroes/src/app/heroes/heroes.component.css @@ -6,39 +6,26 @@ width: 15em; } .heroes li { - cursor: pointer; position: relative; - left: 0; + cursor: pointer; background-color: #EEE; margin: .5em; padding: .3em 0; height: 1.6em; border-radius: 4px; } + .heroes li:hover { color: #607D8B; background-color: #DDD; left: .1em; } -.heroes li.selected { - background-color: #CFD8DC; - color: white; -} -.heroes li.selected:hover { - background-color: #BBD8DC; - color: white; -} -.heroes .badge { - display: inline-block; - font-size: small; - color: white; - padding: 0.8em 0.7em 0 0.7em; - background-color:#405061; - line-height: 1em; + +.heroes a { + color: #333; + text-decoration: none; position: relative; - left: -1px; - top: -4px; - height: 1.8em; - margin-right: .8em; - border-radius: 4px 0 0 4px; + display: block; + width: 250px; } + diff --git a/angular-tour-of-heroes/src/app/heroes/heroes.component.html b/angular-tour-of-heroes/src/app/heroes/heroes.component.html index 5ad0b60..7cdbc43 100644 --- a/angular-tour-of-heroes/src/app/heroes/heroes.component.html +++ b/angular-tour-of-heroes/src/app/heroes/heroes.component.html @@ -2,12 +2,9 @@ - - - diff --git a/angular-tour-of-heroes/src/app/heroes/heroes.component.ts b/angular-tour-of-heroes/src/app/heroes/heroes.component.ts index 6aebf70..d678a02 100644 --- a/angular-tour-of-heroes/src/app/heroes/heroes.component.ts +++ b/angular-tour-of-heroes/src/app/heroes/heroes.component.ts @@ -10,10 +10,6 @@ import { HeroService } from '../hero.service'; }) export class HeroesComponent implements OnInit { heroes: Hero[]; - hero: Hero = { - id: 1, - name: 'Windstorm' - }; constructor(private heroService: HeroService) { } @@ -21,11 +17,6 @@ export class HeroesComponent implements OnInit { this.getHeroes(); } - selectedHero: Hero; - onSelect(hero: Hero): void { - this.selectedHero = hero; - } - getHeroes(): void { this.heroService.getHeroes() .subscribe(heroes => this.heroes = heroes);