generated from VLADIMIR/template_frontend
up
This commit is contained in:
+103
-23
@@ -12,6 +12,7 @@ import {
|
|||||||
NRate,
|
NRate,
|
||||||
NSelect,
|
NSelect,
|
||||||
NSpace,
|
NSpace,
|
||||||
|
NTable,
|
||||||
NTabPane,
|
NTabPane,
|
||||||
NTabs,
|
NTabs,
|
||||||
NText,
|
NText,
|
||||||
@@ -1064,6 +1065,26 @@ const reviewsCount = ref(0)
|
|||||||
const answersQuestions = ref<Question[]>([])
|
const answersQuestions = ref<Question[]>([])
|
||||||
const answersTeams = ref<TeamAnswers[]>([])
|
const answersTeams = ref<TeamAnswers[]>([])
|
||||||
|
|
||||||
|
const resultQuestions = ref<ResultsQuestion[]>([])
|
||||||
|
const resultTeams = ref<TeamResult[]>([])
|
||||||
|
const isLoadingResults = ref(false)
|
||||||
|
const hasResultsError = ref(false)
|
||||||
|
|
||||||
|
async function loadAnswerResults() {
|
||||||
|
isLoadingResults.value = true
|
||||||
|
hasResultsError.value = false
|
||||||
|
try {
|
||||||
|
const res = await client.GetGameResults({ gameID: Number(gameId) })
|
||||||
|
resultQuestions.value = res.questions || []
|
||||||
|
resultTeams.value = res.teams || []
|
||||||
|
} catch (err) {
|
||||||
|
hasResultsError.value = true
|
||||||
|
console.error('Не удалось загрузить таблицу результатов', err)
|
||||||
|
} finally {
|
||||||
|
isLoadingResults.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Баллы по ключу "teamID:questionCode" (undefined — балл не выставлен)
|
// Баллы по ключу "teamID:questionCode" (undefined — балл не выставлен)
|
||||||
const scores = ref<Record<string, number | undefined>>({})
|
const scores = ref<Record<string, number | undefined>>({})
|
||||||
|
|
||||||
@@ -1090,6 +1111,7 @@ async function loadGameAnswers() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
scores.value = next
|
scores.value = next
|
||||||
|
await loadAnswerResults()
|
||||||
}
|
}
|
||||||
|
|
||||||
async function openReviewsModal() {
|
async function openReviewsModal() {
|
||||||
@@ -1538,31 +1560,78 @@ useSimplePolling(() => {
|
|||||||
</n-tab-pane>
|
</n-tab-pane>
|
||||||
<n-tab-pane v-if="canManageGame" name="answers" tab="Проверка ответов">
|
<n-tab-pane v-if="canManageGame" name="answers" tab="Проверка ответов">
|
||||||
<div class="game-tab-content">
|
<div class="game-tab-content">
|
||||||
<div v-if="answersQuestions.length == 0" class="answers-empty">
|
<UiBlock>
|
||||||
Вопросы дела не заданы или команды ещё не отвечали.
|
<p class="screens-title">Таблица результатов</p>
|
||||||
</div>
|
<p>Сохранённые оценки. Таблица обновляется после сохранения баллов.</p>
|
||||||
<UiBlock v-for="question in answersQuestions" :key="question.code">
|
<n-text v-if="isLoadingResults">Загрузка результатов…</n-text>
|
||||||
<p class="answers-question-title">{{ question.code }}: {{ question.text }}</p>
|
<n-alert v-else-if="hasResultsError" type="error">
|
||||||
<p class="answers-question-answer">
|
Не удалось загрузить таблицу результатов.
|
||||||
Правильный ответ:<br /><span class="correct-answer">{{ question.answer || '—' }}</span>
|
</n-alert>
|
||||||
</p>
|
<p v-else-if="resultTeams.length === 0">Результатов пока нет.</p>
|
||||||
<div v-for="team in answersTeams" :key="team.team?.ID" class="answers-team-row">
|
<div v-else class="answer-results-scroll">
|
||||||
<div class="answers-team-name">
|
<n-table :single-line="false">
|
||||||
{{ team.team?.name }}
|
<thead>
|
||||||
</div>
|
<tr>
|
||||||
<div class="answers-team-answer">
|
<th scope="col">Место</th>
|
||||||
{{ teamAnswer(team, question.code) || '—' }}
|
<th scope="col">Команда</th>
|
||||||
</div>
|
<th v-for="question in resultQuestions" :key="question.code" scope="col">
|
||||||
<n-input-number
|
{{ question.code }}
|
||||||
:value="scores[scoreKey(team.team?.ID, question.code)]"
|
</th>
|
||||||
@update:value="onScoreUpdate(scoreKey(team.team?.ID, question.code), $event)"
|
<th scope="col">Сумма</th>
|
||||||
placeholder="Балл"
|
<th scope="col">Поездки</th>
|
||||||
class="answers-score-input"
|
</tr>
|
||||||
/>
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr v-for="team in resultTeams" :key="team.team?.ID">
|
||||||
|
<td>{{ team.place }}</td>
|
||||||
|
<td>{{ team.team?.name }}</td>
|
||||||
|
<td v-for="question in resultQuestions" :key="question.code">
|
||||||
|
{{ team.answers?.find((answer) => answer.questionCode === question.code)?.score ?? '—' }}
|
||||||
|
</td>
|
||||||
|
<td>{{ team.totalScore }}</td>
|
||||||
|
<td>{{ team.actionsCount }}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</n-table>
|
||||||
</div>
|
</div>
|
||||||
</UiBlock>
|
</UiBlock>
|
||||||
|
<div
|
||||||
|
v-if="answersQuestions.length === 0 || answersTeams.length === 0"
|
||||||
|
class="answers-empty"
|
||||||
|
>
|
||||||
|
Вопросы дела не заданы или команды ещё не отвечали.
|
||||||
|
</div>
|
||||||
|
<template v-else>
|
||||||
|
<UiBlock v-for="team in answersTeams" :key="team.team?.ID">
|
||||||
|
<h3 class="answers-team-name">{{ team.team?.name }}</h3>
|
||||||
|
<div
|
||||||
|
v-for="question in answersQuestions"
|
||||||
|
:key="question.code"
|
||||||
|
class="answers-question"
|
||||||
|
>
|
||||||
|
<p class="answers-question-title">{{ question.code }}: {{ question.text }}</p>
|
||||||
|
<p class="answers-question-answer">
|
||||||
|
Правильный ответ:<br /><span class="correct-answer">{{ question.answer || '—' }}</span>
|
||||||
|
</p>
|
||||||
|
<div class="answers-team-row">
|
||||||
|
<div class="answers-team-answer">
|
||||||
|
{{ teamAnswer(team, question.code) || '—' }}
|
||||||
|
</div>
|
||||||
|
<n-input-number
|
||||||
|
:value="scores[scoreKey(team.team?.ID, question.code)]"
|
||||||
|
@update:value="onScoreUpdate(scoreKey(team.team?.ID, question.code), $event)"
|
||||||
|
placeholder="Балл"
|
||||||
|
class="answers-score-input"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</UiBlock>
|
||||||
|
</template>
|
||||||
<n-flex justify="end">
|
<n-flex justify="end">
|
||||||
<n-button @click="saveAllScores()" :disabled="answersQuestions.length == 0">
|
<n-button
|
||||||
|
@click="saveAllScores()"
|
||||||
|
:disabled="answersQuestions.length === 0 || answersTeams.length === 0"
|
||||||
|
>
|
||||||
Сохранить баллы
|
Сохранить баллы
|
||||||
</n-button>
|
</n-button>
|
||||||
</n-flex>
|
</n-flex>
|
||||||
@@ -1980,10 +2049,19 @@ useSimplePolling(() => {
|
|||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.answer-results-scroll {
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
|
||||||
.answers-empty {
|
.answers-empty {
|
||||||
color: #777;
|
color: #777;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.answers-question {
|
||||||
|
margin-top: 16px;
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
}
|
||||||
|
|
||||||
.answers-question-title {
|
.answers-question-title {
|
||||||
font-size: 17px;
|
font-size: 17px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
@@ -2015,8 +2093,10 @@ useSimplePolling(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.answers-team-name {
|
.answers-team-name {
|
||||||
|
font-size: 18px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
width: 180px;
|
margin: 0;
|
||||||
|
overflow-wrap: anywhere;
|
||||||
}
|
}
|
||||||
|
|
||||||
.answers-team-answer {
|
.answers-team-answer {
|
||||||
|
|||||||
Reference in New Issue
Block a user