diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app.routing.ts b/SessionCompanion/SessionCompanion/ClientApp/src/app.routing.ts index 684f3c4..934f5a4 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/app.routing.ts +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app.routing.ts @@ -36,7 +36,7 @@ const routes: Routes = [ path: 'select-character', component: SelectCharacterComponent, 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 198fa74..b8b0bb0 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/app/app.module.ts +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/app.module.ts @@ -37,6 +37,8 @@ import { AbilityCardComponent } from './components/ability-card/ability-card.com import { GameMasterSpellsTableComponent } from './components/game-master-spells-table/game-master-spells-table.component'; import { GameMasterArmorsTableComponent } from './components/game-master-armors-table/game-master-armors-table.component'; import { GameMasterCharacterActionsDialogComponent } from './components/game-master-character-actions-dialog/game-master-character-actions-dialog.component'; +import { GameMasterWeaponsTableComponent } from './components/game-master-weapons-table/game-master-weapons-table.component'; +import { AbilitiesComponent } from './components/abilities/abilities.component'; @NgModule({ declarations: [ @@ -83,6 +85,8 @@ import { GameMasterCharacterActionsDialogComponent } from './components/game-mas entryComponents: [ GameMasterSpellsTableComponent, GameMasterArmorsTableComponent, + GameMasterWeaponsTableComponent, + AbilitiesComponent, GameMasterCharacterActionsDialogComponent, ], }) diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/abilities/abilities.component.css b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/abilities/abilities.component.css new file mode 100644 index 0000000..e69de29 diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/abilities/abilities.component.html b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/abilities/abilities.component.html new file mode 100644 index 0000000..df7c03d --- /dev/null +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/abilities/abilities.component.html @@ -0,0 +1,6 @@ +
+ + +
diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/abilities/abilities.component.ts b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/abilities/abilities.component.ts new file mode 100644 index 0000000..13d52ee --- /dev/null +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/abilities/abilities.component.ts @@ -0,0 +1,38 @@ +import { Component, OnInit } from '@angular/core'; +import {CharacterStatsViewModel} from "../../../types/viewmodels/character-viewmodels/CharacterStatsViewModel"; +import {Store} from "@ngrx/store"; +import {AppState} from "../../store/models/app-state.model"; +import {CharacterService} from "../../../services/character.service"; +import {first} from "rxjs/operators"; +import {ErrorResponse} from "../../../types/ErrorResponse"; +import {HttpErrorResponse} from "@angular/common/http"; + +@Component({ + selector: 'app-abilities', + templateUrl: './abilities.component.html', + styleUrls: ['./abilities.component.css'] +}) +export class AbilitiesComponent implements OnInit { + characterStats: CharacterStatsViewModel[]; + + constructor(private store: Store, private characterService: CharacterService) {} + + ngOnInit() { + this.getCharacterStats(); + } + + getCharacterStats() { + this.store.select( s => s.playerStore.characterId).pipe(first()).subscribe((characterId) => { + this.characterService.getCharacterStats(characterId).pipe(first()).subscribe((characterStats) => { + console.log(characterStats) + this.characterStats = characterStats; + }, (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/ability-card/ability-card.component.css b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/ability-card/ability-card.component.css index d728057..cc66099 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/ability-card/ability-card.component.css +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/ability-card/ability-card.component.css @@ -1,30 +1,84 @@ +#ability-value:hover{ + opacity: 0.5; + cursor: pointer; +} + +#ability-saving-throws:hover{ + opacity: 0.5; + cursor: pointer; +} + +.cardContainerClass { + border: 2px solid; + border-radius: 10px; + box-shadow: 0 0 8px; +} + #main{ width: 480px; - height: 480px; + padding-bottom: 15px; } + +@media (max-width: 468px) { + #main { + width: 340px; + } +} + +@media (min-width: 468px) and (max-width: 768px) { + #main { + width: 420px; + } +} + +@media (min-width: 768px) { + #main { + width: 480px; + } +} + #main>.mat-card{ padding: 0; } .diagonal-line{ width:50px; - background:linear-gradient(45deg,rgb(16 32 40 / 0%) 49%,black,#ffffff00 51%); + background:linear-gradient(45deg,rgb(16 32 40 / 0%) 49%,white,#ffffff00 51%); } + +#ability-card-header { + font-weight: 600; + border-radius: 10px 10px 0 0; +} + +@media (max-width: 468px) { + #ability-card-header { + font-size: 11px; + } +} + #ability-card-content{ display: flex; flex-wrap: wrap; justify-content: space-around; padding-top: 10px; padding-bottom: 10px; + border-radius: 0 0 10px 10px; } #skill-btn{ - border-color: black; + border: 2px solid #9e814d; flex: 1 0 auto; margin-bottom: 10px; margin-left: 10px; margin-right: 10px; + border-radius: 5px; } + +#skill-btn:hover{ + opacity: 0.5; +} + #skill-btn-divider{ - border-left: black 1px solid; + border-left: #9e814d 2px solid; padding-right: 10px; padding-top: 10px; padding-bottom: 10px; diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/ability-card/ability-card.component.html b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/ability-card/ability-card.component.html index 376fea9..6f53f46 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/ability-card/ability-card.component.html +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/ability-card/ability-card.component.html @@ -1,22 +1,22 @@
- + - {{ability.value}} +
{{ability.value}}
Mod: {{ability.modification > 0? '+' + ability.modification : '-' + ability.modification}}
{{ability.name}}
- ST: {{ability.savingThrows > 0? '+' + ability.savingThrows : '-' + ability.savingThrows}} +
ST: {{ability.savingThrows > 0? '+' + ability.savingThrows : '-' + ability.savingThrows}}
- + {{skill.name}}     - + {{skill.value > 0? '+' + skill.value : '-' + skill.value}} diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/ability-card/ability-card.component.ts b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/ability-card/ability-card.component.ts index f525ccd..931a167 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/ability-card/ability-card.component.ts +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/ability-card/ability-card.component.ts @@ -1,5 +1,6 @@ import { Component, Input, OnInit } from '@angular/core'; import { AbilityViewModel } from '../../../types/viewmodels/ability-viewmodels/AbilityViewModel'; +import {CharacterStatsViewModel} from "../../../types/viewmodels/character-viewmodels/CharacterStatsViewModel"; @Component({ selector: 'app-ability-card', @@ -7,7 +8,7 @@ import { AbilityViewModel } from '../../../types/viewmodels/ability-viewmodels/A styleUrls: ['./ability-card.component.css'], }) export class AbilityCardComponent implements OnInit { - @Input() ability: AbilityViewModel; + @Input() ability: CharacterStatsViewModel; @Input() headStyle: { bgColor: string; textColor: string }; @Input() contentStyle: { bgColor: string; textColor: string }; @@ -15,5 +16,29 @@ export class AbilityCardComponent implements OnInit { ngOnInit() { this.ability.skills.sort((a, b) => (a.name > b.name ? 1 : -1)); + this.changeColors(); + } + + changeColors(){ + switch(this.ability.name){ + case 'Charisma': + this.headStyle.bgColor = '#FFEB85'; + break; + case 'Dexterity': + this.headStyle.bgColor = '#4BBE9C'; + break; + case 'Constitution': + this.headStyle.bgColor = 'red'; + break; + case 'Intelligence': + this.headStyle.bgColor = '#5AA9E6'; + break; + case 'Strength': + this.headStyle.bgColor = '#C41E3D'; + break; + case 'Wisdom': + this.headStyle.bgColor = '#9F4BBE'; + break; + } } } diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/game-master-dashboard/game-master-dashboard.component.ts b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/game-master-dashboard/game-master-dashboard.component.ts index 3b57d0d..bd03815 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/game-master-dashboard/game-master-dashboard.component.ts +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/game-master-dashboard/game-master-dashboard.component.ts @@ -15,6 +15,7 @@ import { GameMasterSpellsTableComponent } from '../game-master-spells-table/game import { GameMasterArmorsTableComponent } from '../game-master-armors-table/game-master-armors-table.component'; import { MatDialog } from '@angular/material'; import { GameMasterCharacterActionsDialogComponent } from '../game-master-character-actions-dialog/game-master-character-actions-dialog.component'; +import { GameMasterWeaponsTableComponent } from '../game-master-weapons-table/game-master-weapons-table.component'; @Component({ selector: 'app-game-master-dashboard', @@ -35,10 +36,16 @@ export class GameMasterDashboardComponent implements OnInit, OnDestroy { children: [ { displayName: 'Armor', - iconName: 'ra ra-vest', + iconName: 'ra ra-vest', expanded: false, componentToDisplay: 'GameMasterArmorsTableComponent', }, + { + displayName: 'Weapon', + iconName: 'ra ra-large-hammer', + expanded: false, + componentToDisplay: 'GameMasterWeaponsTableComponent', + }, ], }, { @@ -116,6 +123,9 @@ export class GameMasterDashboardComponent implements OnInit, OnDestroy { case 'GameMasterArmorsTableComponent': this.middleComponentName = GameMasterArmorsTableComponent; break; + case 'GameMasterWeaponsTableComponent': + this.middleComponentName = GameMasterWeaponsTableComponent; + break; } } diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/game-master-weapons-table/game-master-weapons-table.component.css b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/game-master-weapons-table/game-master-weapons-table.component.css new file mode 100644 index 0000000..83e5e96 --- /dev/null +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/game-master-weapons-table/game-master-weapons-table.component.css @@ -0,0 +1,38 @@ +.description-weapon-column { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +table { + width: 100%; + background-color: initial; +} + +mat-paginator { + background-color: initial; + color: white; +} + +::ng-deep .mat-select-arrow { + color: whitesmoke; +} + +::ng-deep .mat-select-value { + color: white; +} + +.mat-sort-header-container { + color: whitesmoke !important; +} + +.mat-form-field { + font-size: 14px; + width: 100%; +} + +td, +th { + color: whitesmoke; + width: 25%; +} diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/game-master-weapons-table/game-master-weapons-table.component.html b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/game-master-weapons-table/game-master-weapons-table.component.html new file mode 100644 index 0000000..966d65d --- /dev/null +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/game-master-weapons-table/game-master-weapons-table.component.html @@ -0,0 +1,43 @@ + + Filter + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Name {{row.name}} Weapon Type {{row.weaponType}} Weight {{row.weight}} Cost {{row.cost}} $ Description {{row.description}}
No data matching the filter "{{input.value}}"
+ + +
diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/game-master-weapons-table/game-master-weapons-table.component.ts b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/game-master-weapons-table/game-master-weapons-table.component.ts new file mode 100644 index 0000000..4a17e31 --- /dev/null +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/game-master-weapons-table/game-master-weapons-table.component.ts @@ -0,0 +1,58 @@ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { MatTableDataSource } from '@angular/material/table'; +import { MatPaginator } from '@angular/material/paginator'; +import { MatSort } from '@angular/material/sort'; +import { WeaponViewModel } from '../../../types/viewmodels/weapon-viewmodels/WeaponViewModel'; + +@Component({ + selector: 'app-game-master-weapons-table', + templateUrl: './game-master-weapons-table.component.html', + styleUrls: ['./game-master-weapons-table.component.css'], +}) +export class GameMasterWeaponsTableComponent implements OnInit { + displayedColumns: string[] = [ + 'Name', + 'WeaponType', + 'Weight', + 'Cost', + 'Description', + ]; + dataSource: MatTableDataSource; + + @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator; + @ViewChild(MatSort, { static: true }) sort: MatSort; + + constructor() { + const weapons = [ + { + id: 1, + name: 'Test', + cost: 123, + weight: 98, + diceCount: 2, + diceValue: 20, + twoHandDamageType: 'Toxic', + description: + 'A japanase battleaxe with a spike on the opposite side of the blade.', + weaponType: 'Two-Handed Melee Weapons', + rangeMeele: 50, + }, + ]; + + this.dataSource = new MatTableDataSource(weapons); + } + + ngOnInit() { + this.dataSource.paginator = this.paginator; + this.dataSource.sort = this.sort; + } + + applyFilter(event: Event) { + const filterValue = (event.target as HTMLInputElement).value; + this.dataSource.filter = filterValue.trim().toLowerCase(); + + if (this.dataSource.paginator) { + this.dataSource.paginator.firstPage(); + } + } +} diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/player-dashboard/player-dashboard.component.html b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/player-dashboard/player-dashboard.component.html index 994aab5..abbccd2 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/player-dashboard/player-dashboard.component.html +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/player-dashboard/player-dashboard.component.html @@ -15,37 +15,32 @@ - - home - Home - - - + query_stats - Statistic and throws + Statistic and throws - + local_mall Equipment - + brightness_4 Spells - + account_circle Profile - + shopping_cart Shop - + exit_to_app Log out @@ -53,7 +48,9 @@ - +
+ +
diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/player-dashboard/player-dashboard.component.ts b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/player-dashboard/player-dashboard.component.ts index 017e2b2..11d9924 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/player-dashboard/player-dashboard.component.ts +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/player-dashboard/player-dashboard.component.ts @@ -1,9 +1,9 @@ import { Component, OnInit } from '@angular/core'; -import { AbilityViewModel } from "../../../types/viewmodels/ability-viewmodels/AbilityViewModel"; import { PlayerSignalRService } from "../../shared/signalR-service/player-signalR.service"; import { first } from "rxjs/operators"; import { Store } from '@ngrx/store'; import { AppState } from 'src/app/store/models/app-state.model'; +import { AbilitiesComponent } from '../abilities/abilities.component'; @Component({ selector: 'app-player-dashboard', @@ -11,6 +11,7 @@ import { AppState } from 'src/app/store/models/app-state.model'; styleUrls: ['./player-dashboard.component.css'], }) export class PlayerDashboardComponent implements OnInit { + middleComponent; isExpanded = false; selected = false; @@ -20,25 +21,17 @@ export class PlayerDashboardComponent implements OnInit { this.store.select(s => s.playerStore.characterId).pipe(first()).subscribe((id) => { this.signalRService.Login(id); }); - } - - ability: AbilityViewModel = { - id: 1, - name: 'Strength', - value: 18, - modification: 2, - canSaveThrows: true, - savingThrows: 1, - skills: [ - { - name: 'Throw', - value: 1, - can: false - } - ] + this.SwitchMiddleComponent('AbilitiesComponent'); } toggle() { - this.isExpanded = !this.isExpanded; + this.isExpanded = !this.isExpanded; + } + + SwitchMiddleComponent(componentName: string) { + switch(componentName){ + case 'AbilitiesComponent': + this.middleComponent = AbilitiesComponent; + } } } diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/services/character.service.ts b/SessionCompanion/SessionCompanion/ClientApp/src/services/character.service.ts index c390a44..db70675 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/services/character.service.ts +++ b/SessionCompanion/SessionCompanion/ClientApp/src/services/character.service.ts @@ -6,6 +6,7 @@ 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"; Injectable({ providedIn: 'root' @@ -41,4 +42,18 @@ export class CharacterService { }) ); } + + 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); + } + }) + ); + } + } diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/types/viewmodels/character-viewmodels/CharacterStatsViewModel.ts b/SessionCompanion/SessionCompanion/ClientApp/src/types/viewmodels/character-viewmodels/CharacterStatsViewModel.ts new file mode 100644 index 0000000..aa01f12 --- /dev/null +++ b/SessionCompanion/SessionCompanion/ClientApp/src/types/viewmodels/character-viewmodels/CharacterStatsViewModel.ts @@ -0,0 +1,13 @@ +export interface CharacterStatsViewModel { + id: number; + name: string; + value: number; + modification: number; + savingThrows: number; + canSaveThrows: boolean; + skills: [{ + name: string; + value: number; + can: boolean; + }]; +} diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/types/viewmodels/weapon-viewmodels/WeaponViewModel.ts b/SessionCompanion/SessionCompanion/ClientApp/src/types/viewmodels/weapon-viewmodels/WeaponViewModel.ts new file mode 100644 index 0000000..27e80a4 --- /dev/null +++ b/SessionCompanion/SessionCompanion/ClientApp/src/types/viewmodels/weapon-viewmodels/WeaponViewModel.ts @@ -0,0 +1,17 @@ +export interface WeaponViewModel { + id: number; + name: string; + cost: number; + weight: number; + diceCount: number; + diceValue: number; + twoHandDiceCount?: number; + twoHandDiceValue?: number; + twoHandDamageType: string; + description: string; + weaponType: string; + rangeMeele: number; + rangeThrowNormal?: number; + rangeThrowLong?: number; + rangeLong?: number; +}