Compare commits

..

4 Commits

Author SHA1 Message Date
Marijn d3bb8d7c57 Fix question order (#99) 2026-05-16 13:33:44 +02:00
Marijn b799dfd5e5 Remove symlink 2026-05-10 10:43:33 +02:00
Marijn 86e7d07078 Actual hotfix 2026-05-09 17:21:04 +02:00
Marijn c68e865a78 Check for excel and ignore empty cells 2026-05-09 17:11:25 +02:00
7 changed files with 46 additions and 11 deletions
+13
View File
@@ -68,6 +68,19 @@ Icon
# Thumbnails
._*
# IDEs
/.idea/
/.vscode/
# Junie
!/.junie/
/.junie/memory/
/.junie/plans/
# Windows
Thumbs.db
Desktop.ini
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
-6
View File
@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="SqlDialectMappings">
<file url="PROJECT" dialect="PostgreSQL" />
</component>
</project>
+13
View File
@@ -61,6 +61,19 @@ The project uses `just` as the primary task runner. Always prefer `just` command
- CSS/Sass is in `assets/styles/`.
- Assets are compiled on-the-fly or mapped; do not look for a `node_modules` folder.
## Key Components
### Controllers
- **Backoffice**: Located in `src/Controller/Backoffice`, handles season and quiz management.
- **Quiz**: `src/Controller/QuizController` handles the candidate-facing side of quizzes.
- **Elimination**: `src/Controller/EliminationController` handles elimination screens.
### Services
- **QuizSpreadsheetService**: Handles importing quizzes from XLSX files.
### Base Classes & Enums
- **AbstractController**: Base class for all controllers, containing common regexes and flash helpers.
- **FlashType Enum**: Used for consistent flash messaging (`FlashType::Success`, `FlashType::Danger`, etc.).
## Key Files
- `composer.json`: Dependency management.
- `importmap.php`: JavaScript module mapping.
+5
View File
@@ -8,6 +8,7 @@ use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Attribute\AsController;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Symfony\Contracts\Translation\TranslatorInterface;
use Tvdt\Enum\FlashType;
@@ -20,6 +21,10 @@ final class LoginController extends AbstractController
#[Route(path: '/login', name: 'tvdt_login_login')]
public function login(): Response
{
if ($this->getUser() instanceof UserInterface) {
return $this->redirectToRoute('tvdt_backoffice_index');
}
// get the login error if there is one
$error = $this->authenticationUtils->getLastAuthenticationError();
// last username entered by the user
@@ -15,6 +15,7 @@ use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
use SymfonyCasts\Bundle\VerifyEmail\Exception\VerifyEmailExceptionInterface;
use Tvdt\Entity\User;
@@ -30,6 +31,10 @@ final class RegistrationController extends AbstractController
public function register(
Request $request,
): Response {
if ($this->getUser() instanceof UserInterface) {
return $this->redirectToRoute('tvdt_backoffice_index');
}
$user = new User();
$form = $this->createForm(RegistrationFormType::class, $user);
$form->handleRequest($request);
+1
View File
@@ -30,6 +30,7 @@ class QuestionRepository extends ServiceEntityRepository
and q1.quiz = :quiz
)
and qz = :quiz
order by q.ordering
DQL)
->setMaxResults(1)
->setParameter('candidate', $candidate)
+9 -5
View File
@@ -95,11 +95,15 @@ class QuizSpreadsheetService
$arrCounter = 1;
while (true) {
if (null === $questionArr[$arrCounter]) {
if (1 === $answerCounter) {
$errors[] = \sprintf('Question %d has no answers', $answerCounter);
}
try {
if (null === $questionArr[$arrCounter]) {
if (1 === $answerCounter) {
$errors[] = \sprintf('Question %d has no answers', $answerCounter);
}
break;
}
} catch (\ErrorException) {
break;
}
@@ -130,6 +134,6 @@ class QuizSpreadsheetService
private function isSpreadsheetFile(File $file): bool
{
return 'xlsx' === $file->getExtension();
return 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' === $file->getMimeType();
}
}