diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app.routing.ts b/SessionCompanion/SessionCompanion/ClientApp/src/app.routing.ts index 934f5a4..b202ed5 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/app.routing.ts +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app.routing.ts @@ -5,6 +5,8 @@ import { RegistrationComponent } from './app/components/registration/registratio import {GameMasterDashboardComponent} from './app/components/game-master-dashboard/game-master-dashboard.component'; import {PlayerDashboardComponent} from './app/components/player-dashboard/player-dashboard.component'; import { SelectCharacterComponent } from './app/components/select-character/select-character.component'; +import {CreateCharacterComponent} from "./app/components/create-character/create-character.component"; +import {PersonalizeTemplateComponent} from "./app/components/personalize-template/personalize-template.component"; const routes: Routes = [ { @@ -37,6 +39,16 @@ const routes: Routes = [ component: SelectCharacterComponent, pathMatch: 'full' }, + { + path: 'create-character-step-1', + component: CreateCharacterComponent, + pathMatch: 'full' + }, + { + path: 'create-character-step-2', + component: PersonalizeTemplateComponent, + pathMatch: 'full' + } ]; export const appRoutingModule = RouterModule.forRoot(routes); diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/app.module.ts b/SessionCompanion/SessionCompanion/ClientApp/src/app/app.module.ts index 9324316..bd0048f 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/app/app.module.ts +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/app.module.ts @@ -62,6 +62,8 @@ import { MessageDialogComponent } from './shared/message-dialog/message-dialog.c import { GameMasterTurntrackerComponent } from './components/game-master-turntracker/game-master-turntracker.component'; import { DragDropModule } from '@angular/cdk/drag-drop'; import { ChooseMonsterDialogComponent } from './components/choose-monster-dialog/choose-monster-dialog.component'; +import { CreateCharacterComponent } from './components/create-character/create-character.component'; +import { PersonalizeTemplateComponent } from './components/personalize-template/personalize-template.component'; @NgModule({ declarations: [ @@ -90,6 +92,8 @@ import { ChooseMonsterDialogComponent } from './components/choose-monster-dialog MessageDialogComponent, GameMasterTurntrackerComponent, ChooseMonsterDialogComponent, + CreateCharacterComponent, + PersonalizeTemplateComponent, ], imports: [ BrowserModule.withServerTransition({ appId: 'ng-cli-universal' }), @@ -151,6 +155,8 @@ import { ChooseMonsterDialogComponent } from './components/choose-monster-dialog MessageDialogComponent, GameMasterTurntrackerComponent, ChooseMonsterDialogComponent, + CreateCharacterComponent, + PersonalizeTemplateComponent, ], }) export class AppModule {} diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/create-character/create-character.component.css b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/create-character/create-character.component.css new file mode 100644 index 0000000..ec7cb8f --- /dev/null +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/create-character/create-character.component.css @@ -0,0 +1,85 @@ +@import '../../../styles.css'; + +mat-form-field { + color: #df7c0f; +} + +:host { + height: 100%; + width: 100%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + +input { + min-width: 150px; + max-width: 500px; + width: 100%; +} + +.container { + margin: 5%; + display: flex; + flex-direction: column; +} +.container h1 { + margin-bottom: 1rem; +} + +.form-container { + padding: 10px; + margin: 5px; +} + +.primary-text { + height: 100px; + color: #df7c0f; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 1%; + margin: 1%; +} + +.header { + font-size: 20px; +} + +.mat-divider--custom-style { + background-color: #9e8b6e; + box-shadow: 0 1px 0 0 #d8d8d8; +} + +@media (max-width: 400px) { + .container { + margin-left: 0%; + width: 300px; + padding-top: 5%; + } +} + +@media (max-width: 400px) { + .container { + margin-left: 0%; + width: 300px; + padding-top: 5%; + } +} + +@media (min-width: 401px) { + .container { + margin-left: 1%; + width: 450px; + padding-top: 10%; + } +} + +@media (min-width: 768px) { + .container { + width: 550px; + padding-top: 5%; + } +} diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/create-character/create-character.component.html b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/create-character/create-character.component.html new file mode 100644 index 0000000..24b8003 --- /dev/null +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/create-character/create-character.component.html @@ -0,0 +1,15 @@ +
+ arrow_back +
Create character
+
Step 1 - Choose one of template
+ + + + account_circle +
{{character.name}}
+ arrow_forward +
{{character.class}}, {{character.race}}
+ +
+
+
diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/create-character/create-character.component.spec.ts b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/create-character/create-character.component.spec.ts new file mode 100644 index 0000000..5e30ca7 --- /dev/null +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/create-character/create-character.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CreateCharacterComponent } from './create-character.component'; + +describe('CreateCharacterComponent', () => { + let component: CreateCharacterComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ CreateCharacterComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(CreateCharacterComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/create-character/create-character.component.ts b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/create-character/create-character.component.ts new file mode 100644 index 0000000..7b1256f --- /dev/null +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/create-character/create-character.component.ts @@ -0,0 +1,66 @@ +import { Component, OnInit } from '@angular/core'; +import { Router } from '@angular/router'; +import { Store } from '@ngrx/store'; +import { AppState } from '../../store/models/app-state.model'; +import { first } from 'rxjs/operators'; +import { ErrorResponse } from '../../../types/ErrorResponse'; +import { HttpErrorResponse } from '@angular/common/http'; +import { CharacterFromTemplatesViewModel } from '../../../types/viewmodels/character-viewmodels/CharacterFromTemplatesViewModel'; +import { CharacterService } from '../../../services/character.service'; +import { + ChooseTemplateToCreateCharacter, + ClearCharacterId, +} from '../../store/actions/player.action'; + +@Component({ + selector: 'app-create-character', + templateUrl: './create-character.component.html', + styleUrls: ['./create-character.component.css'], +}) +export class CreateCharacterComponent implements OnInit { + charactersTemplateList: CharacterFromTemplatesViewModel[]; + + constructor( + private router: Router, + private store: Store, + private characterService: CharacterService + ) {} + + ngOnInit() { + this.getTemplateCharacters(); + } + + onArrowBackClick() { + this.store + .select((s) => s.playerStore.characterId) + .pipe(first()) + .subscribe((characterId) => { + if (characterId !== null) { + this.store.dispatch(new ClearCharacterId()); + } + this.router.navigate(['select-character']); + }); + } + + onCharacterClick(characterId: number) { + this.store.dispatch(new ChooseTemplateToCreateCharacter({ characterId })); + this.router.navigate(['create-character-step-2']); + } + + getTemplateCharacters() { + this.characterService + .getTemplateCharacters() + .pipe(first()) + .subscribe( + (charactersTemplateList) => { + this.charactersTemplateList = charactersTemplateList; + }, + (error: ErrorResponse | HttpErrorResponse) => { + if (error instanceof HttpErrorResponse) { + error = error.error as ErrorResponse; + } + console.error(error.message); + } + ); + } +} diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/personalize-template/personalize-template.component.css b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/personalize-template/personalize-template.component.css new file mode 100644 index 0000000..6f087b8 --- /dev/null +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/personalize-template/personalize-template.component.css @@ -0,0 +1,77 @@ +@import '../../../styles.css'; + +mat-form-field { + color: #df7c0f; +} + +:host { + height: 100%; + width: 100%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + +input { + min-width: 150px; + max-width: 500px; + width: 100%; +} + +.container { + margin: 5%; + display: flex; + flex-direction: column; +} +.container h1 { + margin-bottom: 1rem; +} + +.form-container { + padding: 10px; + margin: 5px; +} + +.primary-text { + height: 100px; + color: #df7c0f; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 1%; + margin: 1%; +} + +.header { + font-size: 20px; +} + +.mat-divider--custom-style { + background-color: #9e8b6e; + box-shadow: 0 1px 0 0 #d8d8d8; +} + +@media (max-width: 400px) { + .container { + margin-left: 0%; + width: 300px; + padding-top: 5%; + } +} + +@media (min-width: 401px) { + .container { + margin-left: 1%; + width: 450px; + padding-top: 10%; + } +} + +@media (min-width: 768px) { + .container { + width: 550px; + padding-top: 5%; + } +} diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/personalize-template/personalize-template.component.html b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/personalize-template/personalize-template.component.html new file mode 100644 index 0000000..bc60759 --- /dev/null +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/personalize-template/personalize-template.component.html @@ -0,0 +1,28 @@ +
+ arrow_back +
Create character
+
Step 2 - Personalize template
+ + + + If the field is left blank, your character will have the default name + + person + + + {{apiErrorMessage}} + + +
diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/personalize-template/personalize-template.component.spec.ts b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/personalize-template/personalize-template.component.spec.ts new file mode 100644 index 0000000..2bf6574 --- /dev/null +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/personalize-template/personalize-template.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PersonalizeTemplateComponent } from './personalize-template.component'; + +describe('PersonalizeTemplateComponent', () => { + let component: PersonalizeTemplateComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ PersonalizeTemplateComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(PersonalizeTemplateComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/personalize-template/personalize-template.component.ts b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/personalize-template/personalize-template.component.ts new file mode 100644 index 0000000..ce59398 --- /dev/null +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/personalize-template/personalize-template.component.ts @@ -0,0 +1,71 @@ +import { Component, OnDestroy, OnInit } from '@angular/core'; +import { Router } from '@angular/router'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { Subscription } from 'rxjs'; +import { CharacterService } from '../../../services/character.service'; +import { ErrorResponse } from '../../../types/ErrorResponse'; +import { HttpErrorResponse } from '@angular/common/http'; +import { AppState } from '../../store/models/app-state.model'; +import { Store } from '@ngrx/store'; +import { first } from 'rxjs/operators'; + +@Component({ + selector: 'app-personalize-template', + templateUrl: './personalize-template.component.html', + styleUrls: ['./personalize-template.component.css'], +}) +export class PersonalizeTemplateComponent implements OnInit { + allSubscriptions = new Subscription(); + apiError = false; + apiErrorMessage = ''; + + constructor( + private router: Router, + private formBuilder: FormBuilder, + private characterService: CharacterService, + private store: Store + ) {} + + public personalizeTemplateFormGroup: FormGroup = this.formBuilder.group({ + newName: ['', [Validators.required]], + }); + + ngOnInit() {} + + onCreateCharacterButton() { + this.store + .select((s) => { + return { + userId: s.appStore.userId, + characterId: s.playerStore.characterId, + }; + }) + .pipe(first()) + .subscribe((result) => { + this.characterService + .createCharacterFromTemplate( + result.characterId, + result.userId, + this.personalizeTemplateFormGroup.value['newName'] + ) + .pipe(first()) + .subscribe( + () => { + this.router.navigate(['select-character']); + }, + (error: ErrorResponse | HttpErrorResponse) => { + console.error(error); + if (error instanceof HttpErrorResponse) { + error = error.error as ErrorResponse; + } + this.apiError = true; + this.apiErrorMessage = error.message; + } + ); + }); + } + + onArrowBackClick() { + this.router.navigate(['create-character-step-1']); + } +} diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/player-weapons-table/player-weapons-table.component.ts b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/player-weapons-table/player-weapons-table.component.ts index 89d454a..b9db9f7 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/player-weapons-table/player-weapons-table.component.ts +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/player-weapons-table/player-weapons-table.component.ts @@ -13,22 +13,20 @@ import { AppState } from '../../store/models/app-state.model'; @Component({ selector: 'app-player-weapons-table', templateUrl: './player-weapons-table.component.html', - styleUrls: ['./player-weapons-table.component.css'] + styleUrls: ['./player-weapons-table.component.css'], }) export class PlayerWeaponsTableComponent implements OnInit { weapons: WeaponViewModel[]; - displayedColumns: string[] = [ - 'name', - 'weaponType', - 'weight', - 'cost', - ]; + displayedColumns: string[] = ['name', 'weaponType', 'weight', 'cost']; dataSource: MatTableDataSource; @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator; @ViewChild(MatSort, { static: true }) sort: MatSort; - constructor(private store: Store, private equipmentService: EquipmentService) {} + constructor( + private store: Store, + private equipmentService: EquipmentService + ) {} ngOnInit() { this.getCharacterWeapons(); @@ -40,7 +38,7 @@ export class PlayerWeaponsTableComponent implements OnInit { .pipe(first()) .subscribe((characterId) => { this.equipmentService - .getCharacterWeapons(1) + .getCharacterWeapons(characterId) .pipe(first()) .subscribe( (result) => { diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/registration/registration.component.css b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/registration/registration.component.css index 41aa481..1db5afb 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/registration/registration.component.css +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/registration/registration.component.css @@ -64,6 +64,17 @@ input { } @media (min-width: 768px) { + .container { + width: 550px; + padding-top: 0; + } + .form-container { + padding: 10px; + margin: 0px; + } +} + +@media (min-width: 1800px) { .container { width: 550px; padding-top: 5%; diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/registration/registration.component.html b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/registration/registration.component.html index 9f07043..b7ab5c5 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/registration/registration.component.html +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/registration/registration.component.html @@ -38,7 +38,8 @@ required placeholder="Confirm Password" type="password" - name="confirmPassword"/> + name="confirmPassword" + (keyup.enter)="Register()"/> lock Confirm your password diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/select-character/select-character.component.css b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/select-character/select-character.component.css index 41aa481..725318b 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/select-character/select-character.component.css +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/select-character/select-character.component.css @@ -69,3 +69,8 @@ input { padding-top: 5%; } } + +.mat-divider--custom-style { + background-color: #9e8b6e; + box-shadow: 0 1px 0 0 #d8d8d8; +} diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/select-character/select-character.component.html b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/select-character/select-character.component.html index 5eae2cc..fca5add 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/select-character/select-character.component.html +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/select-character/select-character.component.html @@ -1,15 +1,28 @@
arrow_back +
Select character
+ - account_circle -
{{character.name}}
+
{{character.name}}
arrow_forward
{{character.className}} level: {{character.level}}
- +
+
or
+
+
Create character
+ + + + account_circle +
Create character
+ arrow_forward +
+
+
diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/select-character/select-character.component.ts b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/select-character/select-character.component.ts index bb796df..bd411ee 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/select-character/select-character.component.ts +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/select-character/select-character.component.ts @@ -1,44 +1,57 @@ -import {Component, OnInit} from '@angular/core'; +import { Component, OnInit } from '@angular/core'; import { Router } from '@angular/router'; -import {first} from 'rxjs/operators'; -import {ClearUserId} from '../../store/actions/app.actions'; -import {ErrorResponse} from '../../../types/ErrorResponse'; -import {HttpErrorResponse} from '@angular/common/http'; -import {Store} from '@ngrx/store'; -import {AppState} from '../../store/models/app-state.model'; -import {CharacterService} from '../../../services/character.service'; -import {CharacterForLoginViewModel} from '../../../types/viewmodels/character-viewmodels/CharacterForLoginViewModel'; -import {AddCharacterId} from '../../store/actions/player.action'; +import { first } from 'rxjs/operators'; +import { ClearUserId } from '../../store/actions/app.actions'; +import { ErrorResponse } from '../../../types/ErrorResponse'; +import { HttpErrorResponse } from '@angular/common/http'; +import { Store } from '@ngrx/store'; +import { AppState } from '../../store/models/app-state.model'; +import { CharacterService } from '../../../services/character.service'; +import { CharacterForLoginViewModel } from '../../../types/viewmodels/character-viewmodels/CharacterForLoginViewModel'; +import { AddCharacterId } from '../../store/actions/player.action'; @Component({ selector: 'app-select-character', templateUrl: './select-character.component.html', - styleUrls: ['./select-character.component.css'] + styleUrls: ['./select-character.component.css'], }) export class SelectCharacterComponent implements OnInit { charactersList: CharacterForLoginViewModel[]; - constructor(private router: Router, private store: Store, private characterService: CharacterService) {} + constructor( + private router: Router, + private store: Store, + private characterService: CharacterService + ) {} ngOnInit() { this.getUserCharactersList(); } getUserCharactersList() { - this.store.select(s => s.appStore.userId).pipe(first()).subscribe((userId) => { - this.characterService.getUserCharactersList(userId).pipe(first()).subscribe((charactersList) => { - this.charactersList = charactersList; - }, (error: ErrorResponse | HttpErrorResponse) => { - if (error instanceof HttpErrorResponse) { - error = error.error as ErrorResponse; - } - console.error(error.message); - } ); - }); + this.store + .select((s) => s.appStore.userId) + .pipe(first()) + .subscribe((userId) => { + this.characterService + .getUserCharactersList(userId) + .pipe(first()) + .subscribe( + (charactersList) => { + this.charactersList = charactersList; + }, + (error: ErrorResponse | HttpErrorResponse) => { + if (error instanceof HttpErrorResponse) { + error = error.error as ErrorResponse; + } + console.error(error.message); + } + ); + }); } onCharacterClick(characterId: number) { - this.store.dispatch(new AddCharacterId({characterId})); + this.store.dispatch(new AddCharacterId({ characterId })); this.router.navigate(['player']); } @@ -46,4 +59,8 @@ export class SelectCharacterComponent implements OnInit { this.store.dispatch(new ClearUserId()); this.router.navigate(['login']); } + + onCreateCharacter() { + this.router.navigate(['create-character-step-1']); + } } diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/select-role/select-role.component.css b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/select-role/select-role.component.css index 9eaea08..e8be538 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/select-role/select-role.component.css +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/select-role/select-role.component.css @@ -47,7 +47,7 @@ @media (min-width: 768px) { .container { - padding-top: 10%; + padding-top: 6%; } .button { margin: 20px; @@ -59,3 +59,9 @@ font-size: 40px; } } + +@media (min-width: 1800px) { + .container { + padding-top: 10%; + } +} diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/sign-in/sign-in.component.css b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/sign-in/sign-in.component.css index 41aa481..1db5afb 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/sign-in/sign-in.component.css +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/sign-in/sign-in.component.css @@ -64,6 +64,17 @@ input { } @media (min-width: 768px) { + .container { + width: 550px; + padding-top: 0; + } + .form-container { + padding: 10px; + margin: 0px; + } +} + +@media (min-width: 1800px) { .container { width: 550px; padding-top: 5%; diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/sign-in/sign-in.component.html b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/sign-in/sign-in.component.html index 6eede7b..ce59bc5 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/sign-in/sign-in.component.html +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/sign-in/sign-in.component.html @@ -26,7 +26,9 @@ required placeholder="Password" type="password" - name="password"/> + name="password" + (keyup.enter)="onLoginButtonClick()" + /> lock Password is required diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/store/actions/player.action.ts b/SessionCompanion/SessionCompanion/ClientApp/src/app/store/actions/player.action.ts index 690c305..47b872c 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/app/store/actions/player.action.ts +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/store/actions/player.action.ts @@ -2,7 +2,9 @@ import {Action} from '@ngrx/store'; export enum PlayerActionTypes { ADD_CHARACTER_ID= '[PLAYER] Add character id', - CLEAR_CHARACTER_ID = '[PLAYER] Clear character id' + CLEAR_CHARACTER_ID = '[PLAYER] Clear character id', + CHOOSE_TEMPLATE_TO_CREATE_CHARACTER = '[PLAYER] Choose template to create character', + CREATED_CHARACTER_FROM_TEMPLATE = '[PLAYER] Created character from template' } export class AddCharacterId implements Action { @@ -21,4 +23,20 @@ export class ClearCharacterId implements Action { } } -export type PlayerAction = AddCharacterId | ClearCharacterId; +export class ChooseTemplateToCreateCharacter implements Action { + readonly type = PlayerActionTypes.CHOOSE_TEMPLATE_TO_CREATE_CHARACTER; + + constructor(public payload: {characterId: number}) { + + } +} + +export class CreateCharacterFromTemplate implements Action { + readonly type = PlayerActionTypes.CREATED_CHARACTER_FROM_TEMPLATE; + + constructor() { + + } +} + +export type PlayerAction = AddCharacterId | ClearCharacterId | ChooseTemplateToCreateCharacter | CreateCharacterFromTemplate; diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/store/reducers/player.reducer.ts b/SessionCompanion/SessionCompanion/ClientApp/src/app/store/reducers/player.reducer.ts index 9a12b52..2d63ac3 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/app/store/reducers/player.reducer.ts +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/store/reducers/player.reducer.ts @@ -9,6 +9,10 @@ export function PlayerReducer(state: PlayerStoreModel = initialState, action: Pl switch (action.type) { case PlayerActionTypes.ADD_CHARACTER_ID: return {...state, characterId: action.payload.characterId}; + case PlayerActionTypes.CHOOSE_TEMPLATE_TO_CREATE_CHARACTER: + return {...state, characterId: action.payload.characterId}; + case PlayerActionTypes.CREATED_CHARACTER_FROM_TEMPLATE: + return {...state}; case PlayerActionTypes.CLEAR_CHARACTER_ID: return { characterId: null}; default: diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/services/character.service.ts b/SessionCompanion/SessionCompanion/ClientApp/src/services/character.service.ts index db70675..f457055 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/services/character.service.ts +++ b/SessionCompanion/SessionCompanion/ClientApp/src/services/character.service.ts @@ -1,16 +1,18 @@ -import {Inject, Injectable} from '@angular/core'; -import {HttpClient, HttpParams} from '@angular/common/http'; -import {Observable, of, throwError} from 'rxjs'; -import {ErrorResponse} from '../types/ErrorResponse'; -import {Either} from '../types/Either'; -import {CharacterForLoginViewModel} from '../types/viewmodels/character-viewmodels/CharacterForLoginViewModel'; -import {switchMap, retry} from 'rxjs/operators'; -import {LoggedCharactersViewModel} from '../types/viewmodels/character-viewmodels/LoggedCharactersViewModel'; -import {CharacterStatsViewModel} from "../types/viewmodels/character-viewmodels/CharacterStatsViewModel"; +import { Inject, Injectable } from '@angular/core'; +import { HttpClient, HttpParams } from '@angular/common/http'; +import { Observable, of, throwError } from 'rxjs'; +import { ErrorResponse } from '../types/ErrorResponse'; +import { Either } from '../types/Either'; +import { CharacterForLoginViewModel } from '../types/viewmodels/character-viewmodels/CharacterForLoginViewModel'; +import { switchMap, retry } from 'rxjs/operators'; +import { LoggedCharactersViewModel } from '../types/viewmodels/character-viewmodels/LoggedCharactersViewModel'; +import { CharacterStatsViewModel } from '../types/viewmodels/character-viewmodels/CharacterStatsViewModel'; +import { CharacterFromTemplatesViewModel } from '../types/viewmodels/character-viewmodels/CharacterFromTemplatesViewModel'; +import { SuccessResponse } from '../types/SuccessResponse'; Injectable({ - providedIn: 'root' -}) + providedIn: 'root', +}); export class CharacterService { private baseUrl = 'api/character/'; constructor(private http: HttpClient, @Inject('BASE_URL') baseUrl: string) { @@ -18,42 +20,101 @@ export class CharacterService { } getLoggedCharacters(): Observable { - return this.http.get>(this.baseUrl + 'loggedCharacters').pipe( - switchMap(response => { - if (response.isLeft) { - return of(response.left); - } else { - return throwError(response.right); - } - }), - retry(3) - ); + return this.http + .get>( + this.baseUrl + 'loggedCharacters' + ) + .pipe( + switchMap((response) => { + if (response.isLeft) { + return of(response.left); + } else { + return throwError(response.right); + } + }), + retry(3) + ); } - getUserCharactersList(userId: number): Observable { - const params = new HttpParams().set('userId', userId.toString()) - return this.http.get>(this.baseUrl + 'userCharactersList', {params}).pipe( - switchMap(response => { - if (response.isLeft) { - return of(response.left); - } else { - return throwError(response.right); - } - }) - ); + getUserCharactersList( + userId: number + ): Observable { + const params = new HttpParams().set('userId', userId.toString()); + return this.http + .get>( + this.baseUrl + 'userCharactersList', + { params } + ) + .pipe( + switchMap((response) => { + if (response.isLeft) { + return of(response.left); + } else { + return throwError(response.right); + } + }) + ); } - getCharacterStats(characterId: number): Observable { - const params = new HttpParams().set('characterId', characterId.toString()) - return this.http.get>( this.baseUrl + 'characterStats', {params}).pipe( - switchMap( response => { - if (response.isLeft) { - return of(response.left); - } else { - return throwError(response.right); - } - }) - ); + getCharacterStats( + characterId: number + ): Observable { + const params = new HttpParams().set('characterId', characterId.toString()); + return this.http + .get>( + this.baseUrl + 'characterStats', + { params } + ) + .pipe( + switchMap((response) => { + if (response.isLeft) { + return of(response.left); + } else { + return throwError(response.right); + } + }) + ); } + getTemplateCharacters(): Observable { + return this.http + .get>( + this.baseUrl + 'getTemplateCharacters' + ) + .pipe( + switchMap((response) => { + if (response.isLeft) { + return of(response.left); + } else { + return throwError(response.right); + } + }) + ); + } + + createCharacterFromTemplate( + characterId: number, + userId: number, + newName: string + ): Observable { + const params = new HttpParams() + .set('characterId', characterId.toString()) + .set('userId', userId.toString()) + .set('newName', newName); + return this.http + .post>( + this.baseUrl + 'createCharacterFromTemplate', + null, + { params } + ) + .pipe( + switchMap((response) => { + if (response.isLeft) { + return of(response.left); + } else { + return throwError(response.right); + } + }) + ); + } } diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/styles.css b/SessionCompanion/SessionCompanion/ClientApp/src/styles.css index cbfb6da..32aa9dc 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/styles.css +++ b/SessionCompanion/SessionCompanion/ClientApp/src/styles.css @@ -41,6 +41,10 @@ opacity: 0.5; } +.arrow-forward:hover { + opacity: 0.5; +} + /* icon in mat-form-field*/ ::ng-deep mat-form-field { color: #df7c0f !important; diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/types/viewmodels/character-viewmodels/CharacterFromTemplatesViewModel.ts b/SessionCompanion/SessionCompanion/ClientApp/src/types/viewmodels/character-viewmodels/CharacterFromTemplatesViewModel.ts new file mode 100644 index 0000000..cbc7927 --- /dev/null +++ b/SessionCompanion/SessionCompanion/ClientApp/src/types/viewmodels/character-viewmodels/CharacterFromTemplatesViewModel.ts @@ -0,0 +1,6 @@ +export interface CharacterFromTemplatesViewModel { + id: number; + name: string; + race: string; + class: number; +} diff --git a/SessionCompanion/SessionCompanion/Controllers/CharacterController.cs b/SessionCompanion/SessionCompanion/Controllers/CharacterController.cs index 1b03b8b..23def0e 100644 --- a/SessionCompanion/SessionCompanion/Controllers/CharacterController.cs +++ b/SessionCompanion/SessionCompanion/Controllers/CharacterController.cs @@ -116,7 +116,7 @@ namespace SessionCompanion.Controllers /// /// liste podstawowych informacji o postaciach z templatki [HttpGet("getTemplateCharacters")] - public async Task>> GetTemplateCharacters() + public async Task, ErrorResponse>> GetTemplateCharacters() { var races = _raceService.Get().ToList(); var classes = _classService.Get().ToList(); @@ -159,4 +159,4 @@ namespace SessionCompanion.Controllers } } } -} \ No newline at end of file +}