Skip to content

Commit

Permalink
Puzzles overview page with data!
Browse files Browse the repository at this point in the history
  • Loading branch information
JanMikes committed Nov 1, 2023
1 parent 1c4aa65 commit 1d5e27e
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 1 deletion.
11 changes: 10 additions & 1 deletion src/Controller/PuzzlesController.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,25 @@

namespace SpeedPuzzling\Web\Controller;

use SpeedPuzzling\Web\Query\GetPuzzlesOverview;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

final class PuzzlesController extends AbstractController
{
public function __construct(
readonly private GetPuzzlesOverview $getPuzzlesOverview,
)
{
}

#[Route(path: '/puzzle', name: 'puzzles', methods: ['GET'])]
public function __invoke(Request $request): Response
{
return $this->render('puzzles.html.twig');
return $this->render('puzzles.html.twig', [
'puzzles' => $this->getPuzzlesOverview->all(),
]);
}
}
52 changes: 52 additions & 0 deletions src/Query/GetPuzzlesOverview.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

declare(strict_types=1);

namespace SpeedPuzzling\Web\Query;

use Doctrine\DBAL\Connection;
use SpeedPuzzling\Web\Results\PuzzleOverview;

readonly final class GetPuzzlesOverview
{
public function __construct(
private Connection $database,
) {
}

/**
* @return array<PuzzleOverview>
*/
public function all(): array
{
$query = <<<SQL
SELECT puzzle.name AS puzzle_name, puzzle.pieces_count, manufacturer.name AS manufacturer_name, AVG(puzzle_solving_time.seconds_to_solve) AS average_time, COUNT(puzzle_solving_time.id) AS solved_count, MIN(puzzle_solving_time.seconds_to_solve) AS fastest_time
FROM puzzle
LEFT JOIN puzzle_solving_time ON puzzle_solving_time.puzzle_id = puzzle.id
INNER JOIN manufacturer ON puzzle.manufacturer_id = manufacturer.id
WHERE approved = true
GROUP BY puzzle.name, puzzle.pieces_count, manufacturer.name
HAVING MIN(puzzle_solving_time.seconds_to_solve) > 0
ORDER BY puzzle.name ASC
SQL;

$data = $this->database
->executeQuery($query)
->fetchAllAssociative();

return array_map(static function(array $row): PuzzleOverview {
/**
* @var array{
* puzzle_name: string,
* manufacturer_name: string,
* pieces_count: int,
* average_time: string,
* fastest_time: int,
* solved_count: int
* } $row
*/

return PuzzleOverview::fromDatabaseRow($row);
}, $data);
}
}
40 changes: 40 additions & 0 deletions src/Results/PuzzleOverview.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

declare(strict_types=1);

namespace SpeedPuzzling\Web\Results;

readonly final class PuzzleOverview
{
public function __construct(
public string $puzzleName,
public string $manufacturerName,
public int $piecesCount,
public int $averageTime,
public int $fastestTime,
public int $solvedCount,
) {
}

/**
* @param array{
* puzzle_name: string,
* manufacturer_name: string,
* pieces_count: int,
* average_time: string,
* fastest_time: int,
* solved_count: int,
* } $row
*/
public static function fromDatabaseRow(array $row): self
{
return new self(
puzzleName: $row['puzzle_name'],
manufacturerName: $row['manufacturer_name'],
piecesCount: $row['pieces_count'],
averageTime: (int) $row['average_time'],
fastestTime: $row['fastest_time'],
solvedCount: $row['solved_count'],
);
}
}
20 changes: 20 additions & 0 deletions templates/puzzles.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,24 @@

{% block content %}
<h1>Puzzle</h1>

<div class="masonry-grid" data-columns="3">
{% for puzzle in puzzles %}
<div class="masonry-grid-item">
<div class="card border-0 shadow">
<div class="card-body">
<h5 class="card-title">{{ puzzle.puzzleName }}</h5>
<p class="card-text fs-sm text-muted">
<b>{{ puzzle.manufacturerName }}</b><br>
{{ puzzle.piecesCount }} dílků<br>
Nejrychlejší čas: {{ puzzle.fastestTime|date('H:i:s', 'UTC') }}<br>
Průměrný čas: {{ puzzle.averageTime|date('H:i:s', 'UTC') }}<br>
Počet složení: {{ puzzle.solvedCount }}
</p>
<a href="#" class="btn btn-sm btn-primary">Chci vidět časy!</a>
</div>
</div>
</div>
{% endfor %}
</div>
{% endblock %}

0 comments on commit 1d5e27e

Please sign in to comment.