diff --git a/src/app/app.component.css b/src/app/app.component.css
index e69de29..23fba11 100644
--- a/src/app/app.component.css
+++ b/src/app/app.component.css
@@ -0,0 +1,7 @@
+.app-body {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ margin-top: 1rem;
+}
\ No newline at end of file
diff --git a/src/app/app.component.html b/src/app/app.component.html
index bbc6764..147b83f 100644
--- a/src/app/app.component.html
+++ b/src/app/app.component.html
@@ -6,6 +6,11 @@
\ No newline at end of file
diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index 68478a8..3f586bc 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -1,9 +1,17 @@
import { Component } from '@angular/core';
+import { GameFacade } from './store/game';
+
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
+ gameStatus$ = this.gameFacade.gameStatus$;
+
+ constructor(
+ private readonly gameFacade: GameFacade
+ ) { }
+
}
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index dcd047a..467dd0b 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -1,26 +1,47 @@
-import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
+import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { ReactiveFormsModule, FormsModule } from '@angular/forms';
-import { MatButtonModule } from '@angular/material/button';
-import { MatToolbarModule } from '@angular/material/toolbar';
import { StoreModule } from '@ngrx/store';
import { EffectsModule } from '@ngrx/effects';
+import { MatButtonModule } from '@angular/material/button';
+import { MatCardModule } from '@angular/material/card';
+import { MatIconModule } from '@angular/material/icon';
+import { MatRadioModule } from '@angular/material/radio';
+import { MatToolbarModule } from '@angular/material/toolbar';
+
import { AppComponent } from './app.component';
import { GameStoreModule } from './store';
+import { DirectivesModule } from './directives/directives.module';
+
+import { GameCardComponent } from './game-card/game-card.component';
+import { MatchResultsComponent } from './match-results/match-results.component';
+
+const materialModules = [
+ MatButtonModule,
+ MatCardModule,
+ MatIconModule,
+ MatRadioModule,
+ MatToolbarModule
+];
@NgModule({
declarations: [
- AppComponent
+ AppComponent,
+ GameCardComponent,
+ MatchResultsComponent
],
imports: [
BrowserModule,
BrowserAnimationsModule,
- MatButtonModule,
- MatToolbarModule,
+ ReactiveFormsModule,
+ FormsModule,
+ ...materialModules,
StoreModule.forRoot({}, {}),
EffectsModule.forRoot([]),
+ DirectivesModule,
GameStoreModule
],
providers: [],
diff --git a/src/app/game-card/game-card.component.css b/src/app/game-card/game-card.component.css
new file mode 100644
index 0000000..2d900d1
--- /dev/null
+++ b/src/app/game-card/game-card.component.css
@@ -0,0 +1,24 @@
+:host {
+ display: block;
+}
+
+.game-card {
+ width: 420px;
+}
+
+.full-width-field {
+ width: 100%;
+}
+
+:host ::ng-deep .mat-radio-group {
+ display: flex;
+ flex-direction: row;
+ justify-content: space-around;
+ margin: 1rem 0;
+}
+
+:host ::ng-deep .mat-radio-label {
+ display: flex;
+ flex-direction: column-reverse;
+ margin: 1rem 0;
+}
\ No newline at end of file
diff --git a/src/app/game-card/game-card.component.html b/src/app/game-card/game-card.component.html
new file mode 100644
index 0000000..4fe09ee
--- /dev/null
+++ b/src/app/game-card/game-card.component.html
@@ -0,0 +1,16 @@
+
+
+
\ No newline at end of file
diff --git a/src/app/game-card/game-card.component.ts b/src/app/game-card/game-card.component.ts
new file mode 100644
index 0000000..a3f8c2c
--- /dev/null
+++ b/src/app/game-card/game-card.component.ts
@@ -0,0 +1,33 @@
+import { Component, OnInit } from '@angular/core';
+import { FormBuilder, FormGroup, Validators } from '@angular/forms';
+
+import { GameFacade } from "../store/game";
+
+@Component({
+ selector: 'app-game-card',
+ templateUrl: './game-card.component.html',
+ styleUrls: ['./game-card.component.css']
+})
+export class GameCardComponent implements OnInit {
+ form: FormGroup;
+ choices = ['rock', 'paper', 'scissors'];
+
+ constructor(
+ private readonly fb: FormBuilder,
+ private readonly gameFacade: GameFacade
+ ) { }
+
+ ngOnInit(): void {
+ this.form = this.fb.group({
+ playerChoice: [undefined, [Validators.required]]
+ });
+ }
+
+ submit(event, gameForm): void {
+ event.preventDefault();
+ this.gameFacade.play(this.form.value.playerChoice);
+ this.form.reset();
+ gameForm.resetForm();
+ }
+
+}
diff --git a/src/app/match-results/match-results.component.css b/src/app/match-results/match-results.component.css
new file mode 100644
index 0000000..e74500e
--- /dev/null
+++ b/src/app/match-results/match-results.component.css
@@ -0,0 +1,23 @@
+:host {
+ display: block;
+}
+
+.match-results {
+ width: 420px;
+}
+
+.match-results-text {
+ font-weight: bold;
+}
+
+.match-visual {
+ display: flex;
+ flex-direction: row;
+ margin: 1rem 0;
+ justify-content: space-around;
+ width: 100%;
+}
+
+.match-visual .vs {
+ font-size: 3rem;
+}
\ No newline at end of file
diff --git a/src/app/match-results/match-results.component.html b/src/app/match-results/match-results.component.html
new file mode 100644
index 0000000..94656cc
--- /dev/null
+++ b/src/app/match-results/match-results.component.html
@@ -0,0 +1,17 @@
+
+ Match Results
+
+
+ You {{ results.result }}!
+
+

+
vs
+

+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/app/match-results/match-results.component.ts b/src/app/match-results/match-results.component.ts
new file mode 100644
index 0000000..1d0303f
--- /dev/null
+++ b/src/app/match-results/match-results.component.ts
@@ -0,0 +1,21 @@
+import { Component } from '@angular/core';
+
+import { GameFacade } from '../store/game';
+
+@Component({
+ selector: 'app-match-results',
+ templateUrl: './match-results.component.html',
+ styleUrls: ['./match-results.component.css']
+})
+export class MatchResultsComponent {
+ results$ = this.gameFacade.recentGameResults$;
+
+ constructor(
+ private readonly gameFacade: GameFacade
+ ) { }
+
+ playAgain(): void {
+ this.gameFacade.reset();
+ }
+
+}
diff --git a/src/app/store/game/game.facade.ts b/src/app/store/game/game.facade.ts
index 2aed9be..7b21cbe 100644
--- a/src/app/store/game/game.facade.ts
+++ b/src/app/store/game/game.facade.ts
@@ -1,23 +1,25 @@
import { Injectable } from '@angular/core';
import { Store, select } from '@ngrx/store';
-import * as gameActions from './game.actions';
+import * as GameActions from './game.actions';
+import * as GameQuery from './game.selectors';
@Injectable()
export class GameFacade {
+ recentGameResults$ = this.store.pipe(select(GameQuery.selectRecentMatchResults));
// gameHistory$ = this.store.pipe(select(getGameHistory));
// scores$ = this.store.pipe(select(getScores));
- // gameStatus$ = this.store.pipe(select(getGameStatus));
+ gameStatus$ = this.store.pipe(select(GameQuery.selectGameStatus));
constructor(
private readonly store: Store
) { }
play(playerChoice: string): void {
- this.store.dispatch(gameActions.playMatch({ playerChoice }));
+ this.store.dispatch(GameActions.playMatch({ playerChoice }));
}
reset(): void {
- this.store.dispatch(gameActions.resetMatch());
+ this.store.dispatch(GameActions.resetMatch());
}
}
diff --git a/src/app/store/game/game.selectors.ts b/src/app/store/game/game.selectors.ts
index 859744e..029389b 100644
--- a/src/app/store/game/game.selectors.ts
+++ b/src/app/store/game/game.selectors.ts
@@ -4,3 +4,5 @@ import * as fromGame from './game.reducer';
export const selectGameState = createFeatureSelector(
fromGame.gameFeatureKey
);
+export const selectGameStatus = createSelector(selectGameState, fromGame.getGameStatus);
+export const selectRecentMatchResults = createSelector(selectGameState, fromGame.getRecentMatchHistory);
\ No newline at end of file