mirror of
https://github.com/MarijnDoeve/TijdVoorDeTest.git
synced 2026-03-07 13:14:20 +01:00
Compare commits
16 Commits
2bfef94bbe
...
v0.0.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
cfb69c8dab
|
|||
|
35ec71302b
|
|||
|
b7a570928a
|
|||
|
d80436534f
|
|||
|
|
14e2dd490e | ||
|
|
68e54b1110 | ||
|
|
e615b2cdea | ||
|
|
4b45a2c557 | ||
| c6fe553341 | |||
|
69a2b9c811
|
|||
|
f31a7d527d
|
|||
| ed3cf7644f | |||
| 77d21b004f | |||
|
379fafcd16
|
|||
|
7586d2d8ac
|
|||
|
9e41376244
|
11
.github/dependabot.yml
vendored
Normal file
11
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
# To get started with Dependabot version updates, you'll need to specify which
|
||||
# package ecosystems to update and where the package manifests are located.
|
||||
# Please see the documentation for all configuration options:
|
||||
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "composer" # See documentation for possible values
|
||||
directory: "/" # Location of package manifests
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
25
.github/workflows/ci.yml
vendored
25
.github/workflows/ci.yml
vendored
@@ -4,6 +4,8 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
tags:
|
||||
- '*'
|
||||
pull_request: ~
|
||||
workflow_dispatch: ~
|
||||
|
||||
@@ -18,10 +20,12 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Lint Dockerfile
|
||||
uses: hadolint/hadolint-action@v3.1.0
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Build Docker images
|
||||
uses: docker/bake-action@v4
|
||||
uses: docker/bake-action@v5
|
||||
with:
|
||||
pull: true
|
||||
load: true
|
||||
@@ -53,12 +57,17 @@ jobs:
|
||||
run: docker compose exec -T php vendor/bin/phpunit
|
||||
- name: Doctrine Schema Validator
|
||||
run: docker compose exec -T php bin/console -e test doctrine:schema:validate
|
||||
lint:
|
||||
name: Docker Lint
|
||||
deploy:
|
||||
name: Deploy
|
||||
environment:
|
||||
name: ${{ startsWith(github.ref, 'refs/tags/') && 'production' || (github.ref == 'refs/heads/main' && 'acceptance' || '') }}
|
||||
url: ${{ vars.URL }}
|
||||
needs: tests
|
||||
runs-on: ubuntu-latest
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Lint Dockerfile
|
||||
uses: hadolint/hadolint-action@v3.1.0
|
||||
|
||||
- shell: bash
|
||||
env:
|
||||
PORTAINER_WEBHOOK: ${{secrets.PORTAINER_WEBHOOK}}
|
||||
run: |
|
||||
curl -v -X POST "$PORTAINER_WEBHOOK"
|
||||
|
||||
@@ -24,6 +24,8 @@ services:
|
||||
database:
|
||||
networks:
|
||||
- internal
|
||||
ports:
|
||||
- "5430:5432"
|
||||
networks:
|
||||
web:
|
||||
external: true
|
||||
|
||||
@@ -9,21 +9,21 @@
|
||||
"php": ">=8.4",
|
||||
"ext-ctype": "*",
|
||||
"ext-iconv": "*",
|
||||
"doctrine/dbal": "^4.2.3",
|
||||
"doctrine/doctrine-bundle": "^2.14.0",
|
||||
"doctrine/dbal": "^4.3.3",
|
||||
"doctrine/doctrine-bundle": "^2.16.1",
|
||||
"doctrine/doctrine-migrations-bundle": "^3.4.2",
|
||||
"doctrine/orm": "^3.3.3",
|
||||
"easycorp/easyadmin-bundle": "^4.24.7",
|
||||
"phpdocumentor/reflection-docblock": "^5.6.2",
|
||||
"phpoffice/phpspreadsheet": "^4.3.1",
|
||||
"phpstan/phpdoc-parser": "^2.1",
|
||||
"doctrine/orm": "^3.5.2",
|
||||
"easycorp/easyadmin-bundle": "^4.25.0",
|
||||
"phpdocumentor/reflection-docblock": "^5.6.3",
|
||||
"phpoffice/phpspreadsheet": "^5.1",
|
||||
"phpstan/phpdoc-parser": "^2.3",
|
||||
"runtime/frankenphp-symfony": "^0.2.0",
|
||||
"sentry/sentry-symfony": "^5.2",
|
||||
"sentry/sentry-symfony": "^5.4",
|
||||
"symfony/asset": "7.3.*",
|
||||
"symfony/asset-mapper": "7.3.*",
|
||||
"symfony/console": "7.3.*",
|
||||
"symfony/dotenv": "7.3.*",
|
||||
"symfony/flex": "^2.7.1",
|
||||
"symfony/flex": "^2.8.2",
|
||||
"symfony/form": "7.3.*",
|
||||
"symfony/framework-bundle": "7.3.*",
|
||||
"symfony/mailer": "7.3.*",
|
||||
@@ -35,10 +35,10 @@
|
||||
"symfony/serializer": "7.3.*",
|
||||
"symfony/twig-bundle": "7.3.*",
|
||||
"symfony/uid": "7.3.*",
|
||||
"symfony/ux-turbo": "^2.26.1",
|
||||
"symfony/ux-turbo": "^2.30.0",
|
||||
"symfony/yaml": "7.3.*",
|
||||
"symfonycasts/sass-bundle": "^0.8.2",
|
||||
"symfonycasts/verify-email-bundle": "^1.17.3",
|
||||
"symfonycasts/sass-bundle": "^0.8.3",
|
||||
"symfonycasts/verify-email-bundle": "^1.17.4",
|
||||
"thecodingmachine/safe": "^3.3.0",
|
||||
"twig/extra-bundle": "^3.21",
|
||||
"twig/intl-extra": "^3.21",
|
||||
@@ -46,23 +46,23 @@
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/doctrine-fixtures-bundle": "^4.1",
|
||||
"friendsofphp/php-cs-fixer": "^3.75.0",
|
||||
"friendsofphp/php-cs-fixer": "^3.87.1",
|
||||
"phpstan/extension-installer": "^1.4.3",
|
||||
"phpstan/phpstan": "^2.1.17",
|
||||
"phpstan/phpstan-doctrine": "^2.0.3",
|
||||
"phpstan/phpstan-phpunit": "^2.0.6",
|
||||
"phpstan/phpstan-symfony": "^2.0.6",
|
||||
"phpunit/phpunit": "^12.2.1",
|
||||
"rector/rector": "^2.0.17",
|
||||
"phpstan/phpstan": "^2.1.22",
|
||||
"phpstan/phpstan-doctrine": "^2.0.5",
|
||||
"phpstan/phpstan-phpunit": "^2.0.7",
|
||||
"phpstan/phpstan-symfony": "^2.0.8",
|
||||
"phpunit/phpunit": "^12.3.8",
|
||||
"rector/rector": "^2.1.6",
|
||||
"roave/security-advisories": "dev-latest",
|
||||
"symfony/browser-kit": "7.3.*",
|
||||
"symfony/css-selector": "7.3.*",
|
||||
"symfony/maker-bundle": "^1.63.0",
|
||||
"symfony/maker-bundle": "^1.64.0",
|
||||
"symfony/phpunit-bridge": "7.3.*",
|
||||
"symfony/stopwatch": "7.3.*",
|
||||
"symfony/web-profiler-bundle": "7.3.*",
|
||||
"thecodingmachine/phpstan-safe-rule": "^1.4.1",
|
||||
"vincentlanglet/twig-cs-fixer": "^3.7.1"
|
||||
"vincentlanglet/twig-cs-fixer": "^3.9.0"
|
||||
},
|
||||
"config": {
|
||||
"allow-plugins": {
|
||||
|
||||
1678
composer.lock
generated
1678
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -29,6 +29,7 @@ readonly class AddSettingsCommand
|
||||
if (null !== $season->getSettings()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$io->text('Adding settings to season : '.$season->getSeasonCode());
|
||||
$season->setSettings(new SeasonSettings());
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ namespace App\Controller\Admin;
|
||||
use App\Entity\Answer;
|
||||
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
|
||||
|
||||
/** @extends AbstractCrudController<Answer> */
|
||||
class AnswerCrudController extends AbstractCrudController
|
||||
{
|
||||
public static function getEntityFqcn(): string
|
||||
|
||||
@@ -7,6 +7,7 @@ namespace App\Controller\Admin;
|
||||
use App\Entity\Candidate;
|
||||
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
|
||||
|
||||
/** @extends AbstractCrudController<Candidate> */
|
||||
class CandidateCrudController extends AbstractCrudController
|
||||
{
|
||||
public static function getEntityFqcn(): string
|
||||
|
||||
@@ -7,6 +7,7 @@ namespace App\Controller\Admin;
|
||||
use App\Entity\GivenAnswer;
|
||||
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
|
||||
|
||||
/** @extends AbstractCrudController<GivenAnswer> */
|
||||
class GivenAnswerCrudController extends AbstractCrudController
|
||||
{
|
||||
public static function getEntityFqcn(): string
|
||||
|
||||
@@ -7,6 +7,7 @@ namespace App\Controller\Admin;
|
||||
use App\Entity\Question;
|
||||
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
|
||||
|
||||
/** @extends AbstractCrudController<Question> */
|
||||
class QuestionCrudController extends AbstractCrudController
|
||||
{
|
||||
public static function getEntityFqcn(): string
|
||||
|
||||
@@ -7,7 +7,8 @@ namespace App\Controller\Admin;
|
||||
use App\Entity\QuizCandidate;
|
||||
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
|
||||
|
||||
class CorrectionCrudController extends AbstractCrudController
|
||||
/** @extends AbstractCrudController<QuizCandidate> */
|
||||
class QuizCorrectionCrudController extends AbstractCrudController
|
||||
{
|
||||
public static function getEntityFqcn(): string
|
||||
{
|
||||
@@ -7,6 +7,7 @@ namespace App\Controller\Admin;
|
||||
use App\Entity\Quiz;
|
||||
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
|
||||
|
||||
/** @extends AbstractCrudController<Quiz> */
|
||||
class QuizCrudController extends AbstractCrudController
|
||||
{
|
||||
public static function getEntityFqcn(): string
|
||||
|
||||
@@ -7,6 +7,7 @@ namespace App\Controller\Admin;
|
||||
use App\Entity\Season;
|
||||
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
|
||||
|
||||
/** @extends AbstractCrudController<Season> */
|
||||
class SeasonCrudController extends AbstractCrudController
|
||||
{
|
||||
public static function getEntityFqcn(): string
|
||||
|
||||
@@ -7,6 +7,7 @@ namespace App\Controller\Admin;
|
||||
use App\Entity\User;
|
||||
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
|
||||
|
||||
/** @extends AbstractCrudController<User> */
|
||||
class UserCrudController extends AbstractCrudController
|
||||
{
|
||||
public static function getEntityFqcn(): string
|
||||
|
||||
@@ -69,7 +69,7 @@ class SeasonController extends AbstractController
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$candidates = $form->get('candidates')->getData();
|
||||
foreach (explode("\n", (string) $candidates) as $candidate) {
|
||||
$season->addCandidate(new Candidate($candidate));
|
||||
$season->addCandidate(new Candidate(mb_rtrim($candidate)));
|
||||
}
|
||||
|
||||
$this->em->flush();
|
||||
|
||||
@@ -57,6 +57,7 @@ final class RegistrationController extends AbstractController
|
||||
} catch (TransportExceptionInterface $e) {
|
||||
$logger->error($e->getMessage());
|
||||
}
|
||||
|
||||
$response = $security->login($user, 'form_login', 'main');
|
||||
\assert($response instanceof Response);
|
||||
|
||||
|
||||
@@ -39,15 +39,8 @@ class RegistrationFormType extends AbstractType
|
||||
'second_options' => ['label' => $this->translator->trans('Repeat Password')],
|
||||
'mapped' => false,
|
||||
'constraints' => [
|
||||
new NotBlank([
|
||||
'message' => 'Please enter a password',
|
||||
]),
|
||||
new Length([
|
||||
'min' => 8,
|
||||
'minMessage' => 'Your password should be at least {{ limit }} characters',
|
||||
// max length allowed by Symfony for security reasons
|
||||
'max' => 4096,
|
||||
]),
|
||||
new NotBlank(message: 'Please enter a password'),
|
||||
new Length(min: 8, max: 4096, minMessage: 'Your password should be at least {{ limit }} characters'),
|
||||
],
|
||||
'translation_domain' => false,
|
||||
])
|
||||
|
||||
@@ -31,13 +31,9 @@ class UploadQuizFormType extends AbstractType
|
||||
'required' => true,
|
||||
'translation_domain' => false,
|
||||
'constraints' => [
|
||||
new File([
|
||||
'maxSize' => '1024k',
|
||||
'mimeTypes' => [
|
||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
],
|
||||
'mimeTypesMessage' => $this->translator->trans('Please upload a valid XLSX file'),
|
||||
]),
|
||||
new File(maxSize: '1024k', mimeTypes: [
|
||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
], mimeTypesMessage: $this->translator->trans('Please upload a valid XLSX file')),
|
||||
],
|
||||
])
|
||||
;
|
||||
|
||||
@@ -68,9 +68,9 @@ class CandidateRepository extends ServiceEntityRepository
|
||||
join c.givenAnswers ga
|
||||
join ga.answer a
|
||||
join c.quizData qc
|
||||
where qc.quiz = :quiz
|
||||
where qc.quiz = :quiz and ga.quiz = :quiz
|
||||
group by ga.quiz, c.id, qc.id
|
||||
order by score desc, time desc
|
||||
order by score desc, time asc
|
||||
DQL
|
||||
)->setParameter('quiz', $quiz)->getResult();
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ use App\Entity\Quiz;
|
||||
use App\Entity\Season;
|
||||
use App\Entity\User;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
use Symfony\Component\Security\Core\Authorization\Voter\Vote;
|
||||
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
|
||||
|
||||
/** @extends Voter<string, Season> */
|
||||
@@ -37,7 +38,7 @@ final class SeasonVoter extends Voter
|
||||
}
|
||||
|
||||
/** @param Season|Elimination|Quiz|Candidate|Answer|Question $subject */
|
||||
protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool
|
||||
protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token, ?Vote $vote = null): bool
|
||||
{
|
||||
$user = $token->getUser();
|
||||
if (!$user instanceof User) {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
{% block importmap %}{{ importmap('backoffice') }}{% endblock %}
|
||||
{% block title %}Tijd voor de test | {% endblock %}
|
||||
{% block nav %}{{ include('backoffice/nav.html.twig') }}{% endblock %}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% extends 'backoffice/base.html.twig' %}
|
||||
|
||||
{% block title %}Hello BackofficeController!{% endblock %}
|
||||
{% block title %}{{ parent() }}Backoffice{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div class="d-flex flex-row align-items-center">
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
{% extends 'backoffice/base.html.twig' %}
|
||||
|
||||
{% block title %}{{ parent() }}{{ quiz.season.name }}{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h2 class="py-2">{{ 'Quiz'|trans }}: {{ quiz.season.name }} - {{ quiz.name }}</h2>
|
||||
<div class="py-2 btn-group" data-controller="bo--quiz">
|
||||
@@ -51,7 +53,7 @@
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
EMPTY
|
||||
{{ 'EMPTY'|trans }}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
@@ -125,15 +127,16 @@
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5" id="staticBackdropLabel">Please Confirm</h1>
|
||||
<h1 class="modal-title fs-5" id="staticBackdropLabel">{{ 'Please Confirm'|trans }}</h1>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
Are you sure you want to clear all the results? This will also delete al the eliminations.
|
||||
{{ 'Are you sure you want to clear all the results? This will also delete al the eliminations.'|trans }}
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">No</button>
|
||||
<a href="{{ path('app_backoffice_quiz_clear', {quiz: quiz.id}) }}" class="btn btn-danger">Yes</a>
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{{ 'No'|trans }}</button>
|
||||
<a href="{{ path('app_backoffice_quiz_clear', {quiz: quiz.id}) }}"
|
||||
class="btn btn-danger">{{ 'Yes'|trans }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -146,19 +149,18 @@
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5" id="staticBackdropLabel">Please Confirm</h1>
|
||||
<h1 class="modal-title fs-5" id="staticBackdropLabel">{{ 'Please Confirm'|trans }}</h1>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
Are you sure you want to delete this quiz?
|
||||
{{ 'Are you sure you want to delete this quiz?'|trans }}
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">No</button>
|
||||
<a href="{{ path('app_backoffice_quiz_delete', {quiz: quiz.id}) }}" class="btn btn-danger">Yes</a>
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{{ 'No'|trans }}</button>
|
||||
<a href="{{ path('app_backoffice_quiz_delete', {quiz: quiz.id}) }}"
|
||||
class="btn btn-danger">{{ 'Yes'|trans }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block title %}
|
||||
{% endblock %}
|
||||
|
||||
@@ -21,5 +21,5 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block title %}
|
||||
|
||||
{{ parent() }}Backoffice
|
||||
{% endblock %}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{% extends 'backoffice/base.html.twig' %}
|
||||
{% block title %}{{ parent() }}{{ season.name }}{% endblock %}
|
||||
{% block body %}
|
||||
<h2 class="py-2">{{ 'Season'|trans }}: {{ season.name }}</h2>
|
||||
<div class="row">
|
||||
|
||||
@@ -33,6 +33,14 @@
|
||||
<source>Already have an account? Log in</source>
|
||||
<target>Heb je al een account? Log in</target>
|
||||
</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>
|
||||
</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>
|
||||
</trans-unit>
|
||||
<trans-unit id=".QFPbFe" resname="Back">
|
||||
<source>Back</source>
|
||||
<target>Terug</target>
|
||||
@@ -89,6 +97,10 @@
|
||||
<source>Download Template</source>
|
||||
<target>Download sjabloon</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="FfYlwX8" resname="EMPTY">
|
||||
<source>EMPTY</source>
|
||||
<target>LEEG</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="JZi_tm0" resname="Email">
|
||||
<source>Email</source>
|
||||
<target>E-mail</target>
|
||||
@@ -137,6 +149,10 @@
|
||||
<source>Name</source>
|
||||
<target>Naam</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="wd1MvZW" resname="No">
|
||||
<source>No</source>
|
||||
<target>Nee</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="gefhnBC" resname="Next">
|
||||
<source>Next</source>
|
||||
<target>Volgende</target>
|
||||
@@ -161,9 +177,13 @@
|
||||
<source>Password</source>
|
||||
<target>Wachtwoord</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="VbgD9L8" resname="Please Confirm">
|
||||
<source>Please Confirm</source>
|
||||
<target>Bevestig Alsjeblieft</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="6EclFME" resname="Please Confirm your Email">
|
||||
<source>Please Confirm your Email</source>
|
||||
<target>messages</target>
|
||||
<target>Bevestig je e-mailadres alsjeblieft</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="lSX_PHJ" resname="Please sign in">
|
||||
<source>Please sign in</source>
|
||||
@@ -285,6 +305,10 @@
|
||||
<source>Time</source>
|
||||
<target>Tijd</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="pRCwpOT" resname="Yes">
|
||||
<source>Yes</source>
|
||||
<target>Ja</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="0afY1NF" resname="You have no seasons yet.">
|
||||
<source>You have no seasons yet.</source>
|
||||
<target>Je hebt nog geen seizoenen.</target>
|
||||
|
||||
Reference in New Issue
Block a user