initialize pitch types on login

This commit is contained in:
Sascha Kühl 2025-03-30 22:24:06 +02:00
parent bae8d26e59
commit 30a19cc110
10 changed files with 63 additions and 39 deletions

View File

@ -1,15 +1,9 @@
<template>
<ion-app>
<ion-router-outlet />
</ion-app>
</template>
<script setup lang="ts"> <script setup lang="ts">
import { IonApp, IonRouterOutlet } from '@ionic/vue'; import { IonApp, IonRouterOutlet } from '@ionic/vue';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { useStore } from 'vuex' import { useStore } from 'vuex'
import { AppStore } from '@/store'; import { AppStore } from '@/store';
import { onMounted, onBeforeUnmount } from "vue"; import { onMounted, onBeforeUnmount, ref } from "vue";
import EventBus from "./common/EventBus"; import EventBus from "./common/EventBus";
const router = useRouter(); const router = useRouter();
@ -20,13 +14,30 @@ const logout = () => {
router.push('/login'); router.push('/login');
} }
const isOnline = ref(navigator.onLine);
onMounted(() => { onMounted(() => {
EventBus.on("logout", () => { EventBus.on("logout", () => {
logout(); logout();
}); });
window.addEventListener("online", () => isOnline.value = true);
window.addEventListener("offline", () => isOnline.value = false);
if (isOnline.value) {
router.push("/login");
} else {
// checkStoredUserData();
}
}); });
onBeforeUnmount(() => { onBeforeUnmount(() => {
EventBus.remove("logout", null); EventBus.remove("logout", null);
}) })
</script> </script>
<template>
<ion-app>
<ion-router-outlet />
</ion-app>
</template>

View File

@ -1,5 +1,4 @@
export default class AuthHeader { export default function authHeader(): any {
public header(): any {
const user = JSON.parse(localStorage.getItem('user') || '""'); const user = JSON.parse(localStorage.getItem('user') || '""');
if (user && user.accessToken) { if (user && user.accessToken) {
@ -8,5 +7,4 @@ export default class AuthHeader {
} else { } else {
return {}; return {};
} }
}
} }

View File

@ -1,5 +1,6 @@
import PitchType from "@/types/PitchType"; import PitchType from "@/types/PitchType";
import api from './Api'; import api from './Api';
import authHeader from './AuthHeader';
class PitchTypeService { class PitchTypeService {
private static instance: PitchTypeService; private static instance: PitchTypeService;
@ -15,18 +16,13 @@ class PitchTypeService {
} }
async getAllPitchTypes(): Promise<PitchType[]> { async getAllPitchTypes(): Promise<PitchType[]> {
const users = await api.get('/pitch_types'); const users = await api.get('/pitch_types', { headers: authHeader() });
return users.data; return users.data;
} }
async getPitchType(id: number): Promise<PitchType> { async getPitchType(id: number): Promise<PitchType> {
const pitchType = await api.get(`/pitch_types/${id}`); const pitchType = await api.get(`/pitch_types/${id}`, { headers: authHeader() });
return pitchType.data; return pitchType.data;
// if (pitcher !== undefined) {
// return pitcher;
// } else {
// return Promise.reject();
// }
} }
} }

View File

@ -39,7 +39,7 @@ const auth: Module<AuthState, RootState> = {
commit('logout'); commit('logout');
}, },
register({ commit }: AuthActionContext, user) { register({ commit }: AuthActionContext, user) {
return AuthService.register(user.firstName, user.email, user.password).then( return AuthService.register(user.email, user.password).then(
response => { response => {
commit('registerSuccess'); commit('registerSuccess');
return Promise.resolve(response.data); return Promise.resolve(response.data);

View File

@ -1,3 +1,4 @@
import { InjectionKey } from 'vue'
import { createStore, Store } from 'vuex'; import { createStore, Store } from 'vuex';
import auth, {AuthState} from './auth'; import auth, {AuthState} from './auth';
import pitchTypes, {PitchTypeState} from './pitchType'; import pitchTypes, {PitchTypeState} from './pitchType';
@ -8,6 +9,8 @@ export interface RootState {
pitchTypes: PitchTypeState; pitchTypes: PitchTypeState;
} }
export const key: InjectionKey<Store<RootState>> = Symbol()
const store = createStore<RootState>({ const store = createStore<RootState>({
modules: { modules: {
auth, auth,

View File

@ -28,6 +28,7 @@ const pitchTypes: Module<PitchTypeState, RootState> = {
}, },
mutations: { mutations: {
initializedPitchTypes(state, pitchTypeList: PitchType[]) { initializedPitchTypes(state, pitchTypeList: PitchType[]) {
localStorage.setItem("pitchTypes", JSON.stringify(pitchTypeList));
state.pitchTypes = pitchTypeList; state.pitchTypes = pitchTypeList;
} }
} }

View File

@ -29,7 +29,7 @@
</ion-card> </ion-card>
</ion-content> </ion-content>
<ion-footer> <ion-footer>
<ion-button expand="full" color="success" @click="gotoPitcherList">Goto Pitcher List</ion-button> <ion-button expand="full" color="success" @click="gotoHome">Home</ion-button>
</ion-footer> </ion-footer>
</ion-page> </ion-page>
</template> </template>
@ -79,10 +79,10 @@ export default defineComponent({
const router = useRouter(); const router = useRouter();
const bps = ref<BullpenSessionService>(bullpenSessionService); const bps = ref<BullpenSessionService>(bullpenSessionService);
const gotoPitcherList = () => { const gotoHome = () => {
router.push({ name: 'Pitchers' }); router.push('/home');
} }
return {bps, gotoPitcherList}; return {bps, gotoHome};
} }
}); });

View File

@ -1,21 +1,26 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue'; // import { ref } from 'vue';
import { IonPage, IonHeader, IonToolbar, IonTitle, IonContent, IonAvatar, IonButton, IonIcon } from '@ionic/vue'; import { IonPage, IonHeader, IonToolbar, IonTitle, IonContent, IonAvatar, IonButton, IonIcon } from '@ionic/vue';
import { playOutline, statsChartOutline, personOutline } from 'ionicons/icons'; import { playOutline, statsChartOutline, personOutline } from 'ionicons/icons';
import img from '../assets/groot.jpg' import img from '../assets/groot.jpg'
import {useRouter} from "vue-router";
const userImage = ref('../assets/groot.jpg'); // Replace with actual user image URL const router = useRouter();
// const userImage = ref('../assets/groot.jpg'); // Replace with actual user image URL
const startBullpen = () => { const startBullpen = () => {
console.log('Starting bullpen session'); console.log('Starting bullpen session');
router.push({ path: '/prepare' });
}; };
const showStats = () => { const showStats = () => {
console.log('Showing bullpen stats'); console.log('Showing bullpen stats');
router.push({ path: '/stats' });
}; };
const showProfile = () => { const showProfile = () => {
console.log('Showing profile'); console.log('Showing profile');
router.push({ path: '/profile' });
}; };
</script> </script>

View File

@ -16,12 +16,12 @@
<ion-list> <ion-list>
<ion-item> <ion-item>
<ion-icon name="person" class="icon-login"></ion-icon> <ion-icon :icon="personOutline" class="icon-login"></ion-icon>
<ion-input name="user" v-model="email" v-bind="emailAttrs" type="text" required placeholder="Username"></ion-input> <ion-input name="user" v-model="email" v-bind="emailAttrs" type="text" required placeholder="Username"></ion-input>
</ion-item> </ion-item>
<br /> <br />
<ion-item> <ion-item>
<ion-icon name="lock" class="icon-login"></ion-icon> <ion-icon :icon="lockClosedOutline" class="icon-login"></ion-icon>
<ion-input name="password" v-model="password" v-bind="passwordAttrs" type="password" required placeholder="Password"></ion-input> <ion-input name="password" v-model="password" v-bind="passwordAttrs" type="password" required placeholder="Password"></ion-input>
</ion-item> </ion-item>
@ -79,6 +79,7 @@ import {
IonInput, IonInput,
IonIcon, IonIcon,
} from "@ionic/vue"; } from "@ionic/vue";
import { lockClosedOutline, personOutline } from 'ionicons/icons';
import { useForm } from 'vee-validate'; import { useForm } from 'vee-validate';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { useStore } from 'vuex' import { useStore } from 'vuex'
@ -104,7 +105,7 @@ const loggedIn = computed(() => store.state.auth.isAuthenticated);
onMounted(() => { onMounted(() => {
if (loggedIn.value) { if (loggedIn.value) {
router.push('/prepare'); onLogin();
} }
}); });
@ -114,10 +115,11 @@ const submit = handleSubmit(values => {
password: values.password, password: values.password,
}).then( }).then(
() => { () => {
router.push('/prepare'); onLogin();
}, },
error => { error => {
loading.value = false; loading.value = false;
console.log(error);
// message.value = // message.value =
// (error.response && error.response.data && error.response.data.message) || // (error.response && error.response.data && error.response.data.message) ||
// error.message || // error.message ||
@ -128,4 +130,13 @@ const submit = handleSubmit(values => {
loading.value = false; loading.value = false;
}); });
const onLogin = () => {
console.log('check if pitch types are available.');
store.dispatch('pitchTypes/initialize').then(() => {
router.push('/home');
}, error => {
console.log(error);
});
}
</script> </script>

9
app/src/vuex.d.ts vendored
View File

@ -1,13 +1,12 @@
import { Store } from 'vuex' import { Store } from 'vuex'
import Pitcher from 'types/Pitcher' import {AuthState} from '@/store/auth'
import {PitchTypeState} from '@/store/pitchType'
declare module 'vue' { declare module 'vue' {
// declare your own auth states // declare your own auth states
interface State { interface State {
status: { auth: AuthState,
loggedIn: boolean pitchTypes: PitchTypeState
},
user: Pitcher | null
} }
// provide typings for `this.$auth` // provide typings for `this.$auth`