updated app workflow to match backend changes, added server type
This commit is contained in:
parent
c4725a5d73
commit
1fa86d69ae
|
|
@ -13,6 +13,7 @@
|
||||||
/>
|
/>
|
||||||
<meta name="format-detection" content="telephone=no" />
|
<meta name="format-detection" content="telephone=no" />
|
||||||
<meta name="msapplication-tap-highlight" content="no" />
|
<meta name="msapplication-tap-highlight" content="no" />
|
||||||
|
<!-- <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">-->
|
||||||
|
|
||||||
<link rel="shortcut icon" type="image/png" href="/favicon.png" />
|
<link rel="shortcut icon" type="image/png" href="/favicon.png" />
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,10 @@ import { RouteRecordRaw } from 'vue-router';
|
||||||
import PitcherList from '../views/PitcherList.vue'
|
import PitcherList from '../views/PitcherList.vue'
|
||||||
import LoginView from '../views/LoginView.vue'
|
import LoginView from '../views/LoginView.vue'
|
||||||
import HomeView from '../views/HomeView.vue'
|
import HomeView from '../views/HomeView.vue'
|
||||||
import PreparePitch from "@/views/PreparePitch.vue";
|
import BullpenView from "@/views/BullpenView.vue";
|
||||||
import FinalizePitch from "@/views/FinalizePitch.vue";
|
import BullpenSummaryView from "@/views/BullpenSummaryView.vue";
|
||||||
import BullpenStats from "@/views/BullpenStats.vue";
|
|
||||||
import SetupView from '@/views/SetupView.vue';
|
import SetupView from '@/views/SetupView.vue';
|
||||||
|
import backendService from '@/services/BackendService'
|
||||||
|
|
||||||
const routes: Array<RouteRecordRaw> = [
|
const routes: Array<RouteRecordRaw> = [
|
||||||
{ path: '/', redirect: '/login' },
|
{ path: '/', redirect: '/login' },
|
||||||
|
|
@ -15,10 +15,8 @@ const routes: Array<RouteRecordRaw> = [
|
||||||
{ path: '/setup', component: SetupView },
|
{ path: '/setup', component: SetupView },
|
||||||
{ path: '/home', component: HomeView },
|
{ path: '/home', component: HomeView },
|
||||||
{ path: '/pitchers', component: PitcherList },
|
{ path: '/pitchers', component: PitcherList },
|
||||||
{ path: '/bullpen', component: PreparePitch },
|
{ path: '/bullpen', component: BullpenView },
|
||||||
{ path: '/prepare', component: PreparePitch },
|
{ path: '/summary', component: BullpenSummaryView }
|
||||||
{ path: '/finalize', component: FinalizePitch },
|
|
||||||
{ path: '/stats', component: BullpenStats }
|
|
||||||
]
|
]
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
|
|
@ -28,20 +26,19 @@ const router = createRouter({
|
||||||
|
|
||||||
router.beforeEach((to, from, next) => {
|
router.beforeEach((to, from, next) => {
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
const serverAddress = localStorage.getItem('serverAddress');
|
|
||||||
const isAuthenticated = store.state.auth.isAuthenticated;
|
const isAuthenticated = store.state.auth.isAuthenticated;
|
||||||
|
|
||||||
if (to.meta.requiresAuth && !isAuthenticated) {
|
if (to.meta.requiresAuth && !isAuthenticated) {
|
||||||
return next('/login');
|
return next('/login');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!serverAddress && to.path !== '/setup') {
|
if (!backendService.hasServer() && to.path !== '/setup') {
|
||||||
return next('/setup');
|
return next('/setup');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (serverAddress && to.path === '/setup') {
|
// if (serverAddress && to.path === '/setup') {
|
||||||
return next('/login');
|
// return next('/login');
|
||||||
}
|
// }
|
||||||
|
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
|
||||||
|
const server = JSON.parse(localStorage.getItem("server") || '""');
|
||||||
|
|
||||||
const instance = axios.create({
|
const instance = axios.create({
|
||||||
baseURL: "http://localhost:8080/api",
|
baseURL: `${server.protocol}://${server.host}:${server.port}/api`,
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
import Server from "@/types/Server";
|
||||||
|
|
||||||
|
class BackendService {
|
||||||
|
hasServer(): boolean {
|
||||||
|
return localStorage.getItem("server") !== null;
|
||||||
|
}
|
||||||
|
getServer(): Server {
|
||||||
|
return JSON.parse(localStorage.getItem("server") || '{"protocol":"https","host":"localhost","port":8080}');
|
||||||
|
}
|
||||||
|
updateServer(server: Server): void {
|
||||||
|
localStorage.setItem("server", JSON.stringify(server));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new BackendService();
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import Pitch from "@/types/Pitch";
|
import Pitch from "@/types/Pitch";
|
||||||
import User from "@/types/User";
|
import User from "@/types/User";
|
||||||
import Bullpen from '@/types/Bullpen';
|
import Bullpen from '@/types/Bullpen';
|
||||||
import PitchTypeService from '@/services/PitchTypeService';
|
|
||||||
import api from '@/services/Api';
|
import api from '@/services/Api';
|
||||||
|
|
||||||
export class BullpenSessionService {
|
export class BullpenSessionService {
|
||||||
|
|
@ -18,10 +17,9 @@ export class BullpenSessionService {
|
||||||
public save(bullpen: Bullpen): Promise<Bullpen> {
|
public save(bullpen: Bullpen): Promise<Bullpen> {
|
||||||
console.log(JSON.stringify(bullpen, null, 2));
|
console.log(JSON.stringify(bullpen, null, 2));
|
||||||
return api
|
return api
|
||||||
.post('/bullpen_session', {
|
.post('/bullpen_session', bullpen)
|
||||||
bullpen
|
|
||||||
})
|
|
||||||
.then(response => {
|
.then(response => {
|
||||||
|
console.log(JSON.stringify(response.data, null, 2));
|
||||||
return response.data;
|
return response.data;
|
||||||
}, (error) => {
|
}, (error) => {
|
||||||
console.log(JSON.stringify(error, null, 2));
|
console.log(JSON.stringify(error, null, 2));
|
||||||
|
|
@ -30,9 +28,9 @@ export class BullpenSessionService {
|
||||||
|
|
||||||
public createPitch(): Pitch {
|
public createPitch(): Pitch {
|
||||||
return {
|
return {
|
||||||
id: 0,
|
id: undefined,
|
||||||
pitchTime: new Date(),
|
pitchTime: new Date(),
|
||||||
pitchTypeId: PitchTypeService.getLocalPitchTypes()[0].id,
|
pitchTypeId: 0,
|
||||||
aimedArea: 0,
|
aimedArea: 0,
|
||||||
hitArea: 0
|
hitArea: 0
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
export default interface Pitch {
|
export default interface Pitch {
|
||||||
id: number,
|
id: number | undefined,
|
||||||
pitchTime: Date,
|
pitchTime: Date,
|
||||||
pitchTypeId: number,
|
pitchTypeId: number,
|
||||||
aimedArea: number,
|
aimedArea: number,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
export default interface Server {
|
||||||
|
protocol: string,
|
||||||
|
host: string,
|
||||||
|
port: number
|
||||||
|
}
|
||||||
|
|
@ -16,6 +16,7 @@ import {
|
||||||
IonTitle,
|
IonTitle,
|
||||||
IonToolbar
|
IonToolbar
|
||||||
} from '@ionic/vue';
|
} from '@ionic/vue';
|
||||||
|
import PitchType from "@/types/PitchType";
|
||||||
import {useRouter} from 'vue-router';
|
import {useRouter} from 'vue-router';
|
||||||
import {computed} from 'vue';
|
import {computed} from 'vue';
|
||||||
import {useStore} from 'vuex';
|
import {useStore} from 'vuex';
|
||||||
|
|
@ -23,23 +24,36 @@ import {useStore} from 'vuex';
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
|
|
||||||
|
const isAuthenticated = computed(() => store.state.auth.isAuthenticated);
|
||||||
const pitcher = computed(() => store.state.auth.user);
|
const pitcher = computed(() => store.state.auth.user);
|
||||||
const bullpen = computed(() => store.state.bullpen.bullpen);
|
const pitchTypes = computed(() => store.state.pitchTypes.pitchTypes);
|
||||||
|
const bullpen = computed(() => store.state.bullpen);
|
||||||
|
|
||||||
|
console.log(JSON.stringify(bullpen.value.bullpen, null, 2));
|
||||||
|
|
||||||
|
const determinePitchTypeName = (id: number): string => {
|
||||||
|
const pitchType = pitchTypes.value.find((pitchType: PitchType) => pitchType.id === id);
|
||||||
|
|
||||||
|
return pitchType?.name ?? 'Unknown';
|
||||||
|
}
|
||||||
|
|
||||||
const gotoHome = () => {
|
const gotoHome = () => {
|
||||||
router.push('/home');
|
store.dispatch("bullpen/finish", bullpen.value.bullpen);
|
||||||
};
|
router.push({path: '/home'});
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<ion-page>
|
<ion-page>
|
||||||
<ion-header :translucent="true">
|
<ion-header :translucent="true">
|
||||||
<ion-toolbar>
|
<ion-toolbar>
|
||||||
<ion-title>Bullpen Stats for {{ pitcher.firstName }} {{ pitcher.lastName }}</ion-title>
|
<ion-title v-if="isAuthenticated">Bullpen Summary {{ pitcher.firstName }} {{ pitcher.lastName }}</ion-title>
|
||||||
|
<ion-title v-else>Bullpen Summary</ion-title>
|
||||||
</ion-toolbar>
|
</ion-toolbar>
|
||||||
</ion-header>
|
</ion-header>
|
||||||
<ion-content>
|
<ion-content>
|
||||||
<ion-card v-for="(pitch, index) in bullpen.pitches" :key="index">
|
<ion-card v-for="(pitch, index) in bullpen.bullpen.pitches" :key="index">
|
||||||
<ion-card-header>
|
<ion-card-header>
|
||||||
<ion-card-title>Pitch {{index+1}}</ion-card-title>
|
<ion-card-title>Pitch {{index+1}}</ion-card-title>
|
||||||
</ion-card-header>
|
</ion-card-header>
|
||||||
|
|
@ -47,7 +61,7 @@ const gotoHome = () => {
|
||||||
<ion-list>
|
<ion-list>
|
||||||
<ion-item>
|
<ion-item>
|
||||||
<ion-label>Pitch Type</ion-label>
|
<ion-label>Pitch Type</ion-label>
|
||||||
<ion-badge>{{pitch.pitchType.name}}</ion-badge>
|
<ion-badge>{{determinePitchTypeName(pitch.pitchTypeId)}}</ion-badge>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<ion-item>
|
<ion-item>
|
||||||
<ion-label>Planned Pitch Area</ion-label>
|
<ion-label>Planned Pitch Area</ion-label>
|
||||||
|
|
@ -44,20 +44,20 @@ const gotoFinalizePitch = () => {
|
||||||
currentStep.value = BullpenStep.Finish;
|
currentStep.value = BullpenStep.Finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
const finalizeAndNextPitch = () => {
|
const nextPitch = () => {
|
||||||
store.commit("bullpen/addPitch", pitch.value);
|
storePitch();
|
||||||
pitch.value = BullpenSessionService.createPitch();
|
|
||||||
currentStep.value = BullpenStep.Prepare;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const finalizeAndEndBullpen = () => {
|
const finishBullpen = () => {
|
||||||
|
storePitch();
|
||||||
|
bullpen.value.bullpen.finishedAt = new Date();
|
||||||
|
router.push({ path: '/summary' });
|
||||||
|
}
|
||||||
|
|
||||||
|
const storePitch = () => {
|
||||||
store.commit("bullpen/addPitch", pitch.value);
|
store.commit("bullpen/addPitch", pitch.value);
|
||||||
pitch.value = BullpenSessionService.createPitch();
|
pitch.value = BullpenSessionService.createPitch();
|
||||||
currentStep.value = BullpenStep.Prepare;
|
currentStep.value = BullpenStep.Prepare;
|
||||||
const bp = bullpen.value.bullpen;
|
|
||||||
bp.finishedAt = new Date();
|
|
||||||
store.dispatch("bullpen/finish", bp);
|
|
||||||
router.push({ name: 'BullpenStats' });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const setPlannedPitchArea = (hitArea: number) => {
|
const setPlannedPitchArea = (hitArea: number) => {
|
||||||
|
|
@ -96,7 +96,7 @@ const pitchAreaCssClasses = (area: number, name: string) => {
|
||||||
<ion-card-title>Select Pitch type</ion-card-title>
|
<ion-card-title>Select Pitch type</ion-card-title>
|
||||||
</ion-card-header>
|
</ion-card-header>
|
||||||
<ion-card-content>
|
<ion-card-content>
|
||||||
<ion-button v-for="(pitchType, index) in pitchTypes" :key="index" :color="pitchType.id !== pitch.pitchTypeId ? 'primary' : 'warning'" @click="setPitchType(pitchType)">
|
<ion-button :disabled="currentStep === BullpenStep.Finish" v-for="(pitchType, index) in pitchTypes" :key="index" :color="pitchType.id !== pitch.pitchTypeId ? 'primary' : 'warning'" @click="setPitchType(pitchType)">
|
||||||
<ion-label>{{pitchType.abbreviation}}</ion-label>
|
<ion-label>{{pitchType.abbreviation}}</ion-label>
|
||||||
</ion-button>
|
</ion-button>
|
||||||
</ion-card-content>
|
</ion-card-content>
|
||||||
|
|
@ -180,10 +180,10 @@ const pitchAreaCssClasses = (area: number, name: string) => {
|
||||||
<ion-grid>
|
<ion-grid>
|
||||||
<ion-row>
|
<ion-row>
|
||||||
<ion-col>
|
<ion-col>
|
||||||
<ion-button color="success" expand="full" @click="finalizeAndNextPitch" :disabled="pitch.hitArea === 0">Save Pitch<br/>&<br/>Next Pitch</ion-button>
|
<ion-button color="success" expand="full" @click="nextPitch" :disabled="pitch.hitArea === 0">Next Pitch</ion-button>
|
||||||
</ion-col>
|
</ion-col>
|
||||||
<ion-col>
|
<ion-col>
|
||||||
<ion-button color="success" expand="full" @click="finalizeAndEndBullpen" :disabled="pitch.hitArea === 0">Save Pitch<br/>&<br/>End Session</ion-button>
|
<ion-button color="success" expand="full" @click="finishBullpen" :disabled="pitch.hitArea === 0">Finish Session</ion-button>
|
||||||
</ion-col>
|
</ion-col>
|
||||||
</ion-row>
|
</ion-row>
|
||||||
</ion-grid>
|
</ion-grid>
|
||||||
|
|
@ -1,159 +0,0 @@
|
||||||
<script setup lang="ts">
|
|
||||||
import {
|
|
||||||
IonContent,
|
|
||||||
IonHeader,
|
|
||||||
IonFooter,
|
|
||||||
IonToolbar,
|
|
||||||
IonTitle,
|
|
||||||
IonPage,
|
|
||||||
IonCard,
|
|
||||||
IonCardContent,
|
|
||||||
IonCardHeader,
|
|
||||||
IonCardTitle, IonButton,
|
|
||||||
IonGrid, IonRow, IonCol
|
|
||||||
} from "@ionic/vue";
|
|
||||||
import BullpenSessionService from "@/services/BullpenSessionService";
|
|
||||||
import {useRouter} from "vue-router";
|
|
||||||
import {ref} from 'vue';
|
|
||||||
|
|
||||||
const router = useRouter();
|
|
||||||
const bps = ref(BullpenSessionService);
|
|
||||||
|
|
||||||
const finalizeAndNextPitch = () => {
|
|
||||||
bps.value.nextPitch();
|
|
||||||
router.push({ name: 'PreparePitch' });
|
|
||||||
}
|
|
||||||
|
|
||||||
const finalizeAndEndBullpen = () => {
|
|
||||||
bps.value.nextPitch();
|
|
||||||
bps.value.finishSession();
|
|
||||||
router.push({ name: 'BullpenStats' });
|
|
||||||
}
|
|
||||||
|
|
||||||
const setRealPitchArea = (hitArea: number) => {
|
|
||||||
bps.value.currentBullpenPitch().realPitchArea = hitArea;
|
|
||||||
};
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<ion-page>
|
|
||||||
<ion-header :translucent="true">
|
|
||||||
<ion-toolbar>
|
|
||||||
<ion-title>Finalize Pitch for {{ bps.getPitcher().firstName }} {{ bps.getPitcher().lastName }}</ion-title>
|
|
||||||
</ion-toolbar>
|
|
||||||
</ion-header>
|
|
||||||
<ion-content>
|
|
||||||
<ion-card>
|
|
||||||
<ion-card-header>
|
|
||||||
<ion-card-title>Select Real Pitch Hit Area</ion-card-title>
|
|
||||||
</ion-card-header>
|
|
||||||
<ion-card-content>
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 360 360">
|
|
||||||
<polygon :class="{'wasted-selected': bps.currentBullpenPitch().realPitchArea === 21}" class="wasted" points="0,0 105,0 105,60 60,60 60,105 0,105" @click="setRealPitchArea(21)" />
|
|
||||||
<rect :class="{'wasted-selected': bps.currentBullpenPitch().realPitchArea === 22}" class="wasted" x="105" y="0" width="150" height="60" @click="setRealPitchArea(22)" />
|
|
||||||
<polygon :class="{'wasted-selected': bps.currentBullpenPitch().realPitchArea === 23}" class="wasted" points="255,0 360,0 360,105 300,105 300,60, 255,60" @click="setRealPitchArea(23)" />
|
|
||||||
<rect :class="{'wasted-selected': bps.currentBullpenPitch().realPitchArea === 24}" class="wasted" x="0" y="105" width="60" height="150" @click="setRealPitchArea(24)" />
|
|
||||||
<rect :class="{'wasted-selected': bps.currentBullpenPitch().realPitchArea === 25}" class="wasted" x="300" y="105" width="60" height="150" @click="setRealPitchArea(25)" />
|
|
||||||
<polygon :class="{'wasted-selected': bps.currentBullpenPitch().realPitchArea === 26}" class="wasted" points="0,255 60,255 60,300 105,300 105,360 0,360" @click="setRealPitchArea(26)" />
|
|
||||||
<rect :class="{'wasted-selected': bps.currentBullpenPitch().realPitchArea === 27}" class="wasted" x="105" y="300" width="150" height="60" @click="setRealPitchArea(27)" />
|
|
||||||
<polygon :class="{'wasted-selected': bps.currentBullpenPitch().realPitchArea === 28}" class="wasted" points="255,300 300,300 300,255 360,255 360,360 255,360" @click="setRealPitchArea(28)" />
|
|
||||||
|
|
||||||
<text x="30" y="40" class="number" @click="setRealPitchArea(21)" >21</text>
|
|
||||||
<text x="180" y="40" class="number" @click="setRealPitchArea(22)" >22</text>
|
|
||||||
<text x="330" y="40" class="number" @click="setRealPitchArea(23)" >23</text>
|
|
||||||
<text x="30" y="190" class="number" @click="setRealPitchArea(24)" >24</text>
|
|
||||||
<text x="330" y="190" class="number" @click="setRealPitchArea(25)" >25</text>
|
|
||||||
<text x="30" y="330" class="number" @click="setRealPitchArea(26)" >26</text>
|
|
||||||
<text x="180" y="330" class="number" @click="setRealPitchArea(27)" >27</text>
|
|
||||||
<text x="330" y="330" class="number" @click="setRealPitchArea(28)" >28</text>
|
|
||||||
|
|
||||||
<polygon :class="{'edge-selected': bps.currentBullpenPitch().realPitchArea === 11}" class="edge" points="60,60 155,60 155,105 105,105 105,155, 60,155" @click="setRealPitchArea(11)" />
|
|
||||||
<rect :class="{'edge-selected': bps.currentBullpenPitch().realPitchArea === 12}" class="edge" x="155" y="60" width="50" height="45" @click="setRealPitchArea(12)" />
|
|
||||||
<polygon :class="{'edge-selected': bps.currentBullpenPitch().realPitchArea === 13}" class="edge" points="205,60 300,60 300,155 255,155 255,105, 205,105" @click="setRealPitchArea(13)" />
|
|
||||||
<rect :class="{'edge-selected': bps.currentBullpenPitch().realPitchArea === 14}" class="edge" x="60" y="155" width="45" height="50" @click="setRealPitchArea(14)" />
|
|
||||||
<rect :class="{'edge-selected': bps.currentBullpenPitch().realPitchArea === 15}" class="edge" x="255" y="155" width="45" height="50" @click="setRealPitchArea(15)" />
|
|
||||||
<polygon :class="{'edge-selected': bps.currentBullpenPitch().realPitchArea === 16}" class="edge" points="60,205 105,205 105,255 155,255 155,300, 60,300" @click="setRealPitchArea(16)" />
|
|
||||||
<rect :class="{'edge-selected': bps.currentBullpenPitch().realPitchArea === 17}" class="edge" x="155" y="255" width="50" height="45" @click="setRealPitchArea(17)" />
|
|
||||||
<polygon :class="{'edge-selected': bps.currentBullpenPitch().realPitchArea === 18}" class="edge" points="205,255 255,255 255,205 300,205 300,300 205,300" @click="setRealPitchArea(18)" />
|
|
||||||
|
|
||||||
<text x="80" y="90" class="number" @click="setRealPitchArea(11)">11</text>
|
|
||||||
<text x="180" y="90" class="number" @click="setRealPitchArea(12)">12</text>
|
|
||||||
<text x="275" y="90" class="number" @click="setRealPitchArea(13)">13</text>
|
|
||||||
<text x="80" y="190" class="number" @click="setRealPitchArea(14)">14</text>
|
|
||||||
<text x="275" y="190" class="number" @click="setRealPitchArea(15)">15</text>
|
|
||||||
<text x="80" y="285" class="number" @click="setRealPitchArea(16)">16</text>
|
|
||||||
<text x="180" y="285" class="number" @click="setRealPitchArea(17)">17</text>
|
|
||||||
<text x="275" y="285" class="number" @click="setRealPitchArea(18)">18</text>
|
|
||||||
|
|
||||||
<rect :class="{'inside-selected': bps.currentBullpenPitch().realPitchArea === 1}" class="inside" x="105" y="105" width="50" height="50" @click="setRealPitchArea(1)"/>
|
|
||||||
<rect :class="{'inside-selected': bps.currentBullpenPitch().realPitchArea === 2}" class="inside" x="155" y="105" width="50" height="50" @click="setRealPitchArea(2)"/>
|
|
||||||
<rect :class="{'inside-selected': bps.currentBullpenPitch().realPitchArea === 3}" class="inside" x="205" y="105" width="50" height="50" @click="setRealPitchArea(3)"/>
|
|
||||||
<rect :class="{'inside-selected': bps.currentBullpenPitch().realPitchArea === 4}" class="inside" x="105" y="155" width="50" height="50" @click="setRealPitchArea(4)"/>
|
|
||||||
<rect :class="{'inside-selected': bps.currentBullpenPitch().realPitchArea === 5}" class="inside" x="155" y="155" width="50" height="50" @click="setRealPitchArea(5)"/>
|
|
||||||
<rect :class="{'inside-selected': bps.currentBullpenPitch().realPitchArea === 6}" class="inside" x="205" y="155" width="50" height="50" @click="setRealPitchArea(6)"/>
|
|
||||||
<rect :class="{'inside-selected': bps.currentBullpenPitch().realPitchArea === 7}" class="inside" x="105" y="205" width="50" height="50" @click="setRealPitchArea(7)"/>
|
|
||||||
<rect :class="{'inside-selected': bps.currentBullpenPitch().realPitchArea === 8}" class="inside" x="155" y="205" width="50" height="50" @click="setRealPitchArea(8)"/>
|
|
||||||
<rect :class="{'inside-selected': bps.currentBullpenPitch().realPitchArea === 9}" class="inside" x="205" y="205" width="50" height="50" @click="setRealPitchArea(9)"/>
|
|
||||||
|
|
||||||
<text x="130" y="140" class="number" @click="setRealPitchArea(1)">1</text>
|
|
||||||
<text x="180" y="140" class="number" @click="setRealPitchArea(2)">2</text>
|
|
||||||
<text x="230" y="140" class="number" @click="setRealPitchArea(3)">3</text>
|
|
||||||
<text x="130" y="190" class="number" @click="setRealPitchArea(4)">4</text>
|
|
||||||
<text x="180" y="190" class="number" @click="setRealPitchArea(5)">5</text>
|
|
||||||
<text x="230" y="190" class="number" @click="setRealPitchArea(6)">6</text>
|
|
||||||
<text x="130" y="240" class="number" @click="setRealPitchArea(7)">7</text>
|
|
||||||
<text x="180" y="240" class="number" @click="setRealPitchArea(8)">8</text>
|
|
||||||
<text x="230" y="240" class="number" @click="setRealPitchArea(9)">9</text>
|
|
||||||
</svg>
|
|
||||||
</ion-card-content>
|
|
||||||
</ion-card>
|
|
||||||
</ion-content>
|
|
||||||
<ion-footer>
|
|
||||||
<ion-grid>
|
|
||||||
<ion-row>
|
|
||||||
<ion-col><ion-button color="success" expand="full" @click="finalizeAndNextPitch" :disabled="bps.currentBullpenPitch().realPitchArea === 0">Save Pitch<br/>&<br/>Next Pitch</ion-button></ion-col>
|
|
||||||
<ion-col><ion-button color="success" expand="full" @click="finalizeAndEndBullpen" :disabled="bps.currentBullpenPitch().realPitchArea === 0">Save Pitch<br/>&<br/>End Session</ion-button></ion-col>
|
|
||||||
</ion-row>
|
|
||||||
</ion-grid>
|
|
||||||
</ion-footer>
|
|
||||||
</ion-page>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.wasted {
|
|
||||||
fill: firebrick;
|
|
||||||
stroke: black;
|
|
||||||
stroke-width: 1;
|
|
||||||
}
|
|
||||||
.wasted-selected {
|
|
||||||
fill: orangered;
|
|
||||||
stroke: black;
|
|
||||||
stroke-width: 1;
|
|
||||||
}
|
|
||||||
.edge {
|
|
||||||
fill: lightgreen;
|
|
||||||
stroke: black;
|
|
||||||
stroke-width: 1;
|
|
||||||
}
|
|
||||||
.edge-selected {
|
|
||||||
fill: aquamarine;
|
|
||||||
stroke: black;
|
|
||||||
stroke-width: 1;
|
|
||||||
}
|
|
||||||
.inside {
|
|
||||||
fill: green;
|
|
||||||
stroke: black;
|
|
||||||
stroke-width: 1;
|
|
||||||
}
|
|
||||||
.inside-selected {
|
|
||||||
fill: darkolivegreen;
|
|
||||||
stroke: black;
|
|
||||||
stroke-width: 1;
|
|
||||||
}
|
|
||||||
.number {
|
|
||||||
text-anchor: middle;
|
|
||||||
fill: white;
|
|
||||||
font-size: 30px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -22,7 +22,7 @@ if (pitcher.value === undefined || pitcher.value === null || pitcher.value === '
|
||||||
|
|
||||||
const startBullpen = () => {
|
const startBullpen = () => {
|
||||||
console.log('Starting bullpen session');
|
console.log('Starting bullpen session');
|
||||||
router.push({ path: '/prepare' });
|
router.push({ path: '/bullpen' });
|
||||||
};
|
};
|
||||||
|
|
||||||
const showStats = () => {
|
const showStats = () => {
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import { computed, ref, onMounted } from "vue";
|
||||||
import {
|
import {
|
||||||
IonPage,
|
IonPage,
|
||||||
IonIcon,
|
IonIcon,
|
||||||
|
IonLabel,
|
||||||
IonButton,
|
IonButton,
|
||||||
IonContent,
|
IonContent,
|
||||||
IonInput
|
IonInput
|
||||||
|
|
@ -22,6 +23,7 @@ import { useStore } from 'vuex'
|
||||||
import * as yup from 'yup';
|
import * as yup from 'yup';
|
||||||
|
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
|
const server = JSON.parse(localStorage.getItem("server") || '""');
|
||||||
|
|
||||||
const schema = yup.object({
|
const schema = yup.object({
|
||||||
email: yup.string().email('Invalid email address').required('Email is required'),
|
email: yup.string().email('Invalid email address').required('Email is required'),
|
||||||
|
|
@ -29,7 +31,7 @@ const schema = yup.object({
|
||||||
.string()
|
.string()
|
||||||
.min(8, 'Minimum 8 characters')
|
.min(8, 'Minimum 8 characters')
|
||||||
.matches(/\d/, 'Must include a number')
|
.matches(/\d/, 'Must include a number')
|
||||||
.matches(/[^A-Za-z\d]/, 'Must include a special character')
|
// .matches(/[^A-Za-z\d]/, 'Must include a special character')
|
||||||
.required('Password is required'),
|
.required('Password is required'),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -63,10 +65,6 @@ const submit = handleSubmit((values, { resetForm }) => {
|
||||||
error => {
|
error => {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
console.log(error);
|
console.log(error);
|
||||||
// message.value =
|
|
||||||
// (error.response && error.response.data && error.response.data.message) ||
|
|
||||||
// error.message ||
|
|
||||||
// error.toString();
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}, ({errors}) => {
|
}, ({errors}) => {
|
||||||
|
|
@ -83,6 +81,11 @@ const onLogin = () => {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const changeServer = () => {
|
||||||
|
router.push({ path: '/setup'});
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -95,6 +98,7 @@ const onLogin = () => {
|
||||||
<div class="logo-container">
|
<div class="logo-container">
|
||||||
<img src="../assets/Bonn_Capitals_Insignia.png" alt="Logo" class="logo" />
|
<img src="../assets/Bonn_Capitals_Insignia.png" alt="Logo" class="logo" />
|
||||||
</div>
|
</div>
|
||||||
|
<ion-label>{{server.protocol}}://{{server.host}}:{{server.port}}</ion-label>
|
||||||
</div>
|
</div>
|
||||||
<form @submit="submit" class="form-container">
|
<form @submit="submit" class="form-container">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
|
|
@ -136,9 +140,8 @@ const onLogin = () => {
|
||||||
</Field>
|
</Field>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ion-button expand="block" class="rounded-button" type="submit">
|
<ion-button expand="block" class="rounded-button" type="submit">Login</ion-button>
|
||||||
Login
|
<ion-button expand="block" class="rounded-button" @click="changeServer">Change Server</ion-button>
|
||||||
</ion-button>
|
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</ion-content>
|
</ion-content>
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ onMounted(async () => {
|
||||||
|
|
||||||
const goToPreparePitch = (pitcher: User) => {
|
const goToPreparePitch = (pitcher: User) => {
|
||||||
bps.value.startSession( pitcher );
|
bps.value.startSession( pitcher );
|
||||||
router.push({ name: 'PreparePitch' });
|
router.push({ path: '/bullpen' });
|
||||||
};
|
};
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,17 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue';
|
import {ref} from 'vue';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import {IonButton, IonContent, IonCol, IonHeader, IonInput, IonPage, IonTitle, IonToolbar} from '@ionic/vue';
|
import backendService from '@/services/BackendService'
|
||||||
|
import {IonButton, IonContent, IonCol, IonHeader, IonInput, IonPage, IonTitle, IonToolbar, IonCheckbox} from '@ionic/vue';
|
||||||
|
|
||||||
const serverAddress = ref('');
|
const server = ref(backendService.getServer());
|
||||||
|
|
||||||
|
const useSsl = ref(server.value.protocol === 'https' );
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const saveServerAddress = () => {
|
const saveServerAddress = () => {
|
||||||
localStorage.setItem('serverAddress', serverAddress.value);
|
server.value.protocol = useSsl.value ? 'https' : 'http';
|
||||||
|
backendService.updateServer(server.value);
|
||||||
router.push('/login');
|
router.push('/login');
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -23,8 +27,15 @@ const saveServerAddress = () => {
|
||||||
<ion-content class="ion-padding">
|
<ion-content class="ion-padding">
|
||||||
<ion-row>
|
<ion-row>
|
||||||
<ion-col class="ion-padding">
|
<ion-col class="ion-padding">
|
||||||
<ion-input name="ipaddress" v-model="serverAddress" type="text" required placeholder="Enter server address"></ion-input>
|
<ion-input name="ipaddress" v-model="server.host" type="text" required placeholder="Enter server address"></ion-input>
|
||||||
</ion-col>
|
</ion-col>
|
||||||
|
</ion-row>
|
||||||
|
<ion-row>
|
||||||
|
<ion-col>
|
||||||
|
<ion-checkbox name="ssl" v-model="useSsl">Use SSL</ion-checkbox>
|
||||||
|
</ion-col>
|
||||||
|
</ion-row>
|
||||||
|
<ion-row>
|
||||||
<ion-col>
|
<ion-col>
|
||||||
<ion-button type="button" fill="solid" expand="full" @click="saveServerAddress">Save</ion-button>
|
<ion-button type="button" fill="solid" expand="full" @click="saveServerAddress">Save</ion-button>
|
||||||
</ion-col>
|
</ion-col>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue