AAAAAAAAAAA
This commit is contained in:
23
frontend/package-lock.json
generated
23
frontend/package-lock.json
generated
@@ -11,6 +11,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@quasar/extras": "^1.16.4",
|
"@quasar/extras": "^1.16.4",
|
||||||
"axios": "^1.11.0",
|
"axios": "^1.11.0",
|
||||||
|
"bootstrap-icons": "^1.13.1",
|
||||||
"quasar": "^2.16.0",
|
"quasar": "^2.16.0",
|
||||||
"vue": "^3.4.18",
|
"vue": "^3.4.18",
|
||||||
"vue-router": "^4.0.0"
|
"vue-router": "^4.0.0"
|
||||||
@@ -2322,9 +2323,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/axios": {
|
"node_modules/axios": {
|
||||||
"version": "1.11.0",
|
"version": "1.12.1",
|
||||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/axios/-/axios-1.12.1.tgz",
|
||||||
"integrity": "sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==",
|
"integrity": "sha512-Kn4kbSXpkFHCGE6rBFNwIv0GQs4AvDT80jlveJDKFxjbTYMUeB4QtsdPCv6H8Cm19Je7IU6VFtRl2zWZI0rudQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"follow-redirects": "^1.15.6",
|
"follow-redirects": "^1.15.6",
|
||||||
@@ -2447,6 +2448,22 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
|
"node_modules/bootstrap-icons": {
|
||||||
|
"version": "1.13.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.13.1.tgz",
|
||||||
|
"integrity": "sha512-ijombt4v6bv5CLeXvRWKy7CuM3TRTuPEuGaGKvTV5cz65rQSY8RQ2JcHt6b90cBBAC7s8fsf2EkQDldzCoXUjw==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/twbs"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/bootstrap"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/brace-expansion": {
|
"node_modules/brace-expansion": {
|
||||||
"version": "1.1.12",
|
"version": "1.1.12",
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@quasar/extras": "^1.16.4",
|
"@quasar/extras": "^1.16.4",
|
||||||
"axios": "^1.11.0",
|
"axios": "^1.11.0",
|
||||||
|
"bootstrap-icons": "^1.13.1",
|
||||||
"quasar": "^2.16.0",
|
"quasar": "^2.16.0",
|
||||||
"vue": "^3.4.18",
|
"vue": "^3.4.18",
|
||||||
"vue-router": "^4.0.0"
|
"vue-router": "^4.0.0"
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
@@ -11,7 +11,7 @@ img {
|
|||||||
|
|
||||||
|
|
||||||
.dart {
|
.dart {
|
||||||
position: fixed;
|
position: absolute;
|
||||||
transform: translate(-50%, -50%);
|
transform: translate(-50%, -50%);
|
||||||
width: 200px;
|
width: 200px;
|
||||||
height: auto;
|
height: auto;
|
||||||
@@ -25,9 +25,7 @@ img {
|
|||||||
.dartBoardDiv {
|
.dartBoardDiv {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
height: 100vh;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.numpadBtn {
|
.numpadBtn {
|
||||||
|
|||||||
@@ -134,9 +134,6 @@
|
|||||||
<router-view />
|
<router-view />
|
||||||
</q-page-container>
|
</q-page-container>
|
||||||
|
|
||||||
</q-layout>
|
|
||||||
|
|
||||||
<q-layout view="hHh lpR fFf">
|
|
||||||
<q-footer bordered class="bg-grey-2 text-dark">
|
<q-footer bordered class="bg-grey-2 text-dark">
|
||||||
<q-toolbar class="justify-around">
|
<q-toolbar class="justify-around">
|
||||||
<q-btn flat round icon="settings" @click="onSettingsClick" />
|
<q-btn flat round icon="settings" @click="onSettingsClick" />
|
||||||
@@ -166,11 +163,15 @@ function onSettingsClick () {
|
|||||||
router.push("/user/settings")
|
router.push("/user/settings")
|
||||||
}
|
}
|
||||||
function onGameClick () {
|
function onGameClick () {
|
||||||
const path = LocalStorage.getItem('returnPath', route.fullPath)
|
const path = route.fullPath
|
||||||
if (path) {
|
const savedPath = LocalStorage.getItem('returnPath', route.fullPath)
|
||||||
router.push(path)
|
console.log(path)
|
||||||
} else {
|
if (path == "/user/settings" || path == "/rules") {
|
||||||
router.push("/")
|
if (savedPath) {
|
||||||
|
router.push(savedPath)
|
||||||
|
} else {
|
||||||
|
router.push("/")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function onRulesClick () {
|
function onRulesClick () {
|
||||||
|
|||||||
@@ -3,16 +3,64 @@
|
|||||||
Digitale Helfer für Dart
|
Digitale Helfer für Dart
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<q-page class="flex flex-center">
|
<div class="q-pa-lg flex flex-center" style="gap: 24px;">
|
||||||
|
<q-card
|
||||||
|
class="q-pa-lg shadow-3"
|
||||||
|
style="width: 400px; max-width: 90vw; border-radius: 16px;"
|
||||||
|
>
|
||||||
|
<q-card-section class="text-center">
|
||||||
|
<q-icon name="bi-controller" size="48px" color="primary" />
|
||||||
|
<div class="text-h6 q-mt-md">Create a Game</div>
|
||||||
|
</q-card-section>
|
||||||
|
|
||||||
|
<q-card-actions align="center">
|
||||||
|
<q-btn
|
||||||
|
label="Go!"
|
||||||
|
color="primary"
|
||||||
|
to="/game/select"
|
||||||
|
rounded
|
||||||
|
unelevated
|
||||||
|
size="lg"
|
||||||
|
class="full-width"
|
||||||
|
/>
|
||||||
|
</q-card-actions>
|
||||||
|
</q-card>
|
||||||
|
|
||||||
|
<q-card
|
||||||
|
class="q-pa-lg shadow-3"
|
||||||
|
style="width: 400px; max-width: 90vw; border-radius: 16px;"
|
||||||
|
>
|
||||||
|
<q-card-section class="text-center">
|
||||||
|
<q-icon name="public" size="48px" color="primary" />
|
||||||
|
<div class="text-h6 q-mt-md">Join a Game</div>
|
||||||
|
</q-card-section>
|
||||||
|
|
||||||
|
<q-card-actions align="center">
|
||||||
|
<q-btn
|
||||||
|
label="Go!"
|
||||||
|
color="primary"
|
||||||
|
to="/game/online/join"
|
||||||
|
rounded
|
||||||
|
unelevated
|
||||||
|
size="lg"
|
||||||
|
class="full-width"
|
||||||
|
/>
|
||||||
|
</q-card-actions>
|
||||||
|
</q-card>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex flex-center">
|
||||||
<img
|
<img
|
||||||
alt = "Quasar logo"
|
alt = "Quasar logo"
|
||||||
src = "~assets/quasar-logo-vertical.svg"
|
src = "~assets/quasar-logo-vertical.svg"
|
||||||
style = "width: 200px; height: 200px"
|
style = "width: 200px; height: 200px"
|
||||||
/>
|
/>
|
||||||
</q-page>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import 'bootstrap-icons/font/bootstrap-icons.css';
|
||||||
|
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { LocalStorage } from 'quasar'
|
import { LocalStorage } from 'quasar'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
|
|||||||
356
frontend/src/pages/game/Components/dartPickerComponent.vue
Normal file
356
frontend/src/pages/game/Components/dartPickerComponent.vue
Normal file
@@ -0,0 +1,356 @@
|
|||||||
|
<script setup>
|
||||||
|
|
||||||
|
import { onMounted } from 'vue'
|
||||||
|
|
||||||
|
const fields = {
|
||||||
|
//
|
||||||
|
// Middle
|
||||||
|
//
|
||||||
|
0: {
|
||||||
|
name: "Bulls Eye",
|
||||||
|
points: 50
|
||||||
|
},
|
||||||
|
1: {
|
||||||
|
name: "Bull",
|
||||||
|
points: 25
|
||||||
|
},
|
||||||
|
//
|
||||||
|
// 1 Ring
|
||||||
|
//
|
||||||
|
100: {
|
||||||
|
name: "20",
|
||||||
|
points: 20
|
||||||
|
},
|
||||||
|
101: {
|
||||||
|
name: "1",
|
||||||
|
points: 1
|
||||||
|
},
|
||||||
|
102: {
|
||||||
|
name: "18",
|
||||||
|
points: 18
|
||||||
|
},
|
||||||
|
103: {
|
||||||
|
name: "4",
|
||||||
|
points: 4
|
||||||
|
},
|
||||||
|
104: {
|
||||||
|
name: "13",
|
||||||
|
points: 13
|
||||||
|
},
|
||||||
|
105: {
|
||||||
|
name: "6",
|
||||||
|
points: 6
|
||||||
|
},
|
||||||
|
106: {
|
||||||
|
name: "10",
|
||||||
|
points: 10
|
||||||
|
},
|
||||||
|
107: {
|
||||||
|
name: "15",
|
||||||
|
points: 15
|
||||||
|
},
|
||||||
|
108: {
|
||||||
|
name: "2",
|
||||||
|
points: 2
|
||||||
|
},
|
||||||
|
109: {
|
||||||
|
name: "17",
|
||||||
|
points: 17
|
||||||
|
},
|
||||||
|
110: {
|
||||||
|
name: "3",
|
||||||
|
points: 3
|
||||||
|
},
|
||||||
|
111: {
|
||||||
|
name: "19",
|
||||||
|
points: 19
|
||||||
|
},
|
||||||
|
112: {
|
||||||
|
name: "7",
|
||||||
|
points: 7
|
||||||
|
},
|
||||||
|
113: {
|
||||||
|
name: "16",
|
||||||
|
points: 16
|
||||||
|
},
|
||||||
|
114: {
|
||||||
|
name: "8",
|
||||||
|
points: 8
|
||||||
|
},
|
||||||
|
115: {
|
||||||
|
name: "11",
|
||||||
|
points: 11
|
||||||
|
},
|
||||||
|
116: {
|
||||||
|
name: "14",
|
||||||
|
points: 14
|
||||||
|
},
|
||||||
|
117: {
|
||||||
|
name: "9",
|
||||||
|
points: 9
|
||||||
|
},
|
||||||
|
118: {
|
||||||
|
name: "12",
|
||||||
|
points: 12
|
||||||
|
},
|
||||||
|
119: {
|
||||||
|
name: "5",
|
||||||
|
points: 5
|
||||||
|
},
|
||||||
|
//
|
||||||
|
// 2 Ring
|
||||||
|
//
|
||||||
|
200: {
|
||||||
|
name: "Triple 20",
|
||||||
|
points: 20
|
||||||
|
},
|
||||||
|
201: {
|
||||||
|
name: "Triple 1",
|
||||||
|
points: 1
|
||||||
|
},
|
||||||
|
202: {
|
||||||
|
name: "Triple 18",
|
||||||
|
points: 18
|
||||||
|
},
|
||||||
|
203: {
|
||||||
|
name: "Triple 4",
|
||||||
|
points: 4
|
||||||
|
},
|
||||||
|
204: {
|
||||||
|
name: "Triple 13",
|
||||||
|
points: 13
|
||||||
|
},
|
||||||
|
205: {
|
||||||
|
name: "Triple 6",
|
||||||
|
points: 6
|
||||||
|
},
|
||||||
|
206: {
|
||||||
|
name: "Triple 10",
|
||||||
|
points: 10
|
||||||
|
},
|
||||||
|
207: {
|
||||||
|
name: "Triple 15",
|
||||||
|
points: 15
|
||||||
|
},
|
||||||
|
208: {
|
||||||
|
name: "Triple 2",
|
||||||
|
points: 2
|
||||||
|
},
|
||||||
|
209: {
|
||||||
|
name: "Triple 17",
|
||||||
|
points: 17
|
||||||
|
},
|
||||||
|
210: {
|
||||||
|
name: "Triple 3",
|
||||||
|
points: 3
|
||||||
|
},
|
||||||
|
211: {
|
||||||
|
name: "Triple 19",
|
||||||
|
points: 19
|
||||||
|
},
|
||||||
|
212: {
|
||||||
|
name: "Triple 7",
|
||||||
|
points: 7
|
||||||
|
},
|
||||||
|
213: {
|
||||||
|
name: "Triple 16",
|
||||||
|
points: 16
|
||||||
|
},
|
||||||
|
214: {
|
||||||
|
name: "Triple 8",
|
||||||
|
points: 8
|
||||||
|
},
|
||||||
|
215: {
|
||||||
|
name: "Triple 11",
|
||||||
|
points: 11
|
||||||
|
},
|
||||||
|
216: {
|
||||||
|
name: "Triple 14",
|
||||||
|
points: 14
|
||||||
|
},
|
||||||
|
217: {
|
||||||
|
name: "Triple 9",
|
||||||
|
points: 9
|
||||||
|
},
|
||||||
|
218: {
|
||||||
|
name: "Triple 12",
|
||||||
|
points: 12
|
||||||
|
},
|
||||||
|
219: {
|
||||||
|
name: "Triple 5",
|
||||||
|
points: 5
|
||||||
|
},
|
||||||
|
//
|
||||||
|
// 3 Ring
|
||||||
|
//
|
||||||
|
300: {
|
||||||
|
name: "20",
|
||||||
|
points: 20
|
||||||
|
},
|
||||||
|
301: {
|
||||||
|
name: "1",
|
||||||
|
points: 1
|
||||||
|
},
|
||||||
|
302: {
|
||||||
|
name: "18",
|
||||||
|
points: 18
|
||||||
|
},
|
||||||
|
303: {
|
||||||
|
name: "4",
|
||||||
|
points: 4
|
||||||
|
},
|
||||||
|
304: {
|
||||||
|
name: "13",
|
||||||
|
points: 13
|
||||||
|
},
|
||||||
|
305: {
|
||||||
|
name: "6",
|
||||||
|
points: 6
|
||||||
|
},
|
||||||
|
306: {
|
||||||
|
name: "10",
|
||||||
|
points: 10
|
||||||
|
},
|
||||||
|
307: {
|
||||||
|
name: "15",
|
||||||
|
points: 15
|
||||||
|
},
|
||||||
|
308: {
|
||||||
|
name: "2",
|
||||||
|
points: 2
|
||||||
|
},
|
||||||
|
309: {
|
||||||
|
name: "17",
|
||||||
|
points: 17
|
||||||
|
},
|
||||||
|
310: {
|
||||||
|
name: "3",
|
||||||
|
points: 3
|
||||||
|
},
|
||||||
|
311: {
|
||||||
|
name: "19",
|
||||||
|
points: 19
|
||||||
|
},
|
||||||
|
312: {
|
||||||
|
name: "7",
|
||||||
|
points: 7
|
||||||
|
},
|
||||||
|
313: {
|
||||||
|
name: "16",
|
||||||
|
points: 16
|
||||||
|
},
|
||||||
|
314: {
|
||||||
|
name: "8",
|
||||||
|
points: 8
|
||||||
|
},
|
||||||
|
315: {
|
||||||
|
name: "11",
|
||||||
|
points: 11
|
||||||
|
},
|
||||||
|
316: {
|
||||||
|
name: "14",
|
||||||
|
points: 14
|
||||||
|
},
|
||||||
|
317: {
|
||||||
|
name: "9",
|
||||||
|
points: 9
|
||||||
|
},
|
||||||
|
318: {
|
||||||
|
name: "12",
|
||||||
|
points: 12
|
||||||
|
},
|
||||||
|
319: {
|
||||||
|
name: "5",
|
||||||
|
points: 5
|
||||||
|
},
|
||||||
|
//
|
||||||
|
// 4 Ring
|
||||||
|
//
|
||||||
|
400: {
|
||||||
|
name: "Double 20",
|
||||||
|
points: 20
|
||||||
|
},
|
||||||
|
401: {
|
||||||
|
name: "Double 1",
|
||||||
|
points: 1
|
||||||
|
},
|
||||||
|
402: {
|
||||||
|
name: "Double 18",
|
||||||
|
points: 18
|
||||||
|
},
|
||||||
|
403: {
|
||||||
|
name: "Double 4",
|
||||||
|
points: 4
|
||||||
|
},
|
||||||
|
404: {
|
||||||
|
name: "Double 13",
|
||||||
|
points: 13
|
||||||
|
},
|
||||||
|
405: {
|
||||||
|
name: "Double 6",
|
||||||
|
points: 6
|
||||||
|
},
|
||||||
|
406: {
|
||||||
|
name: "Double 10",
|
||||||
|
points: 10
|
||||||
|
},
|
||||||
|
407: {
|
||||||
|
name: "Double 15",
|
||||||
|
points: 15
|
||||||
|
},
|
||||||
|
408: {
|
||||||
|
name: "Double 2",
|
||||||
|
points: 2
|
||||||
|
},
|
||||||
|
409: {
|
||||||
|
name: "Double 17",
|
||||||
|
points: 17
|
||||||
|
},
|
||||||
|
410: {
|
||||||
|
name: "Double 3",
|
||||||
|
points: 3
|
||||||
|
},
|
||||||
|
411: {
|
||||||
|
name: "Double 19",
|
||||||
|
points: 19
|
||||||
|
},
|
||||||
|
412: {
|
||||||
|
name: "Double 7",
|
||||||
|
points: 7
|
||||||
|
},
|
||||||
|
413: {
|
||||||
|
name: "Double 16",
|
||||||
|
points: 16
|
||||||
|
},
|
||||||
|
414: {
|
||||||
|
name: "Double 8",
|
||||||
|
points: 8
|
||||||
|
},
|
||||||
|
415: {
|
||||||
|
name: "Double 11",
|
||||||
|
points: 11
|
||||||
|
},
|
||||||
|
416: {
|
||||||
|
name: "Double 14",
|
||||||
|
points: 14
|
||||||
|
},
|
||||||
|
417: {
|
||||||
|
name: "Double 9",
|
||||||
|
points: 9
|
||||||
|
},
|
||||||
|
418: {
|
||||||
|
name: "Double 12",
|
||||||
|
points: 12
|
||||||
|
},
|
||||||
|
419: {
|
||||||
|
name: "Double 5",
|
||||||
|
points: 5
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const emit = defineEmits(['sendFields'])
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
emit("sendFields", fields)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
@@ -48,7 +48,7 @@ import { useRouter } from 'vue-router'
|
|||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const $q = useQuasar();
|
const $q = useQuasar();
|
||||||
const gameID = ref();
|
const gameID = ref(null);
|
||||||
const gameCreator = ref(null);
|
const gameCreator = ref(null);
|
||||||
const gamePlayers = ref([]);
|
const gamePlayers = ref([]);
|
||||||
const user = ref({ username:"", id:0 });
|
const user = ref({ username:"", id:0 });
|
||||||
|
|||||||
52
frontend/src/pages/game/endGamePage.vue
Normal file
52
frontend/src/pages/game/endGamePage.vue
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
<template>
|
||||||
|
<q-page padding>
|
||||||
|
<q-table
|
||||||
|
title="Game Rounds"
|
||||||
|
:rows="gameData"
|
||||||
|
:columns="columns"
|
||||||
|
row-key="id"
|
||||||
|
:sort-method="sortByPlayedAt"
|
||||||
|
>
|
||||||
|
<template v-slot:body-cell-end_points="props">
|
||||||
|
{{ calculateEndPoints(props.row) }}
|
||||||
|
</template>
|
||||||
|
</q-table>
|
||||||
|
</q-page>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
// Sample data
|
||||||
|
const gameData = ref([
|
||||||
|
{ id: 1, game: 2, user: 1, round_number: 1, start_points: 0, first_throw: 50, second_throw: 0, third_throw: 0, end_points: 0, played_at: "2025-09-14T16:42:53.000Z" },
|
||||||
|
{ id: 2, game: 2, user: 1, round_number: 1, start_points: 0, first_throw: 3, second_throw: 17, third_throw: 0, end_points: 0, played_at: "2025-09-14T16:45:08.000Z" },
|
||||||
|
{ id: 3, game: 2, user: 1, round_number: 1, start_points: 0, first_throw: 50, second_throw: 2, third_throw: 0, end_points: 0, played_at: "2025-09-14T16:49:12.000Z" },
|
||||||
|
{ id: 4, game: 2, user: 1, round_number: 1, start_points: 0, first_throw: 4, second_throw: 0, third_throw: 17, end_points: 0, played_at: "2025-09-14T16:52:33.000Z" },
|
||||||
|
{ id: 5, game: 2, user: 1, round_number: 1, start_points: 0, first_throw: 3, second_throw: 2, third_throw: 0, end_points: 0, played_at: "2025-09-14T16:55:24.000Z" },
|
||||||
|
{ id: 6, game: 2, user: 3, round_number: 1, start_points: 0, first_throw: 50, second_throw: 17, third_throw: 0, end_points: 0, played_at: "2025-09-14T16:56:28.000Z" },
|
||||||
|
{ id: 7, game: 2, user: 2, round_number: 1, start_points: 0, first_throw: 3, second_throw: 19, third_throw: 0, end_points: 0, played_at: "2025-09-14T16:58:06.000Z" }
|
||||||
|
])
|
||||||
|
|
||||||
|
// Table columns
|
||||||
|
const columns = [
|
||||||
|
{ name: 'round_number', label: 'Round', field: 'round_number', align: 'left' },
|
||||||
|
{ name: 'user', label: 'User', field: 'user', align: 'left' },
|
||||||
|
|
||||||
|
{ name: 'first_throw', label: 'Throw 1', field: 'first_throw', align: 'left' },
|
||||||
|
{ name: 'second_throw', label: 'Throw 2', field: 'second_throw', align: 'left' },
|
||||||
|
{ name: 'third_throw', label: 'Throw 3', field: 'third_throw', align: 'left' },
|
||||||
|
|
||||||
|
{ name: 'end_points', label: 'End Points', field: 'end_points', align: 'left' },
|
||||||
|
]
|
||||||
|
|
||||||
|
// Custom sort by played_at
|
||||||
|
function sortByPlayedAt(a, b) {
|
||||||
|
return new Date(a.played_at) - new Date(b.played_at)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate total points for a row
|
||||||
|
function calculateEndPoints(row) {
|
||||||
|
return row.first_throw + row.second_throw + row.third_throw
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -1,7 +1,361 @@
|
|||||||
<template>
|
<template>
|
||||||
Game
|
<dartPickerComponent @sendFields="handleFields"/>
|
||||||
|
|
||||||
|
<img
|
||||||
|
v-for="(dart, index) in darts"
|
||||||
|
:key="index"
|
||||||
|
src = "~assets//dart.svg"
|
||||||
|
class = "dart"
|
||||||
|
:style="{
|
||||||
|
top: dart.top + 'px',
|
||||||
|
left: dart.left + 'px'
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div class="q-pa-md flex flex-center">
|
||||||
|
<q-card
|
||||||
|
class="q-pa-lg shadow-3"
|
||||||
|
style="width: 100vw; padding: 25px;"
|
||||||
|
>
|
||||||
|
<q-card-section>
|
||||||
|
<div v-if="gameIsLocal" class="text-h6 q-mt-md">Local Game</div>
|
||||||
|
<div v-if="!gameIsLocal" class="text-h6 q-mt-md">Online Game</div>
|
||||||
|
|
||||||
|
<div class="text-subtitle2 text-black">
|
||||||
|
Current player: {{ courentPlayer.username }}
|
||||||
|
</div>
|
||||||
|
</q-card-section>
|
||||||
|
|
||||||
|
<q-separator />
|
||||||
|
|
||||||
|
<q-card-section v-if="courentPlayer.id != user.id && !gameIsLocal" class="flex flex-center">
|
||||||
|
<div class="text-h1">Waiting for Player...</div>
|
||||||
|
</q-card-section>
|
||||||
|
|
||||||
|
<q-card-section v-if="courentPlayer.id == user.id || gameIsLocal" >
|
||||||
|
<div class = "dartBoardDiv" v-touch-pan.prevent.mouse = "onPan">
|
||||||
|
<div class="text-h5 text-black">{{ gamePoints }}</div>
|
||||||
|
|
||||||
|
<div class="text-h6 text-black">{{ selected.name ?? "0" }}</div>
|
||||||
|
|
||||||
|
<img id = "dartBoard" class = "dartBoard" src = "~assets/dartBoard.svg" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="courentDart != 3" class="row justify-center q-gutter-md q-pa-lg">
|
||||||
|
<q-btn
|
||||||
|
label="Set!"
|
||||||
|
color="primary"
|
||||||
|
@click="set"
|
||||||
|
rounded
|
||||||
|
unelevated
|
||||||
|
size="lg"
|
||||||
|
class="full-width"
|
||||||
|
style="max-width: 20vw;"
|
||||||
|
/>
|
||||||
|
<br>
|
||||||
|
<q-btn
|
||||||
|
label="Skip"
|
||||||
|
color="primary"
|
||||||
|
@click="skip"
|
||||||
|
rounded
|
||||||
|
unelevated
|
||||||
|
size="lg"
|
||||||
|
class="full-width"
|
||||||
|
style="max-width: 20svw;"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</q-card-section>
|
||||||
|
|
||||||
|
<q-card-actions v-if="courentDart == 3 && courentPlayer.id == user.id || courentDart == 3 && gameIsLocal" align="center">
|
||||||
|
<q-btn
|
||||||
|
label="Submit!"
|
||||||
|
color="primary"
|
||||||
|
@click="submit"
|
||||||
|
rounded
|
||||||
|
unelevated
|
||||||
|
size="lg"
|
||||||
|
class="full-width"
|
||||||
|
style="max-width: 50vw;"
|
||||||
|
/>
|
||||||
|
</q-card-actions>
|
||||||
|
</q-card>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
//
|
import dartPickerComponent from "./Components/dartPickerComponent.vue"
|
||||||
|
import { ref, onMounted, onUnmounted } from "vue";
|
||||||
|
import { useQuasar, LocalStorage } from 'quasar'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
import { api } from 'src/boot/axios';
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
const $q = useQuasar();
|
||||||
|
|
||||||
|
const user = ref({ username:"", id:0 });
|
||||||
|
const gameID = ref(null);
|
||||||
|
const gameIsLocal = ref(null);
|
||||||
|
|
||||||
|
const courentDart = ref(0)
|
||||||
|
const darts = ref([
|
||||||
|
{ top: null, left: null, points: null },
|
||||||
|
{ top: null, left: null, points: null },
|
||||||
|
{ top: null, left: null, points: null }
|
||||||
|
])
|
||||||
|
|
||||||
|
const courentPlayer = ref({ username:null, id:null })
|
||||||
|
const gamePoints = ref(null)
|
||||||
|
const turnOrder = ref(null)
|
||||||
|
|
||||||
|
const posRelative = ref({ top: null, left: null })
|
||||||
|
const distanceFromCenter = ref(null)
|
||||||
|
const dartRing = ref(null)
|
||||||
|
const degrees = ref(null)
|
||||||
|
const field = ref(null)
|
||||||
|
const selected = ref({ id: null, name: null, points: null })
|
||||||
|
const fields = ref({})
|
||||||
|
|
||||||
|
var canUpdate = false
|
||||||
|
|
||||||
|
const storedUser = LocalStorage.getItem("user")
|
||||||
|
if (storedUser) {
|
||||||
|
user.value = storedUser
|
||||||
|
} else {
|
||||||
|
router.push("/user/username")
|
||||||
|
}
|
||||||
|
|
||||||
|
const storedgameID = LocalStorage.getItem("gameID")
|
||||||
|
if (storedgameID) {
|
||||||
|
gameID.value = storedgameID
|
||||||
|
|
||||||
|
api.get(`/api/games/${gameID.value}`)
|
||||||
|
|
||||||
|
.then(function (response) {
|
||||||
|
|
||||||
|
gameIsLocal.value = response.data.is_local
|
||||||
|
courentPlayer.value.id = response.data.current_playing_user
|
||||||
|
updateCourentPlayerUsername()
|
||||||
|
turnOrder.value = response.data.turn_order
|
||||||
|
|
||||||
|
gamePoints.value = response.data.players.find(
|
||||||
|
player => player.id === courentPlayer.value.id
|
||||||
|
)?.points || 0
|
||||||
|
|
||||||
|
|
||||||
|
canUpdate = true
|
||||||
|
})
|
||||||
|
|
||||||
|
.catch(function (error) {
|
||||||
|
console.log(error);
|
||||||
|
|
||||||
|
$q.notify({
|
||||||
|
type: "negative",
|
||||||
|
message: error.response.data.error,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
router.push("/")
|
||||||
|
}
|
||||||
|
|
||||||
|
async function update() {
|
||||||
|
if (!canUpdate) {return}
|
||||||
|
|
||||||
|
api.get(`/api/games/${gameID.value}`)
|
||||||
|
|
||||||
|
.then(function (response) {
|
||||||
|
|
||||||
|
courentPlayer.value.id = response.data.current_playing_user
|
||||||
|
gamePoints.value = response.data.players.find(
|
||||||
|
player => player.id === courentPlayer.value.id
|
||||||
|
)?.points || 0
|
||||||
|
|
||||||
|
updateCourentPlayerUsername()
|
||||||
|
})
|
||||||
|
|
||||||
|
.catch(function (error) {
|
||||||
|
console.log(error);
|
||||||
|
|
||||||
|
$q.notify({
|
||||||
|
type: "negative",
|
||||||
|
message: error.response.data.error,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function updateCourentPlayerUsername() {
|
||||||
|
api.get(`/api/users/${courentPlayer.value.id}`)
|
||||||
|
|
||||||
|
.then(function (response) {
|
||||||
|
|
||||||
|
courentPlayer.value.username = response.data.username
|
||||||
|
})
|
||||||
|
|
||||||
|
.catch(function (error) {
|
||||||
|
console.log(error);
|
||||||
|
|
||||||
|
$q.notify({
|
||||||
|
type: "negative",
|
||||||
|
message: error.response.data.error,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function distanceBetween(x1, y1, x2, y2) {
|
||||||
|
const dx = x2 - x1;
|
||||||
|
const dy = y2 - y1;
|
||||||
|
|
||||||
|
return Math.sqrt(dx * dx + dy * dy);
|
||||||
|
}
|
||||||
|
|
||||||
|
function degreesBetweenPoints(x1, y1, x2, y2) {
|
||||||
|
let degrees = Math.atan2(y2 - y1, x2 - x1) * (180 / Math.PI)
|
||||||
|
degrees = degrees - 90 + 18/2
|
||||||
|
if (degrees < 0) degrees += 360
|
||||||
|
return degrees
|
||||||
|
// Damit ich nicht vergesse woher die zahlen kommen 😅:
|
||||||
|
// 90 da sonst die 0° rechts währe
|
||||||
|
// 18 da 360° / 20 (Dart hat 20 felder rund um wehn ich zhälen kann)
|
||||||
|
// /2 da um ein halbes feld zurück zu gehen da ich zu fauel bin das später mit einzurechen :D
|
||||||
|
}
|
||||||
|
|
||||||
|
function onPan({ position, isFinal }) {
|
||||||
|
if (courentDart.value > 2) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const offset = -50;
|
||||||
|
|
||||||
|
darts.value[courentDart.value].top = position.top + offset
|
||||||
|
darts.value[courentDart.value].left = position.left
|
||||||
|
|
||||||
|
|
||||||
|
const dartBoard = document.getElementById('dartBoard')
|
||||||
|
const dartRect = dartBoard.getBoundingClientRect()
|
||||||
|
|
||||||
|
const centerTop = dartRect.top + dartRect.height / 2
|
||||||
|
const centerLeft = dartRect.left + dartRect.width / 2
|
||||||
|
|
||||||
|
posRelative.value.top = Math.round(position.top - centerTop + offset)
|
||||||
|
posRelative.value.left = Math.round(position.left - centerLeft)
|
||||||
|
|
||||||
|
const distance = distanceBetween(darts.value[courentDart.value].left, darts.value[courentDart.value].top, centerLeft, centerTop)
|
||||||
|
degrees.value = degreesBetweenPoints(darts.value[courentDart.value].left, darts.value[courentDart.value].top, centerLeft, centerTop)
|
||||||
|
field.value = Math.floor(degrees.value/18)
|
||||||
|
|
||||||
|
if (distance < dartRect.height / 2) {
|
||||||
|
distanceFromCenter.value = distance
|
||||||
|
var id
|
||||||
|
|
||||||
|
// ich muss noch die richtigen werte aus der svg ausrechnen :C
|
||||||
|
if (distance < dartRect.height / 45) {
|
||||||
|
dartRing.value = 0
|
||||||
|
id = String(0)
|
||||||
|
|
||||||
|
} else if (distance < dartRect.height / 20) {
|
||||||
|
dartRing.value = 1
|
||||||
|
id = String(1)
|
||||||
|
|
||||||
|
} else if (distance < dartRect.height / 3.5) {
|
||||||
|
dartRing.value = 2
|
||||||
|
id = String(1)
|
||||||
|
if (field.value < 10) id = id + String(0)
|
||||||
|
id = id + String(field.value)
|
||||||
|
|
||||||
|
} else if (distance < dartRect.height / 3.2) {
|
||||||
|
dartRing.value = 3
|
||||||
|
id = String(2)
|
||||||
|
if (field.value < 10) id = id + String(0)
|
||||||
|
id = id + String(field.value)
|
||||||
|
|
||||||
|
} else if (distance < dartRect.height / 2.16) {
|
||||||
|
dartRing.value = 4
|
||||||
|
id = String(3)
|
||||||
|
if (field.value < 10) id = id + String(0)
|
||||||
|
id = id + String(field.value)
|
||||||
|
|
||||||
|
} else if (distance < dartRect.height) {
|
||||||
|
dartRing.value = 5
|
||||||
|
id = String(4)
|
||||||
|
if (field.value < 10) id = id + String(0)
|
||||||
|
id = id + String(field.value)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
selected.value.id = id
|
||||||
|
selected.value.name = fields.value[Number(id)].name
|
||||||
|
selected.value.points = fields.value[Number(id)].points
|
||||||
|
|
||||||
|
} else {
|
||||||
|
distanceFromCenter.value = null
|
||||||
|
dartRing.value = null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isFinal) {
|
||||||
|
console.log("end")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function set() {
|
||||||
|
if (courentDart.value <= 2) {
|
||||||
|
darts.value[courentDart.value].points = selected.value.points
|
||||||
|
courentDart.value += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function skip() {
|
||||||
|
if (courentDart.value <= 2) {
|
||||||
|
darts.value[courentDart.value].left = -100
|
||||||
|
darts.value[courentDart.value].top = -100
|
||||||
|
courentDart.value += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function submit() {
|
||||||
|
|
||||||
|
api.post(`/api/games/${gameID.value}/turns`, {
|
||||||
|
"user": courentPlayer.value.id,
|
||||||
|
"first_throw": darts.value[0].points ?? 0,
|
||||||
|
"second_throw": darts.value[1].points ?? 0,
|
||||||
|
"third_throw": darts.value[2].points ?? 0,
|
||||||
|
})
|
||||||
|
|
||||||
|
.then(function () {
|
||||||
|
|
||||||
|
$q.notify({
|
||||||
|
type: "positive",
|
||||||
|
message: "Success!",
|
||||||
|
});
|
||||||
|
|
||||||
|
darts.value[0].top = 0; darts.value[0].left = 0; darts.value[0].points = null
|
||||||
|
darts.value[1].top = 0; darts.value[1].left = 0; darts.value[1].points = null
|
||||||
|
darts.value[2].top = 0; darts.value[2].left = 0; darts.value[2].points = null
|
||||||
|
|
||||||
|
courentDart.value = 0
|
||||||
|
})
|
||||||
|
|
||||||
|
.catch(function (error) {
|
||||||
|
console.log(error);
|
||||||
|
|
||||||
|
$q.notify({
|
||||||
|
type: "negative",
|
||||||
|
message: error.response.data.error,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleFields = (data) => {
|
||||||
|
fields.value = data
|
||||||
|
}
|
||||||
|
|
||||||
|
let intervalId = null
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
update()
|
||||||
|
|
||||||
|
intervalId = setInterval(update, 1000)
|
||||||
|
})
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
clearInterval(intervalId)
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ const routes = [
|
|||||||
{ path: 'game/local/create', component: () => import('pages/game/createLocalGamePage.vue') },
|
{ path: 'game/local/create', component: () => import('pages/game/createLocalGamePage.vue') },
|
||||||
{ path: 'game/online/create', component: () => import('pages/game/createOnlineGamePage.vue') },
|
{ path: 'game/online/create', component: () => import('pages/game/createOnlineGamePage.vue') },
|
||||||
{ path: 'game/online/join', component: () => import('pages/game/joinOnlineGamePage.vue') },
|
{ path: 'game/online/join', component: () => import('pages/game/joinOnlineGamePage.vue') },
|
||||||
|
{ path: 'game/end', component: () => import('pages/game/endGamePage.vue') },
|
||||||
|
|
||||||
{ path: 'error', component: () => import('pages/ErrorPage.vue') }
|
{ path: 'error', component: () => import('pages/ErrorPage.vue') }
|
||||||
],
|
],
|
||||||
|
|||||||
Reference in New Issue
Block a user