Compare commits
10 Commits
1d96c9c54b
...
2301b164fa
| Author | SHA1 | Date |
|---|---|---|
|
|
2301b164fa | |
|
|
d4b2a3057a | |
|
|
de9832c903 | |
|
|
55f20a5a1d | |
|
|
2e1370392e | |
|
|
1719473dcc | |
|
|
970ab96c7a | |
|
|
c8b43b76f8 | |
|
|
604f4c3320 | |
|
|
a431dc8ae4 |
|
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "app",
|
"name": "app",
|
||||||
"version": "1.1.0",
|
"version": "1.1.1",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "app",
|
"name": "app",
|
||||||
"version": "1.1.0",
|
"version": "1.1.1",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@capacitor/android": "6.1.2",
|
"@capacitor/android": "6.1.2",
|
||||||
"@capacitor/app": "6.0.1",
|
"@capacitor/app": "6.0.1",
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "app",
|
"name": "app",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "1.1.0",
|
"version": "1.1.1",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,7 @@ const logoutUser = () => {
|
||||||
<ion-icon slot="icon-only" :icon="chevronBack"></ion-icon>
|
<ion-icon slot="icon-only" :icon="chevronBack"></ion-icon>
|
||||||
</ion-button>
|
</ion-button>
|
||||||
</ion-buttons>
|
</ion-buttons>
|
||||||
<ion-title>Menu Content</ion-title>
|
<ion-title>User Menu</ion-title>
|
||||||
</ion-toolbar>
|
</ion-toolbar>
|
||||||
</ion-header>
|
</ion-header>
|
||||||
<ion-content>
|
<ion-content>
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ export class BullpenSessionService extends ApiService<Bullpen> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public findByPitcherId(id: number, page: number, size: number): Promise<Pageable<Bullpen>> {
|
public fetchAllByUser(id: number, page: number, size: number): Promise<Pageable<Bullpen>> {
|
||||||
return api
|
return api
|
||||||
.get('/bullpen_session', { params: {
|
.get('/bullpen_session', { params: {
|
||||||
user: id,
|
user: id,
|
||||||
|
|
|
||||||
|
|
@ -15,20 +15,20 @@ class PlayerService extends ApiService<Player> {
|
||||||
gender: 'male',
|
gender: 'male',
|
||||||
bats: 'right',
|
bats: 'right',
|
||||||
throws: 'right',
|
throws: 'right',
|
||||||
height: 187,
|
height: 0,
|
||||||
weight: 84,
|
weight: 0,
|
||||||
state: 'active',
|
state: 'active',
|
||||||
jerseyNumber: 23,
|
jerseyNumber: 0,
|
||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
updatedAt: new Date(),
|
updatedAt: new Date(),
|
||||||
user: {
|
user: {
|
||||||
id: 0,
|
id: 0,
|
||||||
auth: {
|
auth: {
|
||||||
email: 'test@de.de',
|
email: '',
|
||||||
password: 'test$123'
|
password: ''
|
||||||
},
|
},
|
||||||
firstName: 'Demo',
|
firstName: '',
|
||||||
lastName: 'Player',
|
lastName: '',
|
||||||
dateOfBirth: new Date(),
|
dateOfBirth: new Date(),
|
||||||
roles: ['player'],
|
roles: ['player'],
|
||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {computed, ref} from 'vue';
|
import {computed, ref, reactive} from 'vue';
|
||||||
import {
|
import {
|
||||||
IonPage,
|
IonPage,
|
||||||
IonHeader,
|
IonHeader,
|
||||||
|
|
@ -7,24 +7,33 @@ import {
|
||||||
IonTitle,
|
IonTitle,
|
||||||
IonContent,
|
IonContent,
|
||||||
IonAvatar,
|
IonAvatar,
|
||||||
IonButton,
|
|
||||||
IonButtons,
|
IonButtons,
|
||||||
IonIcon,
|
IonIcon,
|
||||||
IonMenuButton,
|
IonMenuButton,
|
||||||
IonFab,
|
IonFab,
|
||||||
IonFabButton
|
IonFabButton,
|
||||||
|
IonInfiniteScroll,
|
||||||
|
IonInfiniteScrollContent,
|
||||||
|
InfiniteScrollCustomEvent,
|
||||||
|
IonList,
|
||||||
|
IonItem,
|
||||||
|
IonLabel, IonBadge,
|
||||||
} from '@ionic/vue';
|
} from '@ionic/vue';
|
||||||
import {
|
import {
|
||||||
playOutline,
|
playOutline,
|
||||||
statsChartOutline,
|
statsChartOutline,
|
||||||
personOutline,
|
personOutline,
|
||||||
|
baseball,
|
||||||
add,
|
add,
|
||||||
personAddOutline
|
personAddOutline, baseballOutline
|
||||||
} from 'ionicons/icons';
|
} from 'ionicons/icons';
|
||||||
import {useStore} from "vuex";
|
import {useStore} from "vuex";
|
||||||
import {useRouter} from "vue-router";
|
import {useRouter} from "vue-router";
|
||||||
import BullpenSessionService from "@/services/BullpenSessionService";
|
import BullpenSessionService from "@/services/BullpenSessionService";
|
||||||
import TokenService from "@/services/TokenService";
|
import TokenService from "@/services/TokenService";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
import Bullpen from "@/types/Bullpen";
|
||||||
|
import PitchType from "@/types/PitchType";
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
|
|
@ -60,6 +69,39 @@ const addPlayer = () => {
|
||||||
router.push({ path: '/player/create' });
|
router.push({ path: '/player/create' });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const items = reactive<Bullpen[]>([]);
|
||||||
|
const page = ref(0);
|
||||||
|
|
||||||
|
const generateItems = () => {
|
||||||
|
BullpenSessionService
|
||||||
|
.fetchAllByUser(user.value.id, page.value, 10)
|
||||||
|
.then((bullpens) => {
|
||||||
|
++page.value;
|
||||||
|
bullpens.data.forEach((bullpen: Bullpen) => {
|
||||||
|
items.push(bullpen);
|
||||||
|
})
|
||||||
|
}, error => {
|
||||||
|
console.log(error);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const formatDate = (date: Date) => {
|
||||||
|
return dayjs(date).format('YYYY.MM.DD HH:mm');
|
||||||
|
}
|
||||||
|
|
||||||
|
// const determinePitchTypeName = (id: number): string => {
|
||||||
|
// const pitchType = store.state.pitchTypes.find((pitchType: PitchType) => pitchType.id === id);
|
||||||
|
//
|
||||||
|
// return pitchType?.name ?? 'Unknown';
|
||||||
|
// }
|
||||||
|
|
||||||
|
const ionInfinite = (event: InfiniteScrollCustomEvent) => {
|
||||||
|
generateItems();
|
||||||
|
setTimeout(() => event.target.complete(), 500);
|
||||||
|
};
|
||||||
|
|
||||||
|
generateItems();
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -75,7 +117,24 @@ const addPlayer = () => {
|
||||||
</ion-toolbar>
|
</ion-toolbar>
|
||||||
</ion-header>
|
</ion-header>
|
||||||
|
|
||||||
<ion-content class="ion-padding">
|
<ion-content>
|
||||||
|
<ion-list>
|
||||||
|
<ion-item v-for="(bullpen, index) in items" :key="index">
|
||||||
|
<ion-icon aria-hidden="true" :icon="baseball" slot="start"></ion-icon>
|
||||||
|
<ion-label>Bullpen from ({{formatDate(bullpen.startedAt)}})</ion-label>
|
||||||
|
<!-- <ion-list v-for="(pitch, index) in bullpen.pitches" :key="index">-->
|
||||||
|
<!-- <ion-item>-->
|
||||||
|
<!-- <ion-icon slot="start" :icon="baseballOutline" class="icon-login"></ion-icon>-->
|
||||||
|
<!-- <ion-label>{{determinePitchTypeName(pitch.pitchTypeId)}}</ion-label>-->
|
||||||
|
<!-- <ion-badge>{{pitch.aimedArea}}</ion-badge>-->
|
||||||
|
<!-- <ion-badge>{{pitch.hitArea}}</ion-badge>-->
|
||||||
|
<!-- </ion-item>-->
|
||||||
|
<!-- </ion-list>-->
|
||||||
|
</ion-item>
|
||||||
|
</ion-list>
|
||||||
|
<ion-infinite-scroll @ionInfinite="ionInfinite">
|
||||||
|
<ion-infinite-scroll-content></ion-infinite-scroll-content>
|
||||||
|
</ion-infinite-scroll>
|
||||||
<!-- <div class="user-container">-->
|
<!-- <div class="user-container">-->
|
||||||
<!-- <ion-avatar class="user-avatar">-->
|
<!-- <ion-avatar class="user-avatar">-->
|
||||||
<!-- <template v-if="userImage">-->
|
<!-- <template v-if="userImage">-->
|
||||||
|
|
|
||||||
|
|
@ -1,37 +1,12 @@
|
||||||
services:
|
services:
|
||||||
db:
|
postgres:
|
||||||
image: postgres:15
|
image: postgres:14-alpine
|
||||||
restart: unless-stopped
|
container_name: postgres14
|
||||||
env_file: ./.env.development
|
|
||||||
environment:
|
|
||||||
POSTGRES_DB: $DB_NAME
|
|
||||||
POSTGRES_USER: $DB_USER
|
|
||||||
POSTGRES_PASSWORD: $DB_PASSWORD
|
|
||||||
ports:
|
ports:
|
||||||
- $DB_PORT:$DB_PORT
|
- "5432:5432"
|
||||||
volumes:
|
volumes:
|
||||||
- db_data:/var/lib/postgresql/data
|
- ~/apps/postgres:/var/lib/postgresql/data
|
||||||
|
|
||||||
app-dev:
|
|
||||||
image: node:20-alpine
|
|
||||||
restart: unless-stopped
|
|
||||||
env_file: ./.env.development
|
|
||||||
working_dir: /app
|
|
||||||
volumes:
|
|
||||||
- .:/app
|
|
||||||
- /app/node_modules
|
|
||||||
ports:
|
|
||||||
- '$NODE_LOCAL_PORT:$NODE_DOCKER_PORT'
|
|
||||||
environment:
|
environment:
|
||||||
NODE_ENV: development
|
POSTGRES_USER: postgres
|
||||||
DB_HOST: db
|
POSTGRES_PASSWORD: postgres
|
||||||
DB_PORT: $DB_PORT
|
POSTGRES_DB: bullpen-dev
|
||||||
DB_NAME: $DB_NAME
|
|
||||||
DB_USER: $DB_USER
|
|
||||||
DB_PASS: $DB_PASSWORD
|
|
||||||
command: sh -c "npm install && npm run dev"
|
|
||||||
depends_on:
|
|
||||||
- db
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
db_data:
|
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "bullpen-backend",
|
"name": "bullpen-backend",
|
||||||
"version": "1.1.0",
|
"version": "1.1.1",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "bullpen-backend",
|
"name": "bullpen-backend",
|
||||||
"version": "1.1.0",
|
"version": "1.1.1",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bcryptjs": "^3.0.2",
|
"bcryptjs": "^3.0.2",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "bullpen-backend",
|
"name": "bullpen-backend",
|
||||||
"version": "1.1.0",
|
"version": "1.1.1",
|
||||||
"main": "server.js",
|
"main": "server.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"prebuild": "node -p \"'const BULLPEN_VERSION = ' + JSON.stringify(require('./package.json').version) + ';'\"\n\nmodule.exports = BULLPEN_VERSION; > config/version.js",
|
"prebuild": "node -p \"'const BULLPEN_VERSION = ' + JSON.stringify(require('./package.json').version) + ';'\"\n\nmodule.exports = BULLPEN_VERSION; > config/version.js",
|
||||||
|
|
@ -15,6 +15,9 @@
|
||||||
"start:prod": "npm run cross-env NODE_ENV=production node server.js",
|
"start:prod": "npm run cross-env NODE_ENV=production node server.js",
|
||||||
"start:dev": "cross-env NODE_ENV=development nodemon server.js",
|
"start:dev": "cross-env NODE_ENV=development nodemon server.js",
|
||||||
"migrate:dev": "cross-env NODE_ENV=development npx sequelize-cli db:migrate",
|
"migrate:dev": "cross-env NODE_ENV=development npx sequelize-cli db:migrate",
|
||||||
|
"seed:bullpen": "cross-env NODE_ENV=development npx sequelize-cli db:seed --seed 05-bullpens.js",
|
||||||
|
"dev:db:start": "docker-compose -f docker-compose.dev.yml up -d",
|
||||||
|
"dev:db:stop": "docker-compose -f docker-compose.dev.yml down -v",
|
||||||
"test:db:start": "docker-compose -f docker-compose.test.yml up -d",
|
"test:db:start": "docker-compose -f docker-compose.test.yml up -d",
|
||||||
"test:db:stop": "docker-compose -f docker-compose.test.yml down -v",
|
"test:db:stop": "docker-compose -f docker-compose.test.yml down -v",
|
||||||
"test:run": "dotenv -e .env.test -- jest --runInBand --detectOpenHandles",
|
"test:run": "dotenv -e .env.test -- jest --runInBand --detectOpenHandles",
|
||||||
|
|
|
||||||
|
|
@ -16,5 +16,8 @@ docker-compose up --build -d
|
||||||
docker-compose exec app npx sequelize-cli db:migrate
|
docker-compose exec app npx sequelize-cli db:migrate
|
||||||
docker-compose exec app npx sequelize-cli db:seed:all
|
docker-compose exec app npx sequelize-cli db:seed:all
|
||||||
|
|
||||||
|
// seed one specific file
|
||||||
|
docker-compose exec app npx sequelize db:seed --seed my_seeder_file.js
|
||||||
|
|
||||||
docker-compose exec app sh
|
docker-compose exec app sh
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -1,48 +1,69 @@
|
||||||
const process = require('process');
|
const process = require('process');
|
||||||
const {createPlayer, createUsers} = require("../helper/seeder.helper");
|
const {createPlayer, createUsers} = require("../helper/seeder.helper");
|
||||||
|
|
||||||
const createBullpen = async (queryInterface, demoPlayer) => {
|
|
||||||
|
const pickRandomValueFromArray = (values) => {
|
||||||
|
return values[Math.floor(Math.random() * values.length)];
|
||||||
|
}
|
||||||
|
|
||||||
|
const shouldMatch = (percentage) => {
|
||||||
|
return Math.random() * 100 < percentage;
|
||||||
|
}
|
||||||
|
|
||||||
|
const createBullpens = async (queryInterface, demoPlayer) => {
|
||||||
const startDate = new Date();
|
const startDate = new Date();
|
||||||
const endDate = new Date(new Date().setTime(startDate.getTime() + 10 * 60000));
|
// const endDate = new Date(new Date().setTime(startDate.getTime() + (10 * 60000)));
|
||||||
|
// create 20 bullpens for demo player
|
||||||
const bullpens = [...Array(20).keys()].map(key => {
|
const bullpens = [...Array(20).keys()].map(key => {
|
||||||
|
const days = 5 + key;
|
||||||
|
const startedAt = new Date(new Date().setDate(startDate.getDate() - days));
|
||||||
return {
|
return {
|
||||||
pitcherId: demoPlayer.user.id,
|
pitcherId: demoPlayer.userId,
|
||||||
startedAt: new Date(new Date().setDate(startDate.getDate()-5)),
|
startedAt: startedAt,
|
||||||
finishedAt: new Date(new Date().setDate(startDate.getDate()-5)),
|
finishedAt: new Date(new Date().setTime(startedAt.getTime() + (10 * 60000))),
|
||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
updatedAt: new Date()
|
updatedAt: new Date()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
await queryInterface.bulkInsert('BullpenSessions', bullpens);
|
await queryInterface.bulkInsert('BullpenSessions', bullpens);
|
||||||
|
|
||||||
const pitchTypeIds = await queryInterface
|
const pitchTypeIds = (await queryInterface
|
||||||
.select(null, 'PitchTypes')
|
.select(null, 'PitchTypes'))
|
||||||
.map(pitchType => pitchType.id);
|
.map(pitchType => pitchType.id);
|
||||||
|
|
||||||
// red: 21-28
|
// red: 21-28
|
||||||
// orange: 11-18:
|
// orange: 11-18:
|
||||||
// green: 1-9
|
// green: 1-9
|
||||||
const bullpenChart = [
|
const bullpenChart = [
|
||||||
[21,22,23,24,25,26,27,28],
|
1,2,3,4,5,6,7,8,9,
|
||||||
[11,12,13,14,15,16,17,18],
|
11,12,13,14,15,16,17,18,
|
||||||
[1,2,3,4,5,6,7,8,9]
|
21,22,23,24,25,26,27,28
|
||||||
]
|
];
|
||||||
|
|
||||||
const dbBullpens = await queryInterface.select(null, 'BullpenSessions', {
|
const dbBullpens = await queryInterface.select(null, 'BullpenSessions', {
|
||||||
where: {
|
where: {
|
||||||
pitcherId: demoPlayer.user.id
|
pitcherId: demoPlayer.userId
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
[...Array(20).keys()].map(key => {
|
// fill pitches for each bullpen
|
||||||
|
const pitches = dbBullpens.map(bullpen => {
|
||||||
|
return [...Array(20).keys()].map(key => {
|
||||||
|
const aimedArea = pickRandomValueFromArray(bullpenChart);
|
||||||
|
const hitArea = shouldMatch(30) ? aimedArea : pickRandomValueFromArray(bullpenChart);
|
||||||
return {
|
return {
|
||||||
pitchTypeId: pitchTypeIds[Math.floor(Math.random() * pitchTypeIds.length)],
|
pitchTypeId: pickRandomValueFromArray(pitchTypeIds),
|
||||||
pitchTime: new Date(2025, 3, 22, 16, 7, 21),
|
bullpenSessionId: bullpen.id,
|
||||||
aimedArea: 11,
|
pitchTime: new Date(new Date().setTime(bullpen.startedAt.getTime() + key * 60000)),
|
||||||
hitArea: 12
|
aimedArea: aimedArea,
|
||||||
}
|
hitArea: hitArea,
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date()
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
await queryInterface.bulkInsert('Pitches', pitches.flat());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @type {import('sequelize-cli').Migration} */
|
/** @type {import('sequelize-cli').Migration} */
|
||||||
|
|
@ -50,6 +71,14 @@ module.exports = {
|
||||||
async up (queryInterface, /*Sequelize*/) {
|
async up (queryInterface, /*Sequelize*/) {
|
||||||
if (process.env.NODE_ENV !== 'development') return;
|
if (process.env.NODE_ENV !== 'development') return;
|
||||||
|
|
||||||
|
let demoPlayer = (await queryInterface.select(null, 'Players', {
|
||||||
|
where: {
|
||||||
|
height: 187,
|
||||||
|
weight: 85,
|
||||||
|
}
|
||||||
|
})).shift();
|
||||||
|
|
||||||
|
if (demoPlayer === undefined) {
|
||||||
const roles = await queryInterface.select(null, 'Roles');
|
const roles = await queryInterface.select(null, 'Roles');
|
||||||
const players = [{
|
const players = [{
|
||||||
email: 'demo@bullpen.com',
|
email: 'demo@bullpen.com',
|
||||||
|
|
@ -66,18 +95,19 @@ module.exports = {
|
||||||
state: 'active'
|
state: 'active'
|
||||||
}];
|
}];
|
||||||
|
|
||||||
const dbPlayers = await createPlayer(queryInterface, roles, players);
|
await createPlayer(queryInterface, roles, players);
|
||||||
const demoPlayer = dbPlayers
|
demoPlayer = (await queryInterface.select(null, 'Players', {
|
||||||
.filter(player => player.user.auth.email === 'demo@bullpen.com').shift();
|
where: {
|
||||||
|
height: 187,
|
||||||
for (let i = 0; i < 10; ++i) {
|
weight: 85,
|
||||||
createBullpen(queryInterface, demoPlayer);
|
|
||||||
}
|
}
|
||||||
|
})).shift();
|
||||||
|
}
|
||||||
|
|
||||||
|
await createBullpens(queryInterface, demoPlayer);
|
||||||
},
|
},
|
||||||
|
|
||||||
async down (queryInterface, /*Sequelize*/) {
|
async down (/*queryInterface,*/ /*Sequelize*/) {
|
||||||
if (process.env.NODE_ENV !== 'development') return;
|
// if (process.env.NODE_ENV !== 'development') return;
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue