Add breadcrumbs and UI consistency updates across backoffice templates

This commit is contained in:
2026-03-09 22:37:24 +01:00
parent 45f11f3564
commit b6a227febe
19 changed files with 298 additions and 153 deletions
+1 -1
View File
@@ -23,7 +23,7 @@ fixtures:
docker compose exec php bin/console doctrine:fixtures:load --purge-with-truncate --no-interaction --group=dev
translations:
docker compose exec php bin/console translation:extract --force --format=xliff --sort=asc --clean nl
docker compose exec php bin/console translation:extract --force --format=xliff --sort=asc nl
fix-cs:
docker compose exec php vendor/bin/php-cs-fixer fix
+2 -1
View File
@@ -53,11 +53,12 @@ class QuizController extends AbstractController
)]
public function overview(Season $season, Quiz $quiz): Response
{
$fetchedQuiz = $this->quizRepository->fetchWithQuestions($quiz->id);
$fetchedQuiz = $this->quizRepository->fetchWithQuestionsAndCandidates($quiz->id);
return $this->render('backoffice/quiz.html.twig', [
'season' => $season,
'quiz' => $fetchedQuiz,
'questionErrors' => $fetchedQuiz->getQuestionErrors(),
'activeTab' => 'overview',
'template' => 'backoffice/quiz/tab_overview.html.twig',
]);
-79
View File
@@ -54,85 +54,6 @@ class Question
return $this;
}
public function getErrors(): ?string
{
if (0 === \count($this->answers)) {
return 'This question has no answers';
}
$correctAnswers = $this->answers->filter(static fn (Answer $answer): bool => $answer->isRightAnswer)->count();
if (0 === $correctAnswers) {
return 'This question has no correct answers';
}
if ($correctAnswers > 1) {
return 'This question has multiple correct answers';
}
// Check if any answer in the entire quiz has candidate relations
$hasCandidateRelations = false;
foreach ($this->quiz->questions as $quizQuestion) {
foreach ($quizQuestion->answers as $answer) {
if ($answer->candidates->count() > 0) {
$hasCandidateRelations = true;
break 2;
}
}
}
// Only validate candidate-answer relations if at least one exists in the quiz
if ($hasCandidateRelations) {
$seasonCandidates = $this->quiz->season->candidates;
$candidateCounts = [];
// Count how many times each candidate appears in answers
foreach ($this->answers as $answer) {
foreach ($answer->candidates as $candidate) {
$candidateId = $candidate->id->toString();
if (!isset($candidateCounts[$candidateId])) {
$candidateCounts[$candidateId] = ['name' => $candidate->name, 'count' => 0];
}
++$candidateCounts[$candidateId]['count'];
}
}
// Check for missing and duplicate candidates
$missing = [];
$duplicates = [];
foreach ($seasonCandidates as $candidate) {
$candidateId = $candidate->id->toString();
$count = $candidateCounts[$candidateId]['count'] ?? 0;
if (0 === $count) {
$missing[] = $candidate->name;
} elseif ($count > 1) {
$duplicates[] = $candidate->name;
}
}
if (!empty($missing) || !empty($duplicates)) {
$errors = [];
if (!empty($missing)) {
// If all candidates are missing, show a special message
if (\count($missing) === $seasonCandidates->count()) {
$errors[] = 'No candidates assigned to this question';
} else {
$errors[] = 'Missing candidates: '.implode(', ', $missing);
}
}
if (!empty($duplicates)) {
$errors[] = 'Duplicate candidates: '.implode(', ', $duplicates);
}
return implode('. ', $errors);
}
}
return null;
}
public function __toString(): string
{
return $this->question;
+97
View File
@@ -68,4 +68,101 @@ class Quiz
return $this;
}
/**
* Get errors for all questions in the quiz.
* Returns an array where keys are question IDs and values are error messages.
* @return array<string, string>
*/
public function getQuestionErrors(): array
{
$errors = [];
// Check if any answer in the entire quiz has candidate relations
$hasCandidateRelations = false;
foreach ($this->questions as $question) {
foreach ($question->answers as $answer) {
if ($answer->candidates->count() > 0) {
$hasCandidateRelations = true;
break 2;
}
}
}
foreach ($this->questions as $question) {
$error = $this->getQuestionError($question, $hasCandidateRelations);
if ($error !== null) {
$errors[$question->id->toString()] = $error;
}
}
return $errors;
}
private function getQuestionError(Question $question, bool $hasCandidateRelations): ?string
{
if (0 === \count($question->answers)) {
return 'This question has no answers';
}
$correctAnswers = $question->answers->filter(static fn (Answer $answer): bool => $answer->isRightAnswer)->count();
if (0 === $correctAnswers) {
return 'This question has no correct answers';
}
if ($correctAnswers > 1) {
return 'This question has multiple correct answers';
}
// Only validate candidate-answer relations if at least one exists in the quiz
if ($hasCandidateRelations) {
$seasonCandidates = $this->season->candidates;
$candidateCounts = [];
// Count how many times each candidate appears in answers
foreach ($question->answers as $answer) {
foreach ($answer->candidates as $candidate) {
$candidateId = $candidate->id->toString();
if (!isset($candidateCounts[$candidateId])) {
$candidateCounts[$candidateId] = ['name' => $candidate->name, 'count' => 0];
}
$candidateCounts[$candidateId]['count']++;
}
}
// Check for missing and duplicate candidates
$missing = [];
$duplicates = [];
foreach ($seasonCandidates as $candidate) {
$candidateId = $candidate->id->toString();
$count = $candidateCounts[$candidateId]['count'] ?? 0;
if ($count === 0) {
$missing[] = $candidate->name;
} elseif ($count > 1) {
$duplicates[] = $candidate->name;
}
}
if (!empty($missing) || !empty($duplicates)) {
$errors = [];
if (!empty($missing)) {
// If all candidates are missing, show a special message
if (count($missing) === $seasonCandidates->count()) {
$errors[] = 'No candidates assigned to this question';
} else {
$errors[] = 'Missing candidates: ' . implode(', ', $missing);
}
}
if (!empty($duplicates)) {
$errors[] = 'Duplicate candidates: ' . implode(', ', $duplicates);
}
return implode('. ', $errors);
}
}
return null;
}
}
+2
View File
@@ -30,6 +30,7 @@ class Season
/** @var Collection<int, Quiz> */
#[ORM\OneToMany(targetEntity: Quiz::class, mappedBy: 'season', cascade: ['persist'], orphanRemoval: true)]
#[ORM\OrderBy(['id' => 'ASC'])]
public private(set) Collection $quizzes;
/** @var Collection<int, Candidate> */
@@ -39,6 +40,7 @@ class Season
/** @var Collection<int, User> */
#[ORM\ManyToMany(targetEntity: User::class, inversedBy: 'seasons')]
#[ORM\OrderBy(['email' => 'ASC'])]
public private(set) Collection $owners;
#[ORM\JoinColumn(nullable: true, onDelete: 'SET NULL')]
+5 -1
View File
@@ -17,12 +17,16 @@ class SettingsForm extends AbstractType
{
$builder
->add('showNumbers', options: [
'label' => 'Show Numbers',
'label_attr' => ['class' => 'checkbox-switch'],
'attr' => ['role' => 'switch', 'switch' => null]])
->add('confirmAnswers', options: [
'label' => 'Confirm Answers',
'label_attr' => ['class' => 'checkbox-switch'],
'attr' => ['role' => 'switch', 'switch' => null]])
->add('save', SubmitType::class)
->add('save', SubmitType::class, [
'label' => 'Save',
])
;
}
+17
View File
@@ -116,4 +116,21 @@ class QuizRepository extends ServiceEntityRepository
where q.id = :id
dql)->setParameter('id', $id)->getSingleResult();
}
/**
* Fetch quiz with all relations needed for error checking.
* This includes: questions, answers, answer candidates, and season candidates.
*/
public function fetchWithQuestionsAndCandidates(Uuid $id): Quiz
{
return $this->getEntityManager()->createQuery(<<<dql
select q, qz, a, ac, s, sc from Tvdt\Entity\Quiz q
join q.questions qz
join qz.answers a
left join a.candidates ac
join q.season s
left join s.candidates sc
where q.id = :id
dql)->setParameter('id', $id)->getSingleResult();
}
}
+11
View File
@@ -2,3 +2,14 @@
{% block importmap %}{{ importmap('backoffice') }}{% endblock %}
{% block title %}Tijd voor de test | {% endblock %}
{% block nav %}{{ include('backoffice/nav.html.twig') }}{% endblock %}
{% block main %}
<div class="container">
<div class="mt-3">
{% block breadcrumbs %}{% endblock %}
</div>
{{ include('flashes.html.twig') }}
{% block body %}
{% endblock body %}
</div>
{% endblock %}
+11 -3
View File
@@ -2,9 +2,17 @@
{% block title %}{{ parent() }}Backoffice{% endblock %}
{% block breadcrumbs %}
<nav aria-label="breadcrumb" class="mb-3">
<ol class="breadcrumb">
<li class="breadcrumb-item active" aria-current="page">{{ 'Home'|trans }}</li>
</ol>
</nav>
{% endblock %}
{% block body %}
<div class="d-flex flex-row align-items-center">
<h2 class="py-2 pe-2">
<div class="d-flex flex-row align-items-center mb-3">
<h2 class="mb-0 pe-2">
{{ is_granted('ROLE_ADMIN') ? 'All Seasons'|trans : 'Your Seasons'|trans }}
</h2>
<a class="link" href="{{ path('tvdt_backoffice_season_add') }}">
@@ -12,7 +20,7 @@
</a>
</div>
{% if seasons %}
<table class="table table-hover">
<table class="table table-hover mb-3">
<thead>
<tr>
{% if is_granted('ROLE_ADMIN') %}
@@ -1,20 +1,17 @@
{% extends 'backoffice/base.html.twig' %}
{% block body %}
<div class="row">
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{{ path('tvdt_backoffice_index') }}">Home</a></li>
<li class="breadcrumb-item"><a
href="{{ path('tvdt_backoffice_season', {seasonCode: elimination.quiz.season.seasonCode}) }}">{{ elimination.quiz.season.name }}</a>
</li>
<li class="breadcrumb-item"><a
href="{{ path('tvdt_backoffice_quiz', {seasonCode: elimination.quiz.season.seasonCode, quiz: elimination.quiz.id}) }}">{{ elimination.quiz.name }}</a>
</li>
<li class="breadcrumb-item active" aria-current="page">Prepare Elimination</li>
</ol>
</nav>
</div>
{% block breadcrumbs %}
<nav aria-label="breadcrumb" class="mb-3">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{{ path('tvdt_backoffice_index') }}">{{ 'Home'|trans }}</a></li>
<li class="breadcrumb-item"><a href="{{ path('tvdt_backoffice_season', {seasonCode: elimination.quiz.season.seasonCode}) }}">{{ elimination.quiz.season.name }}</a></li>
<li class="breadcrumb-item"><a href="{{ path('tvdt_backoffice_quiz', {seasonCode: elimination.quiz.season.seasonCode, quiz: elimination.quiz.id}) }}">{{ elimination.quiz.name }}</a></li>
<li class="breadcrumb-item active" aria-current="page">{{ 'Prepare Elimination'|trans }}</li>
</ol>
</nav>
{% endblock %}
{% block body %}
<div class="row">
<div class="col-12 col-md-6">
<form method="post">
@@ -32,7 +29,7 @@
</div>
</div>
{% endfor %}
<div class="btn-group py-2">
<div class="btn-group mb-3">
<button type="submit" class="btn btn-primary" name="start" value="0">{{ 'Save'|trans }}</button>
<button type="submit" class="btn btn-success" name="start"
value="1">{{ 'Save and start elimination'|trans }}</button>
@@ -42,7 +39,7 @@
</form>
</div>
<div class="col-12 col-md-6">
<p>Hier kan dus weer wat uitleg komen</p>
<p class="mb-3">{{ 'Help text for preparing elimination'|trans }}</p>
</div>
</div>
{% endblock %}
+12 -2
View File
@@ -2,6 +2,16 @@
{% block title %}{{ parent() }}{{ season.name }}{% endblock %}
{% block breadcrumbs %}
<nav aria-label="breadcrumb" class="mb-3">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{{ path('tvdt_backoffice_index') }}">{{ 'Home'|trans }}</a></li>
<li class="breadcrumb-item"><a href="{{ path('tvdt_backoffice_season', {seasonCode: season.seasonCode}) }}">{{ season.name }}</a></li>
<li class="breadcrumb-item active" aria-current="page">{{ quiz.name }}</li>
</ol>
</nav>
{% endblock %}
{% block body %}
{% set tabs = [
{id: 'overview', label: 'Overview'|trans, route: 'tvdt_backoffice_quiz_overview'},
@@ -9,8 +19,8 @@
{id: 'candidates', label: 'Candidates'|trans, route: 'tvdt_backoffice_quiz_candidates'},
] %}
<h2 class="py-2">{{ 'Quiz'|trans }}: {{ season.name }} - {{ quiz.name }}</h2>
<ul class="nav nav-tabs pt-2">
<h2 class="mb-3">{{ 'Quiz'|trans }}: {{ season.name }} - {{ quiz.name }}</h2>
<ul class="nav nav-tabs mb-3">
{% for tab in tabs %}
<li class="nav-item">
<a class="nav-link{{ activeTab == tab.id ? ' active' }}" href="{{ path(tab.route, {seasonCode: season.seasonCode, quiz: quiz.id}) }}">
@@ -17,7 +17,7 @@
{% endif %}
</div>
<h3 class="mb-0">{{ currentIndex + 1 }}. {{ question }}</h3>
<h4 class="mb-0">{{ currentIndex + 1 }}. {{ question }}</h4>
<div>
{% if currentIndex is not null and currentIndex < (questions|length - 1) %}
@@ -31,12 +31,12 @@
</div>
<form method="post">
<table class="table table-hover table-striped">
<table class="table table-hover table-striped mb-3">
<thead>
<tr>
<th scope="col">{{ 'Candidate'|trans }}</th>
{% for answer in question.answers %}
<th>{{ answer }}</th>
<th scope="col">{{ answer }}</th>
{% endfor %}
</tr>
</thead>
@@ -1,5 +1,5 @@
<h4 class="py-2">Quick actions</h4>
<div class="py-2 btn-group" data-controller="bo--quiz">
<h4 class="mb-3">Quick actions</h4>
<div class="mb-3 btn-group" data-controller="bo--quiz">
{% if quiz is same as (season.activeQuiz) %}
<a class="btn btn-secondary"
@@ -16,8 +16,7 @@
</button>
</div>
<div id="questions">
<h4 class="py-2">{{ 'Questions'|trans }}</h4>
<h4 class="mb-3">{{ 'Questions'|trans }}</h4>
<div class="accordion">
{%~ for question in quiz.questions ~%}
<div class="accordion-item">
@@ -27,12 +26,8 @@
data-bs-toggle="collapse"
data-bs-target="#question-{{ loop.index0 }}"
aria-controls="question-{{ loop.index0 }}">
{% set questionErrors = question.getErrors %}
{%~ if questionErrors -%}
<span data-bs-toggle="tooltip"
title="{{ questionErrors }}"
class="badge text-bg-danger rounded-pill me-2">!</span>
{% endif %}
{% set questionError = questionErrors[question.id.toString] ?? null %}
<span class="badge rounded-pill me-2{% if questionError %} text-bg-danger{% else %} invisible{% endif %}"{% if questionError %} data-bs-toggle="tooltip" title="{{ questionError }}"{% endif %}>!</span>
{{~ loop.index -}}. {{ question.question -}}
</button>
</h2>
@@ -60,7 +55,6 @@
{{ 'EMPTY'|trans }}
{% endfor %}
</div>
</div>
{# Modal Clear #}
<div class="modal fade" id="clearQuizModal" data-bs-backdrop="static"
@@ -1,7 +1,6 @@
<div class="scores">
<h4 class="py-2">{{ 'Score'|trans }}</h4>
<div class="btn-toolbar" role="toolbar">
<div class="btn-group btn-group-lg me-2">
<h4 class="mb-3">{{ 'Score'|trans }}</h4>
<div class="btn-toolbar mb-3" role="toolbar">
<div class="btn-group me-2">
{# <a class="btn btn-primary">{{ 'Start Elimination'|trans }}</a> #}
<a href="{{ path('tvdt_prepare_elimination', {seasonCode: season.seasonCode, quiz: quiz.id}) }}"
class="btn btn-secondary">{{ 'Prepare Custom Elimination'|trans }}</a>
@@ -18,8 +17,8 @@
{% endif %}
</div>
</div>
<p>{{ 'Number of dropouts:'|trans }} {{ quiz.dropouts }} </p>
<table class="table table-hover">
<p class="mb-3">{{ 'Number of dropouts:'|trans }} {{ quiz.dropouts }} </p>
<table class="table table-hover mb-3">
<thead>
<tr>
<th scope="col">{{ 'Candidate'|trans }}</th>
@@ -75,4 +74,3 @@
{% endfor %}
</tbody>
</table>
</div>
+13 -5
View File
@@ -1,9 +1,19 @@
{% extends 'backoffice/base.html.twig' %}
{% block breadcrumbs %}
<nav aria-label="breadcrumb" class="mb-3">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{{ path('tvdt_backoffice_index') }}">{{ 'Home'|trans }}</a></li>
<li class="breadcrumb-item"><a href="{{ path('tvdt_backoffice_season', {seasonCode: season.seasonCode}) }}">{{ season.name }}</a></li>
<li class="breadcrumb-item active" aria-current="page">{{ 'Add Quiz'|trans }}</li>
</ol>
</nav>
{% endblock %}
{% block body %}
<div class="row">
<div class="col-md-6 col-12">
<h2 class="py-2">{{ t('Add a quiz to %name%', {'%name%': season.name})|trans }} </h2>
<h2 class="mb-3">{{ t('Add a quiz to %name%', {'%name%': season.name})|trans }} </h2>
{{ form_start(form) }}
{{ form_row(form.name) }}
{{ form_row(form.sheet) }}
@@ -11,13 +21,11 @@
{{ form_end(form) }}
</div>
<div class="col-md-6 col-12">
<p class="pt-5">
Hier kan nog tekst komen met wat uitleg
<p class="mb-3">
{{ 'Help text for adding a quiz'|trans }}
</p>
</div>
</div>
{% endblock %}
{% block title %}
+20 -10
View File
@@ -1,37 +1,47 @@
{% extends 'backoffice/base.html.twig' %}
{% block title %}{{ parent() }}{{ season.name }}{% endblock %}
{% block breadcrumbs %}
<nav aria-label="breadcrumb" class="mb-3">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{{ path('tvdt_backoffice_index') }}">{{ 'Home'|trans }}</a></li>
<li class="breadcrumb-item active" aria-current="page">{{ season.name }}</li>
</ol>
</nav>
{% endblock %}
{% block body %}
<h2 class="py-2">{{ 'Season'|trans }}: {{ season.name }}</h2>
<h2 class="mb-3">{{ 'Season'|trans }}: {{ season.name }}</h2>
<div class="row">
<div class="col-md-6 col-12">
<div class="d-flex flex-row align-items-center">
<h4 class="py-2 pe-2">{{ 'Quizzes'|trans }}</h4>
<div class="d-flex flex-row align-items-center mb-3">
<h4 class="mb-0 pe-2">{{ 'Quizzes'|trans }}</h4>
<a class="link"
href="{{ path('tvdt_backoffice_quiz_add', {seasonCode: season.seasonCode}) }}">{{ 'Add'|trans }}</a>
</div>
<div class="list-group">
<div class="list-group mb-3">
{% for quiz in season.quizzes %}
<a class="list-group-item list-group-item-action{% if season.activeQuiz == quiz %} active{% endif %}"
href="{{ path('tvdt_backoffice_quiz', {seasonCode: season.seasonCode, quiz: quiz.id}) }}">{{ quiz.name }}</a>
{% else %}
No quizzes
{{ 'No quizzes'|trans }}
{% endfor %}
</div>
</div>
<div class="col-md-3 col-12">
<div class="d-flex flex-row align-items-center">
<h4 class="py-2 pe-2">{{ 'Candidates'|trans }}</h4>
<div class="d-flex flex-row align-items-center mb-3">
<h4 class="mb-0 pe-2">{{ 'Candidates'|trans }}</h4>
<a class="link"
href="{{ path('tvdt_backoffice_add_candidates', {seasonCode: season.seasonCode}) }}">{{ 'Add Candidate'|trans }}
</a>
</div>
<ul>
<ul class="mb-3">
{% for candidate in season.candidates %}
<li>{{ candidate.name }}</li>{% endfor %}
</ul>
<div class="d-flex flex-row align-items-center">
<h4 class="py-2 pe-2">{{ 'Settings'|trans }}</h4>
<div class="d-flex flex-row align-items-center mb-3">
<h4 class="mb-0 pe-2">{{ 'Settings'|trans }}</h4>
</div>
{{ form(form) }}
</div>
+12 -3
View File
@@ -1,17 +1,26 @@
{% extends 'backoffice/base.html.twig' %}
{% block breadcrumbs %}
<nav aria-label="breadcrumb" class="mb-3">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{{ path('tvdt_backoffice_index') }}">{{ 'Home'|trans }}</a></li>
<li class="breadcrumb-item active" aria-current="page">{{ 'Create a season'|trans }}</li>
</ol>
</nav>
{% endblock %}
{% block body %}
<div class="row">
<div class="col-md-6 col-12">
<h2 class="py-2">{{ 'Create a season'|trans }}</h2>
<h2 class="mb-3">{{ 'Create a season'|trans }}</h2>
{{ form_start(form) }}
{{ form_row(form.name) }}
<button type="submit" class="btn btn-primary">{{ 'Submit'|trans }}</button>
{{ form_end(form) }}
</div>
<div class="col-md-6 col-12">
<p class="pt-5">
Hier kan nog tekst komen met wat uitleg
<p class="mb-3">
{{ 'Help text for creating a season'|trans }}
</p>
</div>
</div>
@@ -1,17 +1,27 @@
{% extends 'backoffice/base.html.twig' %}
{% block breadcrumbs %}
<nav aria-label="breadcrumb" class="mb-3">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{{ path('tvdt_backoffice_index') }}">{{ 'Home'|trans }}</a></li>
<li class="breadcrumb-item"><a href="{{ path('tvdt_backoffice_season', {seasonCode: season.seasonCode}) }}">{{ season.name }}</a></li>
<li class="breadcrumb-item active" aria-current="page">{{ 'Add Candidates'|trans }}</li>
</ol>
</nav>
{% endblock %}
{% block body %}
<div class="row">
<div class="col-md-6 col-12">
<h2 class="py-2">{{ 'Add Candidates'|trans }}</h2>
<h2 class="mb-3">{{ 'Add Candidates'|trans }}</h2>
{{ form_start(form) }}
{{ form_row(form.candidates) }}
<button type="submit" class="btn btn-primary">{{ 'Submit'|trans }}</button>
{{ form_end(form) }}
</div>
<div class="col-md-6 col-12">
<p class="pt-5">
Hier kan nog tekst komen met wat uitleg
<p class="mb-3">
{{ 'Help text for adding candidates'|trans }}
</p>
</div>
</div>
+55 -7
View File
@@ -21,6 +21,10 @@
<source>Add Candidates</source>
<target>Voeg kandidaten toe</target>
</trans-unit>
<trans-unit id="g4GCvSW" resname="Add Quiz">
<source>Add Quiz</source>
<target>Test toevoegen</target>
</trans-unit>
<trans-unit id="ehB6pAw" resname="Add a quiz to %name%">
<source>Add a quiz to %name%</source>
<target>Voeg een test toe aan %name%</target>
@@ -35,11 +39,11 @@
</trans-unit>
<trans-unit id="Qu1euq_" resname="Are you sure you want to clear all the results? This will also delete al the eliminations.">
<source>Are you sure you want to clear all the results? This will also delete al the eliminations.</source>
<target>Weet je zeker datatype je de resultaten will leegmaken? Dit gooit ook alle eliminaties weg.</target>
<target>Weet je zeker dat je de resultaten wilt leegmaken? Dit gooit ook alle eliminaties weg.</target>
</trans-unit>
<trans-unit id="Ec4twG8" resname="Are you sure you want to delete this quiz?">
<source>Are you sure you want to delete this quiz?</source>
<target>Weet je zeker datatype je deze test will verwijderen?</target>
<target>Weet je zeker dat je deze test wilt verwijderen?</target>
</trans-unit>
<trans-unit id=".QFPbFe" resname="Back">
<source>Back</source>
@@ -49,6 +53,10 @@
<source>Candidate</source>
<target>Kandidaat</target>
</trans-unit>
<trans-unit id="Wk50LUM" resname="Candidate answers saved">
<source>Candidate answers saved</source>
<target>Kandidaatantwoorden opgeslagen</target>
</trans-unit>
<trans-unit id="TiTLBGW" resname="Candidate not found">
<source>Candidate not found</source>
<target>Kandidaat niet gevonden</target>
@@ -115,12 +123,32 @@
</trans-unit>
<trans-unit id="HNMwvRn" resname="Error clearing quiz">
<source>Error clearing quiz</source>
<target>Fout bij leegmaken test</target>
<target>Fout bij het leegmaken van de test</target>
</trans-unit>
<trans-unit id="OGiIhMH" resname="Green">
<source>Green</source>
<target>Groen</target>
</trans-unit>
<trans-unit id="b7rTx0P" resname="Help text for adding a quiz">
<source>Help text for adding a quiz</source>
<target>Upload een XLSX-bestand met vragen en antwoorden voor je test.</target>
</trans-unit>
<trans-unit id="0byYjDw" resname="Help text for adding candidates">
<source>Help text for adding candidates</source>
<target>Voeg kandidaten toe aan dit seizoen. Eén naam per regel.</target>
</trans-unit>
<trans-unit id="SipST._" resname="Help text for creating a season">
<source>Help text for creating a season</source>
<target>Maak een nieuw seizoen aan om tests en kandidaten te beheren.</target>
</trans-unit>
<trans-unit id="Q0rWWbg" resname="Help text for preparing elimination">
<source>Help text for preparing elimination</source>
<target>Kies welke kandidaten groen of rood krijgen voor de eliminatie.</target>
</trans-unit>
<trans-unit id="ExFLJqx" resname="Home">
<source>Home</source>
<target>Home</target>
</trans-unit>
<trans-unit id="k1X7w12" resname="Invalid season code">
<source>Invalid season code</source>
<target>Ongeldige seizoencode</target>
@@ -161,6 +189,10 @@
<source>No active quiz</source>
<target>Geen actieve test</target>
</trans-unit>
<trans-unit id="oNXT2zu" resname="No quizzes">
<source>No quizzes</source>
<target>Geen tests</target>
</trans-unit>
<trans-unit id="swW4qFE" resname="No results">
<source>No results</source>
<target>Geen resultaten</target>
@@ -175,7 +207,7 @@
</trans-unit>
<trans-unit id="PywqOf4" resname="Owner(s)">
<source>Owner(s)</source>
<target>Eigena(a)r(en)</target>
<target>Eigenaar(s)</target>
</trans-unit>
<trans-unit id="GqmFSHc" resname="Password">
<source>Password</source>
@@ -183,11 +215,19 @@
</trans-unit>
<trans-unit id="1ne1Zlc" resname="Penalty">
<source>Penalty</source>
<target>Straf</target>
<target>Straftijd</target>
</trans-unit>
<trans-unit id="VbgD9L8" resname="Please Confirm">
<source>Please Confirm</source>
<target>Bevestig Alsjeblieft</target>
<target>Bevestig alsjeblieft</target>
</trans-unit>
<trans-unit id="ConfAns1" resname="Confirm Answers">
<source>Confirm Answers</source>
<target>Bevestig antwoorden</target>
</trans-unit>
<trans-unit id="ShowNum1" resname="Show Numbers">
<source>Show Numbers</source>
<target>Toon nummers</target>
</trans-unit>
<trans-unit id="6EclFME" resname="Please Confirm your Email">
<source>Please Confirm your Email</source>
@@ -205,6 +245,14 @@
<source>Prepare Custom Elimination</source>
<target>Bereid aangepaste eliminatie voor</target>
</trans-unit>
<trans-unit id="xe_UxWT" resname="Prepare Elimination">
<source>Prepare Elimination</source>
<target>Bereid eliminatie voor</target>
</trans-unit>
<trans-unit id="ouNrIYq" resname="Previous">
<source>Previous</source>
<target>Vorige</target>
</trans-unit>
<trans-unit id="Rx5irUP" resname="Questions">
<source>Questions</source>
<target>Vragen</target>
@@ -267,7 +315,7 @@
</trans-unit>
<trans-unit id="8HUcmWU" resname="Save and start elimination">
<source>Save and start elimination</source>
<target>Opslaan en start eliminatie</target>
<target>Opslaan en eliminatie starten</target>
</trans-unit>
<trans-unit id="uRWqG15" resname="Score">
<source>Score</source>