Add OnlineMode route and extract app styles

Introduce an OnlineMode route and placeholder component, wire it into the router and Home menu (replace the removed local-vs-bot entry). Rename utils/index.ts to router/index.ts and add the new /onlineMode route; update main.ts to import the router from ./router and include the new app.css. Extract shared #game and .game-content styles into GUI/src/app.css and remove the duplicate styles from LocalMode.vue. Make small UI tweaks: adjust GameEndedMenu width, minor formatting/attribute fixes in Layout.vue and LocalMode.vue.
This commit is contained in:
Jonas
2026-03-08 19:15:25 +01:00
parent bb3c482728
commit c18ed5954e
8 changed files with 61 additions and 39 deletions
+1 -5
View File
@@ -6,15 +6,11 @@ let buttons = [
color: "red", color: "red",
componentName: "LocalMode" componentName: "LocalMode"
}, },
{
name: "Lokal gegen Bot",
icon: "mdi-robot-angry-outline",
color: "green",
},
{ {
name: "Online Multiplayer", name: "Online Multiplayer",
icon: "mdi-web", icon: "mdi-web",
color: "blue", color: "blue",
componentName: "OnlineMode"
}, },
] ]
</script> </script>
+4 -4
View File
@@ -7,10 +7,10 @@
<template v-slot:image> <template v-slot:image>
<v-img gradient="to top right, rgba(5, 5, 5, 0.6), rgba(50, 50, 60, 0.6)"></v-img> <v-img gradient="to top right, rgba(5, 5, 5, 0.6), rgba(50, 50, 60, 0.6)"></v-img>
</template> </template>
<v-app-bar-title <v-app-bar-title
class="font-weight-semibold text-white" class="font-weight-semibold text-white"
@click="$router.push('/')" @click="$router.push('/')"
style="cursor: pointer;" style="cursor: pointer"
> >
4-Gewinnt 4-Gewinnt
</v-app-bar-title> </v-app-bar-title>
@@ -22,4 +22,4 @@
</v-app> </v-app>
</template> </template>
<style scoped></style> <style scoped></style>
+17
View File
@@ -0,0 +1,17 @@
#game {
width: 100%;
min-height: calc(100dvh - var(--v-layout-top));
display: flex;
justify-content: center;
align-items: center;
padding: 16px;
box-sizing: border-box;
}
.game-content {
display: flex;
flex-direction: column;
align-items: center;
gap: 16px;
width: 100%;
}
+1 -1
View File
@@ -21,7 +21,7 @@ const message = computed(() => {
</script> </script>
<template> <template>
<v-sheet width="100%" class="text-centered pa-2 w-75" rounded> <v-sheet class="text-centered pa-2 w-50" rounded>
<h1 class="text-center">{{ message}}</h1> <h1 class="text-center">{{ message}}</h1>
<h3 class="text-center">Spiele erneut oder beende das Spiel</h3> <h3 class="text-center">Spiele erneut oder beende das Spiel</h3>
<v-divider class="mb-4"></v-divider> <v-divider class="mb-4"></v-divider>
+3 -1
View File
@@ -1,6 +1,6 @@
import { createApp } from 'vue' import { createApp } from 'vue'
import App from './Layout.vue' import App from './Layout.vue'
import router from './utils' import router from './router'
// Vuetify // Vuetify
import 'vuetify/styles' import 'vuetify/styles'
import { createVuetify } from 'vuetify' import { createVuetify } from 'vuetify'
@@ -22,6 +22,8 @@ import '@fontsource/roboto/700-italic.css'
import '@fontsource/roboto/900-italic.css' import '@fontsource/roboto/900-italic.css'
// Icons // Icons
import '@mdi/font/css/materialdesignicons.css' import '@mdi/font/css/materialdesignicons.css'
// Styles
import "./app.css"
// Vuetify // Vuetify
const vuetify = createVuetify({ const vuetify = createVuetify({
@@ -1,6 +1,7 @@
import Home from '@/Home.vue' import Home from '@/Home.vue'
import NotFound from '@/NotFound.vue' import NotFound from '@/NotFound.vue'
import LocalMode from '@/routes/LocalMode.vue' import LocalMode from '@/routes/LocalMode.vue'
import OnlineMode from '@/routes/OnlineMode.vue'
import { createRouter, createWebHistory } from 'vue-router' import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({ const router = createRouter({
@@ -16,6 +17,11 @@ const router = createRouter({
name: "LocalMode", name: "LocalMode",
component: LocalMode component: LocalMode
}, },
{
path: "/onlineMode",
name: "OnlineMode",
component: OnlineMode
},
{ path: '/:pathMatch(.*)*', name: 'Nicht gefunden', component: NotFound }, { path: '/:pathMatch(.*)*', name: 'Nicht gefunden', component: NotFound },
], ],
}) })
+20 -28
View File
@@ -33,7 +33,7 @@ game.value.onGameStateChanged = (gameState) => {
game.value.onGameEnded = (gameEndedInfo) => { game.value.onGameEnded = (gameEndedInfo) => {
gameEndedInformation.value = gameEndedInfo; gameEndedInformation.value = gameEndedInfo;
currentState.value = CurrentState.EndScreen; currentState.value = CurrentState.EndScreen;
} };
async function startGame() { async function startGame() {
await game.value.start(settings.value); await game.value.start(settings.value);
@@ -41,50 +41,42 @@ async function startGame() {
currentState.value = CurrentState.Game; currentState.value = CurrentState.Game;
} }
async function restart(){ async function restart() {
await game.value.disconnectAll(); await game.value.disconnectAll();
startGame(); startGame();
} }
</script> </script>
<template> <template>
<v-container class="d-flex align-center justify-center fill-height" v-if="currentState === CurrentState.CreatingGame"> <v-container
class="d-flex align-center justify-center fill-height"
v-if="currentState === CurrentState.CreatingGame"
>
<GameCreationMenu v-model:settings="settings" @create-game="startGame()" /> <GameCreationMenu v-model:settings="settings" @create-game="startGame()" />
</v-container> </v-container>
<v-container class="d-flex align-center justify-center fill-height" <v-container
v-else-if="currentState === CurrentState.EndScreen"> class="d-flex align-center justify-center fill-height"
<GameEndedMenu :game-ended-information="gameEndedInformation" @restart-game="restart"></GameEndedMenu> v-else-if="currentState === CurrentState.EndScreen"
>
<GameEndedMenu
:game-ended-information="gameEndedInformation"
@restart-game="restart"
></GameEndedMenu>
</v-container> </v-container>
<div id="game" v-else> <div id="game" v-else>
<div class="game-content"> <div class="game-content">
<Field :game-state="gameField" v-model:current-selection-index="currentSelectionIndex" <Field
@click-on-game-field="game.drop(currentSelectionIndex ?? 1)" /> :game-state="gameField"
v-model:current-selection-index="currentSelectionIndex"
@click-on-game-field="game.drop(currentSelectionIndex ?? 1)"
/>
<InfoField :msg="game.currentDescription"></InfoField> <InfoField :msg="game.currentDescription"></InfoField>
</div> </div>
</div> </div>
</template> </template>
<style scoped> <style scoped></style>
#game {
width: 100%;
min-height: calc(100dvh - var(--v-layout-top));
display: flex;
justify-content: center;
align-items: center;
padding: 16px;
box-sizing: border-box;
}
.game-content {
display: flex;
flex-direction: column;
align-items: center;
gap: 16px;
width: 100%;
}
</style>
+9
View File
@@ -0,0 +1,9 @@
<script setup lang="ts">
</script>
<template>
<h1>Online Modus</h1>
</template>
<style scoped>
</style>