progress on player list

This commit is contained in:
Sascha Kühl 2025-05-27 08:15:03 +02:00
parent a7b784de27
commit 3fa9ff42b5
10 changed files with 61 additions and 35 deletions

View File

@ -1,7 +1,7 @@
import { createRouter, createWebHistory } from '@ionic/vue-router';
import { useStore } from 'vuex'
import { RouteRecordRaw } from 'vue-router';
import PitcherList from '../views/PitcherList.vue'
import PlayerList from '../views/PlayerList.vue'
import LoginView from '../views/LoginView.vue'
import HomeView from '../views/HomeView.vue'
import BullpenView from "@/views/BullpenView.vue";
@ -17,7 +17,7 @@ const routes: Array<RouteRecordRaw> = [
{ path: '/setup', component: SetupView },
{ path: '/home', component: HomeView },
{ path: '/profile', component: ProfileView },
{ path: '/pitchers', component: PitcherList },
{ path: '/player', component: PlayerList },
{ path: '/bullpen', component: BullpenView },
{ path: '/stats', component: BullpenListView },
{ path: '/summary', component: BullpenSummaryView }

View File

@ -28,6 +28,23 @@ class TokenService {
removeUser() {
localStorage.removeItem("auth");
}
isAdmin() {
return this.hasRole('ROLE_ADMIN');
}
isCoach() {
return this.hasRole('ROLE_COACH');
}
isPlayer() {
return this.hasRole('ROLE_PLAYER');
}
private hasRole(role: string) {
const user = this.getUser();
return user?.roles ? user.roles.includes(role) : false;
}
}
export default new TokenService();

View File

@ -5,9 +5,6 @@ import {ActionContext, Module} from 'vuex';
import {RootState} from './index';
import TokenService from "@/services/TokenService";
import UserService from "@/services/UserService";
import PlayerService from "@/services/PlayerService";
import UserInfo from '@/types/UserInfo';
import Player from '@/types/Player';
export interface AuthState {
isAuthenticated: boolean;

View File

@ -18,13 +18,13 @@ const pitchTypes: Module<PlayerState, RootState> = {
determinePlayer({commit}: PlayerActionContext, user: User) {
if (user.roles.includes('ROLE_PLAYER')) {
playerService.fetchByUserId(user.id).then(player => {
commit('initialize', player);
commit('select', player);
});
}
}
},
mutations: {
initialize(state, player: Player) {
select(state, player: Player) {
state.player = player;
}
}

View File

@ -1,3 +1,5 @@
import User from "@/types/User";
export default interface Player {
id: number,
gender: string,
@ -9,5 +11,5 @@ export default interface Player {
state: string,
createdAt: Date,
updatedAt: Date,
userId: number
user: User
}

View File

@ -1,28 +1,32 @@
<script setup lang="ts">
import {computed, ref} from 'vue';
import { IonPage, IonHeader, IonToolbar, IonTitle, IonContent, IonAvatar, IonButton, IonIcon } from '@ionic/vue';
import { playOutline, statsChartOutline, personOutline, logOutOutline } from 'ionicons/icons';
// import userImage from '../assets/groot.jpg'
import { playOutline, statsChartOutline, personOutline, logOutOutline, personAddOutline } from 'ionicons/icons';
import {useStore} from "vuex";
import {useRouter} from "vue-router";
import BullpenSessionService from "@/services/BullpenSessionService";
import TokenService from "@/services/TokenService";
const router = useRouter();
const store = useStore();
const userImage = ref(null);
// const userImage = ref('../assets/groot.jpg');
const pitcher = computed(() => store.state.auth.user);
const user = computed(() => store.state.auth.user);
const player = computed(() => store.state.player.player);
const isAuthenticated = computed(() => store.state.auth.isAuthenticated);
if (pitcher.value === undefined || pitcher.value === null || pitcher.value === '') {
if (user.value === undefined || user.value === null || user.value === '') {
router.push({ path: '/login' });
}
const startBullpen = () => {
store.dispatch("bullpen/start", pitcher.value);
if (player.value === undefined || player.value === null || player.value === '') {
router.push({ path: '/player' });
} else {
store.dispatch("bullpen/start", user.value);
router.push({ path: '/bullpen' });
}
};
const showStats = () => {
@ -43,13 +47,16 @@ const logout = () => {
console.log(error);
});
}
const addPlayer = () => {}
</script>
<template>
<ion-page>
<ion-header>
<ion-toolbar>
<ion-title v-if="isAuthenticated">Home of {{ pitcher.firstName }} {{ pitcher.lastName }}</ion-title>
<ion-title v-if="isAuthenticated">Home of {{ user.firstName }} {{ user.lastName }}</ion-title>
<ion-title v-else>Home</ion-title>
</ion-toolbar>
</ion-header>
@ -64,7 +71,7 @@ const logout = () => {
<ion-icon :icon="personOutline" class="avatar-placeholder" />
</template>
</ion-avatar>
<div v-if="isAuthenticated" class="user-name">{{ pitcher.firstName }} {{ pitcher.lastName }}</div>
<div v-if="isAuthenticated" class="user-name">{{ user.firstName }} {{ user.lastName }}</div>
</div>
<div class="button-grid">
@ -84,6 +91,10 @@ const logout = () => {
<ion-icon :icon="logOutOutline" slot="start" />
Logout
</ion-button>
<ion-button v-if="TokenService.isCoach()" @click="addPlayer" class="grid-button">
<ion-icon :icon="personAddOutline" slot="start" />
Add Player
</ion-button>
</div>
</ion-content>
</ion-page>

View File

@ -1,24 +1,22 @@
<script setup lang="ts">
import { ref, onMounted } from "vue";
import { useRouter } from "vue-router";
import { useStore } from 'vuex'
import { IonContent, IonHeader, IonPage, IonTitle, IonToolbar, IonList, IonItem, IonLabel } from '@ionic/vue';
import UserService from "@/services/UserService";
import User from "@/types/User";
// import BullpenSessionService from "@/services/BullpenSessionService";
import PlayerService from "@/services/PlayerService";
import Player from "@/types/Player";
const pitchers = ref<User[]>([]);
const players = ref<Player[]>([]);
const router = useRouter();
// const bps = ref(BullpenSessionService);
// bps.value.clear();
const store = useStore();
onMounted(async () => {
pitchers.value = await UserService.fetchAll();
players.value = await PlayerService.fetchAll();
});
const goToPreparePitch = (pitcher: User) => {
console.log(pitcher);
// bps.value.startSession( pitcher );
const selectPlayer = (player: Player) => {
console.log(player);
store.commit("player/select", player);
router.push({ path: '/bullpen' });
};
@ -40,8 +38,8 @@ const goToPreparePitch = (pitcher: User) => {
</ion-header>
<ion-list>
<ion-item v-for="(pitcher, index) in pitchers" :key="index" button @click="goToPreparePitch(pitcher)">
<ion-label>{{ pitcher.firstName }} {{ pitcher.lastName }}</ion-label>
<ion-item v-for="(player, index) in players" :key="index" button @click="selectPlayer(player)">
<ion-label>{{ player.user.firstName }} {{ player.user.lastName }}</ion-label>
</ion-item>
</ion-list>
</ion-content>

View File

@ -1,10 +1,10 @@
import { mount } from '@vue/test-utils'
import HomePage from '../../src/views/PitcherList.vue'
import PlayerList from '../../src/views/PlayerList.vue'
import { describe, expect, test } from 'vitest'
describe('PitcherList.vue', () => {
describe('PlayerList.vue', () => {
test('renders home vue', () => {
const wrapper = mount(HomePage)
const wrapper = mount(PlayerList)
expect(wrapper.text()).toMatch('Ready to create an app?')
})
})

View File

@ -34,7 +34,7 @@ exports.findAll = (req, res) => {
Player.findAll({
where: condition,
include: { model: User }
include: ['user']
}).then(data => {
res.send(data);
}).catch(err => {

View File

@ -9,7 +9,8 @@ module.exports = (sequelize, DataTypes) => {
*/
static associate(models) {
Player.belongsTo(models.User, {
foreignKey: "userId"
foreignKey: "userId",
as: "user"
});
}
}