add block game

This commit is contained in:
2026-08-06 00:23:04 +07:00
parent a43b23aad9
commit 115f2498cd
3 changed files with 59 additions and 14 deletions
+12 -6
View File
@@ -2,7 +2,7 @@
import { Footsteps } from '@vicons/ionicons5' import { Footsteps } from '@vicons/ionicons5'
import { ContactMailRound } from '@vicons/material' import { ContactMailRound } from '@vicons/material'
import { Icon } from '@vicons/utils' import { Icon } from '@vicons/utils'
import { type PropType,ref } from 'vue'; import { type PropType, ref } from 'vue';
import BeltBlock from './BeltBlock.vue'; import BeltBlock from './BeltBlock.vue';
import HeaderText from './HeaderText.vue'; import HeaderText from './HeaderText.vue';
@@ -22,6 +22,10 @@ const props = defineProps({
newPlacesCount: { newPlacesCount: {
type: Number, type: Number,
required: true required: true
},
gameStatus: {
type: String,
required: true
} }
}) })
@@ -56,8 +60,6 @@ function getTextForCounter(count: number): string[] {
<MetalPlate class="controller-metal controller-metal-left"></MetalPlate> <MetalPlate class="controller-metal controller-metal-left"></MetalPlate>
<MetalPlate class="controller-metal controller-metal-right"></MetalPlate> <MetalPlate class="controller-metal controller-metal-right"></MetalPlate>
<div class="center-block-700"> <div class="center-block-700">
<div class="controller"> <div class="controller">
@@ -81,11 +83,15 @@ function getTextForCounter(count: number): string[] {
</div> </div>
<div class="game-input"> <div class="game-input">
<input id="run" class="game-input-run" v-model="code" type="text" placeholder="Место назначения"> <input id="run" class="game-input-run" v-model="code" type="text"
:placeholder="props.gameStatus == 'run' ? 'Место назначения' : 'Ходы запрещены'"
:disabled="props.gameStatus != 'run'">
</div> </div>
<div class="game-button-run-shadow"></div> <div class="game-button-run-shadow"></div>
<button class="game-button-run" type="submit" :disabled="code.length == 0" v-on:click="addClickButton"> <button class="game-button-run" type="submit" :disabled="code.length == 0" v-on:click="addClickButton">
<HeaderText>Поехали</HeaderText> <HeaderText v-if="props.gameStatus == 'run'">Поехали</HeaderText>
<HeaderText v-if="props.gameStatus == 'pause' || props.gameStatus == 'draft'">Ждём</HeaderText>
<HeaderText v-if="props.gameStatus == 'finish'">Всё</HeaderText>
</button> </button>
</div> </div>
</div> </div>
@@ -243,7 +249,7 @@ function getTextForCounter(count: number): string[] {
margin: 0 4px; margin: 0 4px;
} }
@media (width >= 1025px) { @media (width >=1025px) {
.center-block-700 { .center-block-700 {
width: 700px; width: 700px;
margin: 0 auto; margin: 0 auto;
+8 -3
View File
@@ -75,8 +75,12 @@ async function getGame(id: number) {
} }
getGame(Number(gameId)) getGame(Number(gameId))
async function toTeamStory(id: number, password: string) { async function toTeamStory(id: number, password: string, newTab: boolean = false) {
router.push('/team-story/' + id + '?password=' + password) const uri = '/team-story/' + id + '?password=' + password
if (newTab) {
window.open(uri, '_blank');
}
router.push(uri)
} }
async function updateGame() { async function updateGame() {
@@ -364,7 +368,7 @@ useSimplePolling(() => {
<n-button @click="openQR(getTeamStoryURL(team.id!, team.password!))"> <n-button @click="openQR(getTeamStoryURL(team.id!, team.password!))">
QR QR
</n-button> </n-button>
<n-button @click="toTeamStory(team.id!, team.password!)"> <n-button @click="toTeamStory(team.id!, team.password!, true)">
Подсмотреть игру Подсмотреть игру
</n-button> </n-button>
<n-button type="error" ghost @click="deleteTeam(team)"> <n-button type="error" ghost @click="deleteTeam(team)">
@@ -498,6 +502,7 @@ useSimplePolling(() => {
margin: 10px 0; margin: 10px 0;
border-radius: 10px; border-radius: 10px;
background-color: #222; background-color: #222;
border: 1px solid #222;
} }
.team-block-hover:hover { .team-block-hover:hover {
+39 -5
View File
@@ -1,8 +1,8 @@
<script setup lang="ts"> <script setup lang="ts">
import { NButton, NFlex } from 'naive-ui' import { NButton, NFlex, NQrCode } from 'naive-ui'
import { useMessage } from 'naive-ui'; import { useMessage } from 'naive-ui';
import { nextTick, ref } from 'vue'; import { nextTick, ref } from 'vue';
import { useRoute } from 'vue-router'; import { useRoute, useRouter } from 'vue-router';
import { getAuthClient } from '@/api/auth_client'; import { getAuthClient } from '@/api/auth_client';
import type { Game, Place } from '@/api/generated/crabs/evening_detective_server'; import type { Game, Place } from '@/api/generated/crabs/evening_detective_server';
@@ -12,9 +12,12 @@ import PlaceBlock from '@/components/PlaceBlock.vue'
import { useSimplePolling } from '@/composables/useSimplePolling'; import { useSimplePolling } from '@/composables/useSimplePolling';
import { useAuthStore } from '@/stores/auth'; import { useAuthStore } from '@/stores/auth';
import MessagePaper from './MessagePaper.vue';
const authStore = useAuthStore() const authStore = useAuthStore()
const client = getAuthClient() const client = getAuthClient()
const message = useMessage() const message = useMessage()
const router = useRouter()
const route = useRoute() const route = useRoute()
const teamId = route.params.id const teamId = route.params.id
const password = route.query.password const password = route.query.password
@@ -39,6 +42,8 @@ const game = ref<Game | undefined>({
const code = ref('') const code = ref('')
const url = window.location.href
const isAtBottom = () => { const isAtBottom = () => {
const container = scrollContainer.value; const container = scrollContainer.value;
if (!container) return false; if (!container) return false;
@@ -140,14 +145,26 @@ useSimplePolling(() => {
<template> <template>
<div class="center-block-custom bottom-margin smooth-scroll" ref="scrollContainer"> <div class="center-block-custom bottom-margin smooth-scroll" ref="scrollContainer">
<div class="width700"> <div class="width700">
<GameInputForm :addAction="addAction" :allPlacesCount="story.places.length" <GameInputForm :addAction="addAction" :allPlacesCount="story.places.length" :newPlacesCount="newPlacesCount"
:newPlacesCount="newPlacesCount"></GameInputForm> :gameStatus="game?.status || ''"></GameInputForm>
<PlaceBlock :place="advancedPlace.place" v-model:mode="advancedPlace.mode" <PlaceBlock :place="advancedPlace.place" v-model:mode="advancedPlace.mode"
v-for="advancedPlace in story.places" v-bind:key="advancedPlace.place.code" :addAction="addAction"> v-for="advancedPlace in story.places" v-bind:key="advancedPlace.place.code" :addAction="addAction">
</PlaceBlock> </PlaceBlock>
<div v-if="authStore.hasRole('author')" class="edit-panel"> <MessagePaper class="qr-main-block" v-if="story.places.length == 0">
<n-space vertical>
<h2 class="qr-main-block-text">Это код этого дела</h2>
<p class="qr-main-block-text">Поделись с командой</p>
<div class="qr-block">
<n-qr-code :value="url" :size="300" :padding="0" />
</div>
<p v-if="game?.status == 'draft'" class="qr-main-block-text">Игра скоро начнется</p>
<p v-if="game?.status == 'run'" class="qr-main-block-text">Игра началась!!!</p>
</n-space>
</MessagePaper>
<div v-if="authStore.hasRole('author') && story.places.length > 0" class="edit-panel">
<n-flex justify="end"> <n-flex justify="end">
<n-button @click="deleteLast">Удалить последний ход</n-button> <n-button @click="deleteLast">Удалить последний ход</n-button>
</n-flex> </n-flex>
@@ -174,6 +191,23 @@ useSimplePolling(() => {
border-radius: 10px; border-radius: 10px;
} }
.qr-main-block {
display: flex;
justify-content: center;
align-items: center;
}
.qr-main-block-text {
text-align: left;
margin: 10px 0;
}
.qr-block {
display: inline-block;
background-color: white;
padding: 12px;
}
@media (width >=1024px) { @media (width >=1024px) {
.bottom-margin { .bottom-margin {
height: calc(100dvh - 70px - 76px); height: calc(100dvh - 70px - 76px);